X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Falock.c;h=37d467ad127e658ee0ee0021998f4a13cfa22924;hb=e48f72c1b5a7ce571c7ced749aed473d20b32526;hp=cf90f9b946bde9e70c4d0139196f96d61fe4b54d;hpb=464fc6b68abab64cd09430b4b8fd3c7034452330;p=openldap diff --git a/servers/slapd/alock.c b/servers/slapd/alock.c index cf90f9b946..37d467ad12 100644 --- a/servers/slapd/alock.c +++ b/servers/slapd/alock.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2005 The OpenLDAP Foundation. + * Copyright 2005-2007 The OpenLDAP Foundation. * Portions Copyright 2004-2005 Symas Corporation. * All rights reserved. * @@ -32,7 +32,9 @@ #include #include #include +#if HAVE_SYS_FILE_H #include +#endif #include #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) {