From 31e4b2dfdbd74f7451abf876dd5d9a674af7adfd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Petr=20=C5=A0tetiar?= Date: Wed, 15 Jan 2020 20:28:38 +0100 Subject: [PATCH] state: fix reboot causing shutdown inside LXC container MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Executing `reboot` command in OpenWrt system runing inside LXC container results in a shutdown of the container instead of rebooting the container. This appears to have been caused by commit 832369078d81 ("state: fix shutdown when running in a container (FS#2425)"), which exits the pid einz instead of the reboot(). While at it, refactor the halting code into separate function to shorten the switch/case block and make it clearer, decrease the indentation level by reversing the container if condition, replace magic 0 with EXIT_SUCCESS constant in exit() and make it wait 1s for reboot message delivery in both container/host cases as well. Ref: FS#2666 Cc: Paul Spooren Fixes: 832369078d81 ("state: fix shutdown when running in a container (FS#2425)") Tested-by: Baptiste Jonglez Signed-off-by: Petr Å tetiar --- state.c | 52 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/state.c b/state.c index 4737d01..e117ea3 100644 --- a/state.c +++ b/state.c @@ -94,6 +94,34 @@ static void set_console(void) set_stdio(tty); } +static void perform_halt() +{ + if (reboot_event == RB_POWER_OFF) + LOG("- power down -\n"); + else + LOG("- reboot -\n"); + + /* Allow time for last message to reach serial console, etc */ + sleep(1); + + if (is_container()) { + reboot(reboot_event); + exit(EXIT_SUCCESS); + return; + } + + /* We have to fork here, since the kernel calls do_exit(EXIT_SUCCESS) + * in linux/kernel/sys.c, which can cause the machine to panic when + * the init process exits... */ + if (!vfork()) { /* child */ + reboot(reboot_event); + _exit(EXIT_SUCCESS); + } + + while (1) + sleep(1); +} + static void state_enter(void) { char ubus_cmd[] = "/sbin/ubusd"; @@ -153,29 +181,9 @@ static void state_enter(void) sync(); sleep(1); #ifndef DISABLE_INIT - if (reboot_event == RB_POWER_OFF) - LOG("- power down -\n"); - else - LOG("- reboot -\n"); - - if (!is_container()) { - /* Allow time for last message to reach serial console, etc */ - sleep(1); - - /* We have to fork here, since the kernel calls do_exit(EXIT_SUCCESS) - * in linux/kernel/sys.c, which can cause the machine to panic when - * the init process exits... */ - if (!vfork( )) { /* child */ - reboot(reboot_event); - _exit(EXIT_SUCCESS); - } - - while (1) - sleep(1); - } else - exit(0); + perform_halt(); #else - exit(0); + exit(EXIT_SUCCESS); #endif break; -- 2.25.1