]> arthur.barton.de Git - netatalk.git/commitdiff
Merge latest CNID DB code from HEAD.
authorjmarcus <jmarcus>
Sat, 9 Feb 2002 20:29:02 +0000 (20:29 +0000)
committerjmarcus <jmarcus>
Sat, 9 Feb 2002 20:29:02 +0000 (20:29 +0000)
15 files changed:
etc/afpd/enumerate.c
etc/afpd/file.c
etc/afpd/fork.c
include/atalk/cnid.h
libatalk/cnid/cnid_add.c
libatalk/cnid/cnid_close.c
libatalk/cnid/cnid_delete.c
libatalk/cnid/cnid_get.c
libatalk/cnid/cnid_lookup.c
libatalk/cnid/cnid_nextid.c
libatalk/cnid/cnid_open.c
libatalk/cnid/cnid_private.h
libatalk/cnid/cnid_resolve.c
libatalk/cnid/cnid_update.c
macros/db3-check.m4

index 90de28f5cc8fe8449f62c37d5d0aa355034543f9..1888d36969a10f8b453824cd44c0bcb0855a8c41 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: enumerate.c,v 1.9.2.3 2002-02-07 23:56:04 srittau Exp $
+ * $Id: enumerate.c,v 1.9.2.4 2002-02-09 20:29:02 jmarcus Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -81,6 +81,18 @@ struct stat *st;
     /* add to cnid db */
     cdir->d_did = cnid_add(vol->v_db, st, dir->d_did, upath,
                            upathlen, cdir->d_did);
