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

Reply via email to