ujail: add dependency on syscall-names-h
[project/procd.git] / state.c
diff --git a/state.c b/state.c
index 1ed70f542f13d3ec7b8a3d3cf2fcf8e31cf42cd8..e117ea302f9301fea4e483b23c08676890f0ced4 100644 (file)
--- a/state.c
+++ b/state.c
@@ -20,6 +20,7 @@
 #include <sys/types.h>
 #include <signal.h>
 
+#include "container.h"
 #include "procd.h"
 #include "syslog.h"
 #include "plug/hotplug.h"
@@ -48,7 +49,7 @@ static void set_stdio(const char* tty)
            !freopen(tty, "w", stdout) ||
            !freopen(tty, "w", stderr) ||
            chdir("/"))
-               ERROR("failed to set stdio\n");
+               ERROR("failed to set stdio: %m\n");
        else
                fcntl(STDERR_FILENO, F_SETFL, fcntl(STDERR_FILENO, F_GETFL) | O_NONBLOCK);
 }
@@ -73,7 +74,7 @@ static void set_console(void)
        }
 
        if (chdir("/dev")) {
-               ERROR("failed to change dir to /dev\n");
+               ERROR("failed to change dir to /dev: %m\n");
                return;
        }
        while (tty!=NULL) {
@@ -87,12 +88,40 @@ static void set_console(void)
                i++;
        }
        if (chdir("/"))
-               ERROR("failed to change dir to /\n");
+               ERROR("failed to change dir to /: %m\n");
 
        if (tty != NULL)
                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";
@@ -111,7 +140,6 @@ static void state_enter(void)
                set_stdio("console");
                LOG("- ubus -\n");
                procd_connect_ubus();
-               service_init();
                service_start_early("ubus", ubus_cmd);
                break;
 
@@ -129,6 +157,8 @@ static void state_enter(void)
 
        case STATE_RUNNING:
                LOG("- init complete -\n");
+               procd_inittab_run("respawnlate");
+               procd_inittab_run("askconsolelate");
                break;
 
        case STATE_SHUTDOWN:
@@ -150,24 +180,11 @@ static void state_enter(void)
                kill(-1, SIGKILL);
                sync();
                sleep(1);
-               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);
-
-               /* 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);
+#ifndef DISABLE_INIT
+               perform_halt();
+#else
+               exit(EXIT_SUCCESS);
+#endif
                break;
 
        default: