From 1bfba3b0be32306b078f5ee527b864e758b2c77b Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Fri, 26 Apr 2019 15:52:54 +0000 Subject: Make a single hpr. Full doc, first draft. --- src/shutdown/deps-exe/s6-linux-init-halt | 5 -- src/shutdown/deps-exe/s6-linux-init-hpr | 5 ++ src/shutdown/deps-exe/s6-linux-init-poweroff | 5 -- src/shutdown/deps-exe/s6-linux-init-reboot | 5 -- src/shutdown/hpr.c | 104 ------------------------ src/shutdown/hpr_shutdown.c | 2 +- src/shutdown/s6-linux-init-halt.c | 7 -- src/shutdown/s6-linux-init-hpr.c | 107 +++++++++++++++++++++++++ src/shutdown/s6-linux-init-poweroff.c | 7 -- src/shutdown/s6-linux-init-reboot.c | 7 -- src/shutdown/s6-linux-init-shutdownd.c | 113 ++++++++++++++------------- 11 files changed, 171 insertions(+), 196 deletions(-) delete mode 100644 src/shutdown/deps-exe/s6-linux-init-halt create mode 100644 src/shutdown/deps-exe/s6-linux-init-hpr delete mode 100644 src/shutdown/deps-exe/s6-linux-init-poweroff delete mode 100644 src/shutdown/deps-exe/s6-linux-init-reboot delete mode 100644 src/shutdown/hpr.c delete mode 100644 src/shutdown/s6-linux-init-halt.c create mode 100644 src/shutdown/s6-linux-init-hpr.c delete mode 100644 src/shutdown/s6-linux-init-poweroff.c delete mode 100644 src/shutdown/s6-linux-init-reboot.c (limited to 'src/shutdown') diff --git a/src/shutdown/deps-exe/s6-linux-init-halt b/src/shutdown/deps-exe/s6-linux-init-halt deleted file mode 100644 index 0c4376c..0000000 --- a/src/shutdown/deps-exe/s6-linux-init-halt +++ /dev/null @@ -1,5 +0,0 @@ -libhpr.a.xyzzy -${LIBUTMPS} --lskarnet -${TAINNOW_LIB} -${SOCKET_LIB} diff --git a/src/shutdown/deps-exe/s6-linux-init-hpr b/src/shutdown/deps-exe/s6-linux-init-hpr new file mode 100644 index 0000000..0c4376c --- /dev/null +++ b/src/shutdown/deps-exe/s6-linux-init-hpr @@ -0,0 +1,5 @@ +libhpr.a.xyzzy +${LIBUTMPS} +-lskarnet +${TAINNOW_LIB} +${SOCKET_LIB} diff --git a/src/shutdown/deps-exe/s6-linux-init-poweroff b/src/shutdown/deps-exe/s6-linux-init-poweroff deleted file mode 100644 index 0c4376c..0000000 --- a/src/shutdown/deps-exe/s6-linux-init-poweroff +++ /dev/null @@ -1,5 +0,0 @@ -libhpr.a.xyzzy -${LIBUTMPS} --lskarnet -${TAINNOW_LIB} -${SOCKET_LIB} diff --git a/src/shutdown/deps-exe/s6-linux-init-reboot b/src/shutdown/deps-exe/s6-linux-init-reboot deleted file mode 100644 index 0c4376c..0000000 --- a/src/shutdown/deps-exe/s6-linux-init-reboot +++ /dev/null @@ -1,5 +0,0 @@ -libhpr.a.xyzzy -${LIBUTMPS} --lskarnet -${TAINNOW_LIB} -${SOCKET_LIB} diff --git a/src/shutdown/hpr.c b/src/shutdown/hpr.c deleted file mode 100644 index a769c8c..0000000 --- a/src/shutdown/hpr.c +++ /dev/null @@ -1,104 +0,0 @@ -/* ISC license. */ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "defaults.h" -#include "hpr.h" - -#ifndef UT_NAMESIZE -#define UT_NAMESIZE 32 -#endif - -#ifndef UT_HOSTSIZE -#define UT_HOSTSIZE 256 -#endif - -#ifndef _PATH_WTMP -#define _PATH_WTMP "/dev/null/wtmp" -#endif - -#define USAGE PROGNAME " [ -h | -p | -r ] [ -d | -w ] [ -W ] [ -f ]" - -int main (int argc, char const *const *argv) -{ - int what = WHATDEFAULT ; - int force = 0 ; - int dowtmp = 1 ; - int dowall = 1 ; - PROG = PROGNAME ; - - { - subgetopt_t l = SUBGETOPT_ZERO ; - for (;;) - { - int opt = subgetopt_r(argc, argv, "hprfdwW", &l) ; - if (opt == -1) break ; - switch (opt) - { - case 'h' : what = 1 ; break ; - case 'p' : what = 2 ; break ; - case 'r' : what = 3 ; break ; - case 'f' : force = 1 ; break ; - case 'd' : dowtmp = 0 ; break ; - case 'w' : dowtmp = 2 ; break ; - case 'W' : dowall = 0 ; break ; - default : strerr_dieusage(100, USAGE) ; - } - } - argc -= l.ind ; argv += l.ind ; - } - - if (geteuid()) - { - errno = EPERM ; - strerr_dief1sys(100, "nice try, peon") ; - } - - if (force) - { - reboot(what == 3 ? RB_AUTOBOOT : what == 2 ? RB_POWER_OFF : RB_HALT_SYSTEM) ; - strerr_diefu1sys(111, "reboot()") ; - } - - if (!tain_now_g()) strerr_warnw1sys("get current time") ; - if (dowtmp) - { - struct utmpx utx = - { - .ut_type = RUN_LVL, - .ut_pid = getpid(), - .ut_line = "~", - .ut_id = "", - .ut_session = getsid(0) - } ; - strncpy(utx.ut_user, what == 3 ? "reboot" : "shutdown", UT_NAMESIZE) ; - if (gethostname(utx.ut_host, UT_HOSTSIZE) < 0) - { - utx.ut_host[0] = 0 ; - strerr_warnwu1sys("gethostname") ; - } - else utx.ut_host[UT_HOSTSIZE - 1] = 0 ; - if (!timeval_from_tain(&utx.ut_tv, &STAMP)) - strerr_warnwu1sys("timeval_from_tain") ; - updwtmpx(_PATH_WTMP, &utx) ; - } - if (dowall) hpr_wall(HPR_WALL_BANNER) ; - if (dowtmp < 2) - { - if (!hpr_shutdown(what, &STAMP, 0)) - strerr_diefu1sys(111, "notify s6-linux-init-shutdownd") ; - } - return 0 ; -} diff --git a/src/shutdown/hpr_shutdown.c b/src/shutdown/hpr_shutdown.c index 9c9ff51..3ede92d 100644 --- a/src/shutdown/hpr_shutdown.c +++ b/src/shutdown/hpr_shutdown.c @@ -9,7 +9,7 @@ int hpr_shutdown (unsigned int what, tain_t const *when, unsigned int grace) { - char pack[5 + TAIN_PACK] = { " hpr"[what] } ; + char pack[5 + TAIN_PACK] = { "Shpr"[what] } ; tain_pack(pack+1, when) ; uint32_pack_big(pack + 1 + TAIN_PACK, (uint32_t)grace) ; return hpr_send(pack, 5 + TAIN_PACK) ; diff --git a/src/shutdown/s6-linux-init-halt.c b/src/shutdown/s6-linux-init-halt.c deleted file mode 100644 index 4ccca1d..0000000 --- a/src/shutdown/s6-linux-init-halt.c +++ /dev/null @@ -1,7 +0,0 @@ -/* ISC license. */ - -#undef PROGNAME -#define PROGNAME "s6-linux-init-halt" -#undef WHATDEFAULT -#define WHATDEFAULT 1 -#include "hpr.c" diff --git a/src/shutdown/s6-linux-init-hpr.c b/src/shutdown/s6-linux-init-hpr.c new file mode 100644 index 0000000..c5f7afb --- /dev/null +++ b/src/shutdown/s6-linux-init-hpr.c @@ -0,0 +1,107 @@ +/* ISC license. */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "defaults.h" +#include "hpr.h" + +#ifndef UT_NAMESIZE +#define UT_NAMESIZE 32 +#endif + +#ifndef UT_HOSTSIZE +#define UT_HOSTSIZE 256 +#endif + +#ifndef _PATH_WTMP +#define _PATH_WTMP "/dev/null/wtmp" +#endif + +#define USAGE "s6-linux-init-hpr [ -h | -p | -r ] [ -d | -w ] [ -W ] [ -f ]" + +int main (int argc, char const *const *argv) +{ + int what = 0 ; + int force = 0 ; + int dowtmp = 1 ; + int dowall = 1 ; + PROG = "s6-linux-init-hpr" ; + + { + subgetopt_t l = SUBGETOPT_ZERO ; + for (;;) + { + int opt = subgetopt_r(argc, argv, "hprfdwW", &l) ; + if (opt == -1) break ; + switch (opt) + { + case 'h' : what = 1 ; break ; + case 'p' : what = 2 ; break ; + case 'r' : what = 3 ; break ; + case 'f' : force = 1 ; break ; + case 'd' : dowtmp = 0 ; break ; + case 'w' : dowtmp = 2 ; break ; + case 'W' : dowall = 0 ; break ; + default : strerr_dieusage(100, USAGE) ; + } + } + argc -= l.ind ; argv += l.ind ; + } + + if (!what) + strerr_dief1x(100, "one of the -h, -p or -r options must be given") ; + + if (geteuid()) + { + errno = EPERM ; + strerr_dief1sys(100, "nice try, peon") ; + } + + if (force) + { + reboot(what == 3 ? RB_AUTOBOOT : what == 2 ? RB_POWER_OFF : RB_HALT_SYSTEM) ; + strerr_diefu1sys(111, "reboot()") ; + } + + if (!tain_now_g()) strerr_warnw1sys("get current time") ; + if (dowtmp) + { + struct utmpx utx = + { + .ut_type = RUN_LVL, + .ut_pid = getpid(), + .ut_line = "~", + .ut_id = "", + .ut_session = getsid(0) + } ; + strncpy(utx.ut_user, what == 3 ? "reboot" : "shutdown", UT_NAMESIZE) ; + if (gethostname(utx.ut_host, UT_HOSTSIZE) < 0) + { + utx.ut_host[0] = 0 ; + strerr_warnwu1sys("gethostname") ; + } + else utx.ut_host[UT_HOSTSIZE - 1] = 0 ; + if (!timeval_from_tain(&utx.ut_tv, &STAMP)) + strerr_warnwu1sys("timeval_from_tain") ; + updwtmpx(_PATH_WTMP, &utx) ; + } + if (dowall) hpr_wall(HPR_WALL_BANNER) ; + if (dowtmp < 2) + { + if (!hpr_shutdown(what, &STAMP, 0)) + strerr_diefu1sys(111, "notify s6-linux-init-shutdownd") ; + } + return 0 ; +} diff --git a/src/shutdown/s6-linux-init-poweroff.c b/src/shutdown/s6-linux-init-poweroff.c deleted file mode 100644 index d25dbb6..0000000 --- a/src/shutdown/s6-linux-init-poweroff.c +++ /dev/null @@ -1,7 +0,0 @@ -/* ISC license. */ - -#undef PROGNAME -#define PROGNAME "s6-linux-init-poweroff" -#undef WHATDEFAULT -#define WHATDEFAULT 2 -#include "hpr.c" diff --git a/src/shutdown/s6-linux-init-reboot.c b/src/shutdown/s6-linux-init-reboot.c deleted file mode 100644 index 3612684..0000000 --- a/src/shutdown/s6-linux-init-reboot.c +++ /dev/null @@ -1,7 +0,0 @@ -/* ISC license. */ - -#undef PROGNAME -#define PROGNAME "s6-linux-init-reboot" -#undef WHATDEFAULT -#define WHATDEFAULT 3 -#include "hpr.c" diff --git a/src/shutdown/s6-linux-init-shutdownd.c b/src/shutdown/s6-linux-init-shutdownd.c index c6d6316..90d43e8 100644 --- a/src/shutdown/s6-linux-init-shutdownd.c +++ b/src/shutdown/s6-linux-init-shutdownd.c @@ -36,6 +36,41 @@ static char const *basedir = BASEDIR ; +static inline void run_stage3 (char const *basedir, char const *const *envp) +{ + pid_t pid ; + size_t basedirlen = strlen(basedir) ; + char stage3[basedirlen + sizeof("/" STAGE3)] ; + char const *stage3_argv[2] = { stage3, 0 } ; + memcpy(stage3, basedir, basedirlen) ; + memcpy(stage3 + basedirlen, "/" STAGE3, sizeof("/" STAGE3)) ; + pid = child_spawn0(stage3_argv[0], stage3_argv, envp) ; + if (pid) + { + int wstat ; + if (wait_pid(pid, &wstat) == -1) strerr_diefu1sys(111, "waitpid") ; + if (WIFSIGNALED(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; + strerr_warnw3x(stage3, " was killed by signal ", fmt) ; + } + else if (WEXITSTATUS(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; + strerr_warnw3x(stage3, " was killed by signal ", fmt) ; + } + else if (WEXITSTATUS(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ; + strerr_warnw3x(stage3, " exited ", fmt) ; + } + } + else strerr_warnwu2sys("spawn ", stage3) ; +} + static inline void prepare_shutdown (char c, unsigned int *what, tain_t *deadline, unsigned int *grace_time) { uint32_t u ; @@ -43,22 +78,23 @@ static inline void prepare_shutdown (char c, unsigned int *what, tain_t *deadlin ssize_t r = sanitize_read(buffer_get(buffer_0small, pack, TAIN_PACK)) ; if (r == -1) strerr_diefu1sys(111, "read from pipe") ; if (r < TAIN_PACK + 4) strerr_dief1x(101, "bad shutdown protocol") ; + *what = byte_chr("Shpr", c, 4) ; tain_unpack(pack, deadline) ; uint32_unpack_big(pack + TAIN_PACK, &u) ; if (u && u <= 300000) *grace_time = u ; - *what = 1 + byte_chr("hpr", c, 3) ; } -static inline void handle_stdin (unsigned int *what, tain_t *deadline, unsigned int *grace_time) +static inline void handle_fifo (buffer *b, unsigned int *what, tain_t *deadline, unsigned int *grace_time) { for (;;) { char c ; - ssize_t r = sanitize_read(buffer_get(buffer_0small, &c, 1)) ; + ssize_t r = sanitize_read(buffer_get(b, &c, 1)) ; if (r == -1) strerr_diefu1sys(111, "read from pipe") ; else if (!r) break ; switch (c) { + case 'S' : case 'h' : case 'p' : case 'r' : @@ -80,7 +116,6 @@ static inline void handle_stdin (unsigned int *what, tain_t *deadline, unsigned static inline void prepare_stage4 (char const *basedir, unsigned int what) { - static char const *table[3] = { "halt", "poweroff", "reboot" } ; buffer b ; int fd ; char buf[512] ; @@ -92,9 +127,9 @@ static inline void prepare_stage4 (char const *basedir, unsigned int what) if (buffer_puts(&b, "#!" EXECLINE_SHEBANGPREFIX "/execlineb -P\n\n" EXECLINE_EXTBINPREFIX "foreground { " - S6_LINUX_INIT_LIBEXECPREFIX "s6-linux-init-umountall }\n" - S6_LINUX_INIT_LIBEXECPREFIX "s6-linux-init-") < 0 - || buffer_puts(&b, table[what-1]) < 0 + S6_LINUX_INIT_BINPREFIX "s6-linux-init-umountall }\n" + S6_LINUX_INIT_BINPREFIX "s6-linux-init-hpr -") < 0 + || buffer_put(&b, "hpr" + what - 1, 1) < 0 || buffer_putsflush(&b, " -f\n") < 0) strerr_diefu2sys(111, "write to ", STAGE4_FILE ".new") ; if (fchmod(fd, S_IRWXU) == -1) @@ -106,10 +141,12 @@ static inline void prepare_stage4 (char const *basedir, unsigned int what) int main (int argc, char const *const *argv, char const *const *envp) { - pid_t pid ; - tain_t deadline ; unsigned int what = 0 ; unsigned int grace_time = 3000 ; + tain_t deadline ; + int fdr, fdw ; + buffer b ; + char buf[64] ; PROG = "s6-linux-init-shutdownd" ; { @@ -139,80 +176,46 @@ int main (int argc, char const *const *argv, char const *const *envp) strerr_warnwu2sys("exec ", stage4_argv[0]) ; } - fd_close(1) ; - fd_close(0) ; - - if (open_read(SHUTDOWND_FIFO)) + fdr = open_read(SHUTDOWND_FIFO) ; + if (fdr == -1 || coe(fdr) == -1) strerr_diefu3sys(111, "open ", SHUTDOWND_FIFO, " for reading") ; - if (open_write(SHUTDOWND_FIFO) != 1) + fdw = open_write(SHUTDOWND_FIFO) ; + if (fdw == -1 || coe(fdw) == -1) strerr_diefu3sys(111, "open ", SHUTDOWND_FIFO, " for writing") ; if (sig_ignore(SIGPIPE) == -1) strerr_diefu1sys(111, "sig_ignore SIGPIPE") ; + buffer_init(&b, &buffer_read, fdr, buf, 64) ; tain_now_g() ; tain_add_g(&deadline, &tain_infinite_relative) ; for (;;) { - iopause_fd x = { .fd = 0, .events = IOPAUSE_READ } ; + iopause_fd x = { .fd = fdr, .events = IOPAUSE_READ } ; int r = iopause_g(&x, 1, &deadline) ; if (r == -1) strerr_diefu1sys(111, "iopause") ; if (!r) { + run_stage3(basedir, envp) ; + tain_now_g() ; if (what) break ; tain_add_g(&deadline, &tain_infinite_relative) ; continue ; } if (x.revents & IOPAUSE_READ) - handle_stdin(&what, &deadline, &grace_time) ; + handle_fifo(&b, &what, &deadline, &grace_time) ; } - - /* Stage 3 */ - + fd_close(fdw) ; + fd_close(fdr) ; fd_close(1) ; - fd_close(0) ; - if (open_readb("/dev/null")) - strerr_diefu1sys(111, "open /dev/null for reading") ; if (open_write("/dev/console") != 1 || ndelay_off(1) == -1) strerr_diefu1sys(111, "open /dev/console for writing") ; - { - size_t basedirlen = strlen(basedir) ; - char stage3[basedirlen + sizeof("/" STAGE3)] ; - char const *stage3_argv[2] = { stage3, 0 } ; - memcpy(stage3, basedir, basedirlen) ; - memcpy(stage3 + basedirlen, "/" STAGE3, sizeof("/" STAGE3)) ; - pid = child_spawn0(stage3_argv[0], stage3_argv, envp) ; - if (pid) - { - int wstat ; - if (wait_pid(pid, &wstat) == -1) strerr_diefu1sys(111, "waitpid") ; - if (WIFSIGNALED(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; - strerr_warnw3x(stage3, " was killed by signal ", fmt) ; - } - else if (WEXITSTATUS(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; - strerr_warnw3x(stage3, " was killed by signal ", fmt) ; - } - else if (WEXITSTATUS(wstat)) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ; - strerr_warnw3x(stage3, " exited ", fmt) ; - } - } - else strerr_warnwu2sys("spawn ", stage3) ; - } + if (fd_copy(2, 1) == -1) strerr_warnwu1sys("fd_copy") ; /* The end is coming! */ prepare_stage4(basedir, what) ; - if (fd_move(2, 1) == -1) strerr_warnwu1sys("fd_move") ; sync() ; if (sig_ignore(SIGTERM) == -1) strerr_warnwu1sys("sig_ignore SIGTERM") ; strerr_warni1x("sending all processes the TERM signal...") ; -- cgit v1.2.3