summaryrefslogtreecommitdiff
path: root/src/shutdown
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2019-05-04 23:12:29 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2019-05-04 23:12:29 +0000
commit97967b6276c0f0ae5ae1ac0e706ce43e2727d03a (patch)
treeadcd4678aa2a1581509dddf0e89566d9bee7a5b2 /src/shutdown
parent91ea846a6f05e9a57b2b3bc3b56a94e0026c5618 (diff)
downloads6-linux-init-97967b6276c0f0ae5ae1ac0e706ce43e2727d03a.tar.xz
Correctly (hopefully) unsupervise stuff before stage 4
Diffstat (limited to 'src/shutdown')
-rw-r--r--src/shutdown/deps-exe/s6-linux-init-shutdownd1
-rw-r--r--src/shutdown/s6-linux-init-shutdownd.c50
2 files changed, 45 insertions, 6 deletions
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)