+    /* Fail out if things go bad with CNID. */
+    if (cdir->d_did == CNID_INVALID) {
+        switch (errno) {
+        case CNID_ERR_PARAM:
+            syslog(LOG_ERR, "adddir: Incorrect parameters passed to cnid_add");
+            return NULL;
+        case CNID_ERR_PATH:
+        case CNID_ERR_DB:
+        case CNID_ERR_MAX:
+            return NULL;
+        }
+    }
 #endif /* CNID_DB */
 
     if (cdir->d_did == 0) {
index a7b2933b3dab2d1b33f184070d75ab3241150390..cfa3545e97dcb035e4124b464b95bf51029e06b6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.29.2.4 2002-02-07 23:56:33 srittau Exp $
+ * $Id: file.c,v 1.29.2.5 2002-02-09 20:29:02 jmarcus Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -224,6 +224,19 @@ int getfilparams(struct vol *vol,
 #ifdef CNID_DB
             aint = cnid_add(vol->v_db, st, dir->d_did, upath,
                             strlen(upath), aint);
+            /* Throw errors if cnid_add fails. */
+            if (aint == CNID_INVALID) {
+                switch (errno) {
+                case CNID_ERR_PARAM:
+                    syslog(LOG_ERR, "getfilparams: Incorrect parameters passed to cnid_add");
+                    return(AFPERR_PARAM);
+                case CNID_ERR_PATH:
+                    return(AFPERR_PARAM);
+                case CNID_ERR_DB:
+                case CNID_ERR_MAX:
+                    return(AFPERR_MISC);
+                }
+            }
 #endif /* CNID_DB */
 
             if (aint == 0) {
@@ -1354,7 +1367,7 @@ int               ibuflen, *rbuflen;
     }
 #endif /* AD_VERSION > AD_VERSION1 */
 
-    if (id = cnid_add(vol->v_db, &st, did, upath, len, id)) {
+    if (id = cnid_add(vol->v_db, &st, did, upath, len, id) != CNID_INVALID) {
         memcpy(rbuf, &id, sizeof(id));
         *rbuflen = sizeof(id);
         return AFP_OK;
index c18c00632504ea1dab7e7647969a6fe7c20cf511..e4881d435079b514caba9671911294e13c7eac94 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: fork.c,v 1.11.2.3 2002-02-07 23:56:58 srittau Exp $
+ * $Id: fork.c,v 1.11.2.4 2002-02-09 20:29:02 jmarcus Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -191,6 +191,18 @@ const u_int16_t     attrbits;
             aint = cnid_add(ofork->of_vol->v_db, &st,
                             ofork->of_dir->d_did,
                             upath, strlen(upath), aint);
+            if (aint == CNID_INVALID) {
+                switch (errno) {
+                case CNID_ERR_PARAM:
+                    syslog(LOG_ERR, "getforkparams: Incorrect parameters passed to cnid_add");
+                    return(AFPERR_PARAM);
+                case CNID_ERR_PATH:
+                    return(AFPERR_PARAM);
+                case CNID_ERR_DB:
+                case CNID_ERR_MAX:
+                    return(AFPERR_MISC);
+                }
+            }
 #endif /* CNID_DB */
 
             if (aint == 0) {
index 19c841719b16a27e501b459c45746150801d0feb..43ac5006aa6eb0b7730524a00f961a8b97291ff3 100644 (file)
 
 #include <netatalk/endian.h>
 
+#define CNID_INVALID   0
+
+#define CNID_ERR_PARAM 0x80000001
+#define CNID_ERR_PATH  0x80000002
+#define CNID_ERR_DB    0x80000003
+#define CNID_ERR_MAX   0x80000004
+
 typedef u_int32_t cnid_t;
 
 /* cnid_open.c */
index 6591088a7d91f2c2b42ba55090f422fdb748c25b..e6a725544d205d049cd4ce9dbfea40e76498bfc6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_add.c,v 1.14.2.3 2001-12-15 06:35:28 jmarcus Exp $
+ * $Id: cnid_add.c,v 1.14.2.4 2002-02-09 20:29:02 jmarcus Exp $
  *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
 
 #include "cnid_private.h"
 
-#define MAX_ABORTS 255
-
 /* add an entry to the CNID databases. we do this as a transaction
  * to prevent messiness. */
-static int add_cnid(CNID_private *db, DB_TXN *ptid, DBT *key, DBT *data) {
+static int add_cnid(CNID_private *db, DBT *key, DBT *data) {
     DBT altkey, altdata;
     DB_TXN *tid;
-    /* We create rc here because using errno is bad.  Why?  Well, if you
-     * use errno once, then call another function which resets it, you're
-     * screwed. */
-    int rc, ret, aborts = 0;
+    int rc, ret;
 
     memset(&altkey, 0, sizeof(altkey));
     memset(&altdata, 0, sizeof(altdata));
 
-    if (0) {
 retry:
-        if ((rc = txn_abort(tid)) != 0) {
-            return rc;
-        }
-        if (++aborts > MAX_ABORTS) {
-            return DB_LOCK_DEADLOCK;
-        }
-    }
-
-    if ((rc = txn_begin(db->dbenv, ptid, &tid, 0)) != 0) {
+    if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) {
         return rc;
     }
 
     /* main database */
     if ((rc = db->db_cnid->put(db->db_cnid, tid, key, data, DB_NOOVERWRITE))) {
         if (rc == DB_LOCK_DEADLOCK) {
+            if ((ret = txn_abort(tid)) != 0) {
+                return ret;
+            }
             goto retry;
         }
-
         goto abort;
     }
 
-
     /* dev/ino database */
     altkey.data = data->data;
     altkey.size = CNID_DEVINO_LEN;
@@ -85,29 +72,32 @@ retry:
     altdata.size = key->size;
     if ((rc = db->db_devino->put(db->db_devino, tid, &altkey, &altdata, 0))) {
         if (rc == DB_LOCK_DEADLOCK) {
+            if ((ret = txn_abort(tid)) != 0) {
+                return ret;
+            }
             goto retry;
         }
-
         goto abort;
     }
 
-
     /* did/name database */
     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))) {
         if (rc == DB_LOCK_DEADLOCK) {
+            if ((ret = txn_abort(tid)) != 0) {
+                return ret;
+            }
             goto retry;
         }
-
         goto abort;
     }
 
     if ((rc = txn_commit(tid, 0)) != 0) {
-        syslog(LOG_ERR, "add_cnid: Failed to commit transaction: %s",
-               db_strerror(rc));
+        syslog(LOG_ERR, "add_cnid: Failed to commit transaction: %s", db_strerror(rc));
         return rc;
     }
+
     return 0;
 
 abort:
@@ -115,7 +105,6 @@ abort:
         return ret;
     }
     return rc;
-
 }
 
 cnid_t cnid_add(void *CNID, const struct stat *st,
@@ -130,7 +119,8 @@ cnid_t cnid_add(void *CNID, const struct stat *st,
     int rc;
 
     if (!(db = CNID) || !st || !name) {
-        return 0;
+        errno = CNID_ERR_PARAM;
+        return CNID_INVALID;
     }
 
     /* Do a lookup. */
@@ -138,8 +128,7 @@ cnid_t cnid_add(void *CNID, const struct stat *st,
     /* ... Return id if it is valid, or if Rootinfo is read-only. */
     if (id || (db->flags & CNIDFLAG_DB_RO)) {
 #ifdef DEBUG
-        syslog(LOG_INFO, "cnid_add: Looked up did %u, name %s as %u",
-               ntohl(did), name, ntohl(id));
+        syslog(LOG_INFO, "cnid_add: Looked up did %u, name %s as %u", ntohl(did), name, ntohl(id));
 #endif
         return id;
     }
@@ -154,7 +143,8 @@ cnid_t cnid_add(void *CNID, const struct stat *st,
 
     if ((data.data = make_cnid_data(st, did, name, len)) == NULL) {
         syslog(LOG_ERR, "cnid_add: Path name is too long");
-        goto cleanup_err;
+        errno = CNID_ERR_PATH;
+        return CNID_INVALID;
     }
 
     data.size = CNID_HEADER_LEN + len + 1;
@@ -164,44 +154,56 @@ cnid_t cnid_add(void *CNID, const struct stat *st,
      * cnid's to the database. */
     if (ntohl(hint) >= CNID_START) {
         /* If the key doesn't exist, add it in.  Don't fiddle with nextID. */
-        rc = add_cnid(db, NULL, &key, &data);
+        rc = add_cnid(db, &key, &data);
         switch (rc) {
         case DB_KEYEXIST: /* Need to use RootInfo after all. */
             break;
         default:
-            syslog(LOG_ERR, "cnid_add: Unable to add CNID %u: %s",
-                   ntohl(hint), db_strerror(rc));
-            goto cleanup_err;
+            syslog(LOG_ERR, "cnid_add: Unable to add CNID %u: %s", ntohl(hint), db_strerror(rc));
+            errno = CNID_ERR_DB;
+            return CNID_INVALID;
         case 0:
 #ifdef DEBUG
-            syslog(LOG_INFO, "cnid_add: Used hint for did %u, name %s as %u",
-                   ntohl(did), name, ntohl(hint));
+            syslog(LOG_INFO, "cnid_add: Used hint for did %u, name %s as %u", ntohl(did), name, ntohl(hint));
 #endif
             return hint;
         }
     }
 
-    /* We need to create a random sleep interval to prevent deadlocks. */
-    (void)srand(getpid() ^ time(NULL));
-    t.tv_sec = 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;
 
+retry:
+    if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) {
+        syslog(LOG_ERR, "cnid_add: Failed to begin transaction: %s", db_strerror(rc));
+        errno = CNID_ERR_DB;
+        return CNID_INVALID;
+    }
+
     /* Get the key. */
-retry_get:
-    switch (rc = db->db_didname->get(db->db_didname, NULL, &rootinfo_key,
-                                     &rootinfo_data, 0)) {
+    switch (rc = db->db_didname->get(db->db_didname, tid, &rootinfo_key,
+                                     &rootinfo_data, DB_RMW)) {
     case DB_LOCK_DEADLOCK:
         if ((rc = txn_abort(tid)) != 0) {
             syslog(LOG_ERR, "cnid_add: txn_abort: %s", db_strerror(rc));
-            goto cleanup_err;
+            errno = CNID_ERR_DB;
+            return CNID_INVALID;
         }
-        goto retry_get;
+        goto retry;
     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) {
+            txn_abort(tid);
+            syslog(LOG_ERR, "cnid_add: FATAL: Cannot add CNID for %s.  CNID database has reached its limit.", name);
+            errno = CNID_ERR_MAX;
+            return CNID_INVALID;
+        }
+        hint = htonl(id);
 #ifdef DEBUG
         syslog(LOG_INFO, "cnid_add: Found rootinfo for did %u, name %s as %u", ntohl(did), name, ntohl(hint));
 #endif
@@ -209,54 +211,12 @@ retry_get:
     case DB_NOTFOUND:
         hint = htonl(CNID_START);
 #ifdef DEBUG
-        syslog(LOG_INFO, "cnid_add: Using CNID_START for did %u, name %s",
-               ntohl(did), name);
+        syslog(LOG_INFO, "cnid_add: Using CNID_START for did %u, name %s", ntohl(did), name);
 #endif
         break;
     default:
-        syslog(LOG_ERR, "cnid_add: Unable to lookup rootinfo: %s",
-               db_strerror(rc));
-        goto cleanup_err;
-    }
-
-
-    if (0) {
-retry:
-        t.tv_usec = rand() % 1000000;
-#ifdef DEBUG
-        syslog(LOG_INFO, "cnid_add: Hitting MAX_ABORTS, sleeping");
-#endif
-        (void)select(0, NULL, NULL, NULL, &t);
-    }
-    if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) {
-        syslog(LOG_ERR, "cnid_add: Failed to begin transaction: %s",
-               db_strerror(rc));
-        goto cleanup_err;
-    }
-
-    /* Search for a new id.  We keep the first id around to check for
-     * wrap-around.  NOTE: I do it this way so that we can go back and
-     * fill in holes. */
-    save = id = ntohl(hint);
-    while ((rc = add_cnid(db, tid, &key, &data)) != 0) {
-        /* Don't use any special CNIDs. */
-        if (++id < CNID_START) {
-            id = CNID_START;
-        }
-        if (rc == DB_LOCK_DEADLOCK) {
-            if ((rc = txn_abort(tid)) != 0) {
-                syslog(LOG_ERR, "cnid_add: txn_abort: %s", db_strerror(rc));
-                goto cleanup_err;
-            }
-            goto retry;
-        }
-
-        if ((rc != DB_KEYEXIST) || (save == id)) {
-            syslog(LOG_ERR, "cnid_add: Unable to add CNID %u: %s",
-                   ntohl(hint), db_strerror(rc));
-            goto cleanup_abort;
-        }
-        hint = htonl(id);
+        syslog(LOG_ERR, "cnid_add: Unable to lookup rootinfo: %s", db_strerror(rc));
+        goto cleanup_abort;
     }
 
     rootinfo_data.data = &hint;
@@ -266,36 +226,42 @@ retry:
     case DB_LOCK_DEADLOCK:
         if ((rc = txn_abort(tid)) != 0) {
             syslog(LOG_ERR, "cnid_add: txn_abort: %s", db_strerror(rc));
-            goto cleanup_err;
+            errno = CNID_ERR_DB;
+            return CNID_INVALID; 
         }
         goto retry;
     case 0:
+        /* The transaction finished, commit it. */
+        if ((rc = txn_commit(tid, 0)) != 0) {
+            syslog(LOG_ERR, "cnid_add: Unable to commit transaction: %s", db_strerror(rc));
+            errno = CNID_ERR_DB;
+            return CNID_INVALID;
+        }
         break;
     default:
-        syslog(LOG_ERR, "cnid_add: Unable to update rootinfo: %s",
-               db_strerror(rc));
+        syslog(LOG_ERR, "cnid_add: Unable to update rootinfo: %s", db_strerror(rc));
         goto cleanup_abort;
     }
 
-cleanup_commit:
-    /* The transaction finished, commit it. */
-    if ((rc = txn_commit(tid, 0)) != 0) {
-        syslog(LOG_ERR, "cnid_add: Unable to commit transaction: %s",
-               db_strerror(rc));
-        goto cleanup_err;
+    /* Now we need to add the CNID data to the databases. */
+    rc = add_cnid(db, &key, &data);
+    if (rc) {
+        syslog(LOG_ERR, "cnid_add: Failed to add CNID for %s to database using hint %u: %s", name, ntohl(hint), db_strerror(rc));
+        errno = CNID_ERR_DB;
+        return CNID_INVALID;
     }
 
 #ifdef DEBUG
-    syslog(LOG_INFO, "cnid_add: Returned CNID for did %u, name %s as %u",
-           ntohl(did), name, ntohl(hint));
+    syslog(LOG_INFO, "cnid_add: Returned CNID for did %u, name %s as %u", ntohl(did), name, ntohl(hint));
 #endif
+
     return hint;
 
 cleanup_abort:
     txn_abort(tid);
 
-cleanup_err:
-    return 0;
+    errno = CNID_ERR_DB;
+    return CNID_INVALID;
 }
 #endif /* CNID_DB */
 
index ecef6c4ec15b481ec3c3f251b8013b6dc843e918..de35433f1879ff766fa1308e4bd06bcd6771232c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_close.c,v 1.12.2.3 2001-12-15 06:35:28 jmarcus Exp $
+ * $Id: cnid_close.c,v 1.12.2.4 2002-02-09 20:29:02 jmarcus Exp $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -42,42 +42,34 @@ void cnid_close(void *CNID) {
             char **list, **first;
             int cfd = -1;
 
-            if ((cfd = open(db->close_file, O_RDWR | O_CREAT, 0666)) > -1) {
 
-                /* Checkpoint the databases until we can checkpoint no
-                 * more. */
+            /* Checkpoint the databases until we can checkpoint no
+             * more. */
+            rc = txn_checkpoint(db->dbenv, 0, 0, 0);
+            while (rc == DB_INCOMPLETE) {
                 rc = txn_checkpoint(db->dbenv, 0, 0, 0);
-                while (rc == DB_INCOMPLETE) {
-                    rc = txn_checkpoint(db->dbenv, 0, 0, 0);
-                }
+            }
 
 #if DB_VERSION_MINOR > 2
-                if ((rc = log_archive(db->dbenv, &list, DB_ARCH_LOG | DB_ARCH_ABS)) != 0) {
+            if ((rc = log_archive(db->dbenv, &list, DB_ARCH_ABS)) != 0) {
 #else /* DB_VERSION_MINOR < 2 */
-                if ((rc = log_archive(db->dbenv, &list, DB_ARCH_LOG | DB_ARCH_ABS, NULL)) != 0) {
+            if ((rc = log_archive(db->dbenv, &list, DB_ARCH_ABS, NULL)) != 0) {
 #endif /* DB_VERSION_MINOR */
-                    syslog(LOG_ERR, "cnid_close: Unable to archive logfiles: %s",
-                           db_strerror(rc));
-                }
+                syslog(LOG_ERR, "cnid_close: Unable to archive logfiles: %s", db_strerror(rc));
+            }
 
-                if (list != NULL) {
-                    for (first = list; *list != NULL; ++list) {
-                        if ((rc = remove(*list)) != 0) {
+            if (list != NULL) {
+                for (first = list; *list != NULL; ++list) {
+                    if ((rc = remove(*list)) != 0) {
 #ifdef DEBUG
-                            syslog(LOG_INFO, "cnid_close: failed to remove %s: %s",
-                                   *list, strerror(rc));
+                        syslog(LOG_INFO, "cnid_close: failed to remove %s: %s", *list, strerror(rc));
 #endif
-                        }
                     }
-                    free(first);
                 }
-                (void)remove(db->close_file);
-                close(cfd);
-            }
-            else {
-                syslog(LOG_ERR, "cnid_close: Failed to open database closing lock file: %s", strerror(errno));
+                free(first);
             }
         }
+        (void)remove(db->lock_file);
     }
 
     db->db_didname->close(db->db_didname, 0);
index a151f7b4a12f15bb671163f3a144887fc214a740..acd7b9555773b24fe8e49a6f7a3a61c36616ba85 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_delete.c,v 1.9.2.3 2001-12-15 06:35:28 jmarcus Exp $
+ * $Id: cnid_delete.c,v 1.9.2.4 2002-02-09 20:29:02 jmarcus Exp $
  *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
@@ -51,12 +51,12 @@ int cnid_delete(void *CNID, const cnid_t id) {
         case DB_NOTFOUND:
 #ifdef DEBUG
             syslog(LOG_INFO, "cnid_delete: CNID %u not in database",
-                   ntohl(id));
+                ntohl(id));
 #endif
             return 0;
         default:
             syslog(LOG_ERR, "cnid_delete: Unable to delete entry: %s",
-                   db_strerror(rc));
+                db_strerror(rc));
             return rc;
         }
     }
@@ -64,7 +64,7 @@ int cnid_delete(void *CNID, const cnid_t id) {
 retry:
     if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) {
         syslog(LOG_ERR, "cnid_delete: Failed to begin transaction: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         return rc;
     }
 
@@ -93,7 +93,7 @@ retry:
         case DB_LOCK_DEADLOCK:
             if ((rc = txn_abort(tid)) != 0) {
                 syslog(LOG_ERR, "cnid_delete: txn_abort: %s",
-                       db_strerror(rc));
+                    db_strerror(rc));
                 return rc;
             }
             goto retry;
@@ -103,7 +103,7 @@ retry:
         default:
             if ((rc = txn_abort(tid)) != 0) {
                 syslog(LOG_ERR, "cnid_delete: txn_abort: %s",
-                       db_strerror(rc));
+                    db_strerror(rc));
                 return rc;
             }
             goto abort_err;
@@ -119,7 +119,7 @@ retry:
         case DB_LOCK_DEADLOCK:
             if ((rc = txn_abort(tid)) != 0) {
                 syslog(LOG_ERR, "cnid_delete: txn_abort: %s",
-                       db_strerror(rc));
+                    db_strerror(rc));
                 return rc;
             }
             goto retry;
@@ -128,7 +128,7 @@ retry:
         default:
             if ((rc = txn_abort(tid)) != 0) {
                 syslog(LOG_ERR, "cnid_delete: txn_abort: %s",
-                       db_strerror(rc));
+                    db_strerror(rc));
                 return rc;
             }
             goto abort_err;
@@ -140,14 +140,14 @@ retry:
 #endif
     if ((rc = txn_commit(tid, 0)) != 0) {
         syslog(LOG_ERR, "cnid_delete: Failed to commit transaction: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         return rc;
     }
     return 0;
 
 abort_err:
     syslog(LOG_ERR, "cnid_delete: Unable to delete CNID %u: %s",
-           ntohl(id), db_strerror(rc));
+        ntohl(id), db_strerror(rc));
     return rc;
 }
 #endif /*CNID_DB */
index 53ca2212851e5dbbaa05fa67ab8930285b8de8f4..3ff1423ba6a78af087117e00e98a81cd11132a7d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_get.c,v 1.9.2.3 2001-12-15 06:35:28 jmarcus Exp $
+ * $Id: cnid_get.c,v 1.9.2.4 2002-02-09 20:29:02 jmarcus Exp $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -53,7 +53,7 @@ cnid_t cnid_get(void *CNID, const cnid_t did, const char *name,
 
         if (rc != DB_NOTFOUND) {
             syslog(LOG_ERR, "cnid_get: Unable to get CNID %u, name %s: %s",
-                   ntohl(did), name, db_strerror(rc));
+                ntohl(did), name, db_strerror(rc));
         }
 
         return 0;
@@ -62,7 +62,7 @@ cnid_t cnid_get(void *CNID, const cnid_t did, const char *name,
     memcpy(&id, data.data, sizeof(id));
 #ifdef DEBUG
     syslog(LOG_INFO, "cnid_get: Returning CNID for %u, name %s as %u",
-           ntohl(did), name, ntohl(id));
+        ntohl(did), name, ntohl(id));
 #endif
     return id;
 }
