ZRY 1 сар өмнө
parent
commit
3112bb6a2b

+ 3 - 0
.idea/dictionaries/root.xml

@@ -0,0 +1,3 @@
+<component name="ProjectDictionaryState">
+  <dictionary name="root" />
+</component>

+ 2 - 0
src/cfg/boot.rs

@@ -3,12 +3,14 @@ use serde::Deserialize;
 #[derive(Deserialize, Clone)]
 pub struct BootConfigDef{
     pub hostname: String,
+    pub yukari_log_debug: bool,
 }
 
 impl BootConfigDef {
     pub fn default() -> BootConfigDef {
         BootConfigDef{
             hostname: "ELIP4NG-Default-Hostname".to_string(),
+            yukari_log_debug: false,
         }
     }
 }

+ 18 - 4
src/cfg/etc.rs

@@ -1,11 +1,11 @@
-use std::collections::HashMap;
 use serde::Deserialize;
-use common_macros::hash_map;
+use toml::Value;
 use crate::cfg::boot::BootConfigDef;
 
 #[derive(Deserialize, Clone)]
 pub struct EtcConfigDef{
     pub sys: SysCfg,
+    pub env: toml::map::Map<String, Value>,
     pub boot_default: BootConfigDef,
     pub secure: SecureCfg,
 }
