diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/daemontools-extras/s6-log.c | 11 | ||||
-rw-r--r-- | src/daemontools-extras/s6-setlock.c | 18 | ||||
-rw-r--r-- | src/libs6/deps-lib/s6 | 4 | ||||
-rw-r--r-- | src/libs6/s6_supervise_lock.c | 9 | ||||
-rw-r--r-- | src/libs6/s6_supervise_lock_mode.c | 85 | ||||
-rw-r--r-- | src/libs6/s6_svc_lock_release.c | 8 | ||||
-rw-r--r-- | src/libs6/s6_svc_lock_take.c | 28 | ||||
-rw-r--r-- | src/libs6/s6_svc_ok.c | 23 | ||||
-rw-r--r-- | src/libs6/s6lockd-helper.c | 17 | ||||
-rw-r--r-- | src/libs6/s6lockd.c | 10 | ||||
-rw-r--r-- | src/supervision/deps-exe/s6-svscan | 1 | ||||
-rw-r--r-- | src/supervision/s6-supervise.c | 95 | ||||
-rw-r--r-- | src/supervision/s6-svscan.c | 47 |
13 files changed, 176 insertions, 180 deletions
diff --git a/src/daemontools-extras/s6-log.c b/src/daemontools-extras/s6-log.c index 2f8438d..5128751 100644 --- a/src/daemontools-extras/s6-log.c +++ b/src/daemontools-extras/s6-log.c @@ -580,13 +580,14 @@ static inline void logdir_init (unsigned int index, uint32_t s, uint32_t n, uint ldp->fd = -1 ; ldp->rstate = ROTSTATE_WRITABLE ; r = mkdir(ldp->dir, S_IRWXU | S_ISGID) ; - if ((r < 0) && (errno != EEXIST)) strerr_diefu2sys(111, "mkdir ", name) ; + if (r < 0 && errno != EEXIST) strerr_diefu2sys(111, "mkdir ", name) ; memcpy(x, name, dirlen) ; memcpy(x + dirlen, "/lock", 6) ; - ldp->fdlock = open_append(x) ; - if ((ldp->fdlock) < 0) strerr_diefu2sys(111, "open_append ", x) ; - if (lock_exnb(ldp->fdlock) < 0) strerr_diefu2sys(111, "lock_exnb ", x) ; - if (coe(ldp->fdlock) < 0) strerr_diefu2sys(111, "coe ", x) ; + ldp->fdlock = openc_create(x) ; + if (ldp->fdlock < 0) strerr_diefu2sys(111, "open ", x) ; + r = fd_lock(ldp->fdlock, 1, 1) ; + if (!r) errno = EBUSY ; + if (r < 1) strerr_diefu2sys(111, "lock ", x) ; memcpy(x + dirlen + 1, "current", 8) ; if (stat(x, &st) < 0) { diff --git a/src/daemontools-extras/s6-setlock.c b/src/daemontools-extras/s6-setlock.c index bc50519..cd938b7 100644 --- a/src/daemontools-extras/s6-setlock.c +++ b/src/daemontools-extras/s6-setlock.c @@ -18,11 +18,6 @@ #define USAGE "s6-setlock [ -r | -w ] [ -n | -N | -t timeout ] lockfile prog..." #define dieusage() strerr_dieusage(100, USAGE) -typedef int lockfunc_t (int) ; -typedef lockfunc_t *lockfunc_t_ref ; - -static lockfunc_t_ref f[2][2] = { { &lock_sh, &lock_shnb }, { &lock_ex, &lock_exnb } } ; - int main (int argc, char const *const *argv) { unsigned int nb = 0, ex = 1 ; @@ -47,14 +42,17 @@ int main (int argc, char const *const *argv) if (nb < 2) { + int r ; int fd = open_create(argv[0]) ; - if (fd == -1) strerr_diefu2sys(111, "open_create ", argv[0]) ; - if ((*f[ex][nb])(fd) == -1) strerr_diefu2sys(1, "lock ", argv[0]) ; + if (fd < 0) strerr_diefu2sys(111, "open_create ", argv[0]) ; + r = fd_lock(fd, ex, nb) ; + if (!r) errno = EBUSY ; + if (r < 1) strerr_diefu2sys(1, "lock ", argv[0]) ; } else { - char const *cargv[3] = { "s6lockd-helper", argv[0], 0 } ; - char const *cenvp[2] = { ex ? "S6LOCK_EX=1" : 0, 0 } ; + char const *cargv[4] = { "s6lockd-helper", ex ? "w" : "r", argv[0], 0 } ; + char const *nullenv = { 0 } ; iopause_fd x = { .events = IOPAUSE_READ } ; tain_t deadline ; int p[2] = { 0, 1 } ; @@ -63,7 +61,7 @@ int main (int argc, char const *const *argv) tain_now_set_stopwatch_g() ; tain_from_millisecs(&deadline, timeout) ; tain_add_g(&deadline, &deadline) ; - pid = child_spawn2(S6_LIBEXECPREFIX "s6lockd-helper", cargv, cenvp, p) ; + pid = child_spawn2(S6_LIBEXECPREFIX "s6lockd-helper", cargv, &nullenv, p) ; if (!pid) strerr_diefu2sys(111, "spawn ", S6_LIBEXECPREFIX "s6lockd-helper") ; x.fd = p[0] ; for (;;) diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6 index ddd86dc..d9d4341 100644 --- a/src/libs6/deps-lib/s6 +++ b/src/libs6/deps-lib/s6 @@ -31,10 +31,6 @@ s6_dtally_pack.o s6_dtally_unpack.o s6_dtally_read.o s6_dtally_write.o -s6_supervise_lock.o -s6_supervise_lock_mode.o -s6_svc_lock_take.o -s6_svc_lock_release.o s6_svc_ok.o s6_svc_write.o s6_svc_writectl.o diff --git a/src/libs6/s6_supervise_lock.c b/src/libs6/s6_supervise_lock.c deleted file mode 100644 index e241320..0000000 --- a/src/libs6/s6_supervise_lock.c +++ /dev/null @@ -1,9 +0,0 @@ -/* ISC license. */ - -#include <sys/stat.h> -#include <s6/s6-supervise.h> - -int s6_supervise_lock (char const *subdir) -{ - return s6_supervise_lock_mode(subdir, S_IRWXU, S_IRUSR | S_IWUSR) ; -} diff --git a/src/libs6/s6_supervise_lock_mode.c b/src/libs6/s6_supervise_lock_mode.c deleted file mode 100644 index d807bec..0000000 --- a/src/libs6/s6_supervise_lock_mode.c +++ /dev/null @@ -1,85 +0,0 @@ -/* ISC license. */ - -#include <limits.h> -#include <unistd.h> -#include <sys/stat.h> -#include <string.h> -#include <errno.h> - -#include <skalibs/strerr2.h> -#include <skalibs/djbunix.h> - -#include <s6/s6-supervise.h> - -#ifdef PATH_MAX -# define S6_PATH_MAX PATH_MAX -#else -# define S6_PATH_MAX 4096 -#endif - -int s6_supervise_lock_mode (char const *subdir, unsigned int subdirmode, unsigned int controlmode) -{ - size_t subdirlen = strlen(subdir) ; - int fdctl, fdctlw, fdlock ; - char control[subdirlen + 9] ; - char lock[subdirlen + 6] ; - memcpy(control, subdir, subdirlen) ; - memcpy(control + subdirlen, "/control", 9) ; - memcpy(lock, subdir, subdirlen) ; - memcpy(lock + subdirlen, "/lock", 6) ; - if (mkdir(subdir, (mode_t)subdirmode) == -1) - { - char buf[S6_PATH_MAX] ; - ssize_t r ; - if (errno == EEXIST) strerr_diefu2sys(111, "mkdir ", subdir) ; - r = readlink(subdir, buf, S6_PATH_MAX) ; - if (r < 0) - { - if (errno != EINVAL) - { - errno = EEXIST ; - strerr_diefu2sys(111, "mkdir ", subdir) ; - } - } - else if (r == S6_PATH_MAX) - { - errno = ENAMETOOLONG ; - strerr_diefu2sys(111, "readlink ", subdir) ; - } - else - { - buf[r] = 0 ; - if (mkdir(buf, (mode_t)subdirmode) == -1) - strerr_diefu2sys(111, "mkdir ", buf) ; - } - } - if (mkfifo(control, controlmode) < 0) - { - struct stat st ; - if (errno != EEXIST) - strerr_diefu2sys(111, "mkfifo ", control) ; - if (stat(control, &st) < 0) - strerr_diefu2sys(111, "stat ", control) ; - if (!S_ISFIFO(st.st_mode)) - strerr_diefu2x(100, control, " is not a FIFO") ; - } - fdlock = openc_create(lock) ; - if (fdlock < 0) - strerr_diefu2sys(111, "open_create ", lock) ; - if (lock_ex(fdlock) < 0) - strerr_diefu2sys(111, "lock ", lock) ; - fdctlw = openc_write(control) ; - if (fdctlw >= 0) strerr_dief1x(100, "directory already locked") ; - if (errno != ENXIO) - strerr_diefu2sys(111, "open_write ", control) ; - fdctl = openc_read(control) ; - if (fdctl < 0) - strerr_diefu2sys(111, "open_read ", control) ; - fdctlw = openc_write(control) ; - if (fdctlw < 0) - strerr_diefu2sys(111, "open_write ", control) ; - fd_close(fdlock) ; - - return fdctl ; - /* we leak fdctlw but it's coe. */ -} diff --git a/src/libs6/s6_svc_lock_release.c b/src/libs6/s6_svc_lock_release.c deleted file mode 100644 index 4a6f68d..0000000 --- a/src/libs6/s6_svc_lock_release.c +++ /dev/null @@ -1,8 +0,0 @@ -/* ISC license. */ - -#include <skalibs/djbunix.h> - -void s6_svc_lock_release (int fd) -{ - fd_close(fd) ; -} diff --git a/src/libs6/s6_svc_lock_take.c b/src/libs6/s6_svc_lock_take.c deleted file mode 100644 index fcb098a..0000000 --- a/src/libs6/s6_svc_lock_take.c +++ /dev/null @@ -1,28 +0,0 @@ -/* ISC license. */ - -#include <sys/stat.h> -#include <string.h> -#include <errno.h> -#include <skalibs/djbunix.h> -#include <s6/s6-supervise.h> - - /* XXX: does not work with dangling S6_SUPERVISE_CTLDIR symlinks */ - -int s6_svc_lock_take (char const *dir) -{ - size_t dirlen = strlen(dir) ; - int fdlock ; - char lock[dirlen + sizeof(S6_SUPERVISE_CTLDIR) + 6] ; - memcpy(lock, dir, dirlen) ; - memcpy(lock + dirlen, "/" S6_SUPERVISE_CTLDIR, sizeof(S6_SUPERVISE_CTLDIR) + 1) ; - if ((mkdir(lock, S_IRWXU) < 0) && (errno != EEXIST)) return -1 ; - memcpy(lock + dirlen + sizeof(S6_SUPERVISE_CTLDIR), "/lock", 6) ; - fdlock = openc_create(lock) ; - if (fdlock < 0) return -1 ; - if (lock_ex(fdlock) < 0) - { - fd_close(fdlock) ; - return -1 ; - } - return fdlock ; -} diff --git a/src/libs6/s6_svc_ok.c b/src/libs6/s6_svc_ok.c index 5e6aa27..4940071 100644 --- a/src/libs6/s6_svc_ok.c +++ b/src/libs6/s6_svc_ok.c @@ -2,24 +2,23 @@ #include <string.h> #include <errno.h> + #include <skalibs/djbunix.h> + #include <s6/s6-supervise.h> int s6_svc_ok (char const *dir) { - size_t dirlen = strlen(dir) ; + int r ; + int e = errno ; int fd ; - char fn[dirlen + 9 + sizeof(S6_SUPERVISE_CTLDIR)] ; + size_t dirlen = strlen(dir) ; + char fn[dirlen + 6 + sizeof(S6_SUPERVISE_CTLDIR)] ; memcpy(fn, dir, dirlen) ; - fn[dirlen] = '/' ; - memcpy(fn + dirlen + 1, S6_SUPERVISE_CTLDIR, sizeof(S6_SUPERVISE_CTLDIR) - 1) ; - memcpy(fn + dirlen + sizeof(S6_SUPERVISE_CTLDIR), "/control", 9) ; - fd = open_write(fn) ; - if (fd < 0) - { - if ((errno == ENXIO) || (errno == ENOENT)) return 0 ; - else return -1 ; - } + memcpy(fn + dirlen, "/" S6_SUPERVISE_CTLDIR "/lock", 6 + sizeof(S6_SUPERVISE_CTLDIR)) ; + fd = open_read(fn) ; + if (fd < 0) return errno == ENOENT ? (errno = e, 0) : -1 ; + r = fd_islocked(fd) ; fd_close(fd) ; - return 1 ; + return r ; } diff --git a/src/libs6/s6lockd-helper.c b/src/libs6/s6lockd-helper.c index 8979c67..469a417 100644 --- a/src/libs6/s6lockd-helper.c +++ b/src/libs6/s6lockd-helper.c @@ -1,24 +1,25 @@ /* ISC license. */ +#include <errno.h> + #include <skalibs/allreadwrite.h> #include <skalibs/strerr2.h> -#include <skalibs/env.h> #include <skalibs/djbunix.h> #define USAGE "s6lockd-helper lockfile" #define dieusage() strerr_dieusage(100, USAGE) -int main (int argc, char const *const *argv, char const *const *envp) +int main (int argc, char const *const *argv) { - int fd ; - char const *x = env_get2(envp, "S6LOCK_EX") ; + int fd, r ; char c ; PROG = "s6lockd-helper" ; - if (argc < 2) dieusage() ; - fd = open_create(argv[1]) ; + if (argc < 3) dieusage() ; + fd = open_create(argv[2]) ; if (fd < 0) strerr_diefu2sys(111, "open ", argv[1]) ; - if (((x && *x) ? lock_ex(fd) : lock_sh(fd)) < 0) - strerr_diefu2sys(111, "lock ", argv[1]) ; + r = fd_lock(fd, argv[1][0] == 'w', 0) ; + if (!r) errno = EBUSY ; + if (r < 1) strerr_diefu2sys(111, "lock ", argv[2]) ; if (fd_write(1, "!", 1) <= 0) strerr_diefu1sys(111, "write to stdout") ; if (fd_read(0, &c, 1) < 0) diff --git a/src/libs6/s6lockd.c b/src/libs6/s6lockd.c index afa8b3e..f2d18f9 100644 --- a/src/libs6/s6lockd.c +++ b/src/libs6/s6lockd.c @@ -131,8 +131,8 @@ static int parse_protocol (struct iovec const *v, void *context) case '<' : /* lock path */ { s6lockio_t f = S6LOCKIO_ZERO ; - char const *cargv[3] = { S6LOCKD_HELPER_PROG, 0, 0 } ; - char const *cenvp[2] = { 0, 0 } ; + char const *cargv[4] = { S6LOCKD_HELPER_PROG, "r", 0, 0 } ; + char const *nullenv = 0 ; uint32_t options, pathlen ; if (v->iov_len < 23) { @@ -150,9 +150,9 @@ static int parse_protocol (struct iovec const *v, void *context) f.id = id ; s[21] = '.' ; s[22] = '/' ; - cargv[1] = (char const *)s + 21 ; - if (options & S6LOCK_OPTIONS_EX) cenvp[0] = "S6LOCK_EX=1" ; - f.pid = child_spawn2(cargv[0], cargv, cenvp, f.p) ; + if (options & S6LOCK_OPTIONS_EX) cargv[1] = "w" ; + cargv[2] = (char const *)s + 21 ; + f.pid = child_spawn2(cargv[0], cargv, &nullenv, f.p) ; if (!f.pid) { answer(errno) ; diff --git a/src/supervision/deps-exe/s6-svscan b/src/supervision/deps-exe/s6-svscan index 0b76878..756dcc2 100644 --- a/src/supervision/deps-exe/s6-svscan +++ b/src/supervision/deps-exe/s6-svscan @@ -1,4 +1,3 @@ -${LIBS6} -lskarnet ${SYSCLOCK_LIB} ${SPAWN_LIB} diff --git a/src/supervision/s6-supervise.c b/src/supervision/s6-supervise.c index da6a187..112ccea 100644 --- a/src/supervision/s6-supervise.c +++ b/src/supervision/s6-supervise.c @@ -3,13 +3,16 @@ /* For SIGWINCH */ #include <skalibs/nonposix.h> -#include <sys/wait.h> #include <unistd.h> #include <string.h> #include <strings.h> #include <errno.h> #include <fcntl.h> +#include <limits.h> #include <signal.h> +#include <sys/stat.h> +#include <sys/wait.h> + #include <skalibs/allreadwrite.h> #include <skalibs/bytestr.h> #include <skalibs/types.h> @@ -20,10 +23,19 @@ #include <skalibs/sig.h> #include <skalibs/selfpipe.h> #include <skalibs/skamisc.h> + #include <s6/ftrigw.h> #include <s6/s6-supervise.h> #define USAGE "s6-supervise dir" +#define CTL S6_SUPERVISE_CTLDIR "/control" +#define LCK S6_SUPERVISE_CTLDIR "/lock" + +#ifdef PATH_MAX +# define S6_PATH_MAX PATH_MAX +#else +# define S6_PATH_MAX 4096 +#endif typedef enum trans_e trans_t, *trans_t_ref ; enum trans_e @@ -625,6 +637,83 @@ static inline void handle_control (int fd) } } +static int trymkdir (char const *s) +{ + char buf[S6_PATH_MAX] ; + ssize_t r ; + if (mkdir(s, 0700) >= 0) return 1 ; + if (errno != EEXIST) strerr_diefu2sys(111, "mkdir ", s) ; + r = readlink(s, buf, S6_PATH_MAX) ; + if (r < 0) + { + struct stat st ; + if (errno != EINVAL) + { + errno = EEXIST ; + strerr_diefu2sys(111, "mkdir ", s) ; + } + if (stat(s, &st) < 0) + strerr_diefu2sys(111, "stat ", s) ; + if (!S_ISDIR(st.st_mode)) + strerr_dief2x(100, s, " exists and is not a directory") ; + return 0 ; + } + else if (r == S6_PATH_MAX) + { + errno = ENAMETOOLONG ; + strerr_diefu2sys(111, "readlink ", s) ; + } + else + { + buf[r] = 0 ; + if (mkdir(buf, 0700) < 0) + strerr_diefu2sys(111, "mkdir ", buf) ; + return 1 ; + } +} + +static inline int control_init (void) +{ + mode_t m = umask(0) ; + int fdctl, fdlck, r ; + if (trymkdir(S6_SUPERVISE_EVENTDIR)) + { + if (chown(S6_SUPERVISE_EVENTDIR, -1, getegid()) < 0) + strerr_diefu1sys(111, "chown " S6_SUPERVISE_EVENTDIR) ; + if (chmod(S6_SUPERVISE_EVENTDIR, 03730) < 0) + strerr_diefu1sys(111, "chmod " S6_SUPERVISE_EVENTDIR) ; + } + + trymkdir(S6_SUPERVISE_CTLDIR) ; + fdlck = open(LCK, O_WRONLY | O_NONBLOCK | O_CREAT | O_CLOEXEC, 0600) ; + if (fdlck < 0) strerr_diefu1sys(111, "open " LCK) ; + r = fd_lock(fdlck, 1, 1) ; + if (r < 0) strerr_diefu1sys(111, "lock " LCK) ; + if (!r) strerr_dief1x(100, "another instance of s6-supervise is already running") ; + /* fdlck leaks but it's coe */ + + if (mkfifo(CTL, 0600) < 0) + { + struct stat st ; + if (errno != EEXIST) + strerr_diefu1sys(111, "mkfifo " CTL) ; + if (stat(CTL, &st) < 0) + strerr_diefu1sys(111, "stat " CTL) ; + if (!S_ISFIFO(st.st_mode)) + strerr_dief1x(100, CTL " is not a FIFO") ; + } + fdctl = openc_read(CTL) ; + if (fdctl < 0) + strerr_diefu1sys(111, "open " CTL " for reading") ; + r = openc_write(CTL) ; + if (r < 0) + strerr_diefu1sys(111, "open " CTL " for writing") ; + /* r leaks but it's coe */ + + umask(m) ; + return fdctl ; +} + int main (int argc, char const *const *argv) { iopause_fd x[3] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ; @@ -640,9 +729,7 @@ int main (int argc, char const *const *argv) memcpy(progname + proglen + 1, argv[1], namelen + 1) ; PROG = progname ; if (!fd_sanitize()) strerr_diefu1sys(111, "sanitize stdin and stdout") ; - if (!ftrigw_fifodir_make(S6_SUPERVISE_EVENTDIR, getegid(), 0)) - strerr_diefu2sys(111, "mkfifodir ", S6_SUPERVISE_EVENTDIR) ; - x[1].fd = s6_supervise_lock(S6_SUPERVISE_CTLDIR) ; + x[1].fd = control_init() ; x[0].fd = selfpipe_init() ; if (x[0].fd == -1) strerr_diefu1sys(111, "init selfpipe") ; if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ; diff --git a/src/supervision/s6-svscan.c b/src/supervision/s6-svscan.c index 3f63c2d..1d17a3a 100644 --- a/src/supervision/s6-svscan.c +++ b/src/supervision/s6-svscan.c @@ -27,6 +27,8 @@ #define USAGE "s6-svscan [ -c maxservices ] [ -t timeout ] [ -d notif ] [ -X consoleholder ] [ dir ]" #define dieusage() strerr_dieusage(100, USAGE) +#define CTL S6_SVSCAN_CTLDIR "/control" +#define LCK S6_SVSCAN_CTLDIR "/lock" #define FINISH_PROG S6_SVSCAN_CTLDIR "/finish" #define CRASH_PROG S6_SVSCAN_CTLDIR "/crash" #define SIGNAL_PROG S6_SVSCAN_CTLDIR "/SIG" @@ -480,6 +482,49 @@ static inline void scan (void) } } +static inline int control_init (void) +{ + mode_t m = umask(0) ; + int fdctl, fdlck, r ; + if (mkdir(S6_SVSCAN_CTLDIR, 0700) < 0) + { + struct stat st ; + if (errno != EEXIST) + strerr_diefu1sys(111, "mkdir " S6_SVSCAN_CTLDIR) ; + if (stat(CTL, &st) < 0) + strerr_diefu1sys(111, "stat " S6_SVSCAN_CTLDIR) ; + if (!S_ISDIR(st.st_mode)) + strerr_dief1x(100, S6_SVSCAN_CTLDIR " exists and is not a directory") ; + } + + fdlck = open(LCK, O_WRONLY | O_NONBLOCK | O_CREAT | O_CLOEXEC, 0600) ; + if (fdlck < 0) strerr_diefu1sys(111, "open " LCK) ; + r = fd_lock(fdlck, 1, 1) ; + if (r < 0) strerr_diefu1sys(111, "lock " LCK) ; + if (!r) strerr_dief1x(100, "another instance of s6-svscan is already running on the same directory") ; + /* fdlck leaks but it's coe */ + + if (mkfifo(CTL, 0600) < 0) + { + struct stat st ; + if (errno != EEXIST) + strerr_diefu1sys(111, "mkfifo " CTL) ; + if (stat(CTL, &st) < 0) + strerr_diefu1sys(111, "stat " CTL) ; + if (!S_ISFIFO(st.st_mode)) + strerr_dief1x(100, CTL " is not a FIFO") ; + } + fdctl = openc_read(CTL) ; + if (fdctl < 0) + strerr_diefu1sys(111, "open " CTL " for reading") ; + r = openc_write(CTL) ; + if (r < 0) + strerr_diefu1sys(111, "open " CTL " for writing") ; + /* r leaks but it's coe */ + + umask(m) ; + return fdctl ; +} int main (int argc, char const *const *argv) { @@ -515,7 +560,7 @@ int main (int argc, char const *const *argv) if (argc && (chdir(argv[0]) < 0)) strerr_diefu1sys(111, "chdir") ; if (consoleholder && coe(consoleholder) < 0) strerr_diefu1sys(111, "coe console holder") ; - x[1].fd = s6_supervise_lock(S6_SVSCAN_CTLDIR) ; + x[1].fd = control_init() ; x[0].fd = selfpipe_init() ; if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ; |