index 01acaff3406c251deffbba26175931a7799d8c67..039bcc77e9372bf43ff1f41ebc76de97030cf05b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_lookup.c,v 1.9.2.3 2001-12-15 06:35:28 jmarcus Exp $
+ * $Id: cnid_lookup.c,v 1.9.2.4 2002-02-09 20:29:02 jmarcus Exp $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -53,7 +53,7 @@ cnid_t cnid_lookup(void *CNID, const struct stat *st, const cnid_t did,
             break;
         default:
             syslog(LOG_ERR, "cnid_lookup: txn_checkpoint: %s",
-                   db_strerror(rc));
+                db_strerror(rc));
             return 0;
         }
     }
@@ -82,7 +82,7 @@ cnid_t cnid_lookup(void *CNID, const struct stat *st, const cnid_t did,
         }
 
         syslog(LOG_ERR, "cnid_lookup: Unable to get CNID dev %u, ino %u: %s",
-               st->st_dev, st->st_ino, db_strerror(rc));
+            st->st_dev, st->st_ino, db_strerror(rc));
         return 0;
     }
 
@@ -100,7 +100,7 @@ cnid_t cnid_lookup(void *CNID, const struct stat *st, const cnid_t did,
         }
 
         syslog(LOG_ERR, "cnid_lookup: Unable to get CNID %u, name %s: %s",
-               ntohl(did), name, db_strerror(rc));
+            ntohl(did), name, db_strerror(rc));
         return 0;
     }
 
