[svn] commit: r1978 - in /experiments/jinmei-onmemdb/src/bin/auth: auth_srv.cc compilezone.cc rbt_datasrc.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Sat May 29 03:55:43 UTC 2010
Author: jinmei
Date: Sat May 29 03:55:43 2010
New Revision: 1978
Log:
fixed bugs in non root case
fixed bugs for larger zones
and other minor improvements
Modified:
experiments/jinmei-onmemdb/src/bin/auth/auth_srv.cc
experiments/jinmei-onmemdb/src/bin/auth/compilezone.cc
experiments/jinmei-onmemdb/src/bin/auth/rbt_datasrc.cc
Modified: experiments/jinmei-onmemdb/src/bin/auth/auth_srv.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/bin/auth/auth_srv.cc (original)
+++ experiments/jinmei-onmemdb/src/bin/auth/auth_srv.cc Sat May 29 03:55:43 2010
@@ -380,11 +380,21 @@
message.setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
if (impl_->mem_datasrc_ != NULL) {
- impl_->processRootQuery(message);
- CompressOffset* offsets = // XXX bad cast
- reinterpret_cast<CompressOffset*>(response_renderer.getArg());
- if (offsets != NULL) {
- memset(offsets, 0xff, sizeof(*offsets));
+ try {
+ impl_->processRootQuery(message);
+ CompressOffset* offsets = // XXX bad cast
+ reinterpret_cast<CompressOffset*>(response_renderer.getArg());
+ if (offsets != NULL) {
+ memset(offsets, 0xff, sizeof(*offsets));
+ }
+ } catch (const Exception& ex) {
+ if (impl_->verbose_mode_) {
+ cerr << "Internal error, returning SERVFAIL: " << ex.what()
+ << endl;
+ }
+ makeErrorMessage(message, response_renderer, Rcode::SERVFAIL(),
+ impl_->verbose_mode_);
+ return (true);
}
} else {
try {
Modified: experiments/jinmei-onmemdb/src/bin/auth/compilezone.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/bin/auth/compilezone.cc (original)
+++ experiments/jinmei-onmemdb/src/bin/auth/compilezone.cc Sat May 29 03:55:43 2010
@@ -93,6 +93,16 @@
cout << "Usage: b10-compilezone -f output_file -o origin zone_file" << endl;
exit(1);
}
+
+void
+dumpDB(const Name& origin, const char& zone_file, const char& output_file) {
+ // Phase 3: re-load the zone into the DB file.
+ RbtDataSrc* datasrc = new RbtDataSrc(origin, output_file, RbtDataSrc::LOAD);
+ loadZoneFile(&zone_file, datasrc);
+ cout << "Write load completed, data size: "
+ << datasrc->getAllocatedMemorySize() << " bytes" << endl;
+ delete datasrc;
+}
}
int
@@ -100,11 +110,27 @@
const char* output_file = NULL;
const char* origin_name = NULL;
int ch;
-
- while ((ch = getopt(argc, argv, "f:o:")) != -1) {
+ bool estimation_only = false;
+ bool dump_only = false;
+ bool check_db = false;
+ int margin = 50; // percentage of the minimal DB size to add
+
+ while ((ch = getopt(argc, argv, "cdef:m:o:")) != -1) {
switch (ch) {
+ case 'c':
+ check_db = true;
+ break;
+ case 'e':
+ estimation_only = true;
+ break;
+ case 'd':
+ dump_only = true;
+ break;
case 'f':
output_file = optarg;
+ break;
+ case 'm':
+ margin = atoi(optarg);
break;
case 'o':
origin_name = optarg;
@@ -121,20 +147,36 @@
argv += optind;
const char* const zone_file = argv[0];
+ const Name origin(origin_name);
+
+ if (dump_only) {
+ dumpDB(origin, *zone_file, *output_file);
+ return (0);
+ }
// Phase 1: load the text based zone file to estimate necessary memory
- const Name origin(origin_name);
+
RbtDataSrc* datasrc = new RbtDataSrc(origin);
loadZoneFile(zone_file, datasrc);
size_t db_memory_size = datasrc->getAllocatedMemorySize();
cout << "Zone load completed, allocated memory: " << db_memory_size
<< " bytes" << endl;
+ // Check the origin node exists:
+ RbtNode rbtnode;
+ if (datasrc->findNode(origin, &rbtnode) != RbtDataSrcSuccess) {
+ isc_throw(Exception, "Can't find the apex node. "
+ "Possibly the DB is broken.");
+ }
delete datasrc;
+
+ if (estimation_only) {
+ return (0);
+ }
// Phase 2: open the DB file, make room for the data if necessary.
// We reserve 50% larger than the estimated size with rounding it up to
// a multiple of "page size".
- db_memory_size += db_memory_size/2;
+ db_memory_size += (db_memory_size * margin) / 100;
db_memory_size = ((db_memory_size + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1)));
fstream dbfile(output_file, ios::out|ios::binary|ios::ate);
if (dbfile.is_open()) {
@@ -159,11 +201,19 @@
}
// Phase 3: re-load the zone into the DB file.
- datasrc = new RbtDataSrc(origin, *output_file, RbtDataSrc::LOAD);
- loadZoneFile(zone_file, datasrc);
- cout << "Write load completed, data size: "
- << datasrc->getAllocatedMemorySize() << " bytes" << endl;
- delete datasrc;
+ dumpDB(origin, *zone_file, *output_file);
+
+ // Phase 4 (optional): as a minimal check confirm the apex node exists.
+ if (check_db) {
+ datasrc = new RbtDataSrc(origin, *output_file, RbtDataSrc::SERVE);
+ if (datasrc->findNode(origin, &rbtnode) != RbtDataSrcSuccess) {
+ isc_throw(Exception, "Can't find the apex node. "
+ "Possibly the DB is broken");
+ }
+ cout << "Looks good: successfully found the apex node in the "
+ "generated DB" << endl;
+ delete datasrc;
+ }
return (0);
}
Modified: experiments/jinmei-onmemdb/src/bin/auth/rbt_datasrc.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/bin/auth/rbt_datasrc.cc (original)
+++ experiments/jinmei-onmemdb/src/bin/auth/rbt_datasrc.cc Sat May 29 03:55:43 2010
@@ -108,7 +108,7 @@
struct RbtDBImpl {
static const size_t ALIGNMENT_SIZE = sizeof(void*);
- enum DBType { MEMORY, FILE };
+ enum DBType { MEMORY, FILE_LOAD, FILE_SERVE };
RbtDataSrcResult addNode(const Name& name, RbtNodeImpl** nodep);
RbtNodeImplPtr createNode(const LabelSequence& sequence);
@@ -127,12 +127,18 @@
DBType dbtype_;
size_t allocated_;
void* base_;
- void* current_; // effective for the FILE mode only
- size_t dbsize_; // effective for the FILE mode only
+ void* current_; // effective for the FILE_LOAD mode only
+ size_t dbsize_; // effective for the FILE_xxx mode only
RbtNodeImplPtr root_;
unsigned int nodecount_;
RbtNodeImpl* apexnode_;
};
+
+inline size_t
+alignUp(size_t size) {
+ return ((size + RbtDBImpl::ALIGNMENT_SIZE - 1) &
+ (~(RbtDBImpl::ALIGNMENT_SIZE - 1)));
+}
class RbtNodeChain {
public:
@@ -245,7 +251,7 @@
impl_->nodecount_ = 0; // meaningless for the SERVE mode
impl_->allocated_ = 0; // ditto
- impl_->dbtype_ = RbtDBImpl::FILE;
+ impl_->dbtype_ = mode == LOAD ? RbtDBImpl::FILE_LOAD : RbtDBImpl::FILE_SERVE;
int fd = open(&dbfile, O_RDWR);
if (fd < 0) {
@@ -256,20 +262,29 @@
read(fd, &dbsize, sizeof(dbsize));
impl_->dbsize_ = (size_t)dbsize;
if (mode == LOAD) {
- impl_->base_ = mmap(NULL, impl_->dbsize_,
- PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0);
+
+ impl_->base_ = mmap(NULL, impl_->dbsize_, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, fd, 0);
if (impl_->base_ == MAP_FAILED) {
close(dbfile);
isc_throw(Exception, "mmap for write failed: " <<
string(strerror(errno)));
}
close(dbfile);
+
+ // In this very simple implementation, "header" is the 64-bit DB size
+ // field followed by an offset pointer to the root node.
+ size_t header_size = sizeof(dbsize) + alignUp(sizeof(impl_->root_));
+
uintptr_t headptr = reinterpret_cast<uintptr_t>(impl_->base_);
- impl_->current_ = reinterpret_cast<void*>(headptr + sizeof(dbsize));
+ impl_->current_ = reinterpret_cast<void*>(headptr + header_size);
impl_->root_ = RbtNodeImplPtr();
impl_->apexnode_ = NULL;
RbtDataSrcResult result = impl_->addNode(origin, &impl_->apexnode_);
- assert(result == RbtDataSrcSuccess); // XXX assert is a bad choice here.
+ if (result != RbtDataSrcSuccess) {
+ munmap(impl_->base_, impl_->dbsize_);
+ isc_throw(Exception, "Failed to add the apexnode: " << result);
+ }
} else {
impl_->base_ = mmap(NULL, impl_->dbsize_,
PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
@@ -281,18 +296,29 @@
close(dbfile);
impl_->current_ = impl_->base_; // unused
uintptr_t headptr = reinterpret_cast<uintptr_t>(impl_->base_);
- impl_->root_ = RbtNodeImplPtr(
- reinterpret_cast<RbtNodeImpl*>(headptr + sizeof(dbsize)),
- impl_->base_);
+ memcpy(&impl_->root_,
+ reinterpret_cast<const void*>(headptr + sizeof(dbsize)),
+ sizeof(impl_->root_));
impl_->apexnode_ = NULL;
RbtDataSrcResult result = impl_->findNode(origin, &impl_->apexnode_);
- assert(result == RbtDataSrcSuccess);
- }
-
+ if (result != RbtDataSrcSuccess) {
+ munmap(impl_->base_, impl_->dbsize_);
+ isc_throw(Exception, "Unexpected result for apexnode: " << result);
+ }
+ }
}
RbtDataSrc::~RbtDataSrc() {
- if (impl_->dbtype_ == RbtDBImpl::FILE) {
+ if (impl_->dbtype_ == RbtDBImpl::FILE_LOAD) {
+ // copy the offset pointer to the root node into the "header".
+ memcpy(reinterpret_cast<char*>(impl_->base_) + sizeof(uint64_t),
+ &impl_->root_, sizeof(impl_->root_));
+
+ // XXX: should check the return values of the following
+ msync(impl_->base_, impl_->dbsize_, MS_SYNC);
+ }
+ if (impl_->dbtype_ == RbtDBImpl::FILE_LOAD ||
+ impl_->dbtype_ == RbtDBImpl::FILE_SERVE) {
munmap(impl_->base_, impl_->dbsize_);
}
delete impl_;
@@ -322,17 +348,18 @@
void *
RbtDBImpl::allocateRegion(const size_t size) {
void* ret;
- const size_t alloc_size = ((size + ALIGNMENT_SIZE - 1) &
- (~(ALIGNMENT_SIZE - 1)));
- if (dbtype_ == FILE) {
+ const size_t alloc_size = alignUp(size);
+ if (dbtype_ == FILE_LOAD) {
uintptr_t curptr = reinterpret_cast<uintptr_t>(current_);
uintptr_t baseptr = reinterpret_cast<uintptr_t>(base_);
assert(curptr - baseptr + alloc_size <= dbsize_); // XXX
ret = current_;
current_ = reinterpret_cast<void*>(
reinterpret_cast<uintptr_t>(current_) + alloc_size);
+ } else if (dbtype_ == MEMORY) {
+ ret = new char[size];
} else {
- ret = new char[size];
+ isc_throw(Exception, "memory allocation required for read-only DB");
}
allocated_ += alloc_size;
@@ -1098,20 +1125,23 @@
return;
}
- uint16_t offset;
+ uint16_t offset = 0xffff;
assert(node->getIndex() < CompressOffset::MAXNODES); // XXX
while (!node->isAbsolute() &&
(offset = offsets->offsets[node->getIndex()]) == 0xffff) {
offsets->offsets[node->getIndex()] = renderer.getLength();
- renderer.writeData(node->getNameData(base) + 1,
- node->getNameLen()); // exclude the end dot
+ renderer.writeData(node->getNameData(base) + 1, node->getNameLen());
node = node->findUp(base);
}
if (node->isAbsolute()) {
offsets->offsets[node->getIndex()] = renderer.getLength();
renderer.writeData(node->getNameData(base) + 1, node->getNameLen());
} else {
- assert(offset != 0xffff);
+ if (offset == 0xffff || offset < 12) {
+ isc_throw(Exception, "invalid offset found in renderName: "
+ << offset << " node index: " << node->getIndex()
+ << " name: " << node->nodeNameToText(base));
+ }
renderer.writeUint16(Name::COMPRESS_POINTER_MARK16 | offset);
}
}
More information about the bind10-changes
mailing list