diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2023-09-11 08:13:01 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2023-09-11 08:13:01 +0000 |
commit | bc3863eaf3e4ae92eac8cd3ce0ca9dcb8915fc36 (patch) | |
tree | 9c6d891677e1d48aa4219636bff1c103d9509a7d /src | |
parent | ddc088fba6016ae839afaa208b0a441869dc936f (diff) | |
download | s6-bc3863eaf3e4ae92eac8cd3ce0ca9dcb8915fc36.tar.xz |
Better s6-setlock; delete the s6lock subsystem
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/conn-tools/deps-exe/s6-ipcserverd | 1 | ||||
-rw-r--r-- | src/conn-tools/s6-ipcserverd.c | 31 | ||||
-rw-r--r-- | src/daemontools-extras/deps-exe/s6-setlock | 4 | ||||
-rw-r--r-- | src/daemontools-extras/s6-setlock.c | 87 | ||||
-rw-r--r-- | src/libs6/deps-lib/s6 | 10 | ||||
-rw-r--r-- | src/libs6/deps-lib/s6lockd | 1 | ||||
-rw-r--r-- | src/libs6/s6lock_acquire.c | 41 | ||||
-rw-r--r-- | src/libs6/s6lock_check.c | 24 | ||||
-rw-r--r-- | src/libs6/s6lock_end.c | 15 | ||||
-rw-r--r-- | src/libs6/s6lock_release.c | 23 | ||||
-rw-r--r-- | src/libs6/s6lock_start.c | 9 | ||||
-rw-r--r-- | src/libs6/s6lock_startf.c | 13 | ||||
-rw-r--r-- | src/libs6/s6lock_update.c | 37 | ||||
-rw-r--r-- | src/libs6/s6lock_wait_and.c | 25 | ||||
-rw-r--r-- | src/libs6/s6lock_wait_or.c | 32 | ||||
-rw-r--r-- | src/libs6/s6lock_zero.c | 5 | ||||
-rw-r--r-- | src/libs6/s6lockd-helper.c | 22 | ||||
-rw-r--r-- | src/libs6/s6lockd.c | 318 | ||||
-rw-r--r-- | src/libs6/s6lockd_openandlock.c | 35 |
19 files changed, 61 insertions, 672 deletions
diff --git a/src/conn-tools/deps-exe/s6-ipcserverd b/src/conn-tools/deps-exe/s6-ipcserverd index bfcb622..19869b2 100644 --- a/src/conn-tools/deps-exe/s6-ipcserverd +++ b/src/conn-tools/deps-exe/s6-ipcserverd @@ -1,3 +1,2 @@ -${LIBS6} -lskarnet ${SOCKET_LIB} diff --git a/src/conn-tools/s6-ipcserverd.c b/src/conn-tools/s6-ipcserverd.c index 2987763..3190985 100644 --- a/src/conn-tools/s6-ipcserverd.c +++ b/src/conn-tools/s6-ipcserverd.c @@ -20,9 +20,8 @@ #include <skalibs/selfpipe.h> #include <skalibs/iopause.h> #include <skalibs/socket.h> -#include <skalibs/exec.h> - -#include <s6/ucspiserver.h> +#include <skalibs/env.h> +#include <skalibs/cspawn.h> #define USAGE "s6-ipcserverd [ -v verbosity ] [ -1 ] [ -P | -p ] [ -c maxconn ] [ -C localmaxconn ] prog..." @@ -55,9 +54,6 @@ static unsigned int numconn = 0 ; static uidnum_t *uidnum ; static unsigned int uidlen = 0 ; - - /* Utility functions */ - static inline void dieusage () { strerr_dieusage(100, USAGE) ; @@ -68,9 +64,6 @@ static inline void X (void) strerr_dief1x(101, "internal inconsistency. Please submit a bug-report.") ; } - - /* Lookup primitives */ - static unsigned int lookup_pid (pid_t pid) { unsigned int i = 0 ; @@ -85,9 +78,6 @@ static inline unsigned int lookup_uid (uid_t uid) return i ; } - - /* Logging */ - static inline void log_start (void) { strerr_warni1x("starting") ; @@ -147,9 +137,6 @@ static inline void log_close (pid_t pid, uid_t uid, int w) strerr_warni6x("end pid ", fmtpid, " uid ", fmtuid, WIFSIGNALED(w) ? " signal " : " exitcode ", fmtw) ; } - - /* Signal handling */ - static void killthem (int sig) { unsigned int i = 0 ; @@ -227,9 +214,6 @@ static inline void handle_signals (void) } } - - /* New connection handling */ - static void new_connection (int s, char const *remotepath, char const *const *argv, char const *const *envp, size_t envlen) { uid_t uid = 0 ; @@ -238,6 +222,12 @@ static void new_connection (int s, char const *remotepath, char const *const *ar size_t rplen = strlen(remotepath) + 1 ; pid_t pid ; unsigned int num, i ; + cspawn_fileaction fa[2] = + { + [0] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = 0, [1] = s } } }, + [1] = { .type = CSPAWN_FA_COPY, .x = { .fd2 = { [0] = 1, [1] = 0 } } } + } ; + char const *newenvp[envlen + 6] ; char fmt[65 + UID_FMT + GID_FMT + UINT_FMT + rplen] ; if (flaglookup && (getpeereid(s, &uid, &gid) < 0)) @@ -272,8 +262,8 @@ static void new_connection (int s, char const *remotepath, char const *const *ar fmt[m++] = 0 ; memcpy(fmt + m, "IPCREMOTEPATH=", 14) ; m += 14 ; memcpy(fmt + m, remotepath, rplen) ; m += rplen ; - - pid = s6_ucspiserver_spawn(s, argv, envp, envlen, fmt, m, 5) ; + env_mergen(newenvp, envlen + 6, envp, envlen, fmt, m, 5) ; + pid = cspawn(argv[0], argv, newenvp, CSPAWN_FLAGS_SELFPIPE_FINISH, fa, 2) ; if (!pid) { if (verbosity) strerr_warnwu2sys("spawn ", argv[0]) ; @@ -295,7 +285,6 @@ static void new_connection (int s, char const *remotepath, char const *const *ar } } - int main (int argc, char const *const *argv) { iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .fd = 0, .events = IOPAUSE_READ | IOPAUSE_EXCEPT } } ; diff --git a/src/daemontools-extras/deps-exe/s6-setlock b/src/daemontools-extras/deps-exe/s6-setlock index 9bb3918..3dc5bdf 100644 --- a/src/daemontools-extras/deps-exe/s6-setlock +++ b/src/daemontools-extras/deps-exe/s6-setlock @@ -1,4 +1,2 @@ -libs6lockd.a.xyzzy -lskarnet -${SYSCLOCK_LIB} -${SPAWN_LIB} +${TIMER_LIB} diff --git a/src/daemontools-extras/s6-setlock.c b/src/daemontools-extras/s6-setlock.c index fea6a11..673caaf 100644 --- a/src/daemontools-extras/s6-setlock.c +++ b/src/daemontools-extras/s6-setlock.c @@ -4,30 +4,40 @@ #include <errno.h> #include <signal.h> -#include <skalibs/allreadwrite.h> #include <skalibs/sgetopt.h> #include <skalibs/strerr.h> #include <skalibs/types.h> #include <skalibs/tai.h> -#include <skalibs/iopause.h> -#include <skalibs/cspawn.h> +#include <skalibs/sig.h> +#include <skalibs/alarm.h> #include <skalibs/djbunix.h> #include <skalibs/exec.h> #include <s6/config.h> -#include "s6lockd.h" -#define USAGE "s6-setlock [ -r | -w ] [ -n | -N | -t timeout ] lockfile prog..." +#define USAGE "s6-setlock [ -r | -w ] [ -n | -N ] [ -t timeout ] [ -d fd ] lockfile prog..." #define dieusage() strerr_dieusage(100, USAGE) +static char const *file ; + +static void sigalrm_handler (int sig) +{ + (void)sig ; + strerr_dief3x(1, "lock ", file, ": timed out") ; +} + int main (int argc, char const *const *argv) { unsigned int nb = 0, ex = 1 ; unsigned int timeout = 0 ; + int dest = -1 ; + int fd ; + int r ; PROG = "s6-setlock" ; + for (;;) { - int opt = lgetopt(argc, argv, "nNrwt:") ; + int opt = lgetopt(argc, argv, "nNrwt:d:") ; if (opt == -1) break ; switch (opt) { @@ -35,47 +45,50 @@ int main (int argc, char const *const *argv) case 'N' : nb = 0 ; break ; case 'r' : ex = 0 ; break ; case 'w' : ex = 1 ; break ; - case 't' : if (!uint0_scan(subgetopt_here.arg, &timeout)) dieusage() ; nb = 2 ; break ; + case 't' : if (!uint0_scan(subgetopt_here.arg, &timeout)) dieusage() ; break ; + case 'd' : { unsigned int u ; if (!uint0_scan(subgetopt_here.arg, &u)) dieusage() ; dest = u ; break ; } default : dieusage() ; } } argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; if (argc < 2) dieusage() ; + file = argv[0] ; - if (nb < 2) s6lockd_openandlock(argv[0], ex, nb) ; + if (ex) + { + fd = open_create(file) ; + if (fd == -1) strerr_diefu3sys(111, "open ", file, " for writing") ; + } else { - char const *cargv[4] = { "s6lockd-helper", ex ? "w" : "r", argv[0], 0 } ; - char const *nullenv = { 0 } ; - iopause_fd x = { .events = IOPAUSE_READ } ; - tain deadline ; - int p[2] = { 0, 1 } ; - pid_t pid ; - char c ; - tain_now_set_stopwatch_g() ; - tain_from_millisecs(&deadline, timeout) ; - tain_add_g(&deadline, &deadline) ; - 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 (;;) + fd = open_read(file) ; + if (fd == -1) { - ssize_t rr ; - int r = iopause_g(&x, 1, &deadline) ; - if (r < 0) strerr_diefu1sys(111, "iopause") ; - if (!r) - { - kill(pid, SIGTERM) ; - errno = ETIMEDOUT ; - strerr_diefu1sys(1, "acquire lock") ; - } - rr = sanitize_read(fd_read(p[0], &c, 1)) ; - if (rr < 0) strerr_diefu1sys(111, "read ack from helper") ; - if (rr) break ; + if (errno != ENOENT) strerr_diefu3sys(111, "open ", file, " for reading") ; + fd = open_create(file) ; + if (fd == -1) strerr_diefu2sys(111, "create ", file) ; + fd_close(fd) ; + fd = open_read(file) ; + if (fd == -1) strerr_diefu3sys(111, "open ", file, " for reading") ; } - if (c != '!') strerr_dief1x(111, "helper sent garbage ack") ; - fd_close(p[0]) ; - if (uncoe(p[1]) < 0) strerr_diefu1sys(111, "uncoe fd to helper") ; } + + if (timeout) + { + tain tto ; + tain_from_millisecs(&tto, timeout) ; + if (!sig_catch(SIGALRM, &sigalrm_handler)) + strerr_diefu1sys(111, "set SIGALRM handler") ; + if (!alarm_timeout(&tto)) + strerr_diefu1sys(111, "set timer") ; + } + r = fd_lock(fd, ex, nb) ; + if (timeout) alarm_disable() ; + + if (!r) errno = EBUSY ; + if (r < 1) strerr_diefu2sys(1, "lock ", file) ; + + if (dest >= 0 && fd_move(dest, fd) == -1) + strerr_diefu1sys(111, "move lock descriptor") ; xexec(argv+1) ; } diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6 index 13b9a83..59999be 100644 --- a/src/libs6/deps-lib/s6 +++ b/src/libs6/deps-lib/s6 @@ -42,16 +42,6 @@ s6_svstatus_pack.o s6_svstatus_read.o s6_svstatus_unpack.o s6_svstatus_write.o -s6lock_acquire.o -s6lock_check.o -s6lock_end.o -s6lock_release.o -s6lock_start.o -s6lock_startf.o -s6lock_update.o -s6lock_wait_and.o -s6lock_wait_or.o -s6lock_zero.o s6_fdholder_delete.o s6_fdholder_delete_async.o s6_fdholder_end.o diff --git a/src/libs6/deps-lib/s6lockd b/src/libs6/deps-lib/s6lockd deleted file mode 100644 index 22cea80..0000000 --- a/src/libs6/deps-lib/s6lockd +++ /dev/null @@ -1 +0,0 @@ -s6lockd_openandlock.o diff --git a/src/libs6/s6lock_acquire.c b/src/libs6/s6lock_acquire.c deleted file mode 100644 index 890f892..0000000 --- a/src/libs6/s6lock_acquire.c +++ /dev/null @@ -1,41 +0,0 @@ -/* ISC license. */ - -#include <sys/uio.h> -#include <string.h> -#include <stdint.h> -#include <errno.h> -#include <skalibs/uint16.h> -#include <skalibs/uint32.h> -#include <skalibs/tai.h> -#include <skalibs/gensetdyn.h> -#include <skalibs/textclient.h> -#include <s6/lock.h> - -int s6lock_acquire (s6lock_t *a, uint16_t *u, char const *path, uint32_t options, tain const *limit, tain const *deadline, tain *stamp) -{ - size_t pathlen = strlen(path) ; - char tmp[23] = "--<" ; - struct iovec v[2] = { { .iov_base = tmp, .iov_len = 23 }, { .iov_base = (char *)path, .iov_len = pathlen + 1 } } ; - uint32_t i ; - if (pathlen > UINT32_MAX) return (errno = ENAMETOOLONG, 0) ; - if (!gensetdyn_new(&a->data, &i)) return 0 ; - if (i > UINT16_MAX) - { - gensetdyn_delete(&a->data, i) ; - return (errno = EMFILE, 0) ; - } - uint16_pack_big(tmp, (uint16_t)i) ; - uint32_pack_big(tmp+3, options) ; - tain_pack(tmp+7, limit) ; - uint32_pack_big(tmp+19, (uint32_t)pathlen) ; - if (!textclient_commandv(&a->connection, v, 2, deadline, stamp)) - { - int e = errno ; - gensetdyn_delete(&a->data, i) ; - errno = e ; - return 0 ; - } - *GENSETDYN_P(unsigned char, &a->data, i) = EAGAIN ; - *u = i ; - return 1 ; -} diff --git a/src/libs6/s6lock_check.c b/src/libs6/s6lock_check.c deleted file mode 100644 index 0602d40..0000000 --- a/src/libs6/s6lock_check.c +++ /dev/null @@ -1,24 +0,0 @@ -/* ISC license. */ - -#include <errno.h> -#include <skalibs/error.h> -#include <skalibs/gensetdyn.h> -#include <s6/lock.h> - -int s6lock_check (s6lock_t *a, uint16_t id) -{ - unsigned char *p = GENSETDYN_P(unsigned char, &a->data, id) ; - switch (*p) - { - case EBUSY : return 1 ; - case EINVAL : return (errno = EINVAL, -1) ; - default : - { - if (error_isagain(*p)) return 0 ; - errno = *p ; - *p = EINVAL ; - gensetdyn_delete(&a->data, id) ; - return -1 ; - } - } -} diff --git a/src/libs6/s6lock_end.c b/src/libs6/s6lock_end.c deleted file mode 100644 index 8611289..0000000 --- a/src/libs6/s6lock_end.c +++ /dev/null @@ -1,15 +0,0 @@ -/* ISC license. */ - -#include <stdint.h> -#include <skalibs/genalloc.h> -#include <skalibs/gensetdyn.h> -#include <skalibs/textclient.h> -#include <s6/lock.h> - -void s6lock_end (s6lock_t *a) -{ - gensetdyn_free(&a->data) ; - genalloc_free(uint16_t, &a->list) ; - textclient_end(&a->connection) ; - *a = s6lock_zero ; -} diff --git a/src/libs6/s6lock_release.c b/src/libs6/s6lock_release.c deleted file mode 100644 index 2c045a6..0000000 --- a/src/libs6/s6lock_release.c +++ /dev/null @@ -1,23 +0,0 @@ -/* ISC license. */ - -#include <errno.h> -#include <skalibs/error.h> -#include <skalibs/uint16.h> -#include <skalibs/gensetdyn.h> -#include <skalibs/textclient.h> -#include <s6/lock.h> - -int s6lock_release (s6lock_t *a, uint16_t i, tain const *deadline, tain *stamp) -{ - unsigned char *p = GENSETDYN_P(unsigned char, &a->data, i) ; - char pack[3] = "-->" ; - if ((*p != EBUSY) && !error_isagain(*p)) - { - s6lock_check(a, i) ; - return 1 ; - } - uint16_pack_big(pack, i) ; - if (!textclient_command(&a->connection, pack, 3, deadline, stamp)) return 0 ; - *p = EINVAL ; - return gensetdyn_delete(&a->data, i) ; -} diff --git a/src/libs6/s6lock_start.c b/src/libs6/s6lock_start.c deleted file mode 100644 index ca8fcc8..0000000 --- a/src/libs6/s6lock_start.c +++ /dev/null @@ -1,9 +0,0 @@ -/* ISC license. */ - -#include <skalibs/textclient.h> -#include <s6/lock.h> - -int s6lock_start (s6lock_t *a, char const *path, tain const *deadline, tain *stamp) -{ - return textclient_start(&a->connection, path, 0, S6LOCK_BANNER1, S6LOCK_BANNER1_LEN, S6LOCK_BANNER2, S6LOCK_BANNER2_LEN, deadline, stamp) ; -} diff --git a/src/libs6/s6lock_startf.c b/src/libs6/s6lock_startf.c deleted file mode 100644 index be6e0c8..0000000 --- a/src/libs6/s6lock_startf.c +++ /dev/null @@ -1,13 +0,0 @@ -/* ISC license. */ - -#include <errno.h> -#include <skalibs/posixplz.h> -#include <skalibs/textclient.h> -#include <s6/lock.h> - -int s6lock_startf (s6lock_t *a, char const *lockdir, tain const *deadline, tain *stamp) -{ - char const *cargv[3] = { S6LOCKD_PROG, lockdir, 0 } ; - if (!lockdir) return (errno = EINVAL, 0) ; - return textclient_startf(&a->connection, cargv, (char const *const *)environ, TEXTCLIENT_OPTION_WAITPID, S6LOCK_BANNER1, S6LOCK_BANNER1_LEN, S6LOCK_BANNER2, S6LOCK_BANNER2_LEN, deadline, stamp) ; -} diff --git a/src/libs6/s6lock_update.c b/src/libs6/s6lock_update.c deleted file mode 100644 index e345230..0000000 --- a/src/libs6/s6lock_update.c +++ /dev/null @@ -1,37 +0,0 @@ -/* ISC license. */ - -#include <sys/uio.h> -#include <stdint.h> -#include <errno.h> - -#include <skalibs/error.h> -#include <skalibs/uint16.h> -#include <skalibs/genalloc.h> -#include <skalibs/gensetdyn.h> -#include <skalibs/textclient.h> - -#include <s6/lock.h> - -#include <skalibs/posixishard.h> - -static int msghandler (struct iovec const *v, void *context) -{ - s6lock_t *a = (s6lock_t *)context ; - char const *s = v->iov_base ; - unsigned char *p ; - uint16_t id ; - if (v->iov_len != 3) return (errno = EPROTO, 0) ; - uint16_unpack_big(s, &id) ; - p = GENSETDYN_P(unsigned char, &a->data, id) ; - if (*p == EBUSY) *p = s[2] ; - else if (error_isagain(*p)) *p = s[2] ? s[2] : EBUSY ; - else return (errno = EPROTO, 0) ; - if (!genalloc_append(uint16_t, &a->list, &id)) return 0 ; - return 1 ; -} - -int s6lock_update (s6lock_t *a) -{ - genalloc_setlen(uint16_t, &a->list, 0) ; - return textclient_update(&a->connection, &msghandler, a) ; -} diff --git a/src/libs6/s6lock_wait_and.c b/src/libs6/s6lock_wait_and.c deleted file mode 100644 index eca7946..0000000 --- a/src/libs6/s6lock_wait_and.c +++ /dev/null @@ -1,25 +0,0 @@ -/* ISC license. */ - -#include <errno.h> -#include <skalibs/iopause.h> -#include <s6/lock.h> - -int s6lock_wait_and (s6lock_t *a, uint16_t const *idlist, unsigned int n, tain const *deadline, tain *stamp) -{ - iopause_fd x = { .fd = -1, .events = IOPAUSE_READ, .revents = 0 } ; - x.fd = s6lock_fd(a) ; - for (; n ; n--, idlist++) - { - for (;;) - { - int r = s6lock_check(a, *idlist) ; - if (r < 0) return r ; - else if (r) break ; - r = iopause_stamp(&x, 1, deadline, stamp) ; - if (r < 0) return r ; - else if (!r) return (errno = ETIMEDOUT, -1) ; - else if (s6lock_update(a) < 0) return -1 ; - } - } - return 0 ; -} diff --git a/src/libs6/s6lock_wait_or.c b/src/libs6/s6lock_wait_or.c deleted file mode 100644 index 4e2a501..0000000 --- a/src/libs6/s6lock_wait_or.c +++ /dev/null @@ -1,32 +0,0 @@ -/* ISC license. */ - -#include <errno.h> - -#include <skalibs/iopause.h> - -#include <s6/lock.h> - -#include <skalibs/posixishard.h> - -int s6lock_wait_or (s6lock_t *a, uint16_t const *idlist, unsigned int n, tain const *deadline, tain *stamp) -{ - iopause_fd x = { -1, IOPAUSE_READ | IOPAUSE_EXCEPT, 0 } ; - x.fd = s6lock_fd(a) ; - if (x.fd < 0) return -1 ; - for (;;) - { - unsigned int i = 0 ; - int r ; - for (; i < n ; i++) - { - r = s6lock_check(a, idlist[i]) ; - if (r < 0) return r ; - else if (r) return i ; - } - r = iopause_stamp(&x, 1, deadline, stamp) ; - if (r < 0) return 0 ; - else if (!r) return (errno = ETIMEDOUT, -1) ; - else if (s6lock_update(a) < 0) return -1 ; - } - return (errno = EPROTO, -1) ; /* can't happen */ -} diff --git a/src/libs6/s6lock_zero.c b/src/libs6/s6lock_zero.c deleted file mode 100644 index 3d35d40..0000000 --- a/src/libs6/s6lock_zero.c +++ /dev/null @@ -1,5 +0,0 @@ -/* ISC license. */ - -#include <s6/lock.h> - -s6lock_t const s6lock_zero = S6LOCK_ZERO ; diff --git a/src/libs6/s6lockd-helper.c b/src/libs6/s6lockd-helper.c deleted file mode 100644 index 7bfcf38..0000000 --- a/src/libs6/s6lockd-helper.c +++ /dev/null @@ -1,22 +0,0 @@ -/* ISC license. */ - -#include <skalibs/allreadwrite.h> -#include <skalibs/strerr.h> - -#include "s6lockd.h" - -#define USAGE "s6lockd-helper r|w lockfile" -#define dieusage() strerr_dieusage(100, USAGE) - -int main (int argc, char const *const *argv) -{ - char c ; - PROG = "s6lockd-helper" ; - if (argc < 3) dieusage() ; - s6lockd_openandlock(argv[2], argv[1][0] == 'w', 0) ; - if (fd_write(1, "!", 1) <= 0) - strerr_diefu1sys(111, "write to stdout") ; - if (fd_read(0, &c, 1) < 0) - strerr_diefu1sys(111, "read from stdin") ; - return 0 ; -} diff --git a/src/libs6/s6lockd.c b/src/libs6/s6lockd.c deleted file mode 100644 index 8cc767a..0000000 --- a/src/libs6/s6lockd.c +++ /dev/null @@ -1,318 +0,0 @@ -/* ISC license. */ - -#include <sys/uio.h> -#include <stdint.h> -#include <unistd.h> -#include <errno.h> -#include <signal.h> - -#include <skalibs/posixishard.h> -#include <skalibs/types.h> -#include <skalibs/allreadwrite.h> -#include <skalibs/error.h> -#include <skalibs/strerr.h> -#include <skalibs/genalloc.h> -#include <skalibs/sig.h> -#include <skalibs/selfpipe.h> -#include <skalibs/tai.h> -#include <skalibs/cspawn.h> -#include <skalibs/djbunix.h> -#include <skalibs/iopause.h> -#include <skalibs/textmessage.h> -#include <skalibs/textclient.h> - -#include <s6/lock.h> - -#define USAGE "s6lockd lockdir" -#define X() strerr_dief1x(101, "internal inconsistency, please submit a bug-report.") - -typedef struct s6lockio_s s6lockio_t, *s6lockio_t_ref ; -struct s6lockio_s -{ - unsigned int xindex ; - unsigned int pid ; - tain limit ; - int p[2] ; - uint16_t id ; /* given by client */ -} ; -#define S6LOCKIO_ZERO { 0, 0, TAIN_ZERO, { -1, -1 }, 0 } -static s6lockio_t const szero = S6LOCKIO_ZERO ; - -static genalloc a = GENALLOC_ZERO ; /* array of s6lockio_t */ - -static void s6lockio_free (s6lockio_t *p) -{ - int e = errno ; - fd_close(p->p[1]) ; - fd_close(p->p[0]) ; - kill(p->pid, SIGTERM) ; - *p = szero ; - errno = e ; -} - -static void cleanup (void) -{ - size_t i = genalloc_len(s6lockio_t, &a) ; - for (; i ; i--) s6lockio_free(genalloc_s(s6lockio_t, &a) + i - 1) ; - genalloc_setlen(s6lockio_t, &a, 0) ; -} - -static void trig (uint16_t id, unsigned char e) -{ - char pack[3] ; - uint16_pack_big(pack, id) ; - pack[2] = e ; - if (!textmessage_put(textmessage_sender_x, pack, 3)) - { - cleanup() ; - strerr_diefu1sys(111, "build answer") ; - } -} - -static void answer (unsigned char c) -{ - if (!textmessage_put(textmessage_sender_1, (char *)&c, 1)) - { - cleanup() ; - strerr_diefu1sys(111, "textmessage_put") ; - } -} - -static void remove (unsigned int i) -{ - size_t n = genalloc_len(s6lockio_t, &a) - 1 ; - s6lockio_free(genalloc_s(s6lockio_t, &a) + i) ; - genalloc_s(s6lockio_t, &a)[i] = genalloc_s(s6lockio_t, &a)[n] ; - genalloc_setlen(s6lockio_t, &a, n) ; -} - -static void handle_signals (void) -{ - for (;;) - { - switch (selfpipe_read()) - { - case -1 : cleanup() ; strerr_diefu1sys(111, "selfpipe_read") ; - case 0 : return ; - case SIGTERM : - case SIGQUIT : - case SIGHUP : - case SIGABRT : - case SIGINT : cleanup() ; _exit(0) ; - case SIGCHLD : wait_reap() ; break ; - default : cleanup() ; X() ; - } - } -} - -static int parse_protocol (struct iovec const *v, void *context) -{ - char *s = v->iov_base ; - uint16_t id ; - if (v->iov_len < 3) - { - cleanup() ; - strerr_dief1x(100, "invalid client request") ; - } - uint16_unpack_big(s, &id) ; - switch (s[2]) - { - case '>' : /* release */ - { - size_t i = genalloc_len(s6lockio_t, &a) ; - for (; i ; i--) if (genalloc_s(s6lockio_t, &a)[i-1].id == id) break ; - if (i) - { - remove(i-1) ; - answer(0) ; - } - else answer(ENOENT) ; - break ; - } - case '<' : /* lock path */ - { - s6lockio_t f = S6LOCKIO_ZERO ; - char const *cargv[4] = { S6LOCKD_HELPER_PROG, "r", 0, 0 } ; - char const *nullenv = 0 ; - uint32_t options, pathlen ; - if (v->iov_len < 23) - { - answer(EPROTO) ; - break ; - } - uint32_unpack_big(s + 3, &options) ; - tain_unpack(s + 7, &f.limit) ; - uint32_unpack_big(s + 19, &pathlen) ; - if (pathlen + 23 != v->iov_len || s[v->iov_len - 1]) - { - answer(EPROTO) ; - break ; - } - f.id = id ; - s[21] = '.' ; - s[22] = '/' ; - 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) ; - break ; - } - if (!genalloc_append(s6lockio_t, &a, &f)) - { - s6lockio_free(&f) ; - answer(errno) ; - break ; - } - answer(0) ; - break ; - } - default : - { - cleanup() ; - strerr_dief1x(100, "invalid client request") ; - } - } - (void)context ; - return 1 ; -} - -int main (int argc, char const *const *argv) -{ - tain deadline ; - PROG = "s6lockd" ; - - if (argc < 2) strerr_dieusage(100, USAGE) ; - if (chdir(argv[1]) < 0) strerr_diefu2sys(111, "chdir to ", argv[1]) ; - if (ndelay_on(0) < 0) strerr_diefu2sys(111, "ndelay_on ", "0") ; - if (ndelay_on(1) < 0) strerr_diefu2sys(111, "ndelay_on ", "1") ; - if (!sig_altignore(SIGPIPE)) strerr_diefu1sys(111, "ignore SIGPIPE") ; - - if (selfpipe_init() == -1) strerr_diefu1sys(111, "selfpipe_init") ; - { - sigset_t set ; - sigemptyset(&set) ; - sigaddset(&set, SIGCHLD) ; - sigaddset(&set, SIGTERM) ; - sigaddset(&set, SIGQUIT) ; - sigaddset(&set, SIGHUP) ; - sigaddset(&set, SIGABRT) ; - sigaddset(&set, SIGINT) ; - if (!selfpipe_trapset(&set)) - strerr_diefu1sys(111, "trap signals") ; - } - - tain_now_set_stopwatch_g() ; - tain_addsec_g(&deadline, 2) ; - - if (!textclient_server_01x_init_g(S6LOCK_BANNER1, S6LOCK_BANNER1_LEN, S6LOCK_BANNER2, S6LOCK_BANNER2_LEN, &deadline)) - strerr_diefu1sys(111, "sync with client") ; - - for (;;) - { - size_t n = genalloc_len(s6lockio_t, &a) ; - iopause_fd x[4 + n] ; - unsigned int i = 0 ; - int r ; - - tain_add_g(&deadline, &tain_infinite_relative) ; - x[0].fd = 0 ; x[0].events = IOPAUSE_EXCEPT | IOPAUSE_READ ; - x[1].fd = 1 ; x[1].events = IOPAUSE_EXCEPT | (textmessage_sender_isempty(textmessage_sender_1) ? 0 : IOPAUSE_WRITE ) ; - x[2].fd = textmessage_sender_fd(textmessage_sender_x) ; - x[2].events = IOPAUSE_EXCEPT | (textmessage_sender_isempty(textmessage_sender_x) ? 0 : IOPAUSE_WRITE) ; - x[3].fd = selfpipe_fd() ; x[3].events = IOPAUSE_READ ; - for (; i < n ; i++) - { - s6lockio_t *p = genalloc_s(s6lockio_t, &a) + i ; - x[4+i].fd = p->p[0] ; - x[4+i].events = IOPAUSE_READ ; - if (p->limit.sec.x && tain_less(&p->limit, &deadline)) deadline = p->limit ; - p->xindex = 4+i ; - } - - r = iopause_g(x, 4 + n, &deadline) ; - if (r < 0) - { - cleanup() ; - strerr_diefu1sys(111, "iopause") ; - } - - /* timeout => seek and destroy */ - if (!r) - { - for (i = 0 ; i < n ; i++) - { - s6lockio_t *p = genalloc_s(s6lockio_t, &a) + i ; - if (p->limit.sec.x && !tain_future(&p->limit)) break ; - } - if (i < n) - { - trig(genalloc_s(s6lockio_t, &a)[i].id, ETIMEDOUT) ; - remove(i) ; - } - continue ; - } - - /* client closed */ - if ((x[0].revents | x[1].revents) & IOPAUSE_EXCEPT) break ; - - /* client is reading */ - if (x[1].revents & IOPAUSE_WRITE) - if (!textmessage_sender_flush(textmessage_sender_1) && !error_isagain(errno)) - { - cleanup() ; - strerr_diefu1sys(111, "flush stdout") ; - } - if (x[2].revents & IOPAUSE_WRITE) - if (!textmessage_sender_flush(textmessage_sender_x) && !error_isagain(errno)) - { - cleanup() ; - strerr_diefu1sys(111, "flush asyncout") ; - } - - /* scan children for successes */ - for (i = 0 ; i < genalloc_len(s6lockio_t, &a) ; i++) - { - s6lockio_t *p = genalloc_s(s6lockio_t, &a) + i ; - if (p->p[0] < 0) continue ; - if (x[p->xindex].revents & IOPAUSE_READ) - { - char c ; - ssize_t r = sanitize_read(fd_read(p->p[0], &c, 1)) ; - if (!r) continue ; - if (r < 0) - { - trig(p->id, errno) ; - remove(i--) ; - } - else if (c != '!') - { - trig(p->id, EPROTO) ; - remove(i--) ; - } - else - { - trig(p->id, 0) ; - p->limit = tain_zero ; - } - } - } - - /* signals arrived */ - if (x[3].revents & (IOPAUSE_READ | IOPAUSE_EXCEPT)) handle_signals() ; - - /* client is writing */ - if (!textmessage_receiver_isempty(textmessage_receiver_0) || x[0].revents & IOPAUSE_READ) - { - if (textmessage_handle(textmessage_receiver_0, &parse_protocol, 0) < 0) - { - if (errno == EPIPE) break ; /* normal exit */ - cleanup() ; - strerr_diefu1sys(111, "handle messages from client") ; - } - } - } - cleanup() ; - return 0 ; -} diff --git a/src/libs6/s6lockd_openandlock.c b/src/libs6/s6lockd_openandlock.c deleted file mode 100644 index ca51934..0000000 --- a/src/libs6/s6lockd_openandlock.c +++ /dev/null @@ -1,35 +0,0 @@ -/* ISC license. */ - -#include <errno.h> - -#include <skalibs/strerr.h> -#include <skalibs/djbunix.h> - -#include "s6lockd.h" - -int s6lockd_openandlock (char const *file, int ex, int nb) -{ - int fd, r ; - if (ex) - { - fd = open_create(file) ; - if (fd < 0) strerr_diefu3sys(111, "open ", file, " for writing") ; - } - else - { - fd = open_read(file) ; - if (fd < 0) - { - if (errno != ENOENT) strerr_diefu3sys(111, "open ", file, " for reading") ; - fd = open_create(file) ; - if (fd < 0) strerr_diefu2sys(111, "create ", file) ; - fd_close(fd) ; - fd = open_read(file) ; - if (fd < 0) strerr_diefu3sys(111, "open ", file, " for reading") ; - } - } - r = fd_lock(fd, ex, nb) ; - if (!r) errno = EBUSY ; - if (r < 1) strerr_diefu2sys(1, "lock ", file) ; - return fd ; -} |