Commit b96c0af7 authored by Martin Blix Grydeland's avatar Martin Blix Grydeland Committed by Tollef Fog Heen

Use file locking on SHMFILE to indicate this file is currently in use

Fixes: #876
parent fb1dfce7
......@@ -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,
......
......@@ -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
......@@ -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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment