diff options
-rw-r--r-- | package/deps.mak | 4 | ||||
-rw-r--r-- | src/shutdown/deps-exe/s6-linux-init-shutdownd | 1 | ||||
-rw-r--r-- | src/shutdown/s6-linux-init-shutdownd.c | 50 |
3 files changed, 47 insertions, 8 deletions
diff --git a/package/deps.mak b/package/deps.mak index 565df1a..486a8af 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -15,7 +15,7 @@ src/shutdown/hpr_shutdown.o src/shutdown/hpr_shutdown.lo: src/shutdown/hpr_shutd src/shutdown/hpr_wall.o src/shutdown/hpr_wall.lo: src/shutdown/hpr_wall.c src/shutdown/hpr.h src/shutdown/s6-linux-init-hpr.o src/shutdown/s6-linux-init-hpr.lo: src/shutdown/s6-linux-init-hpr.c src/include-local/defaults.h src/shutdown/hpr.h src/shutdown/s6-linux-init-shutdown.o src/shutdown/s6-linux-init-shutdown.lo: src/shutdown/s6-linux-init-shutdown.c src/include-local/defaults.h src/shutdown/hpr.h src/include-local/initctl.h -src/shutdown/s6-linux-init-shutdownd.o src/shutdown/s6-linux-init-shutdownd.lo: src/shutdown/s6-linux-init-shutdownd.c src/include-local/defaults.h src/shutdown/hpr.h src/include-local/initctl.h +src/shutdown/s6-linux-init-shutdownd.o src/shutdown/s6-linux-init-shutdownd.lo: src/shutdown/s6-linux-init-shutdownd.c src/include-local/defaults.h src/shutdown/hpr.h src/include-local/initctl.h src/include/s6-linux-init/config.h s6-linux-init: EXTRA_LIBS := s6-linux-init: src/init/s6-linux-init.o -lskarnet @@ -46,5 +46,5 @@ s6-linux-init-hpr: src/shutdown/s6-linux-init-hpr.o libhpr.a.xyzzy ${LIBUTMPS} - s6-linux-init-shutdown: EXTRA_LIBS := ${TAINNOW_LIB} ${SOCKET_LIB} s6-linux-init-shutdown: src/shutdown/s6-linux-init-shutdown.o libhpr.a.xyzzy ${LIBUTMPS} -lskarnet s6-linux-init-shutdownd: EXTRA_LIBS := ${TAINNOW_LIB} ${SOCKET_LIB} -s6-linux-init-shutdownd: src/shutdown/s6-linux-init-shutdownd.o ${LIBUTMPS} -lskarnet +s6-linux-init-shutdownd: src/shutdown/s6-linux-init-shutdownd.o -ls6 ${LIBUTMPS} -lskarnet INTERNAL_LIBS := libhpr.a.xyzzy diff --git a/src/shutdown/deps-exe/s6-linux-init-shutdownd b/src/shutdown/deps-exe/s6-linux-init-shutdownd index 5a7d2fd..01c9db2 100644 --- a/src/shutdown/deps-exe/s6-linux-init-shutdownd +++ b/src/shutdown/deps-exe/s6-linux-init-shutdownd @@ -1,3 +1,4 @@ +-ls6 ${LIBUTMPS} -lskarnet ${TAINNOW_LIB} diff --git a/src/shutdown/s6-linux-init-shutdownd.c b/src/shutdown/s6-linux-init-shutdownd.c index 19d3e19..7f86e66 100644 --- a/src/shutdown/s6-linux-init-shutdownd.c +++ b/src/shutdown/s6-linux-init-shutdownd.c @@ -27,18 +27,45 @@ #include <execline/config.h> +#include <s6/s6-supervise.h> + #include <s6-linux-init/config.h> #include "defaults.h" #include "initctl.h" #include "hpr.h" #define STAGE4_FILE "stage 4" +#define SCANPREFIX S6_LINUX_INIT_TMPFS "/" SCANDIR "/" +#define SCANPREFIXLEN (sizeof(SCANPREFIX) - 1) +#define DOTPREFIX ".s6-linux-init-shutdownd:" +#define DOTPREFIXLEN (sizeof(DOTPREFIX) - 1) +#define DOTSUFFIX ":XXXXXX" +#define DOTSUFFIXLEN (sizeof(DOTSUFFIX) - 1) #define USAGE "s6-linux-init-shutdownd [ -c basedir ] [ -g gracetime ]" #define dieusage() strerr_dieusage(100, USAGE) static char const *basedir = BASEDIR ; +struct at_s +{ + int fd ; + char const *name ; +} ; + +static int renametemp (char const *s, mode_t mode, void *data) +{ + struct at_s *at = data ; + (void)mode ; + return renameat(at->fd, at->name, at->fd, s) ; +} + +static int mkrenametemp (int fd, char const *src, char *dst) +{ + struct at_s at = { .fd = fd, .name = src } ; + return mkfiletemp(dst, &renametemp, 0700, &at) ; +} + static inline void run_stage3 (char const *basedir, char const *const *envp) { pid_t pid ; @@ -140,7 +167,6 @@ static inline void prepare_stage4 (char const *basedir, char what) fd_close(fd) ; if (rename(STAGE4_FILE ".new", STAGE4_FILE) == -1) strerr_diefu4sys(111, "rename ", STAGE4_FILE ".new", " to ", STAGE4_FILE) ; - sleep(20) ; } static inline void unsupervise_tree (void) @@ -149,12 +175,16 @@ static inline void unsupervise_tree (void) { LOGGER_SERVICEDIR, SHUTDOWND_SERVICEDIR, - EARLYGETTY_SERVICEDIR, + /* EARLYGETTY_SERVICEDIR, */ 0 } ; DIR *dir = opendir(S6_LINUX_INIT_TMPFS "/" SCANDIR) ; + int fdd ; if (!dir) strerr_diefu1sys(111, "opendir " S6_LINUX_INIT_TMPFS "/" SCANDIR) ; + fdd = dirfd(dir) ; + if (fdd == -1) + strerr_diefu1sys(111, "dir_fd " S6_LINUX_INIT_TMPFS "/" SCANDIR) ; for (;;) { char const *const *p = except ; @@ -167,10 +197,18 @@ static inline void unsupervise_tree (void) if (!*p) { size_t dlen = strlen(d->d_name) ; - char fn[sizeof(S6_LINUX_INIT_TMPFS "/" SCANDIR "/") + dlen] ; - memcpy(fn, S6_LINUX_INIT_TMPFS "/" SCANDIR "/", sizeof(S6_LINUX_INIT_TMPFS "/" SCANDIR "/") - 1) ; - memcpy(fn + sizeof(S6_LINUX_INIT_TMPFS "/" SCANDIR "/") - 1, d->d_name, dlen + 1) ; - rm_rf(fn) ; + char fn[SCANPREFIXLEN + DOTPREFIXLEN + dlen + DOTSUFFIXLEN + 1] ; + memcpy(fn, SCANPREFIX DOTPREFIX, SCANPREFIXLEN + DOTPREFIXLEN) ; + memcpy(fn + SCANPREFIXLEN + DOTPREFIXLEN, d->d_name, dlen) ; + memcpy(fn + SCANPREFIXLEN + DOTPREFIXLEN + dlen, DOTSUFFIX, DOTSUFFIXLEN + 1) ; + if (mkrenametemp(fdd, d->d_name, fn + SCANPREFIXLEN) == -1) + { + strerr_warnwu4sys("rename " SCANPREFIX, d->d_name, " to something based on ", fn) ; + unlinkat(fdd, d->d_name, 0) ; + /* if it still fails, too bad, it will restart in stage 4 and race */ + } + else + s6_svc_writectl(fn, S6_SUPERVISE_CTLDIR, "dx", 2) ; } } if (errno) |