|
@@ -1,24 +1,98 @@
|
|
|
-use std::io::Error;
|
|
|
+use std::io::{Error, ErrorKind};
|
|
|
use std::time::Duration;
|
|
|
-use crate::logger::LogWriter;
|
|
|
+use crate::{cfg, syscall};
|
|
|
+use crate::logger::{LoggerWriterSpawner, LoggerWriterSpawnerImpl, LogWriter};
|
|
|
|
|
|
pub struct SysInit {
|
|
|
- logger: LogWriter,
|
|
|
- is_ready: bool,
|
|
|
+ logger_spawner: LoggerWriterSpawnerImpl,
|
|
|
+ sysinit_logger: LogWriter,
|
|
|
}
|
|
|
|
|
|
impl SysInit {
|
|
|
- pub fn new(logger: LogWriter) ->SysInit {
|
|
|
- SysInit{logger, is_ready: false}
|
|
|
+ pub fn new(logger_spawner: LoggerWriterSpawnerImpl) ->SysInit {
|
|
|
+ let sysinit_logger = logger_spawner.get_writer("sys_init_task");
|
|
|
+ SysInit{
|
|
|
+ logger_spawner,
|
|
|
+ sysinit_logger,
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- pub async fn prepare(&mut self) -> Option<Error> {
|
|
|
- None
|
|
|
+ pub async fn prepare(&mut self) -> Result<(), Error> {
|
|
|
+ let loader_bin = cfg::CFG.get().await.get_etc_cfg().sys.sys_loader.clone();
|
|
|
+ let stdout_logger = self.logger_spawner.get_writer("sys_loader_stdout");
|
|
|
+ let stderr_logger = self.logger_spawner.get_writer("sys_loader_stderr");
|
|
|
+ let run_res = syscall::proc::exec_async_with_logger(
|
|
|
+ loader_bin, stdout_logger, stderr_logger,
|
|
|
+ ).await;
|
|
|
+ match run_res {
|
|
|
+ Ok(c) => {
|
|
|
+ match c {
|
|
|
+ None => {
|
|
|
+ self.sysinit_logger.info("sys_loader exited with no code.").await;
|
|
|
+ Ok(())
|
|
|
+ }
|
|
|
+ Some(code) => {
|
|
|
+ if code == 0 {
|
|
|
+ self.sysinit_logger.info("sys_loader exited with code 0.").await;
|
|
|
+ std::env::set_var("yukari_sys_loader_exit_code","0");
|
|
|
+ Ok(())
|
|
|
+ } else{
|
|
|
+ self.sysinit_logger.warn(format!("sys_loader exited with non-zero code: {}", code).as_str()).await;
|
|
|
+ std::env::set_var("yukari_sys_loader_exit_code",format!("{}", code));
|
|
|
+ Ok(())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Err(err) => {
|
|
|
+ Err(std::io::Error::new(ErrorKind::Other, format!("error in run sys_loader: {}", err).as_str()))
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
pub async fn run(&mut self) {
|
|
|
+ let mut restart_limit = cfg::CFG.get().await.get_etc_cfg().sys.svc_mgr_exit_restart_limit;
|
|
|
+ let restart_delay = cfg::CFG.get().await.get_etc_cfg().sys.svc_mgr_exit_restart_delay_secs;
|
|
|
loop {
|
|
|
- let _ = tokio::time::sleep(Duration::from_secs(10));
|
|
|
+ let svc_mgr_bin = cfg::CFG.get().await.get_etc_cfg().sys.sys_loader.clone();
|
|
|
+ let stdout_logger = self.logger_spawner.get_writer("svc_mgr_stdout");
|
|
|
+ let stderr_logger = self.logger_spawner.get_writer("svc_mgr_stderr");
|
|
|
+ let run_res = syscall::proc::exec_async_with_logger(
|
|
|
+ svc_mgr_bin, stdout_logger, stderr_logger,
|
|
|
+ ).await;
|
|
|
+ match run_res {
|
|
|
+ Ok(c) => {
|
|
|
+ match c {
|
|
|
+ None => {
|
|
|
+ self.sysinit_logger.warn("svc_mgr exited with no code.").await;
|
|
|
+ }
|
|
|
+ Some(code) => {
|
|
|
+ if code == 0 {
|
|
|
+ self.sysinit_logger.warn("svc_mgr exited with code 0.").await;
|
|
|
+ } else {
|
|
|
+ self.sysinit_logger.warn(format!("svc_mgr exited with non-zero code: {}", code).as_str()).await;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Err(err) => {
|
|
|
+ self.sysinit_logger.warn(format!("error in run svc_mgr: {}", err).as_str()).await;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ match restart_limit {
|
|
|
+ 0 => {
|
|
|
+ self.sysinit_logger.info("restart svc_mgr, retry counter remains: unlimited").await;
|
|
|
+ }
|
|
|
+ 1 => {
|
|
|
+ self.sysinit_logger.error("svc_mgr restart reach limitation.").await;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ _ => {
|
|
|
+ restart_limit = restart_limit - 1;
|
|
|
+ self.sysinit_logger.info(format!("restart svc_mgr, retry counter remains: {}", restart_limit).as_str()).await;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let _ = tokio::time::sleep(Duration::from_secs(restart_delay));
|
|
|
}
|
|
|
}
|
|
|
}
|