main.rs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. use std::{process};
  2. use std::time::Duration;
  3. use tokio::task::JoinSet;
  4. use crate::reaper::Reaper;
  5. use pkg_compile_time::{pkg_compile_date, pkg_compile_time};
  6. use crate::logger::LoggerWriterSpawner;
  7. mod shell;
  8. mod syscall;
  9. mod reaper;
  10. mod logger;
  11. mod sysinit;
  12. mod cfg;
  13. mod env;
  14. const YUKARI_VERSION : &str = env!("CARGO_PKG_VERSION");
  15. #[tokio::main(flavor = "multi_thread", worker_threads = 2)]
  16. async fn main() {
  17. println!("[ @yukari ] ==== yukari - ELIP4NG Init Process. ====");
  18. println!();
  19. let pid = process::id();
  20. if pid != 1 {
  21. panic!("yukari must run as PID 1.");
  22. }
  23. println!("[ @yukari ] hello, this is No.1 process (as init) 'yukari'.");
  24. println!("[ @yukari ] version: {}", YUKARI_VERSION);
  25. println!("[ @yukari ] compiled at: {} {}", pkg_compile_date!(), pkg_compile_time!());
  26. println!();
  27. println!("[ @yukari ] load config...");
  28. cfg::init_config_manager().await;
  29. logger::set_debug_mode_by_cfg().await;
  30. println!("[ @yukari ] you can < PRESS ENTER > at any time to enter maintenance shell.");
  31. println!();
  32. println!("[ @yukari ] ---- yukari sysinit phase ----");
  33. let (reaper_waiter_tx, reaper_waiter_rx) = tokio::sync::oneshot::channel();
  34. let mut logmux = logger::Logger::new();
  35. let logger_reaper = logmux.get_writer("zombie_reaper");
  36. let logger_env_load = logmux.get_writer("env_load");
  37. let logger_spawner_sysinit = logmux.get_spawner();
  38. let zombie_reaper_res = Reaper::new(logger_reaper);
  39. let mut zombie_reaper = match zombie_reaper_res {
  40. Ok(r) => {r}
  41. Err(err) => {
  42. panic!("zombie reaper system init failed: {:?}", err);
  43. }
  44. };
  45. let mut sys_init = sysinit::SysInit::new(logger_spawner_sysinit);
  46. let mut task_set = JoinSet::new();
  47. task_set.spawn(async move {
  48. logmux.printing().await;
  49. });
  50. task_set.spawn(async move {
  51. env::load_env(logger_env_load).await;
  52. let res = sys_init.prepare().await;
  53. println!("[ @yukari ] ---- yukari sysinit phase end ----");
  54. let _ = reaper_waiter_tx.send(());
  55. match res {
  56. Ok(_) => {
  57. println!("[ @yukari ] service management handover to supervisor");
  58. println!();
  59. sys_init.run().await;
  60. }
  61. Err(err) => {
  62. println!("[ @yukari ] error in sysinit phase: {:?}", err);
  63. println!();
  64. loop{
  65. let _ = tokio::time::sleep(Duration::from_secs(10));
  66. }
  67. }
  68. }
  69. });
  70. task_set.spawn_blocking(move || {
  71. shell::shell_wait_enter();
  72. shell::shell_repl();
  73. });
  74. task_set.spawn( async move {
  75. let _ = reaper_waiter_rx.await;
  76. zombie_reaper.reap().await;
  77. });
  78. task_set.join_next().await;
  79. println!("[ @yukari ] < !!! FATAL !!! > one of task exited. No.1 process will quit.");
  80. task_set.abort_all();
  81. println!("[ @yukari ] No.1 process quit. system will reboot after 5 seconds...");
  82. let _ = tokio::time::sleep(Duration::from_secs(5));
  83. syscall::power::safe_reboot();
  84. }