[experimental-ims] 78df00d Use file locking on SHMFILE to indicate this file is currently in use
Geoff Simmons
geoff at varnish-cache.org
Fri Jul 8 11:47:41 CEST 2011
commit 78df00d176c2cc323b4a66024aac2087a09a9e0b
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date: Tue Jun 14 13:09:56 2011 +0200
Use file locking on SHMFILE to indicate this file is currently in use
Fixes: #876
diff --git a/bin/varnishd/mgt_shmem.c b/bin/varnishd/mgt_shmem.c
index f28bc9b..4fc905c 100644
--- a/bin/varnishd/mgt_shmem.c
+++ b/bin/varnishd/mgt_shmem.c
@@ -101,6 +101,7 @@
#include "heritage.h"
#include "vmb.h"
#include "vsm.h"
+#include "flopen.h"
#ifndef MAP_HASSEMAPHORE
#define MAP_HASSEMAPHORE 0 /* XXX Linux */
@@ -125,11 +126,24 @@ vsl_n_check(int fd)
struct VSM_head slh;
int i;
struct stat st;
+ pid_t pid;
AZ(fstat(fd, &st));
if (!S_ISREG(st.st_mode))
ARGV_ERR("\tshmlog: Not a file\n");
+ /* Test if the SHMFILE is locked by other Varnish */
+ if (fltest(fd, &pid) > 0) {
+ fprintf(stderr,
+ "SHMFILE locked by running varnishd master (pid=%jd)\n",
+ (intmax_t)pid);
+ fprintf(stderr,
+ "(Use unique -n arguments if you want multiple "
+ "instances)\n");
+ exit(2);
+ }
+
+ /* Read owning pid from SHMFILE */
memset(&slh, 0, sizeof slh); /* XXX: for flexelint */
i = read(fd, &slh, sizeof slh);
if (i != sizeof slh)
@@ -138,15 +152,11 @@ vsl_n_check(int fd)
return;
if (slh.hdrsize != sizeof slh)
return;
-
if (slh.master_pid != 0 && !kill(slh.master_pid, 0)) {
- fprintf(stderr,
- "SHMFILE owned by running varnishd master (pid=%jd)\n",
- (intmax_t)slh.master_pid);
- fprintf(stderr,
- "(Use unique -n arguments if you want multiple "
- "instances.)\n");
- exit(2);
+ fprintf(stderr,
+ "WARNING: Taking over SHMFILE marked as owned by "
+ "running process (pid=%jd)\n",
+ (intmax_t)slh.master_pid);
}
}
@@ -161,15 +171,20 @@ vsl_buildnew(const char *fn, unsigned size, int fill)
int i;
unsigned u;
char buf[64*1024];
+ int flags;
(void)unlink(fn);
- vsl_fd = open(fn, O_RDWR | O_CREAT | O_EXCL, 0644);
+ vsl_fd = flopen(fn, O_RDWR | O_CREAT | O_EXCL | O_NONBLOCK, 0644);
if (vsl_fd < 0) {
fprintf(stderr, "Could not create %s: %s\n",
fn, strerror(errno));
exit (1);
}
-
+ flags = fcntl(vsl_fd, F_GETFL);
+ assert(flags != -1);
+ flags &= ~O_NONBLOCK;
+ AZ(fcntl(vsl_fd, F_SETFL, flags));
+
memset(&slh, 0, sizeof slh);
slh.magic = VSM_HEAD_MAGIC;
slh.hdrsize = sizeof slh;
@@ -277,7 +292,6 @@ mgt_SHM_Init(const char *l_arg)
vsl_n_check(i);
(void)close(i);
}
- (void)close(i);
vsl_buildnew(VSM_FILENAME, size, fill);
VSM_head = (void *)mmap(NULL, size,
diff --git a/include/flopen.h b/include/flopen.h
index 4bd0209..e5b6030 100644
--- a/include/flopen.h
+++ b/include/flopen.h
@@ -31,6 +31,9 @@
#ifndef FLOPEN_H_INCLUDED
#define FLOPEN_H_INCLUDED
+#include <sys/types.h>
+
int flopen(const char *, int, ...);
+int fltest(int fd, pid_t *pid);
#endif
diff --git a/lib/libvarnish/flopen.c b/lib/libvarnish/flopen.c
index 43882fe..483d8d6 100644
--- a/lib/libvarnish/flopen.c
+++ b/lib/libvarnish/flopen.c
@@ -107,3 +107,27 @@ flopen(const char *path, int flags, ...)
return (fd);
}
}
+
+/* Tests if the given fd is locked through flopen
+ * If pid is non-NULL, stores the pid of the process holding the lock there
+ * Returns 1 if the file is locked
+ * Returns 0 if the file is unlocked
+ * Returns -1 on error (and errno)
+ */
+int
+fltest(int fd, pid_t *pid)
+{
+ struct flock lock;
+
+ memset(&lock, 0, sizeof lock);
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+
+ if (fcntl(fd, F_GETLK, &lock) == -1)
+ return (-1);
+ if (lock.l_type == F_UNLCK)
+ return (0);
+ if (pid != NULL)
+ *pid = lock.l_pid;
+ return (1);
+}
More information about the varnish-commit
mailing list