Index: lib/server_mutex.c =================================================================== RCS file: /data/vl/cvstree/samba/source/lib/server_mutex.c,v retrieving revision 1.1.2.4 diff -u -r1.1.2.4 server_mutex.c --- lib/server_mutex.c 17 Mar 2003 23:06:12 -0000 1.1.2.4 +++ lib/server_mutex.c 27 Jan 2004 13:43:34 -0000 @@ -29,28 +29,109 @@ This locking allows smbd's mutlithread architecture to look like the single-connection that NT makes. */ -static char *mutex_server_name; +static int lock_file_fd = 0; + +static SIG_ATOMIC_T gotalarm; + +/*************************************************************** + Signal function to tell us we timed out. + Shamelessly copied from tdbutil.c. +****************************************************************/ + +static void gotalarm_sig(void) +{ + gotalarm = 1; +} + +/**************************************************************************** + fcntl lock with timeout (in seconds). +****************************************************************************/ + +static int fcntl_getlkw_with_timeout(int fd, struct flock *lock, + unsigned int timeout) +{ + /* Allow fcntl to be interrupted by an alarm. */ + int ret; + gotalarm = 0; + + if (timeout) { + CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); + alarm(timeout); + } + + do { + ret = fcntl(fd, F_SETLKW, lock); + if (ret == -1 && errno == EINTR && gotalarm) + break; + } while (ret == -1 && errno == EINTR); + + if (timeout) { + alarm(0); + CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); + if (gotalarm) + return -1; + } + + return ret; +} BOOL grab_server_mutex(const char *name) { - mutex_server_name = strdup(name); - if (!mutex_server_name) { + pstring mutex_path; + char *lock_file_name; + int res; + + if (lock_file_fd != 0) { + DEBUG(0, ("Already got a lock file fd, name = %s\n", name)); + return False; + } + + pstrcpy(mutex_path, lock_path("mutex")); + mkdir(mutex_path, 0700); + + if (!directory_exist(mutex_path, NULL)) { + DEBUG(0, ("Could not create mutex dir: %s\n", mutex_path)); + return False; + } + + asprintf(&lock_file_name, "%s/%s", mutex_path, name); + + if (!lock_file_name) { DEBUG(0,("grab_server_mutex: malloc failed for %s\n", name)); return False; } - if (!secrets_named_mutex(mutex_server_name, 10)) { - DEBUG(10,("grab_server_mutex: failed for %s\n", name)); - SAFE_FREE(mutex_server_name); + + lock_file_fd = open(lock_file_name, O_RDWR|O_CREAT, 0600); + + if (lock_file_fd < 0) { + DEBUG(0, ("Could not create lock file %s\n", lock_file_name)); + free(lock_file_name); return False; } - return True; + free(lock_file_name); + + { + struct flock lock; + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 1; + + res = fcntl_getlkw_with_timeout(lock_file_fd, &lock, 10); + } + + if (res == -1) { + close(lock_file_fd); + lock_file_fd = 0; + } + + return res; } void release_server_mutex(void) { - if (mutex_server_name) { - secrets_named_mutex_release(mutex_server_name); - SAFE_FREE(mutex_server_name); + if (lock_file_fd != 0) { + close(lock_file_fd); } } Index: torture/torture.c =================================================================== RCS file: /data/vl/cvstree/samba/source/torture/torture.c,v retrieving revision 1.63.2.21 diff -u -r1.63.2.21 torture.c --- torture/torture.c 30 Dec 2003 15:18:25 -0000 1.63.2.21 +++ torture/torture.c 27 Jan 2004 14:23:35 -0000 @@ -4421,6 +4421,33 @@ return True; } +static BOOL run_one_mutex(int client) +{ + char *name; + + asprintf(&name, "test%d", client%10); + + printf("Trying to grab mutex %s\n", name); + + if (grab_server_mutex(name) == 0) + printf("success\n"); + else + printf("failure\n"); + + sleep(1); + + release_server_mutex(); + return True; +} + +static BOOL run_mutex(int dummy) +{ + BOOL correct = True; + + create_procs(run_one_mutex, &correct); + return correct; +} + static double create_procs(BOOL (*fn)(int), BOOL *result) { int i, status; @@ -4570,6 +4597,7 @@ {"IOCTL", torture_ioctl_test, 0}, {"CHKPATH", torture_chkpath_test, 0}, {"FDSESS", run_fdsesstest, 0}, + {"MUTEX", run_mutex, 0}, {NULL, NULL, 0}};