Changeset: 8207b6567c1b for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8207b6567c1b Modified Files: common/utils/msabaoth.c common/utils/mutils.c common/utils/mutils.h Branch: Jun2016 Log Message:
In msab_getStatus, only test for a lock, don't actually lock. There is a race condition in merovingian's forkMserver otherwise. After forking, the client goes off and executes mserver5 which tries to obtain the lock for the farm (.gdk_lock file). In the mean time, the parent of the fork calls msab_getStatus repeatedly until the server has started. If msab_getStatus actually locks the file at the wrong moment, it can prevent mserver5 from locking the file (it only tries once) and mserver5 will exit. See bug 4066. diffs (73 lines): diff --git a/common/utils/msabaoth.c b/common/utils/msabaoth.c --- a/common/utils/msabaoth.c +++ b/common/utils/msabaoth.c @@ -675,7 +675,7 @@ msab_getSingleStatus(const char *pathbuf (void)fclose(f); } } else if ((snprintf(buf, sizeof(buf), "%s/%s/%s", pathbuf, dbname, ".gdk_lock") > 0) & /* no typo */ - ((fd = MT_lockf(buf, F_TLOCK, 4, 1)) == -2)) { + ((fd = MT_lockf(buf, F_TEST, 4, 1)) == -2)) { /* Locking failed; this can be because the lockfile couldn't * be created. Probably there is no Mserver running for * that case also. @@ -709,9 +709,6 @@ msab_getSingleStatus(const char *pathbuf /* no uplog, so presumably never started */ sdb->state = SABdbInactive; } - /* release the lock */ - MT_lockf(buf, F_ULOCK, 4, 1); - close(fd); } snprintf(buf, sizeof(buf), "%s/%s/%s", pathbuf, dbname, MAINTENANCEFILE); if (stat(buf, &statbuf) == -1) { diff --git a/common/utils/mutils.c b/common/utils/mutils.c --- a/common/utils/mutils.c +++ b/common/utils/mutils.c @@ -356,6 +356,13 @@ MT_lockf(char *filename, int mode, off_t ret = LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0, len, 0, &ov); } else if (mode == F_LOCK) { ret = LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, len, 0, &ov); + } else if (mode == F_TEST) { + ret = LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0, len, 0, &ov); + if (ret != 0) { + UnlockFileEx(fh, 0, len, 0, &ov); + close(fd); + return 0; + } } else { close(fd); errno = EINVAL; @@ -408,6 +415,7 @@ lockf(int fd, int cmd, off_t len) #endif /* returns -1 when locking failed, * returns -2 when the lock file could not be opened/created + * returns 0 when mode is F_TEST and the lock file was not locked * returns the (open) file descriptor to the file when locking * returns 0 when unlocking */ int @@ -420,7 +428,7 @@ MT_lockf(char *filename, int mode, off_t if (lseek(fd, off, SEEK_SET) >= 0 && lockf(fd, mode, len) == 0) { - if (mode == F_ULOCK) { + if (mode == F_ULOCK || mode == F_TEST) { close(fd); return 0; } diff --git a/common/utils/mutils.h b/common/utils/mutils.h --- a/common/utils/mutils.h +++ b/common/utils/mutils.h @@ -56,9 +56,10 @@ mutils_export char *dirname(char *path); #define MONETDB_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) -#define F_TLOCK 2 /* test and lock a region for exclusive use */ -#define F_ULOCK 0 /* unlock a previously locked region */ -#define F_LOCK 1 /* lock a region for exclusive use */ +#define F_TEST 3 /* test a region for other processes locks. */ +#define F_TLOCK 2 /* test and lock a region for exclusive use */ +#define F_ULOCK 0 /* unlock a previously locked region */ +#define F_LOCK 1 /* lock a region for exclusive use */ mutils_export int MT_lockf(char *filename, int mode, off_t off, off_t len); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list