]> arthur.barton.de Git - netatalk.git/commitdiff
Hopefully fix a problem when multiple clients mount and unmount a volume
authorjmarcus <jmarcus>
Fri, 14 Dec 2001 03:10:37 +0000 (03:10 +0000)
committerjmarcus <jmarcus>
Fri, 14 Dec 2001 03:10:37 +0000 (03:10 +0000)
repeatedly.  Also, make the cnid.recover file a little more fool-proof.

libatalk/cnid/cnid_close.c
libatalk/cnid/cnid_open.c
libatalk/cnid/cnid_private.h

index 232a6cf9c373284f2e7e775fcba3f775169e26bb..133bf73719b12c533be22f48a6ffafbf78fe600f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_close.c,v 1.17 2001-12-13 15:15:05 jmarcus Exp $
+ * $Id: cnid_close.c,v 1.18 2001-12-14 03:10:37 jmarcus Exp $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -40,33 +40,42 @@ void cnid_close(void *CNID) {
         lock.l_start = lock.l_len = 0;
         if (fcntl(db->lockfd, F_SETLK, &lock) == 0) {
             char **list, **first;
+            int cfd = -1;
 
-            /* Checkpoint the databases until we can checkpoint no
-             * more. */
-            rc = txn_checkpoint(db->dbenv, 0, 0, 0);
-            while (rc == DB_INCOMPLETE) {
+            if ((cfd = open(db->close_file, O_RDWR | O_CREAT, 0666)) > -1) {
+
+                /* 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);
+                }
 
 #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_LOG | 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_LOG | 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);
                 }
-                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));
             }
         }
     }
index e708624296e5eb6268c29535196aaf1157d433d0..520ced1f28e61e5f2bc1fcfc31555c2cc1b489d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_open.c,v 1.27 2001-12-13 03:31:34 jmarcus Exp $
+ * $Id: cnid_open.c,v 1.28 2001-12-14 03:10:37 jmarcus Exp $
  *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
@@ -72,6 +72,7 @@
 #define DBLONGNAME   "longname.db"  /* did/unicode mapping */
 #define DBLOCKFILE   "cnid.lock"
 #define DBRECOVERFILE "cnid.dbrecover"
+#define DBCLOSEFILE  "cnid.close"
 
 #define DBHOMELEN    8
 #define DBLEN        10
@@ -187,7 +188,7 @@ static int compare_unicode(const DBT *a, const DBT *b)
 static int have_lock = 0;
 
 void *cnid_open(const char *dir) {
-    struct stat st, rsb;
+    struct stat st, rsb, csb;
     struct flock lock;
     char path[MAXPATHLEN + 1];
     char recover_file[MAXPATHLEN + 1];
@@ -234,6 +235,15 @@ 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, sleep on the close file. */
+    while(stat(db->close_file, &csb) == 0) {
+        sleep(1);
+    }
+
     strcpy(recover_file, path);
     strcat(recover_file, DBRECOVERFILE);
 
@@ -555,6 +565,10 @@ fail_lock:
     if (db->lockfd > -1) {
         close(db->lockfd);
     }
+    if (rfd > -1) {
+        (void)remove(recover_file);
+        close(rfd);
+    }
 
 fail_adouble:
 
index 1f079843bfd6a0ba89a27866b84ee4b116e5b5c3..eb104e25661c3523edd444689fa4156aa3633ae5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_private.h,v 1.4 2001-11-27 23:38:18 jmarcus Exp $
+ * $Id: cnid_private.h,v 1.5 2001-12-14 03:10:37 jmarcus Exp $
  */
 
 #ifndef LIBATALK_CNID_PRIVATE_H
@@ -46,6 +46,7 @@ typedef struct CNID_private {
 #endif /* EXTENDED_DB */
     DB_ENV* dbenv;
     int lockfd, flags;
+    char close_file[MAXPATHLEN + 1];
 } CNID_private;
 
 /* on-disk data format (in network byte order where appropriate) --