From: jmarcus Date: Fri, 30 Aug 2002 03:12:45 +0000 (+0000) Subject: Introduce Conncurrent Data Store (CDB) support to CNID. This is phase 1. X-Git-Tag: point-did-cleanup~36 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=7c563936748fcb1d7bd32d87d905175e0602d8ae Introduce Conncurrent Data Store (CDB) support to CNID. This is phase 1. In this phase, CDB is a configure option, and is either enabled or disabled for all volumes at compile time. By default, CDB is disabled in favor of transactional data store. CDB has some advantages. It doesn't use transactions or logging, thus it's less likely to be corrupted if the server dies prematurely. It also doesn't eat up disk space with transaction logs. The disadvantage is that it's designed for environments with many readers and one writer. This means that many afpd clients could block while waiting for a write lock on the database. That's why testing is in order. In phase 2, CDB is be configurable on a per-volume basis. Phase 3 (if testing of phase 1 and 2 is good) will be to enable CDB as the default CNID data store scheme. To enable CDB, simply specify the configure argument --with-cdb when configuring with CNID DID support. Submitted by: Dan Wilga --- diff --git a/NEWS b/NEWS index 876e283c..b33a48fd 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ Changes from 1.5.3 * NEW: Add a -noslp option to disable SLP per afpd instance. * NEW: Added -d option for pap to enable debugging at runtime rather than compile time. +* NEW: Add the ability to use Concurrent Data Store instead of full + transactional data store with the CNID DID calculation scheme. * FIX: Cleaned up pap man page, eliminating duplicate pap man page (8). * FIX: Print out pap status in postscript (%%[..]%%) format for LPRng compatibility. diff --git a/acconfig.h b/acconfig.h index e7e4ec1b..07559934 100644 --- a/acconfig.h +++ b/acconfig.h @@ -6,6 +6,7 @@ #undef BSD4_4 #undef CNID_DB #undef FILE_MANGLING +#undef CNID_DB_CDB #undef DISABLE_LOGGER #undef LOGFILEPATH #undef DEBUG diff --git a/configure.in b/configure.in index f7c6cdbd..2f8eb9e5 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -dnl $Id: configure.in,v 1.161 2002-08-25 13:26:19 rlewczuk Exp $ +dnl $Id: configure.in,v 1.162 2002-08-30 03:12:45 jmarcus Exp $ dnl configure.in for netatalk AC_INIT(bin/adv1tov2/adv1tov2.c) @@ -244,7 +244,27 @@ AC_ARG_WITH(mangling, AC_DEFINE(FILE_MANGLING, 1) AC_MSG_RESULT([yes]) fi + else + AC_MSG_RESULT([no]) + fi + , AC_MSG_RESULT([no]) +) + +dnl Determine whether or not to use CDB or transactional DB store +AC_MSG_CHECKING([whether or not to use CNID with Concurrent Data Store]) +AC_ARG_WITH(cdb, + [ --with-cdb enable CNID with Concurrent Data Store], + if test "$withval" = "yes"; then + if test "x$did_scheme" != "xcnid"; then + AC_MSG_ERROR([DID scheme must be CNID to use CDB]) + else + AC_DEFINE(CNID_DB_CDB, 1) + AC_MSG_RESULT([yes]) + fi + else + AC_MSG_RESULT([no]) fi + , AC_MSG_RESULT([no]) ) dnl Check for Berkeley DB3 library diff --git a/libatalk/cnid/cnid_add.c b/libatalk/cnid/cnid_add.c index 816008ec..21281b37 100644 --- a/libatalk/cnid/cnid_add.c +++ b/libatalk/cnid/cnid_add.c @@ -1,5 +1,5 @@ /* - * $Id: cnid_add.c,v 1.29 2002-02-02 19:11:37 jmarcus Exp $ + * $Id: cnid_add.c,v 1.30 2002-08-30 03:12:52 jmarcus Exp $ * * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT. @@ -39,29 +39,39 @@ #include "cnid_private.h" +#ifdef CNID_DB_CDB + #define tid NULL +#endif /* CNID_DB_CDB */ + /* add an entry to the CNID databases. we do this as a transaction * to prevent messiness. */ static int add_cnid(CNID_private *db, DBT *key, DBT *data) { DBT altkey, altdata; +#ifndef CNID_DB_CDB DB_TXN *tid; +#endif /* CNID_DB_CDB */ int rc, ret; memset(&altkey, 0, sizeof(altkey)); memset(&altdata, 0, sizeof(altdata)); +#ifndef CNID_DB_CDB retry: if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) { return rc; } +#endif /* CNID_DB_CDB */ /* main database */ if ((rc = db->db_cnid->put(db->db_cnid, tid, key, data, DB_NOOVERWRITE))) { +#ifndef CNID_DB_CDB if (rc == DB_LOCK_DEADLOCK) { if ((ret = txn_abort(tid)) != 0) { return ret; } goto retry; } +#endif /* CNID_DB_CDB */ goto abort; } @@ -71,12 +81,14 @@ retry: altdata.data = key->data; altdata.size = key->size; if ((rc = db->db_devino->put(db->db_devino, tid, &altkey, &altdata, 0))) { +#ifndef CNID_DB_CDB if (rc == DB_LOCK_DEADLOCK) { if ((ret = txn_abort(tid)) != 0) { return ret; } goto retry; } +#endif /* CNID_DB_CDB */ goto abort; } @@ -84,19 +96,23 @@ retry: altkey.data = (char *) data->data + CNID_DEVINO_LEN; altkey.size = data->size - CNID_DEVINO_LEN; if ((rc = db->db_didname->put(db->db_didname, tid, &altkey, &altdata, 0))) { +#ifndef CNID_DB_CDB if (rc == DB_LOCK_DEADLOCK) { if ((ret = txn_abort(tid)) != 0) { return ret; } goto retry; } +#endif /* CNID_DB_CDB */ goto abort; } +#ifndef CNID_DB_CDB if ((rc = txn_commit(tid, 0)) != 0) { LOG(log_error, logtype_default, "add_cnid: Failed to commit transaction: %s", db_strerror(rc)); return rc; } +#endif /* CNID_DB_CDB */ return 0; @@ -113,7 +129,9 @@ cnid_t cnid_add(void *CNID, const struct stat *st, { CNID_private *db; DBT key, data, rootinfo_key, rootinfo_data; +#ifndef CNID_DB_CDB DB_TXN *tid; +#endif /* CNID_DB_CDB */ struct timeval t; cnid_t id, save; int rc; @@ -175,14 +193,20 @@ cnid_t cnid_add(void *CNID, const struct stat *st, rootinfo_key.data = ROOTINFO_KEY; rootinfo_key.size = ROOTINFO_KEYLEN; +#ifndef CNID_DB_CDB retry: if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) { LOG(log_error, logtype_default, "cnid_add: Failed to begin transaction: %s", db_strerror(rc)); errno = CNID_ERR_DB; return CNID_INVALID; } +#endif /* CNID_DB_CDB */ /* Get the key. */ +#ifdef CNID_DB_CDB + switch (rc = db->db_didname->get(db->db_didname, NULL, &rootinfo_key, + &rootinfo_data, 0)) { +#else /* CNID_DB_CDB */ switch (rc = db->db_didname->get(db->db_didname, tid, &rootinfo_key, &rootinfo_data, DB_RMW)) { case DB_LOCK_DEADLOCK: @@ -192,13 +216,16 @@ retry: return CNID_INVALID; } goto retry; +#endif /* CNID_DB_CDB */ case 0: memcpy(&hint, rootinfo_data.data, sizeof(hint)); id = ntohl(hint); /* If we've hit the max CNID allowed, we return a fatal error. CNID * needs to be recycled before proceding. */ if (++id == CNID_INVALID) { +#ifndef CNID_DB_CDB txn_abort(tid); +#endif /* CNID_DB_CDB */ LOG(log_error, logtype_default, "cnid_add: FATAL: Cannot add CNID for %s. CNID database has reached its limit.", name); errno = CNID_ERR_MAX; return CNID_INVALID; @@ -223,6 +250,7 @@ retry: rootinfo_data.size = sizeof(hint); switch (rc = db->db_didname->put(db->db_didname, tid, &rootinfo_key, &rootinfo_data, 0)) { +#ifndef CNID_DB_CDB case DB_LOCK_DEADLOCK: if ((rc = txn_abort(tid)) != 0) { LOG(log_error, logtype_default, "cnid_add: txn_abort: %s", db_strerror(rc)); @@ -230,13 +258,16 @@ retry: return CNID_INVALID; } goto retry; +#endif /* CNID_DB_CDB */ case 0: +#ifndef CNID_DB_CDB /* The transaction finished, commit it. */ if ((rc = txn_commit(tid, 0)) != 0) { LOG(log_error, logtype_default, "cnid_add: Unable to commit transaction: %s", db_strerror(rc)); errno = CNID_ERR_DB; return CNID_INVALID; } +#endif /* CNID_DB_CDB */ break; default: LOG(log_error, logtype_default, "cnid_add: Unable to update rootinfo: %s", db_strerror(rc)); @@ -258,7 +289,9 @@ retry: return hint; cleanup_abort: +#ifndef CNID_DB_CDB txn_abort(tid); +#endif /* CNID_DB_CDB */ errno = CNID_ERR_DB; return CNID_INVALID; diff --git a/libatalk/cnid/cnid_close.c b/libatalk/cnid/cnid_close.c index 2b76285a..621df818 100644 --- a/libatalk/cnid/cnid_close.c +++ b/libatalk/cnid/cnid_close.c @@ -1,5 +1,5 @@ /* - * $Id: cnid_close.c,v 1.24 2002-06-03 22:58:10 jmarcus Exp $ + * $Id: cnid_close.c,v 1.25 2002-08-30 03:12:52 jmarcus Exp $ */ #ifdef HAVE_CONFIG_H @@ -31,6 +31,7 @@ void cnid_close(void *CNID) { return; } +#ifndef CNID_DB_CDB /* Flush the transaction log and delete the log file if we can. */ if ((db->lockfd > -1) && ((db->flags & CNIDFLAG_DB_RO) == 0)) { struct flock lock; @@ -81,6 +82,7 @@ void cnid_close(void *CNID) { } (void)remove(db->lock_file); } +#endif /* CNID_DB_CDB */ db->db_didname->close(db->db_didname, 0); db->db_devino->close(db->db_devino, 0); @@ -90,9 +92,11 @@ void cnid_close(void *CNID) { #endif /* FILE_MANGLING */ db->dbenv->close(db->dbenv, 0); +#ifndef CNID_DB_CDB if (db->lockfd > -1) { close(db->lockfd); /* This will also release any locks we have. */ } +#endif /* CNID_DB_CDB */ free(db); } diff --git a/libatalk/cnid/cnid_delete.c b/libatalk/cnid/cnid_delete.c index e01beab0..1b0d36d9 100644 --- a/libatalk/cnid/cnid_delete.c +++ b/libatalk/cnid/cnid_delete.c @@ -1,5 +1,5 @@ /* - * $Id: cnid_delete.c,v 1.13 2002-01-19 21:42:08 jmarcus Exp $ + * $Id: cnid_delete.c,v 1.14 2002-08-30 03:12:52 jmarcus Exp $ * * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT. @@ -24,10 +24,16 @@ #include "cnid_private.h" +#ifdef CNID_DB_CDB + #define tid NULL +#endif /* CNID_DB_CDB */ + int cnid_delete(void *CNID, const cnid_t id) { CNID_private *db; DBT key, data; +#ifndef CNID_DB_CDB DB_TXN *tid; +#endif /* CNID_DB_CDB */ int rc, found = 0; if (!(db = CNID) || !id || (db->flags & CNIDFLAG_DB_RO)) { @@ -46,8 +52,10 @@ int cnid_delete(void *CNID, const cnid_t id) { case 0: found = 1; break; +#ifndef CNID_DB_CDB case DB_LOCK_DEADLOCK: break; +#endif /* CNID_DB_CDB */ case DB_NOTFOUND: #ifdef DEBUG LOG(log_info, logtype_default, "cnid_delete: CNID %u not in database", @@ -61,17 +69,20 @@ int cnid_delete(void *CNID, const cnid_t id) { } } +#ifndef CNID_DB_CDB retry: if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) { LOG(log_error, logtype_default, "cnid_delete: Failed to begin transaction: %s", db_strerror(rc)); return rc; } +#endif /* CNID_DB_CDB */ /* Now delete from the main CNID database. */ key.data = (cnid_t *)&id; key.size = sizeof(id); if ((rc = db->db_cnid->del(db->db_cnid, tid, &key, 0))) { +#ifndef CNID_DB_CDB int ret; if ((ret = txn_abort(tid)) != 0) { LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s", db_strerror(ret)); @@ -81,8 +92,11 @@ retry: case DB_LOCK_DEADLOCK: goto retry; default: +#endif /* CNID_DB_CDB */ goto abort_err; +#ifndef CNID_DB_CDB } +#endif /* CNID_DB_CDB */ } /* Now delete from dev/ino database. */ @@ -90,6 +104,7 @@ retry: key.size = CNID_DEVINO_LEN; if ((rc = db->db_devino->del(db->db_devino, tid, &key, 0))) { switch (rc) { +#ifndef CNID_DB_CDB case DB_LOCK_DEADLOCK: if ((rc = txn_abort(tid)) != 0) { LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s", @@ -97,15 +112,18 @@ retry: return rc; } goto retry; +#endif /* CNID_DB_CDB */ case DB_NOTFOUND: /* Quietly fall through if the entry isn't found. */ break; default: +#ifndef CNID_DB_CDB if ((rc = txn_abort(tid)) != 0) { LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s", db_strerror(rc)); return rc; } +#endif /* CNID_DB_CDB */ goto abort_err; } } @@ -116,6 +134,7 @@ retry: key.size = data.size - CNID_DEVINO_LEN; if ((rc = db->db_didname->del(db->db_didname, tid, &key, 0))) { switch (rc) { +#ifndef CNID_DB_CDB case DB_LOCK_DEADLOCK: if ((rc = txn_abort(tid)) != 0) { LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s", @@ -123,14 +142,17 @@ retry: return rc; } goto retry; +#endif /* CNID_DB_CDB */ case DB_NOTFOUND: break; default: +#ifndef CNID_DB_CDB if ((rc = txn_abort(tid)) != 0) { LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s", db_strerror(rc)); return rc; } +#endif /* CNID_DB_CDB */ goto abort_err; } } @@ -138,11 +160,13 @@ retry: #ifdef DEBUG LOG(log_info, logtype_default, "cnid_delete: Deleting CNID %u", ntohl(id)); #endif +#ifndef CNID_DB_CDB if ((rc = txn_commit(tid, 0)) != 0) { LOG(log_error, logtype_default, "cnid_delete: Failed to commit transaction: %s", db_strerror(rc)); return rc; } +#endif /* CNID_DB_CDB */ return 0; abort_err: diff --git a/libatalk/cnid/cnid_get.c b/libatalk/cnid/cnid_get.c index 018fe1a3..ffb7b0d2 100644 --- a/libatalk/cnid/cnid_get.c +++ b/libatalk/cnid/cnid_get.c @@ -1,5 +1,5 @@ /* - * $Id: cnid_get.c,v 1.12 2002-01-19 21:42:08 jmarcus Exp $ + * $Id: cnid_get.c,v 1.13 2002-08-30 03:12:52 jmarcus Exp $ */ #ifdef HAVE_CONFIG_H @@ -47,9 +47,11 @@ cnid_t cnid_get(void *CNID, const cnid_t did, const char *name, key.size = CNID_DID_LEN + len + 1; while ((rc = db->db_didname->get(db->db_didname, NULL, &key, &data, 0))) { +#ifndef CNID_DB_CDB if (rc == DB_LOCK_DEADLOCK) { continue; } +#endif /* CNID_DB_CDB */ if (rc != DB_NOTFOUND) { LOG(log_error, logtype_default, "cnid_get: Unable to get CNID %u, name %s: %s", diff --git a/libatalk/cnid/cnid_lookup.c b/libatalk/cnid/cnid_lookup.c index 99e453de..7a6e3adc 100644 --- a/libatalk/cnid/cnid_lookup.c +++ b/libatalk/cnid/cnid_lookup.c @@ -1,5 +1,5 @@ /* - * $Id: cnid_lookup.c,v 1.13 2002-06-03 22:58:10 jmarcus Exp $ + * $Id: cnid_lookup.c,v 1.14 2002-08-30 03:12:52 jmarcus Exp $ */ #ifdef HAVE_CONFIG_H @@ -40,6 +40,7 @@ cnid_t cnid_lookup(void *CNID, const struct stat *st, const cnid_t did, return 0; } +#ifndef CNID_DB_CDB /* Do a little checkpointing if necessary. I stuck it here as cnid_lookup * gets called when we do directory lookups. Only do this if we're using * a read-write database. */ @@ -61,6 +62,7 @@ cnid_t cnid_lookup(void *CNID, const struct stat *st, const cnid_t did, return 0; } } +#endif /* CNID_DB_CDB */ if ((buf = make_cnid_data(st, did, name, len)) == NULL) { LOG(log_error, logtype_default, "cnid_lookup: Pathname is too long"); @@ -76,9 +78,11 @@ cnid_t cnid_lookup(void *CNID, const struct stat *st, const cnid_t did, key.data = buf; key.size = CNID_DEVINO_LEN; while ((rc = db->db_devino->get(db->db_devino, NULL, &key, &devdata, 0))) { +#ifndef CNID_DB_CDB if (rc == DB_LOCK_DEADLOCK) { continue; } +#endif /* CNID_DB_CDB */ if (rc == DB_NOTFOUND) { devino = 0; @@ -94,9 +98,11 @@ cnid_t cnid_lookup(void *CNID, const struct stat *st, const cnid_t did, key.data = buf + CNID_DEVINO_LEN; key.size = CNID_DID_LEN + len + 1; while ((rc = db->db_didname->get(db->db_didname, NULL, &key, &diddata, 0))) { +#ifndef CNID_DB_CDB if (rc == DB_LOCK_DEADLOCK) { continue; } +#endif /* CNID_DB_CDB */ if (rc == DB_NOTFOUND) { didname = 0; diff --git a/libatalk/cnid/cnid_mangle_add.c b/libatalk/cnid/cnid_mangle_add.c index be9c5553..80336d0e 100644 --- a/libatalk/cnid/cnid_mangle_add.c +++ b/libatalk/cnid/cnid_mangle_add.c @@ -1,5 +1,5 @@ /* - * $Id: cnid_mangle_add.c,v 1.3 2002-06-03 22:55:31 jmarcus Exp $ + * $Id: cnid_mangle_add.c,v 1.4 2002-08-30 03:12:52 jmarcus Exp $ */ #ifdef HAVE_CONFIG_H @@ -22,13 +22,19 @@ #include "cnid_private.h" +#ifdef CNID_DB_CDB + #define tid NULL +#endif /* CNID_DB_CDB */ + /* Add a mangled filename. */ int cnid_mangle_add(void *CNID, char *mfilename, char *filename) { CNID_private *db; DBT key, data; +#ifndef CNID_DB_CDB DB_TXN *tid; +#endif /* CNID_DB_CDB */ cnid_t id; int rc, ret; @@ -44,30 +50,38 @@ cnid_mangle_add(void *CNID, char *mfilename, char *filename) data.data = filename; data.size = strlen(filename) + 1; +#ifndef CNID_DB_CDB retry: if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) { - LOG(log_error, logtype_default, "cnid_mangle_add: Failed to begin transaction: %s", db_strerror(rc)); - return -1; + LOG(log_error, logtype_default, "cnid_mangle_add: Failed to begin transaction: %s", db_strerror(rc)); + return -1; } +#endif /* CNID_DB_CDB */ if ((rc = db->db_mangle->put(db->db_mangle, tid, &key, &data, 0))) { - if ((ret = txn_abort(tid)) != 0) { - LOG(log_error, logtype_default, "cnid_mangle_add: txn_abort: %s", db_strerror(ret)); - return -1; - } - switch (rc) { - case DB_LOCK_DEADLOCK: - goto retry; - default: - LOG(log_error, logtype_default, "cnid_mangle_add: Failed to add mangled filename to the database: %s", db_strerror(rc)); - return -1; - } +#ifndef CNID_DB_CDB + if ((ret = txn_abort(tid)) != 0) { + LOG(log_error, logtype_default, "cnid_mangle_add: txn_abort: %s", db_strerror(ret)); + return -1; + } +#endif /* CNID_DB_CDB */ + switch (rc) { +#ifndef CNID_DB_CDB + case DB_LOCK_DEADLOCK: + goto retry; +#endif /* CNID_DB_CDB */ + default: + LOG(log_error, logtype_default, "cnid_mangle_add: Failed to add mangled filename to the database: %s", db_strerror(rc)); + return -1; + } } +#ifndef CNID_DB_CDB if ((rc = txn_commit(tid, 0)) != 0) { - LOG(log_error, logtype_default, "cnid_mangle_add: Unable to commit transaction: %s", db_strerror(rc)); - return -1; + LOG(log_error, logtype_default, "cnid_mangle_add: Unable to commit transaction: %s", db_strerror(rc)); + return -1; } +#endif /* CNID_DB_CDB */ return 0; } diff --git a/libatalk/cnid/cnid_mangle_get.c b/libatalk/cnid/cnid_mangle_get.c index 0a2908dc..2679a26a 100644 --- a/libatalk/cnid/cnid_mangle_get.c +++ b/libatalk/cnid/cnid_mangle_get.c @@ -1,5 +1,5 @@ /* - * $Id: cnid_mangle_get.c,v 1.5 2002-06-09 07:15:58 jmarcus Exp $ + * $Id: cnid_mangle_get.c,v 1.6 2002-08-30 03:12:52 jmarcus Exp $ */ #ifdef HAVE_CONFIG_H @@ -28,7 +28,6 @@ cnid_mangle_get(void *CNID, char *mfilename) { CNID_private *db; DBT key, data; - DB_TXN *tid; cnid_t id; struct stat st; char *filename; diff --git a/libatalk/cnid/cnid_open.c b/libatalk/cnid/cnid_open.c index 3d8b5fee..310ebbee 100644 --- a/libatalk/cnid/cnid_open.c +++ b/libatalk/cnid/cnid_open.c @@ -1,5 +1,5 @@ /* - * $Id: cnid_open.c,v 1.41 2002-06-03 22:58:10 jmarcus Exp $ + * $Id: cnid_open.c,v 1.42 2002-08-30 03:12:52 jmarcus Exp $ * * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT. @@ -33,7 +33,7 @@ * CNIDs 4-16 are reserved according to page 31 of the AFP 3.0 spec so, * CNID_START begins at 17. */ - + #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ @@ -90,6 +90,9 @@ #define DBVERSION1 0x00000001U #define DBVERSION DBVERSION1 +#ifdef CNID_DB_CDB +#define DBOPTIONS (DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL) +#else /* !CNID_DB_CDB */ #if DB_VERSION_MAJOR >= 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 1) #define DBOPTIONS (DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | \ DB_INIT_LOG | DB_INIT_TXN) @@ -99,7 +102,9 @@ DB_INIT_LOG | DB_INIT_TXN | DB_TXN_NOSYNC)*/ #define DBOPTIONS (DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | \ DB_INIT_LOG | DB_INIT_TXN) #endif /* DB_VERSION_MINOR */ +#endif /* CNID_DB_CDB */ +#ifndef CNID_DB_CDB /* Let's try and use the youngest lock detector if present. * If we can't do that, then let DB3 use its default deadlock detector. */ #if defined DB_LOCK_YOUNGEST @@ -107,6 +112,7 @@ DB_INIT_LOG | DB_INIT_TXN) #else /* DB_LOCK_YOUNGEST */ #define DEAD_LOCK_DETECT DB_LOCK_DEFAULT #endif /* DB_LOCK_YOUNGEST */ +#endif /* CNID_DB_CDB */ #define MAXITER 0xFFFF /* maximum number of simultaneously open CNID * databases. */ @@ -188,7 +194,9 @@ static int compare_unicode(const DBT *a, const DBT *b) void *cnid_open(const char *dir) { struct stat st, rsb, lsb, csb; +#ifndef CNID_DB_CDB struct flock lock; +#endif /* CNID_DB_CDB */ char path[MAXPATHLEN + 1]; CNID_private *db; DBT key, data; @@ -219,15 +227,15 @@ void *cnid_open(const char *dir) { len++; } - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - strcpy(path + len, DBHOME); if ((stat(path, &st) < 0) && (ad_mkdir(path, 0777) < 0)) { LOG(log_error, logtype_default, "cnid_open: DBHOME mkdir failed for %s", path); goto fail_adouble; } +#ifndef CNID_DB_CDB + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; /* Make sure cnid.lock goes in .AppleDB. */ strcat(path, "/"); len++; @@ -254,6 +262,7 @@ void *cnid_open(const char *dir) { else { LOG(log_error, logtype_default, "cnid_open: Cannot establish logfile cleanup lock for database environment %s (open() failed)", path); } +#endif /* CNID_DB_CDB */ path[len + DBHOMELEN] = '\0'; open_flag = DB_CREATE; @@ -266,12 +275,15 @@ void *cnid_open(const char *dir) { goto fail_lock; } +#ifndef CNID_DB_CDB /* Setup internal deadlock detection. */ if ((rc = db->dbenv->set_lk_detect(db->dbenv, DEAD_LOCK_DETECT)) != 0) { LOG(log_error, logtype_default, "cnid_open: set_lk_detect: %s", db_strerror(rc)); goto fail_lock; } +#endif /* CNID_DB_CDB */ +#ifndef CNID_DB_CDB #if DB_VERSION_MAJOR >= 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 1) #if 0 /* Take care of setting the DB_TXN_NOSYNC flag in db3 > 3.1.x. */ @@ -281,6 +293,7 @@ void *cnid_open(const char *dir) { } #endif #endif /* DB_VERSION_MINOR > 1 */ +#endif /* CNID_DB_CDB */ /* Open the database environment. */ if ((rc = db->dbenv->open(db->dbenv, path, DBOPTIONS, 0666)) != 0) { @@ -329,6 +342,24 @@ void *cnid_open(const char *dir) { key.data = DBVERSION_KEY; key.size = DBVERSION_KEYLEN; +#ifdef CNID_DB_CDB + if ((rc = db->db_didname->get(db->db_didname, NULL, &key, &data, 0)) != 0) { + int ret; + { + u_int32_t version = htonl(DBVERSION); + + data.data = &version; + data.size = sizeof(version); + } + if ((ret = db->db_didname->put(db->db_didname, 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); + goto fail_appinit; + } + } +#else /* CNID_DB_CDB */ dbversion_retry: if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) { LOG(log_error, logtype_default, "cnid_open: txn_begin: failed to check db version: %s", @@ -392,6 +423,7 @@ dbversion_retry: db->db_didname->close(db->db_didname, 0); goto fail_appinit; } +#endif /* CNID_DB_CDB */ /* TODO In the future we might check for version number here. */ #if 0 @@ -506,7 +538,7 @@ dbversion_retry: db->db_shortname->close(db->db_shortname, 0); db->db_longname->close(db->db_longname, 0); #endif /* EXTENDED_DB */ - db->db_devino->close(db->db_devino, 0); + db->db_devino->close(db->db_devino, 0); goto fail_appinit; } @@ -550,10 +582,12 @@ fail_appinit: db->dbenv->close(db->dbenv, 0); fail_lock: +#ifndef CNID_DB_CDB if (db->lockfd > -1) { close(db->lockfd); (void)remove(db->lock_file); } +#endif /* CNID_DB_CDB */ fail_adouble: diff --git a/libatalk/cnid/cnid_resolve.c b/libatalk/cnid/cnid_resolve.c index c542a4ed..86bc4789 100644 --- a/libatalk/cnid/cnid_resolve.c +++ b/libatalk/cnid/cnid_resolve.c @@ -1,5 +1,5 @@ /* - * $Id: cnid_resolve.c,v 1.12 2002-03-24 17:43:42 jmarcus Exp $ + * $Id: cnid_resolve.c,v 1.13 2002-08-30 03:12:52 jmarcus Exp $ */ #ifdef HAVE_CONFIG_H @@ -41,9 +41,11 @@ char *cnid_resolve(void *CNID, cnid_t *id, void *buffer, u_int32_t len) { key.data = id; key.size = sizeof(cnid_t); while ((rc = db->db_cnid->get(db->db_cnid, NULL, &key, &data, 0))) { +#ifndef CNID_DB_CDB if (rc == DB_LOCK_DEADLOCK) { continue; } +#endif /* CNID_DB_CDB */ if (rc != DB_NOTFOUND) { LOG(log_error, logtype_default, "cnid_resolve: Unable to get did/name: %s", diff --git a/libatalk/cnid/cnid_update.c b/libatalk/cnid/cnid_update.c index c635d247..1a2dbb1c 100644 --- a/libatalk/cnid/cnid_update.c +++ b/libatalk/cnid/cnid_update.c @@ -1,5 +1,5 @@ /* - * $Id: cnid_update.c,v 1.19 2002-01-24 16:46:53 jmarcus Exp $ + * $Id: cnid_update.c,v 1.20 2002-08-30 03:12:52 jmarcus Exp $ */ #ifdef HAVE_CONFIG_H @@ -21,6 +21,10 @@ #include "cnid_private.h" +#ifdef CNID_DB_CDB + #define tid NULL +#endif /* CNID_DB_CDB */ + /* cnid_update: takes the given cnid and updates the metadata. To * handle the did/name data, there are a bunch of functions to get * and set the various fields. */ @@ -30,7 +34,9 @@ int cnid_update(void *CNID, const cnid_t id, const struct stat *st, { CNID_private *db; DBT key, data, altdata; +#ifndef CNID_DB_CDB DB_TXN *tid; +#endif /* CNID_DB_CDB */ int rc; if (!(db = CNID) || !id || !st || !name || (db->flags & CNIDFLAG_DB_RO)) { @@ -40,21 +46,29 @@ int cnid_update(void *CNID, const cnid_t id, const struct stat *st, memset(&key, 0, sizeof(key)); memset(&altdata, 0, sizeof(altdata)); +#ifndef CNID_DB_CDB retry: if ((rc = txn_begin(db->dbenv, NULL, &tid, 0))) { LOG(log_error, logtype_default, "cnid_update: Failed to begin transaction: %s", db_strerror(rc)); return rc; } +#endif /* CNID_DB_CDB */ /* Get the old info. */ key.data = (cnid_t *)&id; key.size = sizeof(id); memset(&data, 0, sizeof(data)); +#ifdef CNID_DB_CDB + if ((rc = db->db_cnid->get(db->db_cnid, NULL, &key, &data, 0))) { +#else /* CNID_DB_CDB */ if ((rc = db->db_cnid->get(db->db_cnid, tid, &key, &data, DB_RMW))) { txn_abort(tid); +#endif /* CNID_DB_CDB */ switch (rc) { +#ifndef CNID_DB_CDB case DB_LOCK_DEADLOCK: goto retry; +#endif /* CNID_DB_CDB */ case DB_NOTFOUND: /* Silently fail here. We're allowed to do this since this CNID * might have been deleted out from under us, or someone has @@ -70,13 +84,17 @@ retry: key.size = CNID_DEVINO_LEN; if ((rc = db->db_devino->del(db->db_devino, tid, &key, 0))) { switch (rc) { +#ifndef CNID_DB_CDB case DB_LOCK_DEADLOCK: txn_abort(tid); goto retry; +#endif /* CNID_DB_CDB */ case DB_NOTFOUND: break; default: +#ifndef CNID_DB_CDB txn_abort(tid); +#endif /* CNID_DB_CDB */ goto update_err; } } @@ -86,13 +104,17 @@ retry: key.size = data.size - CNID_DEVINO_LEN; if ((rc = db->db_didname->del(db->db_didname, tid, &key, 0))) { switch (rc) { +#ifndef CNID_DB_CDB case DB_LOCK_DEADLOCK: txn_abort(tid); goto retry; +#endif /* CNID_DB_CDB */ case DB_NOTFOUND: break; default: +#ifndef CNID_DB_CDB txn_abort(tid); +#endif /* CNID_DB_CDB */ goto update_err; } } @@ -105,10 +127,14 @@ retry: key.data = (cnid_t *) &id; key.size = sizeof(id); if ((rc = db->db_cnid->put(db->db_cnid, tid, &key, &data, 0))) { +#ifndef CNID_DB_CDB txn_abort(tid); +#endif /* CNID_DB_CDB */ switch (rc) { +#ifndef CNID_DB_CDB case DB_LOCK_DEADLOCK: goto retry; +#endif /* CNID_DB_CDB */ default: goto update_err; } @@ -120,10 +146,14 @@ retry: altdata.data = (cnid_t *) &id; altdata.size = sizeof(id); if ((rc = db->db_devino->put(db->db_devino, tid, &key, &altdata, 0))) { +#ifndef CNID_DB_CDB txn_abort(tid); +#endif /* CNID_DB_CDB */ switch (rc) { +#ifndef CNID_DB_CDB case DB_LOCK_DEADLOCK: goto retry; +#endif /* CNID_DB_CDB */ default: goto update_err; } @@ -133,17 +163,25 @@ retry: key.data = (char *) data.data + CNID_DEVINO_LEN; key.size = data.size - CNID_DEVINO_LEN; if ((rc = db->db_didname->put(db->db_didname, tid, &key, &altdata, 0))) { +#ifndef CNID_DB_CDB txn_abort(tid); +#endif /* CNID_DB_CDB */ switch (rc) { +#ifndef CNID_DB_CDB case DB_LOCK_DEADLOCK: goto retry; +#endif /* CNID_DB_CDB */ default: goto update_err; } } +#ifdef CNID_DB_CDB + return 0; +#else /* CNID_DB_CDB */ return txn_commit(tid, 0); +#endif /* CNID_DB_CDB */ update_err: LOG(log_error, logtype_default, "cnid_update: Unable to update CNID %u: %s",