use std::{process}; use std::time::Duration; use tokio::task::JoinSet; use crate::reaper::Reaper; use pkg_compile_time::{pkg_compile_date, pkg_compile_time}; use crate::logger::LoggerWriterSpawner; mod shell; mod syscall; mod reaper; mod logger; mod sysinit; mod cfg; mod env; #[tokio::main(flavor = "multi_thread", worker_threads = 2)] async fn main() { println!("==== yukari - ELIP4NG Init Process. ===="); println!(); let pid = process::id(); if pid != 1 { panic!("yukari must run as PID 1."); } println!("hello, this is No.1 process (as sysinit) 'yukari'."); println!("this program has been compiled at {} {}", pkg_compile_date!(), pkg_compile_time!()); println!(); println!("load config..."); cfg::init_config_manager().await; logger::set_debug_mode_by_cfg().await; println!("you can < PRESS ENTER > at any time to enter maintenance shell."); println!(); println!("---- yukari sysinit phase ----"); let mut logmux = logger::Logger::new(); let logger_reaper = logmux.get_writer("zombie_reaper"); let logger_env_load = logmux.get_writer("env_load"); /* let logger_sysinit = logmux.get_writer("sys_init_task"); let logger_sys_loader_stdout = logmux.get_writer("sys_loader_stdout"); let logger_sys_loader_stderr = logmux.get_writer("sys_loader_stderr"); let logger_svc_mgr_stdout = logmux.get_writer("svc_mgr_stdout"); let logger_svc_mgr_stderr = logmux.get_writer("svc_mgr_stderr"); */ let logger_spawner_sysinit = logmux.get_spawner(); let zombie_reaper_res = Reaper::new(logger_reaper); let mut zombie_reaper = match zombie_reaper_res { Ok(r) => {r} Err(err) => { panic!("zombie reaper system sysinit failed: {:?}", err); } }; let mut sys_init = sysinit::SysInit::new(logger_spawner_sysinit); let mut task_set = JoinSet::new(); task_set.spawn(async move { logmux.printing().await; }); task_set.spawn(async move { env::load_env(logger_env_load).await; let res = sys_init.prepare().await; println!("---- yukari sysinit phase end ----"); match res { Ok(_) => { println!("service management handover to supervisor"); println!(); sys_init.run().await; } Err(err) => { println!("[Error] error in sysinit phase: {:?}", err); println!(); loop{ let _ = tokio::time::sleep(Duration::from_secs(10)); } } } }); task_set.spawn_blocking(move || { //shell::shell_wait_enter(); shell::shell_repl(); }); task_set.spawn( async move { zombie_reaper.reap().await; }); task_set.join_next().await; println!("[FATAL] one of task exited. No.1 process will quit."); task_set.abort_all(); println!("No.1 process quit. system will reboot after 5 seconds..."); let _ = tokio::time::sleep(Duration::from_secs(5)); syscall::power::safe_reboot(); }