diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-04-18 14:53:46 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-04-18 14:53:46 +0300 |
commit | 7c8140491ce8547fe45a791fb0a185817b5ff8ec (patch) | |
tree | 079f04ba8448930c9bc926bd7d2d71a5efa3b04f /src/lock.c | |
parent | 1c754c175e78d36aec8c4437d5a024169445f798 (diff) | |
download | wydawca-7c8140491ce8547fe45a791fb0a185817b5ff8ec.tar.gz wydawca-7c8140491ce8547fe45a791fb0a185817b5ff8ec.tar.bz2 |
Remove spool locking
* NEWS: Document changes.
* doc/wydawca.texi: Document changes.
* src/Makefile.am: Remove lock.c
* src/lock.c: Delete.
* src/config.c: Remove the locking statement.
* tests/etc/wydawca.cfin: Likewise.
* src/wydawca.c: Check pidfile before startup, unless in dry-run mode.
* src/wydawca.h: Remove prototypes of locking functions
* src/process.c (scan_spool_unlocked): Merge into
scan_spool.
* src/timer.c (struct timer_slot): Use reference counter instead
of timer state
Diffstat (limited to 'src/lock.c')
-rw-r--r-- | src/lock.c | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/src/lock.c b/src/lock.c deleted file mode 100644 index f2ed532..0000000 --- a/src/lock.c +++ /dev/null @@ -1,275 +0,0 @@ -/* wydawca - automatic release submission daemon - Copyright (C) 2007, 2009-2013, 2017, 2019-2020 Sergey Poznyakoff - - Wydawca is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3 of the License, or (at your - option) any later version. - - Wydawca is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with wydawca. If not, see <http://www.gnu.org/licenses/>. */ - -#include "wydawca.h" - -int enable_locking = 1; -char *lockdir; -time_t lock_expire_time = 5 * 60; -time_t lock_timeout = 60; - -#define LOCKFILE_MODE 0644 - -static int -stat_check(const char *file, int fd, int links) -{ - struct stat fn_stat; - struct stat fd_stat; - int err = 0; - int localfd = -1; - - if (fd == -1) { - localfd = open(file, O_RDONLY); - - if (localfd == -1) - return errno; - fd = localfd; - } - - /* We should always be able to stat a valid fd, so this - is an error condition. */ - if (lstat(file, &fn_stat) || fstat(fd, &fd_stat)) - err = errno; - else { - /* If the link and stat don't report the same info, or the - file is a symlink, fail the locking. */ -#define CHK(X) if(X) err = EINVAL - - CHK(!S_ISREG(fn_stat.st_mode)); - CHK(!S_ISREG(fd_stat.st_mode)); - CHK(fn_stat.st_nlink != links); - CHK(fn_stat.st_dev != fd_stat.st_dev); - CHK(fn_stat.st_ino != fd_stat.st_ino); - CHK(fn_stat.st_mode != fd_stat.st_mode); - CHK(fn_stat.st_nlink != fd_stat.st_nlink); - CHK(fn_stat.st_uid != fd_stat.st_uid); - CHK(fn_stat.st_gid != fd_stat.st_gid); - CHK(fn_stat.st_rdev != fd_stat.st_rdev); - -#undef CHK - } - if (localfd != -1) - close(localfd); - - return err; -} - -int -_lock_internal(const char *file, const char *fname) -{ - int err = 0; - int fd; - FILE *fp; - - fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, LOCKFILE_MODE); - if (fd == -1) { - if (errno == EEXIST) - return LOCK_RETRY; - else { - wy_log(LOG_ERR, _("cannot create lock file %s: %s"), - fname, strerror(errno)); - return LOCK_FAILURE; - } - } - close(fd); - - /* Try to link to the lockfile. */ - if (link(fname, file) == -1) { - unlink(fname); - if (errno == EEXIST) - return LOCK_RETRY; - else { - wy_log(LOG_ERR, _("cannot create lock file %s: %s"), - file, strerror(errno)); - return LOCK_FAILURE; - } - } - - if ((fd = open(file, O_RDWR)) == -1) { - unlink(fname); - wy_log(LOG_ERR, _("cannot open lock file %s: %s"), - fname, strerror(errno)); - return LOCK_FAILURE; - } - - err = stat_check(fname, fd, 2); - if (err) { - unlink(fname); - wy_log(LOG_ERR, _("lock file check failed: %s"), strerror(errno)); - return (err == EINVAL) ? LOCK_INVALID : LOCK_FAILURE; - } - - unlink(fname); - - fp = fdopen(fd, "w"); - fprintf(fp, "%lu", (unsigned long) getpid()); - fclose(fp); - - return 0; -} - -static void -expire_stale_lock(const char *file) -{ - int stale = 0; - char buf[80]; - int fd; - int len; - - fd = open(file, O_RDONLY); - if (fd == -1) - return; - - len = read(fd, buf, sizeof(buf) - 1); - if (len > 0) { - pid_t pid; - - buf[len] = 0; - pid = strtoul(buf, NULL, 10); - if (pid > 0) { - /* Process is gone so we try to remove the lock. */ - if (kill(pid, 0) == -1) - stale = 1; - } else - stale = 1; /* Corrupted file, remove the lock. */ - } - - if (!stale && lock_expire_time > 0) { - struct stat stbuf; - fstat(fd, &stbuf); - /* The lock has expired. */ - if ((time(NULL) - stbuf.st_mtime) > lock_expire_time) - stale = 1; - } - - close(fd); - if (stale) - unlink(file); -} - -static char * -host_name() -{ - static char *hostbuf = NULL; - size_t size = 0; - int rc; - - if (hostbuf) - return hostbuf; - - do { - if (!hostbuf) { - size = 256; - hostbuf = grecs_malloc(size); - } else { - size_t ns = size * 2; - if (size < ns) - grecs_alloc_die(); - size = ns; - hostbuf = grecs_realloc(hostbuf, size); - } - } - while ((rc = gethostname(hostbuf, size)) == -1 - && (errno == EINVAL -#ifdef ENAMETOOLONG - || errno == ENAMETOOLONG -#endif - )); - if (rc) { - wy_log(LOG_ERR, _("cannot get hostname: %s"), strerror(rc)); - exit(EX_SOFTWARE); - } - return hostbuf; -} - -int -wydawca_lock(const char *lockname) -{ - char *tempname = NULL; - size_t size = 0; - int rc; - - if (!enable_locking) - return 0; - expire_stale_lock(lockname); - - /* build the NFS hitching-post to the lock file */ - grecs_asprintf(&tempname, &size, "%s.%lu.%lu.%s", - lockname, - (unsigned long) getpid(), - (unsigned long) time(NULL), host_name()); - if (!tempname) - return LOCK_FAILURE; - if (lock_timeout) { - time_t start = time(NULL); - - do { - rc = _lock_internal(lockname, tempname); - if (rc == LOCK_RETRY) - sleep(1); - else - break; - } - while (time(NULL) - start < lock_timeout); - } else - rc = _lock_internal(lockname, tempname); - - free(tempname); - return rc; -} - -void -wydawca_unlock(const char *lockfile) -{ - if (enable_locking) - unlink(lockfile); -} - -static char * -fix_tagname(const char *tag) -{ - char *tagname = grecs_strdup(tag); - char *p; - - for (p = tagname; *p; p++) - if (!isalnum(*p) && *p != '_' && *p != '-') - *p = '_'; - return tagname; -} - -char * -wydawca_lockname(const char *tag) -{ - char *lockname = NULL; - size_t size = 0; - char *tagname = fix_tagname(tag); - grecs_asprintf(&lockname, &size, "%s/LCK.%s", lockdir, tagname); - if (!lockname) - grecs_alloc_die(); - free(tagname); - return lockname; -} - -void -wydawca_lock_init() -{ - if (enable_locking) { - if (!lockdir) - lockdir = grecs_strdup(LOCALSTATEDIR "/lock/" PACKAGE); - if (create_hierarchy(AT_FDCWD, lockdir)) - exit(EX_OSFILE); - } -} |