From 12e7541e13b7e84339452eefa5516a6f01e687b9 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Tue, 30 Apr 2019 00:01:50 +0000 Subject: shutdownd kills most of the supervision tree before stage 4 --- src/shutdown/s6-linux-init-shutdownd.c | 43 ++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'src/shutdown') diff --git a/src/shutdown/s6-linux-init-shutdownd.c b/src/shutdown/s6-linux-init-shutdownd.c index 17b902e..347d488 100644 --- a/src/shutdown/s6-linux-init-shutdownd.c +++ b/src/shutdown/s6-linux-init-shutdownd.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -19,12 +20,14 @@ #include #include #include +#include #include #include #include #include +#include #include "defaults.h" #include "initctl.h" #include "hpr.h" @@ -125,7 +128,7 @@ static inline void prepare_stage4 (char const *basedir, unsigned int what) buffer_init(&b, &buffer_write, fd, buf, 512) ; if (buffer_puts(&b, - "#!" EXECLINE_SHEBANGPREFIX "/execlineb -P\n\n" + "#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n\n" EXECLINE_EXTBINPREFIX "foreground { " S6_LINUX_INIT_BINPREFIX "s6-linux-init-umountall }\n" S6_LINUX_INIT_BINPREFIX "s6-linux-init-hpr -") < 0 @@ -139,6 +142,41 @@ static inline void prepare_stage4 (char const *basedir, unsigned int what) strerr_diefu4sys(111, "rename ", STAGE4_FILE ".new", " to ", STAGE4_FILE) ; } +static inline void unsupervise_tree (void) +{ + static char const *except[] = + { + LOGGER_SERVICEDIR, + SHUTDOWND_SERVICEDIR, + EARLYGETTY_SERVICEDIR, + 0 + } ; + DIR *dir = opendir(S6_LINUX_INIT_TMPFS "/" SCANDIR) ; + if (!dir) + strerr_diefu1sys(111, "opendir " S6_LINUX_INIT_TMPFS "/" SCANDIR) ; + for (;;) + { + char const *const *p = except ; + direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + for (; *p ; p++) if (!strcmp(*p, d->d_name)) break ; + 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) ; + } + } + if (errno) + strerr_diefu1sys(111, "readdir " S6_LINUX_INIT_TMPFS "/" SCANDIR) ; + dir_close(dir) ; +} + int main (int argc, char const *const *argv, char const *const *envp) { unsigned int what = 0 ; @@ -208,7 +246,7 @@ int main (int argc, char const *const *argv, char const *const *envp) fd_close(fdw) ; fd_close(fdr) ; fd_close(1) ; - if (open_write("/dev/console") != 1 || ndelay_off(1) == -1) + if (open("/dev/console", O_WRONLY) != 1) strerr_diefu1sys(111, "open /dev/console for writing") ; if (fd_copy(2, 1) == -1) strerr_warnwu1sys("fd_copy") ; @@ -216,6 +254,7 @@ int main (int argc, char const *const *argv, char const *const *envp) /* The end is coming! */ prepare_stage4(basedir, what) ; + unsupervise_tree() ; sync() ; if (sig_ignore(SIGTERM) == -1) strerr_warnwu1sys("sig_ignore SIGTERM") ; strerr_warni1x("sending all processes the TERM signal...") ; -- cgit v1.2.3