]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/alock.c
Unify use of BDB lockers
[openldap] / servers / slapd / alock.c
index fc9e5290cb87cc6298695aeb18936345fc499bf2..37d467ad127e658ee0ee0021998f4a13cfa22924 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2005 The OpenLDAP Foundation.
+ * Copyright 2005-2007 The OpenLDAP Foundation.
  * Portions Copyright 2004-2005 Symas Corporation.
  * All rights reserved.
  *
@@ -21,7 +21,7 @@
 
 #include "portable.h"
 
-#if SLAPD_BDB || SLAPD_HDB || SLAPD_LDBM
+#if SLAPD_BDB || SLAPD_HDB
 
 #include "alock.h"
 
@@ -32,7 +32,9 @@
 #include <ac/assert.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#if HAVE_SYS_FILE_H
 #include <sys/file.h>
+#endif
 #include <fcntl.h>
 
 #ifdef _WIN32
@@ -229,7 +231,7 @@ alock_read_slot ( alock_info_t * info,
        }
        
        if (alock_read_iattr (slotbuf) != ALOCK_MAGIC) {
-               return 1;
+               return -1;
        }
        slot_data->al_lock  = alock_read_iattr (slotbuf+8);
        slot_data->al_stamp = alock_read_iattr (slotbuf+16);