@@ -117,7 +117,7 @@ cnid_t cnid_lookup(void *CNID, const struct stat *st, const cnid_t did,
     if ((devino && didname) || !(devino || didname)) {
 #ifdef DEBUG
         syslog(LOG_INFO, "cnid_lookup: Looked up did %u, name %s, as %u",
-               ntohl(did), name, ntohl(id));
+            ntohl(did), name, ntohl(id));
 #endif
         return id;
     }
index 3742fbbef9306d6ec1c930ccd38a73b16b1a7e8a..fc917d7e16341a1550dc164f19c80236b3d41efa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_nextid.c,v 1.6.2.3 2001-12-15 06:35:28 jmarcus Exp $
+ * $Id: cnid_nextid.c,v 1.6.2.4 2002-02-09 20:29:02 jmarcus Exp $
  */
 #ifdef unused
 
index 02c07ee00dd27d1d117105159d46bb39a38cd96f..e356013a9b25a618d4bbb2f965ebfda3cc451d70 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_open.c,v 1.19.2.3 2001-12-15 06:35:28 jmarcus Exp $
+ * $Id: cnid_open.c,v 1.19.2.4 2002-02-09 20:29:02 jmarcus Exp $
  *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
@@ -30,7 +30,8 @@
  * 1 -- parent of root directory (handled by afpd) 
  * 2 -- root directory (handled by afpd)
  *
