]> arthur.barton.de Git - netatalk.git/commitdiff
Version check for CNID db version
authorFrank Lahm <franklahm@googlemail.com>
Mon, 22 Nov 2010 16:14:44 +0000 (17:14 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Mon, 22 Nov 2010 16:14:44 +0000 (17:14 +0100)
etc/cnid_dbd/dbd_add.c
etc/cnid_dbd/dbif.c
libatalk/cnid/cdb/cnid_cdb_open.c

index 41de278d2b67553825a88a00edc2dd21ca764e96..ce7bcf1b0bd2de14fce5f9c3c1f6a053108b3ef3 100644 (file)
@@ -83,22 +83,32 @@ int add_cnid(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
 int get_cnid(DBD *dbd, struct cnid_dbd_rply *rply)
 {
     static cnid_t id;
+    static char buf[ROOTINFO_DATALEN];
     DBT rootinfo_key, rootinfo_data;
     int rc;
     cnid_t hint;
-     
-    if (id == 0) {
-        memset(&rootinfo_key, 0, sizeof(rootinfo_key));
-        memset(&rootinfo_data, 0, sizeof(rootinfo_data));
-        rootinfo_key.data = ROOTINFO_KEY;
-        rootinfo_key.size = ROOTINFO_KEYLEN;
 
-        if ((rc = dbif_get(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0)) <= 0) {
+    memset(&rootinfo_key, 0, sizeof(rootinfo_key));
+    memset(&rootinfo_data, 0, sizeof(rootinfo_data));
+    rootinfo_key.data = ROOTINFO_KEY;
+    rootinfo_key.size = ROOTINFO_KEYLEN;
+
+    if (id == 0) {
+        if ((rc = dbif_get(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0)) < 0) {
             rply->result = CNID_DBD_RES_ERR_DB;
             return -1;
         }
-        memcpy(&hint, (char *)rootinfo_data.data +CNID_TYPE_OFS, sizeof(hint));
-        id = ntohl(hint);
+        if (rc == 0) {
+            /* no rootinfo key yet */
+            memcpy(buf, ROOTINFO_DATA, ROOTINFO_DATALEN);
+            id = CNID_START - 1;
+        } else {
+            memcpy(buf, (char *)rootinfo_data.data, ROOTINFO_DATALEN);
+            memcpy(&hint, buf + CNID_TYPE_OFS, sizeof(hint));
+            id = ntohl(hint);
+            if (id < CNID_START - 1)
+                id = CNID_START - 1;
+        }
     }
 
     /* If we've hit the max CNID allowed, we return an error. CNID
@@ -108,9 +118,10 @@ int get_cnid(DBD *dbd, struct cnid_dbd_rply *rply)
         return -1;
     }
 
+    rootinfo_data.data = buf;
     rootinfo_data.size = ROOTINFO_DATALEN;
     hint = htonl(id);
-    memcpy((char *)rootinfo_data.data + CNID_TYPE_OFS, &hint, sizeof(hint));
+    memcpy(buf + CNID_TYPE_OFS, &hint, sizeof(hint));
 
     if (dbif_put(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0) < 0) {
         rply->result = CNID_DBD_RES_ERR_DB;
index 6a11d359e250269402a17f24a4fbaa206abc5fd8..22d9a2cfde92bcbd2edfe2cec2c8293735da8e35 100644 (file)
@@ -530,13 +530,16 @@ int dbif_open(DBD *dbd, struct db_param *dbp, int reindex)
 
     if (reindex)
         LOG(log_info, logtype_cnid, "Reindexing name index...");
+    int version = dbif_getversion(dbd);
+    if (version == -1)
+        return -1;
     if ((ret = dbd->db_table[0].db->associate(dbd->db_table[0].db, 
                                               dbd->db_txn,
                                               dbd->db_table[DBIF_IDX_NAME].db, 
                                               idxname,
                                               (reindex
                                                || 
-                                               ((CNID_VERSION == CNID_VERSION_1) && (dbif_getversion(dbd) == CNID_VERSION_0)))
+                                               ((CNID_VERSION == CNID_VERSION_1) && (version == CNID_VERSION_0)))
                                               ? DB_CREATE : 0)) != 0) {
         LOG(log_error, logtype_cnid, "Failed to associate name index: %s", db_strerror(ret));
         return -1;
@@ -779,7 +782,7 @@ int dbif_del(DBD *dbd, const int dbi, DBT *key, u_int32_t flags)
 }
 
 /*!
- * Return CNID database version number
+ * Initialize or return CNID database version number
  * @returns -1 on error, version number otherwise
  */
 int dbif_getversion(DBD *dbd)
@@ -794,15 +797,19 @@ int dbif_getversion(DBD *dbd)
     key.size = ROOTINFO_KEYLEN;
 
     switch (dbif_get(dbd, DBIF_CNID, &key, &data, 0)) {
-    case 1:
+    case 1: /* found */
         memcpy(&version, (char *)data.data + CNID_DID_OFS, sizeof(version));
         version = ntohl(version);
         LOG(log_debug, logtype_cnid, "CNID database version %u", version);
         ret = version;
         break;
-    default:
-        ret = -1;
+    case 0: /* not found */
+        if (dbif_setversion(dbd, CNID_VERSION) != 0)
+            return -1;
+        ret = CNID_VERSION;
         break;
+    default:
+        return -1;
     }
     return ret;
 }
@@ -813,8 +820,12 @@ int dbif_getversion(DBD *dbd)
  */
 int dbif_setversion(DBD *dbd, int version)
 {
+    int ret;
     DBT key, data;
     uint32_t v;
+    char buf[ROOTINFO_DATALEN];
+
+    LOG(log_debug, logtype_cnid, "Setting CNID database version to %u", version);
 
     v = version;
     v = htonl(v);
@@ -824,13 +835,12 @@ int dbif_setversion(DBD *dbd, int version)
     key.data = ROOTINFO_KEY;
     key.size = ROOTINFO_KEYLEN;
 
-    switch (dbif_get(dbd, DBIF_CNID, &key, &data, 0)) {
-    case 1:
-        break;
-    default:
+    if ((ret = dbif_get(dbd, DBIF_CNID, &key, &data, 0)) == -1)
         return -1;
+    if (ret == 0) {
+        memcpy(buf, ROOTINFO_DATA, ROOTINFO_DATALEN);
+        data.data = buf;
     }
-
     memcpy((char *)data.data + CNID_DID_OFS, &v, sizeof(v));
     data.size = ROOTINFO_DATALEN;
     if (dbif_put(dbd, DBIF_CNID, &key, &data, 0) < 0)
index bf501fd5e9e52aa5bcc9fd7c85314771b5379307..10ecc78d8c34efaf51365820954b1ff5d06c0f6a 100644 (file)
@@ -1,7 +1,4 @@
 /*
-
- * $Id: cnid_cdb_open.c,v 1.5 2010-03-31 09:47:32 franklahm Exp $
- *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
  *
@@ -40,6 +37,8 @@
 #endif /* HAVE_CONFIG_H */
 
 #ifdef CNID_BACKEND_CDB
+
+#include <atalk/cnid_private.h>
 #include "cnid_cdb_private.h"
 
 #ifndef MIN
 #define DBHOMELEN    8
 #define DBLEN        10
 
-/* we version the did/name database so that we can change the format
- * if necessary. the key is in the form of a did/name pair. in this case,
- * we use 0/0. */
-#define DBVERSION_KEY    "\0\0\0\0\0"
-#define DBVERSION_KEYLEN 5
-#define DBVERSION1       0x00000001U
-#define DBVERSION        DBVERSION1
-
 #define DBOPTIONS    (DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL)
 
 #define MAXITER     0xFFFF      /* maximum number of simultaneously open CNID
@@ -355,42 +346,27 @@ struct _cnid_db *cnid_cdb_open(struct cnid_open_args *args)
         goto fail_appinit;
     }
  
-#if 0
-    DBT key, pkey, data;
     /* ---------------------- */
-    /* Check for version.  This way we can update the database if we need
-     * to change the format in any way. */
-    memset(&key, 0, sizeof(key));
-    memset(&pkey, 0, sizeof(DBT));
-    memset(&data, 0, sizeof(data));
-    key.data = DBVERSION_KEY;
-    key.size = DBVERSION_KEYLEN;
+    /* Check for version. "cdb" only supports CNID_VERSION_0, cf cnid_private.h */
 
-    if ((rc = db->db_didname->pget(db->db_didname, NULL, &key, &pkey, &data, 0)) != 0) {
-        int ret;
-        {
-            u_int32_t version = htonl(DBVERSION);
+    DBT key, data;
+    uint32_t version;
 
-            data.data = &version;
-            data.size = sizeof(version);
-        }
-        if ((ret = db->db_didname->put(db->db_cnid, NULL, &key, &data,
-                                       DB_NOOVERWRITE))) {
-            LOG(log_error, logtype_default, "cnid_open: Error putting new version: %s",
-                db_strerror(ret));
-            db->db_didname->close(db->db_didname, 0);
+    memset(&key, 0, sizeof(key));
+    memset(&data, 0, sizeof(data));
+    key.data = ROOTINFO_KEY;
+    key.size = ROOTINFO_KEYLEN;
+
+    if ((rc = db->db_cnid->get(db->db_cnid, NULL, &key, &data, 0)) == 0) {
+        /* If not found, ignore it */
+        memcpy(&version, data.data + CNID_DID_OFS, sizeof(version));
+        version = ntohl(version);
+        LOG(log_debug, logtype_default, "CNID db version %u", version);
+        if (version != CNID_VERSION_0) {
+            LOG(log_error, logtype_default, "Unsupported CNID db version %u, use CNID backend \"dbd\"", version);
             goto fail_appinit;
         }
     }
-#endif
-
-    /* TODO In the future we might check for version number here. */
-#if 0
-    memcpy(&version, data.data, sizeof(version));
-    if (version != ntohl(DBVERSION)) {
-        /* Do stuff here. */
-    }
-#endif /* 0 */
 
     db_env_set_func_yield(my_yield);
     return cdb;