@@ -262,7 +264,8 @@ alock_write_slot ( alock_info_t * info,
        alock_write_iattr (slotbuf+16, slot_data->al_stamp);
        alock_write_iattr (slotbuf+24, slot_data->al_pid);
 
-       strncpy ((char *)slotbuf+32, slot_data->al_appname, ALOCK_MAX_APPNAME-1);
+       if (slot_data->al_appname)
+               strncpy ((char *)slotbuf+32, slot_data->al_appname, ALOCK_MAX_APPNAME-1);
        slotbuf[ALOCK_SLOT_SIZE-1] = '\0';
 
        res = lseek (info->al_fd, 
@@ -290,7 +293,7 @@ alock_write_slot ( alock_info_t * info,
 static int
 alock_query_slot ( alock_info_t * info )
 {
-       int res;
+       int res, nosave;
        alock_slot_t slot_data;
 
        assert (info != NULL);
@@ -302,19 +305,22 @@ alock_query_slot ( alock_info_t * info )
        if (slot_data.al_appname != NULL) free (slot_data.al_appname);
        slot_data.al_appname = NULL;
 
-       if (slot_data.al_lock == ALOCK_UNLOCKED) return ALOCK_UNLOCKED;
+       nosave = slot_data.al_lock & ALOCK_NOSAVE;
+
+       if ((slot_data.al_lock & ALOCK_SMASK) == ALOCK_UNLOCKED)
+               return slot_data.al_lock;
 
        res = alock_test_lock (info->al_fd, info->al_slot);
        if (res < 0) return -1;
        if (res > 0) {
-               if (slot_data.al_lock == ALOCK_UNIQUE) {
-                       return ALOCK_UNIQUE;
+               if ((slot_data.al_lock & ALOCK_SMASK) == ALOCK_UNIQUE) {
+                       return slot_data.al_lock;
                } else {
-                       return ALOCK_LOCKED;
+                       return ALOCK_LOCKED | nosave;
                }
        }
        
-       return ALOCK_DIRTY;
+       return ALOCK_DIRTY | nosave;
 }
 
 int 
@@ -328,12 +334,12 @@ alock_open ( alock_info_t * info,
        alock_slot_t slot_data;
        char * filename;
        int res, max_slot;
-       int dirty_count, live_count;
+       int dirty_count, live_count, nosave;
 
        assert (info != NULL);
        assert (appname != NULL);
        assert (envdir != NULL);
-       assert (locktype >= 1 && locktype <= 2);
+       assert ((locktype & ALOCK_SMASK) >= 1 && (locktype & ALOCK_SMASK) <= 2);
 
        slot_data.al_lock = locktype;
        slot_data.al_stamp = time(NULL);
@@ -370,6 +376,7 @@ alock_open ( alock_info_t * info,
        max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE;
        dirty_count = 0;
        live_count = 0;
+       nosave = 0;
        scan_info.al_fd = info->al_fd;
        for (scan_info.al_slot = 1; 
             scan_info.al_slot < max_slot;
@@ -377,6 +384,10 @@ alock_open ( alock_info_t * info,
                if (scan_info.al_slot != info->al_slot) {
                        res = alock_query_slot (&scan_info);
 
+                       if (res & ALOCK_NOSAVE) {
+                               nosave = ALOCK_NOSAVE;
+                               res ^= ALOCK_NOSAVE;
+                       }
                        if (res == ALOCK_UNLOCKED
                            && info->al_slot == 0) {
                                info->al_slot = scan_info.al_slot;
@@ -429,8 +440,8 @@ alock_open ( alock_info_t * info,
                return ALOCK_UNSTABLE;
        }
        
-       if (dirty_count) return ALOCK_RECOVER;
-       return ALOCK_CLEAN;
+       if (dirty_count) return ALOCK_RECOVER | nosave;
+       return ALOCK_CLEAN | nosave;
 }
 
 int 
@@ -439,7 +450,7 @@ alock_scan ( alock_info_t * info )
        struct stat statbuf;
        alock_info_t scan_info;
        int res, max_slot;
-       int dirty_count, live_count;
+       int dirty_count, live_count, nosave;
 
        assert (info != NULL);
 
@@ -460,12 +471,18 @@ alock_scan ( alock_info_t * info )
        max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE;
        dirty_count = 0;
        live_count = 0;
+       nosave = 0;
        for (scan_info.al_slot = 1; 
             scan_info.al_slot < max_slot;
             ++ scan_info.al_slot) {
                if (scan_info.al_slot != info->al_slot) {
                        res = alock_query_slot (&scan_info);
 
+                       if (res & ALOCK_NOSAVE) {
+                               nosave = ALOCK_NOSAVE;
+                               res ^= ALOCK_NOSAVE;
+                       }
+
                        if (res == ALOCK_LOCKED) {
                                ++live_count;
                                
@@ -491,11 +508,11 @@ alock_scan ( alock_info_t * info )
                        close (info->al_fd);
                        return ALOCK_UNSTABLE;
                } else {
-                       return ALOCK_RECOVER;
+                       return ALOCK_RECOVER | nosave;
                }
        }
        
-       return ALOCK_CLEAN;
+       return ALOCK_CLEAN | nosave;
 }
 
 int
@@ -504,6 +521,9 @@ alock_close ( alock_info_t * info )
        alock_slot_t slot_data;
        int res;
 
+       if ( !info->al_slot )
+               return ALOCK_CLEAN;
+
        (void) memset ((void *) &slot_data, 0, sizeof(alock_slot_t));
 
        res = alock_grab_lock (info->al_fd, 0);
@@ -520,7 +540,7 @@ alock_close ( alock_info_t * info )
                        free (slot_data.al_appname);
                return ALOCK_UNSTABLE;
        }
-       slot_data.al_lock = ALOCK_UNLOCKED;
+       slot_data.al_lock = ALOCK_UNLOCKED | (slot_data.al_lock & ALOCK_NOSAVE);
        res = alock_write_slot (info, &slot_data);
        if (res == -1) {
                close (info->al_fd);
@@ -581,7 +601,7 @@ alock_recover ( alock_info_t * info )
             scan_info.al_slot < max_slot;
             ++ scan_info.al_slot) {
                if (scan_info.al_slot != info->al_slot) {
-                       res = alock_query_slot (&scan_info);
+                       res = alock_query_slot (&scan_info) & ~ALOCK_NOSAVE;
 
                        if (res == ALOCK_LOCKED
                            || res == ALOCK_UNIQUE) {