diff options
Diffstat (limited to 'src/sysbin/init/main.c')
-rw-r--r-- | src/sysbin/init/main.c | 164 |
1 files changed, 136 insertions, 28 deletions
diff --git a/src/sysbin/init/main.c b/src/sysbin/init/main.c index ce09f37..e923ab3 100644 --- a/src/sysbin/init/main.c +++ b/src/sysbin/init/main.c @@ -9,8 +9,8 @@ #include <kogata/btree.h> -pid_t giosrv_pid = 0, login_pid = 0; -fd_pair_t root_gip_chan; +bool loop_exec = true; +pid_t giosrv_pid = 0, login_pid = 0, lx_init_pid = 0; void _parse_cmdline_iter(void* a, void* b) { dbg_printf(" '%s' -> '%s'\n", a, b); @@ -90,7 +90,7 @@ void setup_sys() { if (!ok) PANIC("[init] Could not bind root:/sys to sys:/"); } -void launch_giosrv() { +void launch_giosrv(fd_pair_t *root_gip_chan) { if (giosrv_pid != 0) return; giosrv_pid = sc_new_proc(); @@ -111,7 +111,7 @@ void launch_giosrv() { ok = sc_bind_fs(giosrv_pid, "config", "config"); if (!ok) PANIC("[init] Could not bind config:/ to giosrv"); - ok = sc_bind_fd(giosrv_pid, STD_FD_GIOSRV, root_gip_chan.a); + ok = sc_bind_fd(giosrv_pid, STD_FD_GIOSRV, root_gip_chan->a); if (!ok) PANIC("[init] Could not bind root GIP channel FD to giosrv"); ok = sc_proc_exec(giosrv_pid, "sys:/bin/giosrv.bin"); @@ -120,7 +120,7 @@ void launch_giosrv() { dbg_printf("[init] giosrv started.\n"); } -void launch_login() { +void launch_login(fd_pair_t *root_gip_chan) { if (login_pid != 0) return; login_pid = sc_new_proc(); @@ -141,7 +141,7 @@ void launch_login() { ok = sc_bind_fs(login_pid, "config", "config"); if (!ok) PANIC("[init] Could not bind config:/ to login"); - ok = sc_bind_fd(login_pid, STD_FD_GIP, root_gip_chan.b); + ok = sc_bind_fd(login_pid, STD_FD_GIP, root_gip_chan->b); if (!ok) PANIC("[init] Could not bind root GIP channel FD to login"); ok = sc_proc_exec(login_pid, "sys:/bin/login.bin"); @@ -150,30 +150,99 @@ void launch_login() { dbg_printf("[init] login started.\n"); } -int main(int argc, char **argv) { - dbg_print("[init] Starting up!\n"); +void launch_lx_init(const char* lx_init_app, fd_pair_t *io_chan) { + if (lx_init_pid != 0) return; - // Read kernel cmdline - btree_t *cmdline = read_cmdline(); - if (cmdline == 0) PANIC("[init] Could not parse cmdline"); + lx_init_pid = sc_new_proc(); + if (lx_init_pid == 0) { + PANIC("[init] Could not create process for lx_init"); + } - // setup config: - if (btree_find(cmdline, "config") == 0) { - PANIC("[init] No config=xxx option specified on command line"); - } else { - char* config = (char*)btree_find(cmdline, "config"); - dbg_printf("[init] Loading system configuration: %s\n", config); - ASSERT(strlen(config) < 30); + dbg_printf("[init] Setting up lx_init, pid: %d\n", lx_init_pid); - char buf[50]; - snprintf(buf, 50, "/config/%s", config); - bool ok = sc_fs_subfs("config", "root", buf, FM_READ | FM_WRITE | FM_MMAP | FM_READDIR); - if (!ok) PANIC("[init] Could not setup config:"); + bool ok; + + ok = sc_bind_fs(lx_init_pid, "io", "io"); + if (!ok) PANIC("[init] Could not bind io:/ to lx_init"); + + ok = sc_bind_fs(lx_init_pid, "root", "root"); + if (!ok) PANIC("[init] Could not bind root:/ to lx_init"); + + ok = sc_bind_fs(lx_init_pid, "sys", "sys"); + if (!ok) PANIC("[init] Could not bind sys:/ to lx_init"); + + ok = sc_bind_fs(lx_init_pid, "config", "config"); + if (!ok) PANIC("[init] Could not bind config:/ to lx_init"); + + char app_path[256]; + snprintf(app_path, 256, "/app/%s", lx_init_app); + + ok = sc_bind_subfs(lx_init_pid, "app", "sys", app_path, FM_ALL_MODES); + if (!ok) PANIC("[init] Could not bind app:/ to lx_init"); + + ok = sc_bind_fd(lx_init_pid, STD_FD_STDOUT, io_chan->b); + if (!ok) PANIC("[init] Could not bind stdout channel to lx_init"); + + ok = sc_bind_fd(lx_init_pid, STD_FD_STDERR, io_chan->b); + if (!ok) PANIC("[init] Could not bind stderr channel to lx_init"); + + ok = sc_proc_exec(lx_init_pid, "sys:/bin/lx.bin"); + if (!ok) PANIC("[init] Could not run lx.bin"); + + dbg_printf("[init] lx_init started\n"); +} + +void dump_all(fd_t fd) { + char buf[256]; + while(true){ + int n = sc_read(fd, 0, 255, buf); + if (n > 0) { + buf[n] = 0; + sc_dbg_print(buf); + } else { + break; + } } +} - // Setup sys: - setup_sys(); +int run_lua(const char* lx_init_app) { + // Setup a channel for stdout/stderr printing + fd_pair_t io_chan; + io_chan = sc_make_channel(false); + if (io_chan.a == 0 || io_chan.b == 0) { + PANIC("[init] Could not create Lua emergency I/O channel."); + } + + launch_lx_init(lx_init_app, &io_chan); + + while(true) { + dump_all(io_chan.a); + + proc_status_t s; + sc_proc_wait(0, false, &s); + if (s.pid != 0) { + if (s.pid == lx_init_pid) { + if (!loop_exec) { + dump_all(io_chan.a); + PANIC("[init] lx_init died!\n"); + } + + lx_init_pid = 0; + + dbg_printf("[init] lx_init_app died, restarting.\n"); + launch_lx_init(lx_init_app, &io_chan); + } else { + ASSERT(false); + } + } + + sc_usleep(100000); + } +} +int run_no_lua() { + fd_pair_t root_gip_chan; + // Setup GIP channel for communication between giosrv and login root_gip_chan = sc_make_channel(false); if (root_gip_chan.a == 0 || root_gip_chan.b == 0) { @@ -181,8 +250,8 @@ int main(int argc, char **argv) { } // Launch giosrv && login - launch_giosrv(); - launch_login(); + launch_giosrv(&root_gip_chan); + launch_login(&root_gip_chan); // Make sure no one dies while(true) { @@ -190,21 +259,60 @@ int main(int argc, char **argv) { sc_proc_wait(0, false, &s); if (s.pid != 0) { if (s.pid == giosrv_pid) { + if (!loop_exec) PANIC("[init] giosrv died!\n"); + giosrv_pid = 0; dbg_printf("[init] giosrv died, restarting.\n"); - launch_giosrv(); + launch_giosrv(&root_gip_chan); } else if (s.pid == login_pid) { + if (!loop_exec) PANIC("[init] login died!\n"); + login_pid = 0; dbg_printf("[init] login died, restarting.\n"); - launch_login(); + launch_login(&root_gip_chan); } else { ASSERT(false); } } sc_usleep(1000000); } +} + +int main(int argc, char **argv) { + dbg_print("[init] Starting up!\n"); + + // Read kernel cmdline + btree_t *cmdline = read_cmdline(); + if (cmdline == 0) PANIC("[init] Could not parse cmdline"); + + // setup config: + if (btree_find(cmdline, "config") == 0) { + PANIC("[init] No config=xxx option specified on command line"); + } else { + char* config = (char*)btree_find(cmdline, "config"); + dbg_printf("[init] Loading system configuration: %s\n", config); + ASSERT(strlen(config) < 30); + + char buf[50]; + snprintf(buf, 50, "/config/%s", config); + bool ok = sc_fs_subfs("config", "root", buf, FM_READ | FM_WRITE | FM_MMAP | FM_READDIR); + if (!ok) PANIC("[init] Could not setup config:"); + } + + // Setup sys: + setup_sys(); + + if (btree_find(cmdline, "loop_exec") && + strcmp(btree_find(cmdline, "loop_exec"), "true")) + loop_exec = false; + + if (btree_find(cmdline, "lx_init_app")) { + run_lua(btree_find(cmdline, "lx_init_app")); + } else { + run_no_lua(); + } return 0; } |