diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2019-04-30 00:01:50 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2019-04-30 00:01:50 +0000 |
commit | 12e7541e13b7e84339452eefa5516a6f01e687b9 (patch) | |
tree | f85cdacacc41cb492c21075751c85ff6832b5992 /src | |
parent | 6a57daba8c0ebf143cec2dd4b133c8c662f86857 (diff) | |
download | s6-linux-init-12e7541e13b7e84339452eefa5516a6f01e687b9.tar.xz |
shutdownd kills most of the supervision tree before stage 4
Diffstat (limited to 'src')
-rw-r--r-- | src/shutdown/s6-linux-init-shutdownd.c | 43 |
1 files changed, 41 insertions, 2 deletions
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 <sys/types.h> #include <sys/stat.h> +#include <fcntl.h> #include <string.h> #include <errno.h> #include <signal.h> @@ -19,12 +20,14 @@ #include <skalibs/sgetopt.h> #include <skalibs/sig.h> #include <skalibs/tai.h> +#include <skalibs/direntry.h> #include <skalibs/djbunix.h> #include <skalibs/iopause.h> #include <skalibs/skamisc.h> #include <execline/config.h> +#include <s6-linux-init/config.h> #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...") ; |