- * so, CNID_START begins at 3.
+ * 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
 #define DBOPTIONS    (DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | \
 DB_INIT_LOG | DB_INIT_TXN)
 #else /* DB_VERSION_MINOR < 1 */
-#define DBOPTIONS    (DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | \
-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)*/
+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 */
 
-/* Let's try and use the random deadlock decider if available.  This adds
- * a bit of entropy to the mix that might be beneficial.  If random isn't
- * available, we'll decide deadlocks by kicking off the youngest process.
+/* 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. */
-#ifdef DB_LOCK_RANDOM
-#define DEAD_LOCK_DETECT DB_LOCK_RANDOM
-#elif defined DB_LOCK_YOUNGEST
+#if defined DB_LOCK_YOUNGEST
 #define DEAD_LOCK_DETECT DB_LOCK_YOUNGEST
-#else /* DB_LOCK_RANDOM */
+#else /* DB_LOCK_YOUNGEST */
 #define DEAD_LOCK_DETECT DB_LOCK_DEFAULT
-#endif /* DB_LOCK_RANDOM */
+#endif /* DB_LOCK_YOUNGEST */
 
 #define MAXITER     0xFFFF /* maximum number of simultaneously open CNID
 * databases. */
@@ -188,19 +185,15 @@ static int compare_unicode(const DBT *a, const DBT *b)
 #endif /* DB_VERSION_MINOR */
 }
 
