[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