Forráskód Böngészése

Patch exec service (#10)

* 完成整体Unit文件的解析框架,完成对Service文件的解析

* 完成Service的解析,重构代码结构,优化解析错误处理

* update

* 简要的启动逻辑

* 简要的启动逻辑

* 重构整体数据结构,解决之前出现的问题

* 启动shell(不完善)
GnoCiYeH 1 éve
szülő
commit
17ae466189

+ 2 - 1
Cargo.toml

@@ -14,7 +14,8 @@ hashbrown = "0.11"
 cfg-if = { version = "1.0"}
 
 [target.'cfg(target_os = "dragonos")'.dependencies]
-drstd = {git = "https://git.mirrors.dragonos.org/DragonOS-Community/drstd.git", revision = "a4d693c682"}
+#drstd = {git = "https://github.com/DragonOS-Community/drstd.git", revision = "af10011"}
+drstd = {path = "/home/heyicong/drstd"}
 lazy_static = { version = "1.4.0", default-features = false, features = ["spin_no_std"] }
 
 [target.'cfg(not(target_os = "dragonos"))'.dependencies]

+ 10 - 3
Makefile

@@ -1,8 +1,15 @@
+OUTPUT_DIR = $(DADK_BUILD_CACHE_DIR_DRAGONREACH_0_1_0)
+
 build:
-	cargo -Z build-std=core,alloc,compiler_builtins build --target x86_64-unknown-dragonos
+	cargo -Z build-std=core,alloc,compiler_builtins build --target ./target.json > build.txt
 
 install:
-	cargo -Z build-std=core,alloc,compiler_builtins install --target ./target.json --path .  --root ./DragonReach
+	cp ./parse_test/shell.service $(ROOT_PATH)/bin/sysroot/etc/reach/system/shell.service
+
+	mkdir -p $(OUTPUT_DIR)/tmp
+	cargo -Z build-std=core,alloc,compiler_builtins install --target $(TARGET) --path .  --root $(OUTPUT_DIR)/tmp
+	mv $(OUTPUT_DIR)/tmp/bin/DragonReach $(ROOT_PATH)/bin/user/DragonReach
+	rm -rf $(OUTPUT_DIR)/tmp
 
 build-linux:
-	cargo -Z build-std=core,alloc,compiler_builtins build --target x86_64-unknown-linux-gnu
+	cargo -Z build-std=core,alloc,compiler_builtins build --target x86_64-unknown-linux-gnu

+ 0 - 0
build.txt


+ 8 - 0
parse_test/shell.service

@@ -0,0 +1,8 @@
+[Unit]
+Description=Shell
+
+[Service]
+Type=simple
+ExecStart=/bin/shell.el
+Restart=always
+RestartSec=5000

+ 3 - 2
parse_test/test.service

@@ -5,9 +5,10 @@ Documentation=https://example.com/docs/my-service.html
 
 [Service]
 Type=simple
-ExecStart=/bin/gdb -v
+ExecStart=/bin/gdb
 ExecStartPos=/bin/gcc -v
-ExecStartPre=/bin/gcc -v
+ExecStartPre=/bin/ls
+ExecStopPost=/bin/ls
 WorkingDirectory=/home/heyicong/
 User=myuser
 Group=mygroup

+ 1 - 1
parse_test/test1.service

@@ -5,7 +5,7 @@ Documentation=https://example.com/docs/my-service.html
 
 [Service]
 Type=simple
-ExecStart=/bin/gcc -v
+ExecStart=/bin/ls
 WorkingDirectory=/home/heyicong/
 User=myuser
 Group=mygroup

+ 1 - 1
parse_test/test2.service

@@ -5,7 +5,7 @@ Documentation=https://example.com/docs/my-service.html
 
 [Service]
 Type=simple
-ExecStart=/home/heyicong/DragonOs/bin/sysroot/bin/DragonReach --option1=value1 --option2=value2
+ExecStart=/bin/ls
 WorkingDirectory=/home/heyicong/
 User=myuser
 Group=mygroup

+ 10 - 7
src/error/parse_error/mod.rs

@@ -31,24 +31,27 @@ pub enum ParseErrorType {
 }
 /// 错误信息应该包括错误类型ParseErrorType,当前解析的文件名,当前解析的行号
 #[derive(Debug, PartialEq, Eq, Clone)]
-pub struct ParseError(ParseErrorType,String,usize);
+pub struct ParseError(ParseErrorType, String, usize);
 
 impl ParseError {
-    pub fn new(error_type: ParseErrorType,file_name: String,line_number: usize) -> ParseError {
-        ParseError(error_type,file_name,line_number)
+    pub fn new(error_type: ParseErrorType, file_name: String, line_number: usize) -> ParseError {
+        ParseError(error_type, file_name, line_number)
     }
 
-    pub fn set_file(&mut self,path: &str) {
+    pub fn set_file(&mut self, path: &str) {
         self.1 = path.to_string();
     }
 
-    pub fn set_linenum(&mut self,linenum: usize) {
+    pub fn set_linenum(&mut self, linenum: usize) {
         self.2 = linenum;
     }
 }
 
 impl ErrorFormat for ParseError {
     fn error_format(&self) -> String {
-        format!("Parse Error!,Error Type: {:?}, File: {}, Line: {}",self.0,self.1,self.2)
+        format!(
+            "Parse Error!,Error Type: {:?}, File: {}, Line: {}",
+            self.0, self.1, self.2
+        )
     }
-}
+}

+ 5 - 1
src/error/runtime_error/mod.rs

@@ -1,4 +1,8 @@
 use super::ErrorFormat;
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+use std::format;
+use std::string::String;
 
 #[derive(Debug)]
 pub enum RuntimeErrorType {
@@ -51,6 +55,6 @@ impl RuntimeError {
 
 impl ErrorFormat for RuntimeError {
     fn error_format(&self) -> String {
-        format!("Runtime Error!,Error Type: {:?}",self.0)
+        format!("Runtime Error!,Error Type: {:?}", self.0)
     }
 }

+ 13 - 14
src/executor/dep_graph/mod.rs

@@ -2,13 +2,13 @@
 use drstd as std;
 
 use core::slice::SlicePattern;
-use std::cmp::PartialEq;
 use std::sync::Arc;
 use std::vec::Vec;
+use std::{cmp::PartialEq, sync::Mutex};
 
+use crate::manager::{self, UnitManager};
 use crate::{
     error::runtime_error::{RuntimeError, RuntimeErrorType},
-    manager::GLOBAL_UNIT_MANAGER,
     unit::Unit,
 };
 
@@ -35,11 +35,7 @@ impl DepGraph {
     pub fn add_node(&mut self, value: usize) -> usize {
         let index = self.nodes.len();
         //如果nodes中已经有了这个value则无需重复添加,直接返回nodes中的value对应的index
-        if let Some(idx) = self
-            .value
-            .iter()
-            .position(|x| *x == value)
-        {
+        if let Some(idx) = self.value.iter().position(|x| *x == value) {
             return idx;
         }
         //如果value在nodes中不存在,则添加value
@@ -95,20 +91,23 @@ impl DepGraph {
             let t = self.add_node(*target);
             self.add_edge(s, t);
 
-            let manager = GLOBAL_UNIT_MANAGER.read().unwrap();
-            let after = manager.get_unit_with_id(target).unwrap().unit_base().unit_part().after();
+            let arc_unit = UnitManager::get_unit_with_id(target).unwrap();
+            let unit = arc_unit.lock().unwrap();
+            let after = unit.unit_base().unit_part().after();
 
-            self.add_edges(*target,after);
+            self.add_edges(*target, after);
         }
     }
 
-    pub fn construct_graph(unit: &Arc<dyn Unit>) -> DepGraph {
+    pub fn construct_graph(unit: &Arc<Mutex<dyn Unit>>) -> DepGraph {
         let mut graph: DepGraph = DepGraph::new();
-        graph.add_node(unit.unit_id());
-        let after = unit.unit_base().unit_part().after();
 
+        let unit = unit.lock().unwrap();
+        let uid = unit.unit_id();
+        graph.add_node(uid);
+        let after = (&unit).unit_base().unit_part().after();
         //递归添加边来构建图
-        graph.add_edges(unit.unit_id(), after);
+        graph.add_edges(uid, after);
         return graph;
     }
 }

+ 35 - 6
src/executor/mod.rs

@@ -4,32 +4,61 @@ use drstd as std;
 pub mod dep_graph;
 pub mod service_executor;
 
-use std::process::Child;
 use std::sync::Arc;
+use std::{process::Child, sync::Mutex};
 
 use crate::{
     error::runtime_error::{RuntimeError, RuntimeErrorType},
-    unit::Unit, manager::GLOBAL_UNIT_MANAGER,
+    manager::UnitManager,
+    unit::Unit,
 };
 
 use self::dep_graph::DepGraph;
 
+#[derive(Debug,Clone, Copy)]
+pub enum ExitStatus {
+    Success,
+    Failure,
+    Abnormal,
+    Abort,
+    Watchdog,
+}
+
+impl ExitStatus {
+    /// ## 从错误码获得退出状态
+    /// 
+    /// 注意,该方法只会返回Success(exit_code == 0)和Abnormal(exit_code != 0)两种状态
+    /// 其他DragonReach定义的退出状态需要手动指定
+    /// 
+    /// ### return Success(exit_code == 0)、Abnormal(exit_code != 0)
+    pub fn from_exit_code(exit_code: i32) -> Self{
+        match exit_code {
+            0 => return Self::Success,
+            _ => return Self::Abnormal,
+        }
+    }
+}
+
 //Unit的全局执行器
 pub struct Executor;
 
 impl Executor {
-    pub fn exec(unit: &Arc<dyn Unit>) -> Result<(), RuntimeError> {
+    pub fn exec(unit: &Arc<Mutex<dyn Unit>>) -> Result<(), RuntimeError> {
         //TODO: 优化此处,解析时也用到了拓扑排序,尝试使用那次拓扑排序的结果
         let mut graph = DepGraph::construct_graph(unit);
 
         let sort_ret = graph.topological_sort()?;
-        let manager = GLOBAL_UNIT_MANAGER.read().unwrap();
         for u in sort_ret {
-            if let Err(e) = manager.get_unit_with_id(&u).unwrap().run() {
+            if UnitManager::is_running_unit(&u) {
+                continue;
+            }
+
+            let mutex = UnitManager::get_unit_with_id(&u).unwrap();
+            let mut unit = mutex.lock().unwrap();
+            if let Err(e) = unit.run() {
                 return Err(e);
             }
         }
-
         return Ok(());
     }
 }

+ 190 - 22
src/executor/service_executor/mod.rs

@@ -1,59 +1,227 @@
 #[cfg(target_os = "dragonos")]
 use drstd as std;
 
-use std::{process::Command, sync::Arc};
-
 use crate::{
-    error::runtime_error::{RuntimeError, RuntimeErrorType},
-    manager::{GLOBAL_UNIT_MANAGER, RunnnigUnit},
-    unit::{service::ServiceUnit, UnitState},
+    error::{
+        runtime_error::{RuntimeError, RuntimeErrorType},
+        ErrorFormat,
+    },
+    manager::{RunningUnit, UnitManager},
+    parse::{parse_util::UnitParseUtil, Segment, UnitParser},
+    task::cmdtask::CmdTask,
+    unit::{
+        service::RestartOption,
+        service::{ServiceType, ServiceUnit},
+        Unit, UnitState, UnitType,
+    },
+};
+use std::os::unix::process::CommandExt;
+use std::sync::Mutex;
+use std::vec::Vec;
+use std::{
+    borrow::BorrowMut,
+    cell::RefCell,
+    eprint, eprintln,
+    io::{Error, ErrorKind},
+    print, println,
 };
+use std::{io::BufRead, process::Command, sync::Arc};
+use std::{process::Stdio, string::ToString};
+
+use super::ExitStatus;
 
 pub struct ServiceExecutor;
 
 impl ServiceExecutor {
-    pub fn exec(service: &ServiceUnit) -> Result<(), RuntimeError> {
-        let manager = GLOBAL_UNIT_MANAGER.read().unwrap();
+    pub fn exec(service: &mut ServiceUnit) -> Result<(), RuntimeError> {
+        match *service.service_part().service_type() {
+            ServiceType::Simple => {
+                return Self::exec_simple(service);
+            }
+            ServiceType::Forking => {
+                return Self::exec_forking(service);
+            }
+            ServiceType::Dbus => {
+                return Self::exec_dbus(service);
+            }
+            ServiceType::Notify => {
+                return Self::exec_notify(service);
+            }
+            ServiceType::Idle => {
+                return Self::exec_idle(service);
+            }
+            ServiceType::OneShot => {
+                return Self::exec_one_shot(service);
+            }
+        }
+    }
+    pub fn exec_simple(service: &mut ServiceUnit) -> Result<(), RuntimeError> {
         //处理conflict
         let conflicts = service.unit_base().unit_part().conflicts();
         for u in conflicts {
             // 如果有冲突项enable的时候,该unit不能启动
-            let unit = manager.get_unit_with_id(u).unwrap();
+            let mutex = UnitManager::get_unit_with_id(u).unwrap();
+            let unit = mutex.lock().unwrap();
             if *unit.unit_base().state() == UnitState::Enabled {
-                eprintln!("{}: Service startup failed: conflict unit", unit.unit_base().unit_part().description());
+                eprintln!(
+                    "{}: Service startup failed: conflict unit",
+                    unit.unit_base().unit_part().description()
+                );
                 return Err(RuntimeError::new(RuntimeErrorType::ExecFailed));
             }
         }
 
-        //处理ExecStarts,执行在服务启动前执行的命令
-        let cmds = service.service_part().exec_start_pre();
-        for cmdtask in cmds {
-            cmdtask.exec()?;
+        //获取环境变量
+        //先获取指定的环境变量
+        let mut envs = Vec::from(service.service_part().environment());
+
+        //若指定了环境变量文件,则解析环境变量文件
+        let env_file = service.service_part().environment_file();
+        if env_file.len() > 0 {
+            let env_reader = match UnitParser::get_reader(env_file, UnitType::Unknown) {
+                Ok(reader) => reader,
+                Err(_) => {
+                    return Err(RuntimeError::new(RuntimeErrorType::Custom(
+                        "Incorrect environment variable configuration file".to_string(),
+                    )));
+                }
+            };
+            for line in env_reader.lines() {
+                if let Ok(line) = line {
+                    let x = match UnitParseUtil::parse_env(line.as_str()) {
+                        Ok(v) => v,
+                        Err(_) => {
+                            return Err(RuntimeError::new(RuntimeErrorType::Custom(
+                                "Failed to parse environment variable configuration file"
+                                    .to_string(),
+                            )));
+                        }
+                    };
+                    envs.push(x);
+                }
+            }
         }
 
-        //服务的启动命令
+        //服务配置环境变量,配置工作目录
+        //获取工作目录
+        let mut dir = service.service_part().working_directory();
+        if dir.is_empty() {
+            dir = "/";
+        }
+        //获取启动命令
         let exec_start = service.service_part().exec_start();
-        let proc = Command::new(&exec_start.path).args(&exec_start.cmd).spawn();
+        println!("exec:{}", exec_start.path);
+        //处理ExecStartsPre,准备在服务启动前执行的命令
+        //TODO:设置uid与gid
+        let cmds = service.service_part().exec_start_pre().clone();
+        let proc = unsafe {
+            Command::new(&exec_start.path)
+                .args(&exec_start.cmd)
+                .current_dir(dir)
+                .envs(envs)
+                .stderr(Stdio::inherit())
+                .stdout(Stdio::inherit())
+                .stdin(Stdio::inherit())
+                .pre_exec(move || {
+                    for cmdtask in cmds.clone() {
+                        match cmdtask.exec() {
+                            Ok(_) => (),
+                            Err(e) => {
+                                eprintln!("{}", e.error_format());
+                                return Err(Error::new(
+                                    ErrorKind::Interrupted,
+                                    "ExecStartPreFailed",
+                                ));
+                            }
+                        };
+                    }
+                    Ok(())
+                })
+                .spawn()
+        };
 
         match proc {
             Ok(p) => {
+                println!("Service running...");
                 //修改service状态
-
+                service.mut_unit_base().set_state(UnitState::Enabled);
                 //启动成功后将Child加入全局管理的进程表
-                let mut manager_writer = GLOBAL_UNIT_MANAGER.write().unwrap();
-                manager_writer.running_table.push(RunnnigUnit::new(p,Arc::new(service.clone())));
+                UnitManager::push_running(RunningUnit::new(p, service.unit_id()));
                 //执行启动后命令
-                let cmds = service.service_part().exec_start_pos();
-                for cmd in cmds {
-                    cmd.exec()?
-                }
+                Self::exec_start_pos(service)?;
             }
             Err(err) => {
                 eprintln!("{}: Service startup failed: {}", exec_start.path, err);
                 return Err(RuntimeError::new(RuntimeErrorType::ExecFailed));
             }
         }
+        Ok(())
+    }
+
+    fn exec_dbus(service: &ServiceUnit) -> Result<(), RuntimeError> {
+        Ok(())
+    }
+
+    fn exec_forking(service: &ServiceUnit) -> Result<(), RuntimeError> {
+        Ok(())
+    }
+
+    // 此方法会改变service的启动模式为simple
+    fn exec_idle(service: &mut ServiceUnit) -> Result<(), RuntimeError> {
+        // 将该service加入等待运行队列
+        let _ = service.set_attr(Segment::Service, "Type", "simple");
+        UnitManager::push_a_idle_service(service.unit_id());
+        Ok(())
+    }
+
+    fn exec_notify(service: &ServiceUnit) -> Result<(), RuntimeError> {
+        Ok(())
+    }
+
+    fn exec_one_shot(service: &ServiceUnit) -> Result<(), RuntimeError> {
+        Ok(())
+    }
+
+    fn exec_start_pos(service: &ServiceUnit) -> Result<(), RuntimeError> {
+        let cmds = service.service_part().exec_start_pos();
+        for cmd in cmds {
+            cmd.exec()?;
+        }
+        Ok(())
+    }
+
+    //显式停止时执行的命令
+    fn exec_stop(service: &mut ServiceUnit) -> Result<(), RuntimeError> {
+        let cmds = service.service_part().exec_stop();
+        for cmd in cmds {
+            cmd.exec()?;
+        }
+        Ok(())
+    }
 
+    //停止后执行的命令
+    fn exec_stop_post(service: &mut ServiceUnit) -> Result<(), RuntimeError> {
+        let cmds = service.service_part().exec_stop_post();
+        for cmd in cmds {
+            cmd.exec()?;
+        }
         Ok(())
     }
+
+    //服务退出执行的逻辑(包括自然退出及显式退出)
+    pub fn after_exit(service: &mut ServiceUnit, exit_status: ExitStatus) {
+        //TODO: 需要考虑是否需要在此处执行退出后代码,还是只需要显式退出时才执行
+        let _ = Self::exec_stop_post(service);
+
+        //判断是否需要restart,需要则再次启动服务
+        if service.service_part().restart().is_restart(&exit_status) {
+            let _ = service.run();
+            return;
+        }
+
+        //如果该进程标记了RemainAfterExit,则将其加入特殊标记表
+        if service.service_part().remain_after_exit() {
+            UnitManager::push_flag_running(service.unit_id());
+        }
+    }
 }

+ 152 - 43
src/main.rs

@@ -4,14 +4,10 @@
 
 use cfg_if::cfg_if;
 
-cfg_if!{
+cfg_if! {
     if #[cfg(target_os = "dragonos")]{
         extern crate drstd;
         use drstd as std;
-        use std::print;
-        use std::println;
-        use std::rc::Arc;
-        use unit::service::ServiceUnit;
     }
 }
 
@@ -19,67 +15,180 @@ extern crate hashbrown;
 
 mod contants;
 mod error;
+mod executor;
+mod manager;
 mod parse;
 mod task;
 mod unit;
-mod manager;
-mod executor;
 
 use crate::unit::service;
+use std::eprint;
+use std::eprintln;
+use std::fs;
+use std::print;
+use std::println;
+use std::string::{String, ToString};
+use std::vec::Vec;
+use unit::service::ServiceUnit;
 
 use self::unit::Unit;
+use error::ErrorFormat;
 
 pub struct FileDescriptor(usize);
 
+const DRAGON_REACH_UNIT_DIR: &'static str = "/etc/reach/system/";
+
 #[cfg(target_os = "dragonos")]
 #[no_mangle]
 fn main() {
-    use unit::service::ServiceUnit;
+    // use parse::UnitParser;
 
-    let service = match ServiceUnit::from_path("/bin/test.service"){
-        Ok(service) => service,
-        Err(e) => {
-            println!("Error:{}",e.error_format());
-            return;
-        }
+    // use crate::{
+    //     executor::Executor,
+    //     manager::{Manager, UnitManager},
+    //     parse::parse_util::UnitParseUtil,
+    // };
+    // let id = ServiceUnit::from_path("/etc/reach/system/shell.service").unwrap();
+
+    // if id != 0 {
+    //     let unit = UnitManager::get_unit_with_id(&id).unwrap();
+    //     if let Err(e) = Executor::exec(&unit) {
+    //         eprintln!("Err:{}", e.error_format());
+    //     }
+    // }
+
+    // loop{
+
+    // }
+
+    //================================
+    // use std::process::Command;
+    // use std::process::Stdio;
+    // let proc = unsafe {
+    //     Command::new("/bin/shell.elf")
+    //         .stderr(Stdio::inherit())
+    //         .stdout(Stdio::inherit())
+    //         .stdin(Stdio::inherit())
+    //         .spawn()
+    // };
+
+    // match proc {
+    //     Ok(p) => {
+    //         println!("Service running...");
+    //     }
+    //     Err(err) => {
+    //         eprintln!(": Service startup failed: {}",err);
+    //     }
+    // }
+
+    // loop {
+
+    // }
+
+    //========================================
+
+    use parse::UnitParser;
+
+    use crate::{
+        executor::Executor,
+        manager::{Manager, UnitManager},
+        parse::parse_util::UnitParseUtil,
     };
-    let service = service.as_ref();
-    println!("parse_result:");
-    println!("Description:{:?}", service.unit_base().unit_part().description());
-    println!("Documentation:{:?}",service.unit_base().unit_part().documentation());
-    println!("ServiceType:{:?}",service.service_part().service_type());
-    println!("ExecStrat:{:?}",service.service_part().exec_start());
-    println!("WorkingDirectory:{:?}",service.service_part().working_directory());
-    println!("Environment:{:?}",service.service_part().environment());
-    println!("Restart:{:?}",service.service_part().restart());
-    println!("RestartSec:{:?}",service.service_part().restart_sec());
-    println!("User:{:?}",service.service_part().user());
-    println!("Group:{:?}",service.service_part().group());
-    println!("TimeoutStartSec:{:?}",service.service_part().timeout_start_sec());
-    println!("TimeoutStopSec:{:?}",service.service_part().timeout_stop_sec());
+
+    let mut units_file_name = Vec::new();
+    //读取目录里面的unit文件
+    if let Ok(entries) = fs::read_dir(DRAGON_REACH_UNIT_DIR) {
+        for entry in entries {
+            if let Ok(entry) = entry {
+                let filename = entry.file_name();
+                let filename = filename.to_str().unwrap();
+                units_file_name.push(filename.to_string());
+            }
+        }
+    }
+
+    units_file_name.push(String::from("shell.service"));
+
+    println!("files: {:?}", units_file_name);
+
+    //启动服务
+    for path in units_file_name {
+        let id = match UnitParser::from_path(&path) {
+            Ok(id) => id,
+            Err(e) => {
+                eprintln!("Err:{}", e.error_format());
+                0
+            }
+        };
+
+        if id != 0 {
+            let unit = UnitManager::get_unit_with_id(&id).unwrap();
+            if let Err(e) = Executor::exec(&unit) {
+                eprintln!("Err:{}", e.error_format());
+            } else {
+                println!("Service {} startup success...", id);
+            }
+        }
+    }
+
+    // 启动完服务后进入主循环
+    loop {
+        // 检查各服务运行状态
+        //eprintln!(".");
+        Manager::check_running_status();
+    }
 }
 
 #[cfg(not(target_os = "dragonos"))]
 fn main() {
-    use std::{process::Command, sync::Arc};
+    use parse::UnitParser;
+
+    use crate::{
+        executor::Executor,
+        manager::{Manager, UnitManager},
+        parse::parse_util::UnitParseUtil,
+    };
+
+    let mut units_file_name = Vec::new();
+    // //读取目录里面的unit文件
+    // if let Ok(entries) = fs::read_dir(DRAGON_REACH_UNIT_DIR) {
+    //     for entry in entries {
+    //         if let Ok(entry) = entry {
+    //             if let Ok(file_type) = entry.file_type() {
+    //                 if file_type.is_file() {
+    //                     let filename = entry.file_name();
+    //                     let filename = filename.to_str().unwrap();
+    //                     units_file_name.push(filename.to_string());
+    //                 }
+    //             }
+    //         }
+    //     }
+    // }
 
-    use unit::service::ServiceUnit;
+    units_file_name.push("/home/heyicong/DragonReach/parse_test/test.service");
 
-    use crate::{executor::Executor, error::ErrorFormat};
+    //启动服务
+    for path in units_file_name {
+        let id = match UnitParser::from_path(&path) {
+            Ok(id) => id,
+            Err(e) => {
+                eprintln!("Err:{}", e.error_format());
+                0
+            }
+        };
 
-    let service = match ServiceUnit::from_path("/home/heyicong/DragonReach/parse_test/test.service"){
-        Ok(service) => service,
-        Err(e) => {
-            println!("Error:{}",e.error_format());
-            return;
+        if id != 0 {
+            let unit = UnitManager::get_unit_with_id(&id).unwrap();
+            if let Err(e) = Executor::exec(&unit) {
+                eprintln!("Err:{}", e.error_format());
+            }
         }
-    };
+    }
 
-    let unit: Arc<dyn Unit> = service.clone();
-    println!("unit: {:?}",unit.unit_type());
-    println!("unit: {:?}",unit.unit_base().unit_part().description());
-    if let Err(e) = Executor::exec(&unit) {
-        println!("Error:{}",e.error_format());
-        return;
+    // 启动完服务后进入主循环
+    loop {
+        // 检查各服务运行状态
+        Manager::check_running_status();
+        //println!(".");
     }
 }

+ 62 - 57
src/manager/mod.rs

@@ -1,73 +1,78 @@
 #[cfg(target_os = "dragonos")]
 use drstd as std;
-use std::{
-    sync::{Arc, RwLock}, collections::hash_map::DefaultHasher, process::Child,
-};
-use std::hash::{Hash,Hasher};
+use std::fs::File;
+use std::{eprint, eprintln, os::fd::AsFd, print, println, process::Child, vec::Vec};
 
-use crate::unit::Unit;
-use hashbrown::HashMap;
-use lazy_static::lazy_static;
+pub mod unit_manager;
+use std::io::Read;
+use std::os::unix::io::{AsRawFd, FromRawFd};
+pub use unit_manager::*;
 
-lazy_static! {
-    pub static ref GLOBAL_UNIT_MANAGER: RwLock<UnitManager> = {
-        RwLock::new(UnitManager {
-            id_to_unit: HashMap::new(),
-            path_to_unit: HashMap::new(),
-            running_table: Vec::new(),
-        })
-    };
-}
+use crate::executor::ExitStatus;
 
-pub struct RunnnigUnit(Child,Arc<dyn Unit>);
-impl RunnnigUnit {
-    pub fn new(p:Child,unit: Arc<dyn Unit>) -> Self {
-        RunnnigUnit(p,unit)
-    }
-}
+pub struct Manager;
 
-pub struct UnitManager {
-    // 通过unit_id映射unit
-    pub id_to_unit: HashMap<usize,Arc<dyn Unit>>,
+impl Manager {
+    /// ## 检查处于运行状态的unit状态
+    pub fn check_running_status() {
+        let mut running_manager = RUNNING_TABLE.write().unwrap();
+        let mut dead_unit: Vec<usize> = Vec::new();
+        let mut exited_unit: Vec<(usize, ExitStatus)> = Vec::new();
+        for unit in running_manager.into_iter() {
+            let proc = unit.child();
+            match proc.try_wait() {
+                //进程正常退出
+                Ok(Some(status)) => {
+                    //TODO:交付给相应类型的Unit类型去执行退出后的逻辑
+                    println!("Service exited success");
 
-    // 通过path的hash值来映射Unit
-    pub path_to_unit: HashMap<u64,usize>,
+                    exited_unit.push((
+                        *unit.id(),
+                        ExitStatus::from_exit_code(status.code().unwrap()),
+                    ));
 
-    pub running_table: Vec<RunnnigUnit>
-}
+                    //退出后从表中去除该任务
+                    dead_unit.push(*unit.id());
+                }
+                //进程错误退出(或启动失败)
+                Err(e) => {
+                    eprintln!("unit error: {}", e);
 
-unsafe impl Sync for UnitManager {}
+                    //test
+                    exited_unit.push((
+                        *unit.id(),
+                        ExitStatus::from_exit_code(!0),
+                    ));
 
-impl UnitManager {
-    pub fn insert_into_path_table(&mut self,path: &str,unit: usize){
-        let mut hasher = DefaultHasher::new();
-        path.hash(&mut hasher);
-        let hash = hasher.finish();
-        self.path_to_unit.insert(hash, unit);
-    }
+                    //从表中去除该任务
+                    dead_unit.push(*unit.id());
+                }
+                //进程处于正常运行状态
+                _ => {}
+            }
+        }
+        //释放锁,以便后续删除操作能拿到锁
+        drop(running_manager);
 
-    pub fn contants_path(&self,path: &str) -> bool{
-        let mut hasher = DefaultHasher::new();
-        path.hash(&mut hasher);
-        let hash = hasher.finish();
-        self.path_to_unit.contains_key(&hash)
-    }
+        //从表中清除数据
+        for id in dead_unit {
+            UnitManager::remove_running(id);
+        }
 
-    pub fn get_unit_with_path(&self,path: &str) -> Option<&Arc<dyn Unit>> {
-        let mut hasher = DefaultHasher::new();
-        path.hash(&mut hasher);
-        let hash = hasher.finish();
-        let id = match self.path_to_unit.get(&hash) {
-            Some(id) => id,
-            None => {
-                return None;
+        if UnitManager::running_count() == 0 {
+            let unit = UnitManager::pop_a_idle_service();
+            match unit {
+                Some(unit) => {
+                    let _ = unit.lock().unwrap().run();
+                }
+                None => {}
             }
-        };
-
-        self.id_to_unit.get(id)
-    }
+        }
 
-    pub fn get_unit_with_id(&self,id: &usize) -> Option<&Arc<dyn Unit>>{
-        self.id_to_unit.get(&id)
+        // 交付处理子进程退出逻辑
+        for tmp in exited_unit {
+            let unit = UnitManager::get_unit_with_id(&tmp.0).unwrap();
+            unit.lock().unwrap().after_exit(tmp.1);
+        }
     }
 }

+ 183 - 0
src/manager/unit_manager/mod.rs

@@ -0,0 +1,183 @@
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+use std::hash::{Hash, Hasher};
+use std::{
+    collections::hash_map::DefaultHasher,
+    collections::vec_deque::VecDeque,
+    process::Child,
+    sync::{Arc, Mutex, RwLock},
+    vec::Vec,
+};
+
+use crate::unit::service::ServiceUnit;
+use crate::unit::{service, Unit};
+use hashbrown::HashMap;
+use lazy_static::lazy_static;
+
+lazy_static! {
+    // 对于启动后即使退出亦认为其为运行状态的特殊注册类Service,对于这类进程做一个标记
+    static ref FLAG_RUNNING: RwLock<Vec<usize>> = RwLock::new(Vec::new());
+
+    // 任务等待队列,IDLE类型的service入队等待其它任务完成再执行
+    static ref IDLE_SERVIEC_DEQUE: Mutex<VecDeque<usize>> = Mutex::new(VecDeque::new());
+
+    // id到unit的映射表,全局的Unit管理表
+    static ref ID_TO_UNIT_MAP: RwLock<HashMap<usize,Arc<Mutex<dyn Unit>>>> = RwLock::new(HashMap::new());
+    
+    // 辅助表,通过服务名映射其id
+    static ref PATH_TO_UNIT_MAP: RwLock<HashMap<u64,usize>> = RwLock::new(HashMap::new());
+
+    // 全局运行中的Unit表
+    pub(super) static ref RUNNING_TABLE: RwLock<RunningTableManager> = RwLock::new(RunningTableManager { running_table: Vec::new() });
+}
+
+pub struct RunningTableManager {
+    running_table: Vec<RunningUnit>,
+}
+
+impl<'a> IntoIterator for &'a mut RunningTableManager {
+    type Item = &'a mut RunningUnit;
+    type IntoIter = std::slice::IterMut<'a, RunningUnit>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.running_table.iter_mut()
+    }
+}
+
+pub struct RunningUnit {
+    process: Child,
+    unit_id: usize,
+}
+impl RunningUnit {
+    pub fn new(p: Child, unit: usize) -> Self {
+        RunningUnit {
+            process: p,
+            unit_id: unit,
+        }
+    }
+
+    pub fn child(&mut self) -> &mut Child {
+        &mut self.process
+    }
+
+    pub fn id(&self) -> &usize {
+        &self.unit_id
+    }
+}
+
+pub struct UnitManager;
+
+unsafe impl Sync for UnitManager {}
+
+impl UnitManager {
+    pub fn insert_into_path_table(path: &str, unit: usize) {
+        let mut hasher = DefaultHasher::new();
+        path.hash(&mut hasher);
+        let hash = hasher.finish();
+        PATH_TO_UNIT_MAP.write().unwrap().insert(hash, unit);
+    }
+
+    pub fn contains_path(path: &str) -> bool {
+        let mut hasher = DefaultHasher::new();
+        path.hash(&mut hasher);
+        let hash = hasher.finish();
+        PATH_TO_UNIT_MAP.read().unwrap().contains_key(&hash)
+    }
+
+    pub fn get_unit_with_path(path: &str) -> Option<Arc<Mutex<dyn Unit>>> {
+        let mut hasher = DefaultHasher::new();
+        path.hash(&mut hasher);
+        let hash = hasher.finish();
+        let map = PATH_TO_UNIT_MAP.read().unwrap();
+        let id = match map.get(&hash) {
+            Some(id) => id,
+            None => {
+                return None;
+            }
+        };
+
+        let map = ID_TO_UNIT_MAP.read().unwrap();
+        let ret = map.get(id).cloned();
+        ret
+    }
+
+    pub fn get_unit_with_id(id: &usize) -> Option<Arc<Mutex<dyn Unit>>> {
+        let map = ID_TO_UNIT_MAP.read().unwrap();
+        let ret = map.get(&id).cloned();
+        ret
+    }
+
+    pub fn get_id_with_path(path: &str) -> Option<usize> {
+        let mut hasher = DefaultHasher::new();
+        path.hash(&mut hasher);
+        let hash = hasher.finish();
+        PATH_TO_UNIT_MAP.read().unwrap().get(&hash).cloned()
+    }
+
+    pub fn is_running_unit(id: &usize) -> bool {
+        !RUNNING_TABLE
+            .read()
+            .unwrap()
+            .running_table
+            .iter()
+            .filter(|x| x.unit_id == *id)
+            .collect::<Vec<_>>()
+            .is_empty()
+    }
+
+    pub fn push_running(unit: RunningUnit) {
+        RUNNING_TABLE.write().unwrap().running_table.push(unit);
+    }
+
+    pub fn remove_running(id: usize) {
+        let mut table = RUNNING_TABLE.write().unwrap();
+        match table.running_table.iter().position(|x| x.unit_id == id) {
+            Some(idx) => {
+                table.running_table.remove(idx);
+            }
+            _ => (),
+        }
+    }
+
+    pub fn insert_unit_with_id(id: usize, unit: Arc<Mutex<dyn Unit>>) {
+        let mut map = ID_TO_UNIT_MAP.write().unwrap();
+        if !map.contains_key(&id) {
+            map.insert(id, unit);
+        }
+    }
+
+    pub fn contains_id(id: &usize) -> bool{
+        ID_TO_UNIT_MAP.read().unwrap().contains_key(id)
+    }
+
+    pub fn pop_a_idle_service() -> Option<Arc<Mutex<dyn Unit>>>{
+        let id = IDLE_SERVIEC_DEQUE.lock().unwrap().pop_front();
+        match id {
+            Some(id) => {
+                return Self::get_unit_with_id(&id);
+            }
+            None =>{
+                return None;
+            }
+        }
+    }
+
+    pub fn push_a_idle_service(id: usize){
+        if !Self::contains_id(&id) {
+            return;
+        }
+        IDLE_SERVIEC_DEQUE.lock().unwrap().push_back(id);
+    }
+
+    pub fn push_flag_running(id: usize){
+        let mut t = FLAG_RUNNING.write().unwrap();
+        if t.contains(&id){
+            return;
+        }
+        t.push(id);
+    }
+
+    pub fn running_count() -> usize{
+        return RUNNING_TABLE.read().unwrap().running_table.len();
+    }
+}

+ 10 - 9
src/parse/graph/mod.rs

@@ -1,14 +1,17 @@
+use crate::{
+    error::parse_error::{ParseError, ParseErrorType},
+    unit::UnitType,
+};
 use core::slice::SlicePattern;
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+use std::string::{String, ToString};
+use std::vec::Vec;
 use std::{
     fs::File,
     io::{BufRead, BufReader},
 };
 
-use crate::{
-    error::parse_error::{ParseError, ParseErrorType},
-    unit::UnitType,
-};
-
 use super::{parse_util::UnitParseUtil, UnitParser};
 
 pub struct GraphNode {
@@ -132,8 +135,7 @@ impl Graph {
     pub fn parse_after(path: &String) -> Vec<String> {
         let mut ret = Vec::new();
 
-        let file = File::open(path).expect("Failed to open file");
-        let reader = BufReader::new(file);
+        let reader = UnitParser::get_reader(path, UnitType::Unknown).unwrap();
 
         let mut lines_with_after = Vec::new();
 
@@ -171,14 +173,13 @@ impl Graph {
         dependencies: &mut Vec<String>,
         total_after_count: &mut u32,
     ) -> Result<(), ParseError> {
-        let reader = UnitParser::get_unit_reader(file_path, UnitType::Unknown)?;
+        let reader = UnitParser::get_reader(file_path, UnitType::Unknown)?;
 
         let mut current_after_count = 0;
 
         for line_result in reader.lines() {
             if let Ok(line) = line_result {
                 if line.starts_with("After=") {
-
                     let dependencies_str = &line[6..];
                     let dependency_list: Vec<&str> = dependencies_str.split_whitespace().collect();
 

+ 32 - 17
src/parse/mod.rs

@@ -1,6 +1,7 @@
 use crate::error::parse_error::ParseErrorType;
-use crate::manager::{self, GLOBAL_UNIT_MANAGER};
+use crate::manager::{self, UnitManager};
 use crate::unit::{BaseUnit, Unit};
+use crate::DRAGON_REACH_UNIT_DIR;
 use crate::{
     error::parse_error::ParseError,
     unit::{service::ServiceUnitAttr, BaseUnitAttr, InstallUnitAttr, UnitType},
@@ -16,9 +17,13 @@ use std::fs::File;
 use std::io::{self, BufRead};
 use std::string::String;
 use std::string::ToString;
-use std::sync::Arc;
+use std::sync::{Arc, Mutex};
 use std::vec::Vec;
 
+use self::parse_service::ServiceParser;
+use self::parse_target::TargetParser;
+use self::parse_util::UnitParseUtil;
+
 pub mod graph;
 pub mod parse_service;
 pub mod parse_target;
@@ -153,17 +158,20 @@ pub struct UnitParser;
 impl UnitParser {
     /// @brief 从path获取到BufReader,此方法将会检验文件类型
     ///
-    /// 从path获取到BufReader,此方法将会检验文件类型
+    /// 如果指定UnitType,则进行文件名检查
     ///
     /// @param path 需解析的文件路径
     ///
     /// @param unit_type 指定Unit类型
     ///
     /// @return 成功则返回对应BufReader,否则返回Err
-    pub fn get_unit_reader(
-        path: &str,
-        unit_type: UnitType,
-    ) -> Result<io::BufReader<File>, ParseError> {
+    pub fn get_reader(path: &str, unit_type: UnitType) -> Result<io::BufReader<File>, ParseError> {
+        //判断是否为路径,若不为路径则到定向到默认unit文件夹
+        let mut realpath = path.to_string();
+        if !path.contains('/') {
+            realpath = format!("{}{}", DRAGON_REACH_UNIT_DIR, &path).to_string();
+        }
+        let path = realpath.as_str();
         // 如果指定UnitType,则进行文件名检查,不然直接返回reader
         if unit_type != UnitType::Unknown {
             let suffix = match path.rfind('.') {
@@ -189,6 +197,15 @@ impl UnitParser {
         return Ok(io::BufReader::new(file));
     }
 
+    pub fn from_path(path: &str) -> Result<usize, ParseError> {
+        let unit_type = UnitParseUtil::parse_type(&path);
+        match unit_type {
+            UnitType::Service => ServiceParser::parse(path),
+            UnitType::Target => TargetParser::parse(path),
+            _ => Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0)),
+        }
+    }
+
     /// @brief 将path路径的文件解析为unit_type类型的Unit
     ///
     /// 该方法解析每个Unit共有的段(Unit,Install),其余独有的段属性将会交付T类型的Unit去解析
@@ -202,19 +219,19 @@ impl UnitParser {
         path: &str,
         unit_type: UnitType,
     ) -> Result<usize, ParseError> {
-        let manager = GLOBAL_UNIT_MANAGER.read().unwrap();
-        if manager.contants_path(path) {
-            let unit = manager.get_unit_with_path(path).unwrap();
+        // 如果该文件已解析过,则直接返回id
+        if UnitManager::contains_path(path) {
+            let unit = UnitManager::get_unit_with_path(path).unwrap();
+            let unit = unit.lock().unwrap();
             return Ok(unit.unit_id());
         }
-        drop(manager);
 
         let mut unit: T = T::default();
         let mut unit_base = BaseUnit::default();
         //设置unit类型标记
         unit_base.set_unit_type(unit_type);
 
-        let reader = UnitParser::get_unit_reader(path, unit_type)?;
+        let reader = UnitParser::get_reader(path, unit_type)?;
 
         //用于记录当前段的类型
         let mut segment = Segment::None;
@@ -327,11 +344,9 @@ impl UnitParser {
         }
         unit.set_unit_base(unit_base);
         let id = unit.set_unit_id();
-        let dret: Arc<dyn Unit> = Arc::new(unit);
-
-        let mut manager = GLOBAL_UNIT_MANAGER.write().unwrap();
-        manager.id_to_unit.insert(dret.unit_id(), dret);
-        manager.insert_into_path_table(path, id);
+        let dret: Arc<Mutex<dyn Unit>> = Arc::new(Mutex::new(unit));
+        UnitManager::insert_unit_with_id(id, dret);
+        UnitManager::insert_into_path_table(path, id);
 
         return Ok(id);
     }

+ 7 - 8
src/parse/parse_service/mod.rs

@@ -1,15 +1,16 @@
-use super::UnitParser;
 use super::graph::Graph;
 use super::parse_util::UnitParseUtil;
+use super::UnitParser;
 use crate::error::parse_error::ParseError;
-use crate::manager::GLOBAL_UNIT_MANAGER;
-use crate::unit::service::{ServiceUnit, self};
+use crate::manager::UnitManager;
+use crate::unit::service::{self, ServiceUnit};
 
 #[cfg(target_os = "dragonos")]
 use drstd as std;
 
 use std::any::Any;
 use std::rc::Rc;
+use std::string::ToString;
 use std::sync::Arc;
 pub struct ServiceParser;
 
@@ -21,7 +22,7 @@ impl ServiceParser {
     /// @param path 需解析的文件路径
     ///
     /// @return 成功则返回Ok(Rc<ServiceUnit>),否则返回Err
-    pub fn parse(path: & str) -> Result<Arc<ServiceUnit>, ParseError> {
+    pub fn parse(path: &str) -> Result<usize, ParseError> {
         //预先检查是否存在循环依赖
         let mut graph = Graph::construct_graph(path.to_string())?;
         let ret = graph.topological_sort()?;
@@ -29,10 +30,8 @@ impl ServiceParser {
             let temp_unit = UnitParseUtil::parse_unit_no_type(&p)?;
         }
 
-        let manager = GLOBAL_UNIT_MANAGER.read().unwrap();
-        let result = (&manager).get_unit_with_path(path).unwrap();
+        let result = UnitManager::get_id_with_path(path).unwrap();
 
-        let result : ServiceUnit = result.as_any().downcast_ref::<ServiceUnit>().unwrap().clone();
-        return Ok(Arc::new(result));
+        return Ok(result);
     }
 }

+ 7 - 9
src/parse/parse_target/mod.rs

@@ -1,14 +1,15 @@
-use super::UnitParser;
 use super::graph::Graph;
 use super::parse_util::UnitParseUtil;
+use super::UnitParser;
 use crate::error::parse_error::ParseError;
-use crate::manager::GLOBAL_UNIT_MANAGER;
+use crate::manager::UnitManager;
 use crate::unit::target::TargetUnit;
 
 #[cfg(target_os = "dragonos")]
 use drstd as std;
 
 use std::rc::Rc;
+use std::string::ToString;
 use std::sync::Arc;
 
 pub struct TargetParser;
@@ -21,7 +22,7 @@ impl TargetParser {
     /// @param path 需解析的文件路径
     ///
     /// @return 成功则返回Ok(Rc<ServiceUnit>),否则返回Err
-    pub fn parse(path: &str) -> Result<Arc<TargetUnit>, ParseError> {
+    pub fn parse(path: &str) -> Result<usize, ParseError> {
         //预先检查是否存在循环依赖
         let mut graph = Graph::construct_graph(path.to_string())?;
         let ret = graph.topological_sort()?;
@@ -29,10 +30,7 @@ impl TargetParser {
             let temp_unit = UnitParseUtil::parse_unit_no_type(&p)?;
         }
 
-        let manager = GLOBAL_UNIT_MANAGER.read().unwrap();
-        let result = manager.get_unit_with_path(path).unwrap();
-
-        let result : TargetUnit = result.as_any().downcast_ref::<TargetUnit>().unwrap().clone();
-        return Ok(Arc::new(result));
+        let result = UnitManager::get_id_with_path(path).unwrap();
+        return Ok(result);
     }
-}
+}

+ 35 - 15
src/parse/parse_util/mod.rs

@@ -2,7 +2,7 @@ use crate::{
     contants::{AF_INET, AF_INET6, IPV4_MIN_MTU, IPV6_MIN_MTU, PRIO_MAX, PRIO_MIN},
     error::{parse_error::ParseError, parse_error::ParseErrorType},
     task::cmdtask::CmdTask,
-    unit::{Unit, Url, service::ServiceUnit, UnitType, target::TargetUnit},
+    unit::{service::ServiceUnit, target::TargetUnit, Unit, UnitType, Url},
     FileDescriptor,
 };
 
@@ -10,11 +10,13 @@ use crate::{
 use drstd as std;
 
 use std::{
-    format, fs, path::Path, print, println, string::String, string::ToString, vec, vec::Vec, os::unix::prelude::PermissionsExt, sync::Arc, any::Any,
+    any::Any, format, fs, os::unix::prelude::PermissionsExt, path::Path, print, println,
+    string::String, string::ToString, sync::Arc, vec, vec::Vec,
 };
 
 use super::{
-    parse_service::ServiceParser, parse_target::TargetParser, BASE_IEC, BASE_SI, SEC_UNIT_TABLE, UnitParser,
+    parse_service::ServiceParser, parse_target::TargetParser, UnitParser, BASE_IEC, BASE_SI,
+    SEC_UNIT_TABLE,
 };
 
 #[derive(PartialEq)]
@@ -429,7 +431,7 @@ impl UnitParseUtil {
     /// @param path 需解析的文件
     ///
     /// @return 解析成功则返回Ok(Arc<dyn Unit>),否则返回Err
-    pub fn parse_unit<T: Unit>(path: &str) -> Result<Arc<T>, ParseError> {
+    pub fn parse_unit<T: Unit>(path: &str) -> Result<usize, ParseError> {
         return T::from_path(path);
     }
 
@@ -458,12 +460,8 @@ impl UnitParseUtil {
         //通过文件后缀分发给不同类型的Unit解析器解析
         let unit = match suffix {
             //TODO: 目前为递归,后续应考虑从DragonReach管理的Unit表中寻找是否有该Unit,并且通过记录消除递归
-            "service" => {
-                UnitParser::parse::<ServiceUnit>(path, UnitType::Service)?
-            },
-            "target" => {
-                UnitParser::parse::<TargetUnit>(path, UnitType::Target)?
-            },
+            "service" => UnitParser::parse::<ServiceUnit>(path, UnitType::Service)?,
+            "target" => UnitParser::parse::<TargetUnit>(path, UnitType::Target)?,
             _ => {
                 return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
             }
@@ -472,6 +470,15 @@ impl UnitParseUtil {
         return Ok(unit);
     }
 
+    pub fn parse_env(s: &str) -> Result<(String, String), ParseError> {
+        let s = s.trim().split('=').collect::<Vec<&str>>();
+        if s.len() != 2 {
+            return Err(ParseError::new(ParseErrorType::EINVAL, "".to_string(), 0));
+        }
+
+        return Ok((s[0].to_string(), s[1].to_string()));
+    }
+
     /// @brief 将对应的str解析为对应CmdTask
     ///
     /// 将传入的字符串解析为CmdTask组,解析失败返回错误
@@ -527,13 +534,13 @@ impl UnitParseUtil {
     /// @brief 判断是否为绝对路径,以及指向是否为可执行文件或者sh脚本
     ///
     /// 目前该方法仅判断是否为绝对路径
-    /// 
+    ///
     /// @param path 路径
     ///
     /// @return 解析成功则返回true,否则返回false
     pub fn is_valid_exec_path(path: &str) -> bool {
         let path = Path::new(path);
-        return path.is_absolute()
+        return path.is_absolute();
 
         //TODO: 后续应判断该文件是否为合法文件
         //let path = Path::new(path);
@@ -541,10 +548,10 @@ impl UnitParseUtil {
     }
 
     pub fn is_valid_file(path: &str) -> bool {
-        if !path.starts_with("/"){
+        if !path.starts_with("/") {
             return false;
         }
-        
+
         let path = Path::new(path);
         if let Ok(matadata) = fs::metadata(path) {
             return matadata.is_file();
@@ -556,7 +563,7 @@ impl UnitParseUtil {
     fn is_executable_file(path: &Path) -> bool {
         if let Ok(metadata) = fs::metadata(path) {
             // 检查文件类型是否是普通文件并且具有可执行权限
-            if metadata.is_file(){
+            if metadata.is_file() {
                 let permissions = metadata.permissions().mode();
                 return permissions & 0o111 != 0;
             }
@@ -687,4 +694,17 @@ impl UnitParseUtil {
         }
         return false;
     }
+
+    pub fn parse_type(path: &str) -> UnitType {
+        if let Some(index) = path.rfind('.') {
+            let result = &path[index + 1..];
+            match result {
+                "service" => return UnitType::Service,
+                "target" => return UnitType::Target,
+                //TODO: 添加文件类型
+                _ => return UnitType::Unknown,
+            }
+        }
+        UnitType::Unknown
+    }
 }

+ 3 - 1
src/task/cmdtask/mod.rs

@@ -1,7 +1,7 @@
 #[cfg(target_os = "dragonos")]
 use drstd as std;
 
-use std::{process::Command, string::String};
+use std::{eprint, eprintln, process::Command, string::String, vec::Vec};
 
 use crate::error::runtime_error::{RuntimeError, RuntimeErrorType};
 
@@ -17,6 +17,8 @@ impl CmdTask {
         let result = Command::new(&self.path).args(&self.cmd).output();
         match result {
             Ok(output) => {
+                let stdout = String::from_utf8_lossy(&output.stdout);
+                print!("{}",stdout);
                 if !output.status.success() && !self.ignore {
                     let stderr = String::from_utf8_lossy(&output.stderr);
                     eprintln!("{}: Command failed: {}", self.path, stderr);

+ 16 - 21
src/unit/mod.rs

@@ -2,6 +2,7 @@ use crate::error::parse_error::ParseError;
 use crate::error::parse_error::ParseErrorType;
 use crate::error::runtime_error::RuntimeError;
 use crate::error::runtime_error::RuntimeErrorType;
+use crate::executor::ExitStatus;
 use crate::parse::parse_util::UnitParseUtil;
 use crate::parse::Segment;
 
@@ -12,6 +13,8 @@ use hashbrown::HashMap;
 use std::any::Any;
 use std::default::Default;
 use std::fmt::Debug;
+use std::marker::{Send, Sized, Sync};
+use std::option::Option::Some;
 use std::result::Result;
 use std::result::Result::Err;
 use std::result::Result::Ok;
@@ -40,8 +43,8 @@ pub trait Unit: Sync + Send + Debug {
     ///
     /// @param path 需解析的文件
     ///
-    /// @return 解析成功则返回对应Unit的Arc指针,否则返回Err
-    fn from_path(path: &str) -> Result<Arc<Self>, ParseError>
+    /// @return 解析成功则返回对应Unit的id,否则返回Err
+    fn from_path(path: &str) -> Result<usize, ParseError>
     where
         Self: Sized;
 
@@ -81,7 +84,7 @@ pub trait Unit: Sync + Send + Debug {
     /// ## Unit的工作逻辑
     ///
     /// ### return OK(())/Err
-    fn run(&self) -> Result<(), RuntimeError>;
+    fn run(&mut self) -> Result<(), RuntimeError>;
 
     /// ## 设置unit_id
     ///
@@ -91,25 +94,17 @@ pub trait Unit: Sync + Send + Debug {
         self.mut_unit_base().set_id(ret);
         ret
     }
-}
 
-pub struct Downcast;
-impl Downcast {
-    fn downcast<T: Unit + Clone + 'static>(unit: Arc<dyn Unit>) -> Result<Arc<T>,RuntimeError> {
-        let any = unit.as_any();
-        let unit = match any.downcast_ref::<T>(){
-            Some(v) => v,
-            None => {
-                return Err(RuntimeError::new(RuntimeErrorType::DatabaseError));
-            }
-        };
-        
-        return Ok(Arc::new(unit.clone()));
+    /// ## Unit退出后逻辑
+    /// 
+    /// 一般只有可运行的Unit(如Service)需要重写此函数
+    fn after_exit(&mut self,exit_status: ExitStatus){
+
     }
 }
 
 //Unit状态
-#[derive(Clone, Copy, Debug,PartialEq)]
+#[derive(Clone, Copy, Debug, PartialEq)]
 pub enum UnitState {
     Enabled,
     Disabled,
@@ -375,8 +370,8 @@ impl UnitPart {
 //对应Unit文件的Install段
 #[derive(Debug, Clone)]
 pub struct InstallPart {
-    wanted_by: Vec<Arc<TargetUnit>>,
-    requires_by: Vec<Arc<TargetUnit>>,
+    wanted_by: Vec<usize>,
+    requires_by: Vec<usize>,
     also: Vec<usize>,
     alias: String,
 }
@@ -429,11 +424,11 @@ impl InstallPart {
         return Ok(());
     }
 
-    pub fn wanted_by(&self) -> &[Arc<TargetUnit>] {
+    pub fn wanted_by(&self) -> &[usize] {
         &self.wanted_by
     }
 
-    pub fn requires_by(&self) -> &[Arc<TargetUnit>] {
+    pub fn requires_by(&self) -> &[usize] {
         &self.requires_by
     }
 

+ 50 - 16
src/unit/service/mod.rs

@@ -1,8 +1,9 @@
 use super::{BaseUnit, Unit};
 use crate::error::runtime_error::{RuntimeError, RuntimeErrorType};
 use crate::error::{parse_error::ParseError, parse_error::ParseErrorType};
+use crate::executor::ExitStatus;
 use crate::executor::service_executor::ServiceExecutor;
-use crate::manager::GLOBAL_UNIT_MANAGER;
+use crate::manager::UnitManager;
 use crate::parse::graph::Graph;
 use crate::parse::parse_service::ServiceParser;
 use crate::parse::parse_util::UnitParseUtil;
@@ -17,7 +18,7 @@ use std::rc::Rc;
 use std::string::String;
 use std::sync::Arc;
 use std::vec::Vec;
-#[derive(Clone, Debug,Default)]
+#[derive(Clone, Debug, Default)]
 pub struct ServiceUnit {
     unit_base: BaseUnit,
     service_part: ServicePart,
@@ -39,15 +40,15 @@ impl Default for ServiceType {
     }
 }
 
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy,PartialEq)]
 pub enum RestartOption {
-    AlwaysRestart,
-    OnSuccess,
-    OnFailure,
-    OnAbnormal,
-    OnAbort,
-    OnWatchdog,
-    None,
+    AlwaysRestart,  //总是重启
+    OnSuccess,  //在该服务正常退出时
+    OnFailure,  //在该服务启动失败时
+    OnAbnormal, //在该服务以非0错误码退出时
+    OnAbort,    //在该服务显示退出时(通过DragonReach手动退出)
+    OnWatchdog, //定时观测进程无响应时(当前未实现)
+    None,       //不重启
 }
 
 impl Default for RestartOption {
@@ -56,6 +57,35 @@ impl Default for RestartOption {
     }
 }
 
+impl RestartOption {
+    pub fn is_restart(&self,exit_status: &ExitStatus) -> bool{
+        if *self == Self::AlwaysRestart{
+            return true;
+        }
+
+        match (*self,*exit_status) {
+            (Self::OnSuccess,ExitStatus::Success) =>{
+                return true;
+            },
+            (Self::OnAbnormal,ExitStatus::Abnormal) =>{
+                return true;
+            },
+            (Self::OnAbort,ExitStatus::Abort) =>{
+                return true;
+            },
+            (Self::OnFailure,ExitStatus::Failure) =>{
+                return true;
+            },
+            (Self::OnWatchdog,ExitStatus::Watchdog) =>{
+                return true;
+            },
+            _ => {
+                return false;
+            }
+        }
+    }
+}
+
 #[derive(Debug, Clone, Copy)]
 pub enum MountFlag {
     Shared,
@@ -86,7 +116,7 @@ pub struct ServicePart {
     timeout_start_sec: u64,
     timeout_stop_sec: u64,
     //上下文配置相关
-    environment: Vec<String>,
+    environment: Vec<(String, String)>,
     environment_file: String,
     nice: i8,
     working_directory: String,
@@ -102,7 +132,7 @@ impl Unit for ServiceUnit {
         self
     }
 
-    fn from_path(path: &str) -> Result<Arc<Self>, ParseError>
+    fn from_path(path: &str) -> Result<usize, ParseError>
     where
         Self: Sized,
     {
@@ -137,13 +167,17 @@ impl Unit for ServiceUnit {
         return self.unit_base.unit_id;
     }
 
-    fn run(&self) -> Result<(), RuntimeError> {
+    fn run(&mut self) -> Result<(), RuntimeError> {
         self.exec()
     }
 
     fn mut_unit_base(&mut self) -> &mut BaseUnit {
         return &mut self.unit_base;
     }
+
+    fn after_exit(&mut self,exit_status: ExitStatus) {
+        ServiceExecutor::after_exit(self,exit_status);
+    }
 }
 
 impl ServiceUnit {
@@ -155,7 +189,7 @@ impl ServiceUnit {
         return &self.service_part;
     }
 
-    fn exec(&self) -> Result<(), RuntimeError> {
+    fn exec(&mut self) -> Result<(), RuntimeError> {
         ServiceExecutor::exec(self)
     }
 }
@@ -266,7 +300,7 @@ impl ServicePart {
                 self.timeout_stop_sec = UnitParseUtil::parse_sec(val)?
             }
             ServiceUnitAttr::Environment => {
-                self.environment.push(String::from(val));
+                self.environment.push(UnitParseUtil::parse_env(val)?);
             }
             ServiceUnitAttr::EnvironmentFile => {
                 if !UnitParseUtil::is_valid_file(val) {
@@ -356,7 +390,7 @@ impl ServicePart {
     }
 
     // 上下文配置相关
-    pub fn environment(&self) -> &[String] {
+    pub fn environment(&self) -> &[(String, String)] {
         &self.environment
     }
 

+ 11 - 16
src/unit/target/mod.rs

@@ -1,23 +1,18 @@
 use super::{BaseUnit, Unit};
 use crate::error::parse_error::ParseError;
-use crate::parse::Segment;
 use crate::parse::parse_target::TargetParser;
+use crate::parse::Segment;
+use cfg_if::cfg_if;
 use core::ops::Deref;
+use core::result::Result::{self, Err, Ok};
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+use std::marker::{Send, Sized, Sync};
+use std::rc::Rc;
 use std::sync::Arc;
-use cfg_if::cfg_if;
-
-cfg_if!{
-    if #[cfg(target_os = "dragonos")]{
-        use drstd as std;
-        use std::rc::Rc;
-        use std::vec::Vec;
-    }else{
-        use std::rc::Rc;
-        use std::vec::Vec;
-    }
-}
+use std::vec::Vec;
 
-#[derive(Debug,Clone,Default)]
+#[derive(Debug, Clone, Default)]
 pub struct TargetUnit {
     unit_base: BaseUnit,
     //targets: Vec<Rc<dyn Unit>>,
@@ -28,7 +23,7 @@ impl Unit for TargetUnit {
         self
     }
 
-    fn from_path(path: &str) -> Result<Arc<Self>, ParseError>
+    fn from_path(path: &str) -> Result<usize, ParseError>
     where
         Self: Sized,
     {
@@ -55,7 +50,7 @@ impl Unit for TargetUnit {
         return self.unit_base.unit_id;
     }
 
-    fn run(&self) -> Result<(),crate::error::runtime_error::RuntimeError> {
+    fn run(&mut self) -> Result<(), crate::error::runtime_error::RuntimeError> {
         Ok(())
     }