Do lock failures slightly better, return a special value so we don't

unlink the wrong thing.
This commit is contained in:
nicm 2015-11-24 23:01:51 +00:00
parent 73e30cbda8
commit dca93c56e0
2 changed files with 23 additions and 19 deletions

View File

@ -67,23 +67,21 @@ const char *client_exit_message(void);
/* /*
* Get server create lock. If already held then server start is happening in * Get server create lock. If already held then server start is happening in
* another client, so block until the lock is released and return -1 to * another client, so block until the lock is released and return -2 to
* retry. Ignore other errors - just continue and start the server without the * retry. Return -1 on failure to continue and start the server anyway.
* lock.
*/ */
int int
client_get_lock(char *lockfile) client_get_lock(char *lockfile)
{ {
int lockfd; int lockfd;
if ((lockfd = open(lockfile, O_WRONLY|O_CREAT, 0600)) == -1) {
lockfd = open("/dev/null", O_WRONLY);
if (lockfd == -1)
fatal("open failed");
return (lockfd);
}
log_debug("lock file is %s", lockfile); log_debug("lock file is %s", lockfile);
if ((lockfd = open(lockfile, O_WRONLY|O_CREAT, 0600)) == -1) {
log_debug("open failed: %s", strerror(errno));
return (-1);
}
if (flock(lockfd, LOCK_EX|LOCK_NB) == -1) { if (flock(lockfd, LOCK_EX|LOCK_NB) == -1) {
log_debug("flock failed: %s", strerror(errno)); log_debug("flock failed: %s", strerror(errno));
if (errno != EAGAIN) if (errno != EAGAIN)
@ -91,7 +89,7 @@ client_get_lock(char *lockfile)
while (flock(lockfd, LOCK_EX) == -1 && errno == EINTR) while (flock(lockfd, LOCK_EX) == -1 && errno == EINTR)
/* nothing */; /* nothing */;
close(lockfd); close(lockfd);
return (-1); return (-2);
} }
log_debug("flock succeeded"); log_debug("flock succeeded");
@ -131,12 +129,16 @@ retry:
if (!locked) { if (!locked) {
xasprintf(&lockfile, "%s.lock", path); xasprintf(&lockfile, "%s.lock", path);
if ((lockfd = client_get_lock(lockfile)) == -1) { if ((lockfd = client_get_lock(lockfile)) < 0) {
log_debug("didn't get lock"); log_debug("didn't get lock (%d)", lockfd);
free(lockfile); free(lockfile);
goto retry; lockfile = NULL;
if (lockfd == -2)
goto retry;
} }
log_debug("got lock"); log_debug("got lock (%d)", lockfd);
/* /*
* Always retry at least once, even if we got the lock, * Always retry at least once, even if we got the lock,
@ -148,7 +150,7 @@ retry:
goto retry; goto retry;
} }
if (unlink(path) != 0 && errno != ENOENT) { if (lockfd >= 0 && unlink(path) != 0 && errno != ENOENT) {
free(lockfile); free(lockfile);
close(lockfd); close(lockfd);
return (-1); return (-1);
@ -156,7 +158,7 @@ retry:
fd = server_start(base, lockfd, lockfile); fd = server_start(base, lockfd, lockfile);
} }
if (locked) { if (locked && lockfd >= 0) {
free(lockfile); free(lockfile);
close(lockfd); close(lockfd);
} }

View File

@ -195,9 +195,11 @@ server_start(struct event_base *base, int lockfd, char *lockfile)
server_update_socket(); server_update_socket();
server_client_create(pair[1]); server_client_create(pair[1]);
unlink(lockfile); if (lockfd >= 0) {
free(lockfile); unlink(lockfile);
close(lockfd); free(lockfile);
close(lockfd);
}
start_cfg(); start_cfg();