-static int have_lock = 0;
-
 void *cnid_open(const char *dir) {
-    struct stat st, rsb, csb;
+    struct stat st, rsb, lsb, csb;
     struct flock lock;
     char path[MAXPATHLEN + 1];
-    char recover_file[MAXPATHLEN + 1];
     CNID_private *db;
     DBT key, data;
     DB_TXN *tid;
-    u_int32_t DBEXTRAS = 0;
     int open_flag, len;
-    int rc, rfd = -1;
+    int rc;
 
     if (!dir) {
         return NULL;
@@ -238,27 +231,13 @@ void *cnid_open(const char *dir) {
     strcat(path, "/");
     len++;
 
-    strcpy(db->close_file, path);
-    strcat(db->close_file, DBCLOSEFILE);
-
-    /* Check to make sure that a client isn't in the process of closing
-     * the database environment.  To do this, select on the close file. */
-    while(stat(db->close_file, &csb) == 0) {
-        struct timeval ct;
-        ct.tv_sec = 1;
-        ct.tv_usec = 0;
-        (void)select(0, NULL, NULL, NULL, &ct);
-    }
-
-    strcpy(recover_file, path);
-    strcat(recover_file, DBRECOVERFILE);
-
     /* Search for a byte lock.  This allows us to cleanup the log files
      * at cnid_close() in a clean fashion.
      *
      * NOTE: This won't work if multiple volumes for the same user refer
      * to the sahe directory. */
     strcat(path, DBLOCKFILE);
+    strcpy(db->lock_file, path);
     if ((db->lockfd = open(path, O_RDWR | O_CREAT, 0666)) > -1) {
         lock.l_start = 0;
         lock.l_len = 1;
@@ -275,27 +254,6 @@ void *cnid_open(const char *dir) {
         syslog(LOG_ERR, "cnid_open: Cannot establish logfile cleanup lock for database environment %s (open() failed)", path);
     }
 
-    /* Create a file to represent database recovery.  While this file
-     * exists, the database is being recovered, and all other clients will
-     * select until recovery is complete, and this file goes away. */
-    if (!have_lock && db->lockfd > -1 && lock.l_start == 0) {
-        if (stat(recover_file, &rsb) == 0) {
-            (void)remove(recover_file);
-        }
-        if ((rfd = open(recover_file, O_RDWR | O_CREAT, 0666)) > -1) {
-            DBEXTRAS |= DB_RECOVER;
-            have_lock = 1;
-        }
-    }
-    else if (!have_lock) {
-        while (stat(recover_file, &rsb) == 0) {
-            struct timeval rt;
-            rt.tv_sec = 1;
-            rt.tv_usec = 0;
-            (void)select(0, NULL, NULL, NULL, &rt);
-        }
-    }
-
     path[len + DBHOMELEN] = '\0';
     open_flag = DB_CREATE;
 
@@ -314,15 +272,17 @@ void *cnid_open(const char *dir) {
     }
 
 #if DB_VERSION_MINOR > 1
+#if 0
     /* Take care of setting the DB_TXN_NOSYNC flag in db3 > 3.1.x. */
     if ((rc = db->dbenv->set_flags(db->dbenv, DB_TXN_NOSYNC, 1)) != 0) {
         syslog(LOG_ERR, "cnid_open: set_flags: %s", db_strerror(rc));
         goto fail_lock;
     }
+#endif
 #endif /* DB_VERSION_MINOR > 1 */
 
     /* Open the database environment. */
-    if ((rc = db->dbenv->open(db->dbenv, path, DBOPTIONS | DBEXTRAS, 0666)) != 0) {
+    if ((rc = db->dbenv->open(db->dbenv, path, DBOPTIONS, 0666)) != 0) {
         if (rc == DB_RUNRECOVERY) {
             /* This is the mother of all errors.  We _must_ fail here. */
             syslog(LOG_ERR, "cnid_open: CATASTROPHIC ERROR opening database environment %s.  Run db_recovery -c immediately", path);
@@ -337,7 +297,7 @@ void *cnid_open(const char *dir) {
              * open the environment with no flags. */
             if ((rc = db->dbenv->open(db->dbenv, path, 0, 0666)) != 0) {
                 syslog(LOG_ERR, "cnid_open: dbenv->open of %s failed: %s",
-                       path, db_strerror(rc));
+                    path, db_strerror(rc));
                 goto fail_lock;
             }
         }
@@ -346,34 +306,18 @@ void *cnid_open(const char *dir) {
         syslog(LOG_INFO, "cnid_open: Obtained read-only database environment %s", path);
     }
 
-    /* If we have the recovery lock, close the file, remove it, so other
-     * clients can proceed opening the DB environment. */
-    if (rfd > -1) {
-        (void)remove(recover_file);
-        switch(errno) {
-        case 0:
-        case ENOENT:
-            break;
-        default:
-            syslog(LOG_ERR, "cnid_open: Unable to remove %s: %s",
-                   recover_file, strerror(errno));
-        }
-        close(rfd);
-        rfd = -1;
-    }
-
     /* did/name reverse mapping.  We use a BTree for this one. */
     if ((rc = db_create(&db->db_didname, db->dbenv, 0)) != 0) {
         syslog(LOG_ERR, "cnid_open: Failed to create did/name database: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         goto fail_appinit;
     }
 
-    db->db_didname->set_bt_compare(db->db_didname, &compare_unix);
+    /*db->db_didname->set_bt_compare(db->db_didname, &compare_unix);*/
     if ((rc = db->db_didname->open(db->db_didname, DBDIDNAME, NULL,
-                                   DB_BTREE, open_flag, 0666))) {
+                                   DB_HASH, open_flag, 0666))) {
         syslog(LOG_ERR, "cnid_open: Failed to open did/name database: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         goto fail_appinit;
     }
 
@@ -387,7 +331,7 @@ void *cnid_open(const char *dir) {
 dbversion_retry:
     if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) {
         syslog(LOG_ERR, "cnid_open: txn_begin: failed to check db version: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         db->db_didname->close(db->db_didname, 0);
         goto fail_appinit;
     }
@@ -415,7 +359,7 @@ dbversion_retry:
                 if (ret == DB_LOCK_DEADLOCK) {
                     if ((ret = txn_abort(tid)) != 0) {
                         syslog(LOG_ERR, "cnid_open: txn_abort: %s",
-                               db_strerror(ret));
+                            db_strerror(ret));
                         db->db_didname->close(db->db_didname, 0);
                         goto fail_appinit;
                     }
@@ -426,7 +370,7 @@ dbversion_retry:
                      * successfully or not. */
                     txn_abort(tid);
                     syslog(LOG_ERR, "cnid_open: Error putting new version: %s",
-                           db_strerror(ret));
+                        db_strerror(ret));
                     db->db_didname->close(db->db_didname, 0);
                     goto fail_appinit;
                 }
@@ -435,7 +379,7 @@ dbversion_retry:
         default:
             txn_abort(tid);
             syslog(LOG_ERR, "cnid_open: Failed to check db version: %s",
-                   db_strerror(rc));
+                db_strerror(rc));
             db->db_didname->close(db->db_didname, 0);
             goto fail_appinit;
         }
@@ -443,7 +387,7 @@ dbversion_retry:
 
     if ((rc = txn_commit(tid, 0)) != 0) {
         syslog(LOG_ERR, "cnid_open: Failed to commit db version: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         db->db_didname->close(db->db_didname, 0);
         goto fail_appinit;
     }
@@ -460,7 +404,7 @@ dbversion_retry:
     /* did/macname (31 character) mapping.  Use a BTree for this one. */
     if ((rc = db_create(&db->db_macname, db->dbenv, 0)) != 0) {
         syslog(LOG_ERR, "cnid_open: Failed to create did/macname database: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         db->db_didname->close(db->db_didname, 0);
         goto fail_appinit;
     }
@@ -468,7 +412,7 @@ dbversion_retry:
     db->db_macname->set_bt_compare(db->db_macname, &compare_mac);
     if ((rc = db->db_macname->open(db->db_macname, DBMACNAME, NULL, DB_BTREE, open_flag, 0666)) != 0) {
         syslog(LOG_ERR, "cnid_open: Failed to open did/macname database: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         db->db_didname->close(db->db_didname, 0);
         goto fail_appinit;
     }
@@ -476,7 +420,7 @@ dbversion_retry:
     /* did/shortname (DOS 8.3) mapping.  Use a BTree for this one. */
     if ((rc = db_create(&db->db_shortname, db->dbenv, 0)) != 0) {
         syslog(LOG_ERR, "cnid_open: Failed to create did/shortname database: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         db->db_didname->close(db->db_didname, 0);
         db->db_macname->close(db->db_macname, 0);
         goto fail_appinit;
@@ -485,7 +429,7 @@ dbversion_retry:
     db->db_shortname->set_bt_compare(db->db_shortname, &compare_mac);
     if ((rc = db->db_shortname->open(db->db_shortname, DBSHORTNAME, NULL, DB_BTREE, open_flag, 0666)) != 0) {
         syslog(LOG_ERR, "cnid_open: Failed to open did/shortname database: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         db->db_didname->close(db->db_didname, 0);
         db->db_macname->close(db->db_macname, 0);
         goto fail_appinit;
@@ -494,7 +438,7 @@ dbversion_retry:
     /* did/longname (Unicode) mapping.  Use a BTree for this one. */
     if ((rc = db_create(&db->db_longname, db->dbenv, 0)) != 0) {
         syslog(LOG_ERR, "cnid_open: Failed to create did/longname database: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         db->db_didname->close(db->db_didname, 0);
         db->db_macname->close(db->db_macname, 0);
         db->db_shortname->close(db->db_shortname, 0);
@@ -504,7 +448,7 @@ dbversion_retry:
     db->db_longname->set_bt_compare(db->db_longname, &compare_unicode);
     if ((rc = db->db_longname->open(db->db_longname, DBLONGNAME, NULL, DB_BTREE, open_flag, 0666)) != 0) {
         syslog(LOG_ERR, "cnid_open: Failed to open did/longname database: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         db->db_didname->close(db->db_didname, 0);
         db->db_macname->close(db->db_macname, 0);
         db->db_shortname->close(db->db_shortname, 0);
@@ -515,7 +459,7 @@ dbversion_retry:
     /* dev/ino reverse mapping.  Use a hash for this one. */
     if ((rc = db_create(&db->db_devino, db->dbenv, 0)) != 0) {
         syslog(LOG_ERR, "cnid_open: Failed to create dev/ino database: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         db->db_didname->close(db->db_didname, 0);
 #ifdef EXTENDED_DB
         db->db_macname->close(db->db_macname, 0);
@@ -527,7 +471,7 @@ dbversion_retry:
 
     if ((rc = db->db_devino->open(db->db_devino, DBDEVINO, NULL, DB_HASH, open_flag, 0666)) != 0) {
         syslog(LOG_ERR, "cnid_open: Failed to open devino database: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         db->db_didname->close(db->db_didname, 0);
 #ifdef EXTENDED_DB
         db->db_macname->close(db->db_macname, 0);
@@ -540,7 +484,7 @@ dbversion_retry:
     /* Main CNID database.  Use a hash for this one. */
     if ((rc = db_create(&db->db_cnid, db->dbenv, 0)) != 0) {
         syslog(LOG_ERR, "cnid_open: Failed to create cnid database: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         db->db_didname->close(db->db_didname, 0);
 #ifdef EXTENDED_DB
         db->db_macname->close(db->db_macname, 0);
@@ -554,7 +498,7 @@ dbversion_retry:
 
     if ((rc = db->db_cnid->open(db->db_cnid, DBCNID, NULL, DB_HASH, open_flag, 0666)) != 0) {
         syslog(LOG_ERR, "cnid_open: Failed to open dev/ino database: %s",
-               db_strerror(rc));
+            db_strerror(rc));
         db->db_didname->close(db->db_didname, 0);
 #ifdef EXTENDED_DB
         db->db_macname->close(db->db_macname, 0);
@@ -564,6 +508,10 @@ dbversion_retry:
         goto fail_appinit;
     }
 
+    /* Print out the version of DB3 we're linked against. */
+    syslog(LOG_INFO, "CNID DB initialized using %s",
+        db_version(NULL, NULL, NULL));
+
     return db;
 
 fail_appinit:
@@ -573,10 +521,7 @@ fail_appinit:
 fail_lock:
     if (db->lockfd > -1) {
         close(db->lockfd);
-    }
-    if (rfd > -1) {
-        (void)remove(recover_file);
-        close(rfd);
+        (void)remove(db->lock_file);
     }
 
 fail_adouble:
index a315dfb5db709d3b3a6bee1f4c3ecbbdeda55059..97b33ab8e2202aad491e8e4e9288d67020384cb0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_private.h,v 1.3.2.3 2001-12-15 06:35:28 jmarcus Exp $
+ * $Id: cnid_private.h,v 1.3.2.4 2002-02-09 20:29:02 jmarcus Exp $
  */
 
 #ifndef LIBATALK_CNID_PRIVATE_H
@@ -24,7 +24,7 @@
 #define CNID_DID_LEN             4
 #define CNID_HEADER_LEN          (CNID_DEVINO_LEN + CNID_DID_LEN)
 
-#define CNID_START               3
+#define CNID_START               17
 
 #define CNIDFLAG_ROOTINFO_RO     (1 << 0)
 #define CNIDFLAG_DB_RO           (1 << 1)
@@ -46,7 +46,7 @@ typedef struct CNID_private {
 #endif /* EXTENDED_DB */
     DB_ENV* dbenv;
     int lockfd, flags;
-    char close_file[MAXPATHLEN + 1];
+       char lock_file[MAXPATHLEN + 1];
 } CNID_private;
 
 /* on-disk data format (in network byte order where appropriate) --
index 023a8f60f4d0d74444cf0188e8916e0ece38b242..78e6fedb475869cd276bbbfb9ce7c6ec20d09b0f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_resolve.c,v 1.8.2.3 2001-12-15 06:35:28 jmarcus Exp $
+ * $Id: cnid_resolve.c,v 1.8.2.4 2002-02-09 20:29:02 jmarcus Exp $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -43,7 +43,7 @@ char *cnid_resolve(void *CNID, cnid_t *id) {
 
         if (rc != DB_NOTFOUND) {
             syslog(LOG_ERR, "cnid_resolve: Unable to get did/name: %s",
-                   db_strerror(rc));
+                db_strerror(rc));
         }
 
         *id = 0;
@@ -53,7 +53,7 @@ char *cnid_resolve(void *CNID, cnid_t *id) {
     memcpy(id, (char *)data.data + CNID_DEVINO_LEN, sizeof(cnid_t));
 #ifdef DEBUG
     syslog(LOG_INFO, "cnid_resolve: Returning id = %u, did/name = %s",
-           ntohl(*id), (char *)data.data + CNID_HEADER_LEN);
+        ntohl(*id), (char *)data.data + CNID_HEADER_LEN);
 #endif
     return (char *)data.data + CNID_HEADER_LEN;
 }
index c8d6b52d21801eeb6c67c08b5df8c6d829766410..b851a02c1fec67f68c955abfac8b843bf46f7b85 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_update.c,v 1.12.2.3 2001-12-15 06:35:28 jmarcus Exp $
+ * $Id: cnid_update.c,v 1.12.2.4 2002-02-09 20:29:02 jmarcus Exp $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -42,8 +42,7 @@ int cnid_update(void *CNID, const cnid_t id, const struct stat *st,
 
 retry:
     if ((rc = txn_begin(db->dbenv, NULL, &tid, 0))) {
-        syslog(LOG_ERR, "cnid_update: Failed to begin transaction: %s",
-               db_strerror(rc));
+        syslog(LOG_ERR, "cnid_update: Failed to begin transaction: %s", db_strerror(rc));
         return rc;
     }
 
@@ -148,7 +147,7 @@ retry:
 
 update_err:
     syslog(LOG_ERR, "cnid_update: Unable to update CNID %u: %s",
-           ntohl(id), db_strerror(rc));
+        ntohl(id), db_strerror(rc));
     return -1;
 }
 #endif /* CNID_DB */
index d2b4778c92e082636ccfda815637a37b55dce94b..8f83142669f7649fade0ec9d87f7ef2c6381b728 100644 (file)
@@ -1,4 +1,4 @@
-dnl $Id: db3-check.m4,v 1.6 2001-11-16 21:51:05 jnewman Exp $
+dnl $Id: db3-check.m4,v 1.6.2.1 2002-02-09 20:29:02 jmarcus Exp $
 dnl Autoconf macro to check for the Berkeley DB3 library
 
 AC_DEFUN([AC_PATH_DB3], [
@@ -24,6 +24,7 @@ AC_DEFUN([AC_PATH_DB3], [
                                db3found=yes
                                DB3_CFLAGS="-I$db3dir"
                                DB3_LIBS="-L$db3libdir -ldb"
+                               DB3_PATH="`echo $db3dir | sed 's,include/db3$,,'`"
                        ])
                        CFLAGS="$savedcflags"
                        LDFLAGS="$savedldflags"
@@ -39,4 +40,5 @@ AC_DEFUN([AC_PATH_DB3], [
 
        AC_SUBST(DB3_CFLAGS)
        AC_SUBST(DB3_LIBS)
+       AC_SUBST(DB3_PATH)
 ])