From 05738bfce120114037d4f02c67ec740813f94b89 Mon Sep 17 00:00:00 2001 From: William Hubbs Date: Wed, 12 Apr 2017 17:56:30 -0500 Subject: init: add re-exec capability This will allow the re-execution of the init process after upgrading OpenRC. --- src/rc/openrc-init.c | 22 +++++++++++++++++++--- src/rc/openrc-shutdown.c | 14 ++++++++++++-- 2 files changed, 31 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/rc/openrc-init.c b/src/rc/openrc-init.c index fb3347a4..61052806 100644 --- a/src/rc/openrc-init.c +++ b/src/rc/openrc-init.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -79,6 +80,12 @@ static void init(const char *default_runlevel) waitpid(pid, NULL, 0); } +static void handle_reexec(char *my_name) +{ + execl(my_name, my_name, "reexec", NULL); + return; +} + static void handle_shutdown(const char *runlevel, int cmd) { pid_t pid; @@ -123,10 +130,11 @@ static void signal_handler(int sig) int main(int argc, char **argv) { - char *default_runlevel = NULL; + char *default_runlevel; char buf[2048]; int count; FILE *fifo; + bool reexec = false; struct sigaction sa; if (getpid() != 1) @@ -134,16 +142,22 @@ int main(int argc, char **argv) if (argc > 1) default_runlevel = argv[1]; + else + default_runlevel = NULL; + + if (default_runlevel && strcmp(default_runlevel, "reexec") == 0) + reexec = true; printf("OpenRC init version %s starting\n", VERSION); - init(default_runlevel); + if (! reexec) + init(default_runlevel); memset(&sa, 0, sizeof(sa)); sa.sa_handler = signal_handler; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGINT, &sa, NULL); reboot(RB_DISABLE_CAD); - if (mkfifo(RC_INIT_FIFO, 0600) == -1) + if (mkfifo(RC_INIT_FIFO, 0600) == -1 && errno != EEXIST) perror("mkfifo"); for (;;) { @@ -166,6 +180,8 @@ int main(int argc, char **argv) handle_shutdown("shutdown", RB_POWER_OFF); else if (strcmp(buf, "reboot") == 0) handle_shutdown("reboot", RB_AUTOBOOT); + else if (strcmp(buf, "reexec") == 0) + handle_reexec(argv[0]); } return 0; } diff --git a/src/rc/openrc-shutdown.c b/src/rc/openrc-shutdown.c index 978e8a68..8905d354 100644 --- a/src/rc/openrc-shutdown.c +++ b/src/rc/openrc-shutdown.c @@ -35,11 +35,12 @@ const char *applet = NULL; const char *extraopts = NULL; -const char *getoptstring = "kpr" getoptstring_COMMON; +const char *getoptstring = "HkpRr" getoptstring_COMMON; const struct option longopts[] = { { "halt", no_argument, NULL, 'H'}, { "kexec", no_argument, NULL, 'k'}, { "poweroff", no_argument, NULL, 'p'}, + { "reexec", no_argument, NULL, 'R'}, { "reboot", no_argument, NULL, 'r'}, longopts_COMMON }; @@ -47,11 +48,13 @@ const char * const longopts_help[] = { "halt the system", "reboot the system using kexec", "power off the system", + "re-execute init (use after upgrading)", "reboot the system", longopts_help_COMMON }; const char *usagestring = NULL; -const char *exclusive = "Select one of --halt, --kexec, --poweroff or --reboot"; +const char *exclusive = "Select one of " +"--halt, --kexec, --poweroff, --reexec or --reboot"; static void send_cmd(const char *cmd) { @@ -79,6 +82,7 @@ int main(int argc, char **argv) bool do_kexec = false; bool do_poweroff = false; bool do_reboot = false; + bool do_reexec = false; applet = basename_c(argv[0]); if (geteuid() != 0) @@ -99,6 +103,10 @@ if (geteuid() != 0) do_poweroff = true; cmd_count++; break; + case 'R': + do_reexec = true; + cmd_count++; + break; case 'r': do_reboot = true; cmd_count++; @@ -118,5 +126,7 @@ if (geteuid() != 0) send_cmd("poweroff"); else if (do_reboot) send_cmd("reboot"); + else if (do_reexec) + send_cmd("reexec"); return 0; } -- cgit v1.2.3