@@ -13,10 +13,16 @@ pub struct EtcConfigDef{
 impl EtcConfigDef {
     pub fn default() -> EtcConfigDef {
         EtcConfigDef{
+            sys: SysCfg {
+                sys_loader: "/nagae/elip4ng/bin/chen".to_string(),
+                service_mgr: "/nagae/elip4ng/bin/ran".to_string(),
+                shell_spawner: "/nagae/elip4ng/bin/reimu".to_string(),
+            },
+            env: toml::map::Map::new(),
             boot_default: BootConfigDef::default(),
             secure: SecureCfg{
                 bcrypt_password: "$2a$10$9Nk9um4osOsdDPw.NjgBx.0qbQ/5H/qLXplaNjBeKKj6N13.PE3YK".to_string(),
-            }
+            },
         }
     }
 
@@ -32,7 +38,15 @@ pub struct SecureCfg {
 
 #[derive(Deserialize, Clone)]
 pub struct SysCfg {
-    pub admin_shell: String,
     pub sys_loader: String,
     pub service_mgr: String,
+    pub shell_spawner: String,
+}
+
+#[derive(Deserialize, Clone)]
+pub struct TeletypeCfg {
+    pub baudrate: u32,
+    pub device: String,
+    pub getty: String,
+    pub shell: String,
 }

+ 1 - 1
src/cfg/mod.rs

@@ -11,7 +11,7 @@ use simple_rw_global::tokio::AsyncGlobalContainer;
 use crate::cfg::boot::BootConfigDef;
 use crate::cfg::etc::EtcConfigDef;
 
-const INIT_ETC_CFG_FILENAME:&str = "/etc/init.toml";
+const INIT_ETC_CFG_FILENAME:&str = "/nagae/elip4ng/config/init.toml";
 const INIT_BOOT_CFG_FILENAME:&str = "/boot/config/init.toml";
 
 lazy_static! {

+ 31 - 0
src/env.rs

@@ -0,0 +1,31 @@
+use toml::Value;
+use crate::{cfg, syscall};
+use crate::logger::LogWriter;
+
+pub async fn load_env(logger: LogWriter) {
+    let cfg_inst = cfg::CFG.get().await;
+    let cfg_etc = cfg_inst.get_etc_cfg();
+    let cfg_boot = cfg_inst.get_boot_cfg();
+    logger.debug("load env vars...").await;
+    for (k, v) in cfg_etc.env.iter(){
+        match v {
+            Value::String(val) => {
+                logger.debug(format!("'{}'='{}'", k, val).as_str()).await;
+                std::env::set_var(k, val);
+            }
+            _ => {
+                logger.warn(format!("invalid var '{}' in config.", k).as_str()).await;
+            }
+        }
+    }
+    let hostname = cfg_boot.hostname.as_str();
+    let shn_res = syscall::hostname::set_hostname(hostname);
+    match shn_res {
+        Ok(_) => {
+            logger.debug(format!("set hostname to '{}'.", hostname).as_str()).await;
+        }
+        Err(e) => {
+            logger.warn(format!("failed set hostname to '{}': {:?}", hostname, e).as_str()).await;
+        }
+    }
+}

+ 7 - 0
src/logger/mod.rs

@@ -4,6 +4,7 @@ use tokio::sync::mpsc::{channel, Sender, Receiver};
 
 use std::sync::atomic::{AtomicBool, Ordering};
 use lazy_static::lazy_static;
+use crate::cfg;
 
 lazy_static!{
     static ref DEBUG_MODE: AtomicBool = AtomicBool::new(false);
@@ -108,4 +109,10 @@ impl Display for LogLevel {
 
 pub fn set_debug_mode(mode: bool) {
     DEBUG_MODE.store(mode, Ordering::Relaxed);
+}
+
+pub async fn set_debug_mode_by_cfg() {
+    let cfg_inst = cfg::CFG.get().await;
+    let cfg_boot = cfg_inst.get_boot_cfg();
+    DEBUG_MODE.store(cfg_boot.yukari_log_debug, Ordering::Relaxed);
 }

+ 11 - 10
src/main.rs

@@ -1,4 +1,4 @@
-use std::{process, thread};
+use std::{process};
 use std::time::Duration;
 use tokio::task::JoinSet;
 use crate::reaper::Reaper;
@@ -10,7 +10,7 @@ mod reaper;
 mod logger;
 mod sysinit;
 mod cfg;
-mod tty;
+mod env;
 
 #[tokio::main(flavor = "multi_thread", worker_threads = 2)]
 async fn main() {
@@ -24,22 +24,22 @@ async fn main() {
         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!("spawning tty...");
-    tty::spawn_tty().await;
-
-    println!("hello, this is No.1 process (as sysinit) '/usr/sbin/yukari'.");
-    println!("this program is compile at {} {}", pkg_compile_date!(), pkg_compile_time!());
-    println!();
     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(String::from("reaper"));
-    let logger_sysinit = logmux.get_writer(String::from("sysinit"));
+    let logger_reaper = logmux.get_writer(String::from("zombie_reaper"));
+    let logger_env_load = logmux.get_writer(String::from("env_load"));
+    let logger_sysinit = logmux.get_writer(String::from("sys_init"));
 
     let zombie_reaper_res = Reaper::new(logger_reaper);
     let mut zombie_reaper = match zombie_reaper_res {
@@ -58,6 +58,7 @@ async fn main() {
     });
 
     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 {

+ 1 - 1
src/shell/mgrsh.rs

@@ -15,7 +15,7 @@ pub fn mgr_shell() {
         .add("exec", command! {
             "run a command, without arguments",
             (shell: String) => |shell:String| {
-                syscall::proc::run(shell);
+                syscall::proc::shell_exec_cmd(shell);
                 Ok(CommandStatus::Done)
             }
         })

+ 58 - 0
src/syscall/error.rs

@@ -0,0 +1,58 @@
+use std::fmt::{Debug, Display, Formatter};
+use nix::errno::Errno;
+
+pub struct NixError {
+    errno: Errno
+}
+
+impl Debug for NixError {
+    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        Debug::fmt(&self.errno, f)
+    }
+}
+
+impl Display for NixError {
+    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        Display::fmt(&self.errno, f)
+    }
+}
+
+impl std::error::Error for NixError {
+
+}
+
+impl From<Errno> for NixError {
+    fn from(value: Errno) -> Self {
+        Self{
+            errno: value,
+        }
+    }
+}
+
+pub struct ExecError {
+    err_msg: String
+}
+
+impl Debug for ExecError {
+    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.err_msg)
+    }
+}
+
+impl Display for ExecError {
+    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.err_msg)
+    }
+}
+
+impl std::error::Error for ExecError {
+
+}
+
+impl From<std::io::Error> for ExecError {
+    fn from(value: std::io::Error) -> Self {
+        Self{
+            err_msg: format!("IO Error: {:?}", value)
+        }
+    }
+}

+ 12 - 0
src/syscall/hostname.rs

@@ -0,0 +1,12 @@
+use nix::unistd::sethostname;
+use crate::syscall::error::NixError;
+
+pub fn set_hostname(hostname: &str) -> Result<(), NixError> {
+    let res = sethostname(hostname);
+    match res {
+        Ok(_) => {Result::Ok(())}
+        Err(e) => {
+            Result::Err(NixError::from(e))
+        }
+    }
+}

+ 3 - 1
src/syscall/mod.rs

@@ -1,2 +1,4 @@
 pub mod power;
-pub mod proc;
+pub mod proc;
+pub mod hostname;
+pub mod error;

+ 55 - 18
src/syscall/proc.rs

@@ -1,27 +1,64 @@
-use std::process::{Command};
+use std::io;
+use std::process::{ExitStatus};
+use crate::syscall::error::ExecError;
 
-pub fn run(program: String) {
-    let p = Command::new(program.clone()).spawn();
+fn _exitstatus_convert(res: io::Result<ExitStatus>) -> Result<Option<i32>, ExecError> {
+    match res {
+        Ok(es) => {
+            match es.code() {
+                None => {
+                    Ok(None)
+                }
+                Some(code) => {
+                    Ok(Some(code))
+                }
+            }
+        }
+        Err(e) => {Err(ExecError::from(e))}
+    }
+}
+
+pub fn shell_exec_cmd(program: String) {
+    let r = exec_blocking(program);
+    match r {
+        Ok(ec) => {
+            match ec {
+                None => {
+                    println!("exit with no code.")
+                }
+                Some(c) => {
+                    println!("exit with code {}.", c)
+                }
+            }
+        }
+        Err(err) => {
+            println!("failed run command: {:?}.", err)
+        }
+    }
+}
+
+pub fn exec_blocking(program: String) -> Result<Option<i32>, ExecError> {
+    let p = std::process::Command::new(program.clone()).spawn();
     match p {
         Ok(mut ch) => {
             let res = ch.wait();
-            match res {
-                Ok(es) => {
-                    match es.code() {
-                        None => {
-                            println!("exited with no code");
-                        }
-                        Some(code) => {
-                            println!("exited with code {}", code);
-                        }
-                    };
-                }
-                Err(_) => {}
-            }
+            _exitstatus_convert(res)
         }
         Err(err) => {
-            println!("failed run command {}: {:?}", program.as_str(), err);
-            return;
+            Err(ExecError::from(err))
         }
     }
 }
+
+pub async fn exec_async(program: String) -> Result<Option<i32>, ExecError> {
+    let p = tokio::process::Command::new(program.clone()).spawn();
+    match p {
+        Ok(mut ch) => {
+            let res = ch.wait().await;
+            _exitstatus_convert(res)
+        }
+        Err(err) => {
+            Err(ExecError::from(err))
+        }
+    }
+}

+ 0 - 4
src/tty/mod.rs

@@ -1,4 +0,0 @@
-
-pub async fn spawn_tty() {
-
-}