浏览代码

简要的启动逻辑

GnoCiYeH 1 年之前
父节点
当前提交
4331692e5c

+ 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://git.mirrors.dragonos.org/DragonOS-Community/drstd.git", revision = "a4d693c682"}
+drstd = {path = "/home/heyicong/dragonos-rs-std"}
 lazy_static = { version = "1.4.0", default-features = false, features = ["spin_no_std"] }
 
 [target.'cfg(not(target_os = "dragonos"))'.dependencies]

+ 4 - 2
parse_test/test.service

@@ -1,11 +1,13 @@
 [Unit]
 Description=My Service
 Documentation=https://example.com/docs/my-service.html
-#After=network.target
+#After=/home/heyicong/DragonReach/parse_test/test1.service
 
 [Service]
 Type=simple
-ExecStart=/home/heyicong/DragonOs/bin/sysroot/bin/DragonReach --option1=value1 --option2=value2
+ExecStart=/bin/gdb -v
+ExecStartPos=/bin/gcc -v
+ExecStartPre=/bin/gcc -v
 WorkingDirectory=/home/heyicong/
 User=myuser
 Group=mygroup

+ 20 - 0
parse_test/test1.service

@@ -0,0 +1,20 @@
+[Unit]
+Description=My Service1
+Documentation=https://example.com/docs/my-service.html
+#After=/home/heyicong/DragonReach/parse_test/test2.service
+
+[Service]
+Type=simple
+ExecStart=/bin/gcc -v
+WorkingDirectory=/home/heyicong/
+User=myuser
+Group=mygroup
+Environment=VAR1=value1
+Environment=VAR2=value2
+Restart=on-failure
+RestartSec=5s
+TimeoutStartSec=10s
+TimeoutStopSec=10s
+
+[Install]
+#WantedBy=multi-user.target

+ 20 - 0
parse_test/test2.service

@@ -0,0 +1,20 @@
+[Unit]
+Description=My Service2
+Documentation=https://example.com/docs/my-service.html
+#After=/home/heyicong/DragonReach/parse_test/test.service
+
+[Service]
+Type=simple
+ExecStart=/home/heyicong/DragonOs/bin/sysroot/bin/DragonReach --option1=value1 --option2=value2
+WorkingDirectory=/home/heyicong/
+User=myuser
+Group=mygroup
+Environment=VAR1=value1
+Environment=VAR2=value2
+Restart=on-failure
+RestartSec=5s
+TimeoutStartSec=10s
+TimeoutStopSec=10s
+
+[Install]
+#WantedBy=multi-user.target

+ 5 - 42
src/error/mod.rs

@@ -1,48 +1,11 @@
 #[cfg(target_os = "dragonos")]
 use drstd as std;
-use std::format;
-use std::string::String;
-use std::string::ToString;
-/// 解析错误,错误信息应该包括文件名以及行号
-#[repr(i32)]
-#[derive(Debug, PartialEq, Eq, Clone)]
-#[allow(dead_code, non_camel_case_types)]
-pub enum ParseErrorType {
-    /// 不合法参数
-    EINVAL,
-    /// 结果过大 Result too large.
-    ERANGE,
-    /// 重复定义
-    EREDEF,
-    /// 未预料到的空值
-    EUnexpectedEmpty,
-    /// 语法错误
-    ESyntaxError,
-    /// 非法文件描述符
-    EBADF,
-    /// 非法文件
-    EFILE,
-    /// 不是目录
-    ENODIR,
-}
-/// 错误信息应该包括错误类型ParseErrorType,当前解析的文件名,当前解析的行号
-#[derive(Debug, PartialEq, Eq, Clone)]
-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 mod parse_error;
+pub mod runtime_error;
 
-    pub fn set_file(&mut self,path: &str) {
-        self.1 = path.to_string();
-    }
-
-    pub fn set_linenum(&mut self,linenum: usize) {
-        self.2 = linenum;
-    }
+use std::string::String;
 
-    pub fn error_format(&self) -> String {
-        format!("Parse Error!,Error Type: {:?}, File: {}, Line: {}",self.0,self.1,self.2)
-    }
+pub trait ErrorFormat {
+    fn error_format(&self) -> String;
 }

+ 54 - 0
src/error/parse_error/mod.rs

@@ -0,0 +1,54 @@
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+use std::format;
+use std::string::String;
+use std::string::ToString;
+
+use super::ErrorFormat;
+/// 解析错误,错误信息应该包括文件名以及行号
+#[repr(i32)]
+#[derive(Debug, PartialEq, Eq, Clone)]
+#[allow(dead_code, non_camel_case_types)]
+pub enum ParseErrorType {
+    /// 不合法参数
+    EINVAL,
+    /// 结果过大 Result too large.
+    ERANGE,
+    /// 重复定义
+    EREDEF,
+    /// 未预料到的空值
+    EUnexpectedEmpty,
+    /// 语法错误
+    ESyntaxError,
+    /// 非法文件描述符
+    EBADF,
+    /// 非法文件
+    EFILE,
+    /// 不是目录
+    ENODIR,
+    /// 循环依赖
+    ECircularDependency,
+}
+/// 错误信息应该包括错误类型ParseErrorType,当前解析的文件名,当前解析的行号
+#[derive(Debug, PartialEq, Eq, Clone)]
+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 set_file(&mut self,path: &str) {
+        self.1 = path.to_string();
+    }
+
+    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)
+    }
+}

+ 56 - 0
src/error/runtime_error/mod.rs

@@ -0,0 +1,56 @@
+use super::ErrorFormat;
+
+#[derive(Debug)]
+pub enum RuntimeErrorType {
+    //启动失败
+    ExecFailed,
+
+    // 文件相关错误
+    FileNotFound,
+    FileAccessDenied,
+    InvalidFileFormat,
+
+    // 循环依赖
+    CircularDependency,
+
+    // 转型错误
+    DowncastError,
+
+    // 网络相关错误
+    ConnectionError,
+    Timeout,
+
+    // 数据库相关错误
+    DatabaseError,
+    QueryError,
+
+    // 并发相关错误
+    Deadlock,
+    ThreadPanicked,
+
+    // 配置相关错误
+    ConfigError,
+    InvalidParameter,
+
+    // 其他通用错误
+    OutOfMemory,
+    InvalidInput,
+    UnsupportedOperation,
+
+    // 自定义错误
+    Custom(String),
+}
+
+pub struct RuntimeError(RuntimeErrorType);
+
+impl RuntimeError {
+    pub fn new(error_type: RuntimeErrorType) -> Self {
+        return RuntimeError(error_type);
+    }
+}
+
+impl ErrorFormat for RuntimeError {
+    fn error_format(&self) -> String {
+        format!("Runtime Error!,Error Type: {:?}",self.0)
+    }
+}

+ 100 - 0
src/executor/dep_graph/mod.rs

@@ -0,0 +1,100 @@
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+
+use std::cmp::PartialEq;
+use std::vec::Vec;
+use std::sync::Arc;
+
+use crate::{error::runtime_error::{RuntimeError, RuntimeErrorType}, unit::Unit};
+
+pub struct DepGraphNode<'a> {
+    value: &'a Arc<dyn Unit>,
+    edges: Vec<usize>,
+    incoming_edges: Vec<usize>,
+}
+
+pub struct DepGraph<'a> {
+    nodes: Vec<DepGraphNode<'a>>,
+    value: Vec<&'a Arc<dyn Unit>>,
+}
+
+// 提供拓扑排序方法,在启动服务时确定先后顺序
+impl<'a> DepGraph<'a> {
+    fn new() -> Self {
+        return DepGraph {
+            nodes: Vec::new(),
+            value: Vec::new(),
+        };
+    }
+
+    pub fn add_node(&mut self, value: &'a Arc<dyn Unit>) -> usize {
+        let index = self.nodes.len();
+        //如果nodes中已经有了这个value则无需重复添加,直接返回nodes中的value对应的index
+        if let Some(idx) = self.value.iter().position(|x| x.unit_id() == value.unit_id()) {
+            return idx;
+        }
+        //如果value在nodes中不存在,则添加value
+        self.nodes.push(DepGraphNode {
+            value: value,
+            edges: Vec::new(),
+            incoming_edges: Vec::new(),
+        });
+        self.value.push(value);
+        return index;
+    }
+    pub fn add_edge(&mut self, from: usize, to: usize) {
+        self.nodes[from].edges.push(to);
+        self.nodes[to].incoming_edges.push(from);
+    }
+    pub fn topological_sort(&mut self) -> Result<Vec<&Arc<dyn Unit>>, RuntimeError> {
+        let mut result = Vec::new();
+        let mut visited = Vec::new();
+        let mut stack = Vec::new();
+        for (i, node) in self.nodes.iter().enumerate() {
+            if node.incoming_edges.len() == 0 {
+                stack.push(i);
+            }
+        }
+        while stack.len() > 0 {
+            let index = stack.pop().unwrap();
+            if visited.contains(&index) {
+                continue;
+            }
+            visited.push(index);
+            result.push(self.nodes[index].value);
+            let len = self.nodes[index].edges.len();
+            for i in 0..len {
+                let edge = self.nodes[index].edges[i];
+                self.nodes[edge].incoming_edges.retain(|&x| x != index);
+                if self.nodes[edge].incoming_edges.len() == 0 {
+                    stack.push(edge);
+                }
+            }
+        }
+        if result.len() != self.nodes.len() {
+            return Err(RuntimeError::new(RuntimeErrorType::CircularDependency));
+        }
+        result.reverse();
+        return Ok(result);
+    }
+
+    fn add_edges(&mut self,unit: &'a Arc<dyn Unit>,after: &'a [Arc<dyn Unit>]) {
+        //因为service的依赖关系规模不会很大,故先使用递归实现
+        //TODO:改递归
+        for target in after {
+            let s = self.add_node(unit);
+            let t = self.add_node(target);
+            self.add_edge(s, t);
+            self.add_edges(target, target.unit_base().unit_part().after());
+        }
+    }
+
+    pub fn construct_graph(unit: &'a Arc<dyn Unit>) -> DepGraph<'a> {
+        let mut graph: DepGraph<'_> = DepGraph::new();
+        graph.add_node(unit);
+        let after = unit.unit_base().unit_part().after();
+        //递归添加边来构建图
+        graph.add_edges(unit, after);
+        return graph;
+    }
+}

+ 35 - 0
src/executor/mod.rs

@@ -0,0 +1,35 @@
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+
+pub mod dep_graph;
+pub mod service_executor;
+
+use std::process::Child;
+use std::sync::Arc;
+
+use crate::{
+    error::runtime_error::{RuntimeError, RuntimeErrorType},
+    unit::Unit,
+};
+
+use self::dep_graph::DepGraph;
+
+//Unit的全局执行器
+pub struct Executor;
+
+impl Executor {
+    pub fn exec(unit: &Arc<dyn Unit>) -> Result<(), RuntimeError> {
+        //TODO: 优化此处,解析时也用到了拓扑排序,尝试使用那次拓扑排序的结果
+        let mut graph = DepGraph::construct_graph(unit);
+
+        let sort_ret = graph.topological_sort()?;
+
+        for u in sort_ret {
+            if let Err(e) = u.run() {
+                return Err(e);
+            }
+        }
+
+        return Ok(());
+    }
+}

+ 57 - 0
src/executor/service_executor/mod.rs

@@ -0,0 +1,57 @@
+#[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},
+};
+
+pub struct ServiceExecutor;
+
+impl ServiceExecutor {
+    pub fn exec(service: &ServiceUnit) -> Result<(), RuntimeError> {
+        //处理conflict
+        let conflicts = service.unit_base().unit_part().conflicts();
+        for u in conflicts {
+            // 如果有冲突项enable的时候,该unit不能启动
+            if *u.unit_base().state() == UnitState::Enabled {
+                eprintln!("{}: Service startup failed: conflict unit", u.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 exec_start = service.service_part().exec_start();
+        let proc = Command::new(&exec_start.path).args(&exec_start.cmd).spawn();
+
+        match proc {
+            Ok(p) => {
+                //修改service状态
+
+                //启动成功后将Child加入全局管理的进程表
+                let mut manager_writer = GLOBAL_UNIT_MANAGER.write().unwrap();
+                manager_writer.running_table.push(RunnnigUnit::new(p,Arc::new(service.clone())));
+                //执行启动后命令
+                let cmds = service.service_part().exec_start_pos();
+                for cmd in cmds {
+                    cmd.exec()?
+                }
+            }
+            Err(err) => {
+                eprintln!("{}: Service startup failed: {}", exec_start.path, err);
+                return Err(RuntimeError::new(RuntimeErrorType::ExecFailed));
+            }
+        }
+
+        Ok(())
+    }
+}

+ 18 - 18
src/main.rs

@@ -1,5 +1,7 @@
-#![no_std]
-#![no_main]
+// #![no_std]
+// #![no_main]
+#![feature(slice_pattern)]
+
 use cfg_if::cfg_if;
 
 cfg_if!{
@@ -8,7 +10,7 @@ cfg_if!{
         use drstd as std;
         use std::print;
         use std::println;
-        use std::rc::Rc;
+        use std::rc::Arc;
         use unit::service::ServiceUnit;
     }
 }
@@ -20,6 +22,8 @@ mod error;
 mod parse;
 mod task;
 mod unit;
+mod manager;
+mod executor;
 
 use crate::unit::service;
 
@@ -57,8 +61,12 @@ fn main() {
 
 #[cfg(not(target_os = "dragonos"))]
 fn main() {
+    use std::{process::Command, sync::Arc};
+
     use unit::service::ServiceUnit;
 
+    use crate::{executor::Executor, error::ErrorFormat};
+
     let service = match ServiceUnit::from_path("/home/heyicong/DragonReach/parse_test/test.service"){
         Ok(service) => service,
         Err(e) => {
@@ -67,19 +75,11 @@ fn main() {
         }
     };
 
-    
-    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 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;
+    }
 }

+ 62 - 0
src/manager/mod.rs

@@ -0,0 +1,62 @@
+#[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 crate::unit::Unit;
+use hashbrown::HashMap;
+use lazy_static::lazy_static;
+
+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(),
+        })
+    };
+}
+
+pub struct RunnnigUnit(Child,Arc<dyn Unit>);
+impl RunnnigUnit {
+    pub fn new(p:Child,unit: Arc<dyn Unit>) -> Self {
+        RunnnigUnit(p,unit)
+    }
+}
+
+pub struct UnitManager {
+    // 通过unit_id映射unit
+    pub id_to_unit: HashMap<usize, Arc<dyn Unit>>,
+
+    // 通过path的hash值来映射Unit
+    pub path_to_unit: HashMap<u64,Arc<dyn Unit>>,
+
+    pub running_table: Vec<RunnnigUnit>
+}
+
+unsafe impl Sync for UnitManager {}
+
+impl UnitManager {
+    pub fn insert_into_path_table(&mut self,path: &str,unit: Arc<dyn Unit>){
+        let mut hasher = DefaultHasher::new();
+        path.hash(&mut hasher);
+        let hash = hasher.finish();
+        self.path_to_unit.insert(hash, unit);
+    }
+
+    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)
+    }
+
+    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();
+        self.path_to_unit.get(&hash)
+    }
+}

+ 206 - 0
src/parse/graph/mod.rs

@@ -0,0 +1,206 @@
+use core::slice::SlicePattern;
+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 {
+    value: String,
+    edges: Vec<usize>,
+    incoming_edges: Vec<usize>,
+}
+
+pub struct Graph {
+    total_edge: u32,
+    max_edge: u32,
+    nodes: Vec<GraphNode>,
+    value: Vec<String>,
+}
+
+impl Graph {
+    fn new() -> Self {
+        return Graph {
+            max_edge: 0,
+            total_edge: 0,
+            nodes: Vec::new(),
+            value: Vec::new(),
+        };
+    }
+
+    pub fn add_node(&mut self, value: &String) -> usize {
+        let index = self.nodes.len();
+        //如果nodes中已经有了这个value则无需重复添加,直接返回nodes中的value对应的index
+        if let Some(idx) = self.value.iter().position(|x| *x == *value) {
+            return idx;
+        }
+        //如果value在nodes中不存在,则添加value
+        self.nodes.push(GraphNode {
+            value: value.to_string(),
+            edges: Vec::new(),
+            incoming_edges: Vec::new(),
+        });
+        self.value.push(value.to_string());
+        return index;
+    }
+    pub fn add_edge(&mut self, from: usize, to: usize) {
+        self.total_edge += 1;
+        self.nodes[from].edges.push(to);
+        self.nodes[to].incoming_edges.push(from);
+    }
+    pub fn topological_sort(&mut self) -> Result<Vec<String>, ParseError> {
+        let mut result = Vec::new();
+        let mut visited = Vec::new();
+        let mut stack = Vec::new();
+        for (i, node) in self.nodes.iter().enumerate() {
+            if node.incoming_edges.len() == 0 {
+                stack.push(i);
+            }
+        }
+        while stack.len() > 0 {
+            let index = stack.pop().unwrap();
+            if visited.contains(&index) {
+                continue;
+            }
+            visited.push(index);
+            result.push(self.nodes[index].value.clone());
+            let len = self.nodes[index].edges.len();
+            for i in 0..len {
+                let edge = self.nodes[index].edges[i];
+                self.nodes[edge].incoming_edges.retain(|&x| x != index);
+                if self.nodes[edge].incoming_edges.len() == 0 {
+                    stack.push(edge);
+                }
+            }
+        }
+        if result.len() != self.nodes.len() {
+            return Err(ParseError::new(
+                ParseErrorType::ECircularDependency,
+                "".to_string(),
+                0,
+            ));
+        }
+        result.reverse();
+        return Ok(result);
+    }
+
+    fn add_edges(&mut self, path: &String, after: Vec<String>) {
+        //因为service的依赖关系规模不会很大,故先使用递归实现
+        //TODO:改递归
+        for target in after {
+            let s = self.add_node(&path);
+            let t = self.add_node(&target);
+            self.add_edge(s, t);
+            if self.total_edge > self.max_edge {
+                return;
+            }
+            self.add_edges(&target, Self::parse_after(&target));
+        }
+    }
+
+    pub fn construct_graph(unit: String) -> Result<Graph, ParseError> {
+        //计算整个依赖图中的节点数
+        let mut node_num = 1;
+        let mut dep = Vec::new();
+        Self::get_node_num(&unit, &mut dep, &mut node_num);
+
+        let mut graph: Graph = Graph::new();
+        graph.max_edge = node_num * (node_num - 1);
+
+        graph.add_node(&unit);
+        let after = Self::parse_after(&unit);
+        //递归添加边来构建图
+        graph.add_edges(&unit, after);
+
+        if graph.max_edge < graph.total_edge {
+            return Err(ParseError::new(
+                ParseErrorType::ECircularDependency,
+                unit,
+                0,
+            ));
+        }
+
+        return Ok(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 mut lines_with_after = Vec::new();
+
+        for line_result in reader.lines() {
+            if let Ok(line) = line_result {
+                if line.starts_with("After") {
+                    lines_with_after.push(line);
+                }
+            }
+        }
+
+        for line in lines_with_after {
+            let after = &line.split('=').collect::<Vec<&str>>()[1];
+            let units = after.split_whitespace().collect::<Vec<&str>>();
+
+            for unit in units {
+                ret.push(String::from(unit));
+            }
+        }
+
+        ret
+    }
+
+    /// ## 获取到unit文件依赖图节点数
+    ///
+    /// ### param file_path unit文件路径
+    ///
+    /// ### dependencies 缓存after依赖的容器
+    ///
+    /// ### total_after_count 返回节点数
+    ///
+    /// ### return
+    fn get_node_num(
+        file_path: &str,
+        dependencies: &mut Vec<String>,
+        total_after_count: &mut u32,
+    ) -> Result<(), ParseError> {
+        let reader = UnitParser::get_unit_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();
+
+                    for dependency in dependency_list {
+                        if dependencies.contains(&dependency.to_string()) {
+                            // 循环依赖检查
+                            continue;
+                        }
+
+                        dependencies.push(dependency.to_string());
+
+                        // 递归解析依赖链
+                        Self::get_node_num(dependency, dependencies, total_after_count)?;
+                    }
+
+                    current_after_count += 1;
+                }
+            }
+        }
+
+        *total_after_count += current_after_count;
+
+        Ok(())
+    }
+}

+ 78 - 39
src/parse/mod.rs

@@ -1,7 +1,8 @@
-use crate::error::ParseErrorType;
+use crate::error::parse_error::ParseErrorType;
+use crate::manager::{self, GLOBAL_UNIT_MANAGER};
 use crate::unit::{BaseUnit, Unit};
 use crate::{
-    error::ParseError,
+    error::parse_error::ParseError,
     unit::{service::ServiceUnitAttr, BaseUnitAttr, InstallUnitAttr, UnitType},
 };
 
@@ -13,13 +14,14 @@ use lazy_static::lazy_static;
 use std::format;
 use std::fs::File;
 use std::io::{self, BufRead};
-use std::rc::Rc;
 use std::string::String;
-use std::vec::Vec;
 use std::string::ToString;
+use std::sync::Arc;
+use std::vec::Vec;
 
-pub mod parse_target;
+pub mod graph;
 pub mod parse_service;
+pub mod parse_target;
 pub mod parse_util;
 
 //对应Unit段类型
@@ -158,25 +160,30 @@ impl UnitParser {
     /// @param unit_type 指定Unit类型
     ///
     /// @return 成功则返回对应BufReader,否则返回Err
-    fn get_unit_reader(path: &str, unit_type: UnitType) -> Result<io::BufReader<File>, ParseError> {
-        let suffix = match path.rfind('.') {
-            Some(idx) => &path[idx + 1..],
-            None => {
-                return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(),0));
+    pub fn get_unit_reader(
+        path: &str,
+        unit_type: UnitType,
+    ) -> Result<io::BufReader<File>, ParseError> {
+        // 如果指定UnitType,则进行文件名检查,不然直接返回reader
+        if unit_type != UnitType::Unknown {
+            let suffix = match path.rfind('.') {
+                Some(idx) => &path[idx + 1..],
+                None => {
+                    return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
+                }
+            };
+            let u_type = UNIT_SUFFIX.get(suffix);
+            if u_type.is_none() {
+                return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
+            }
+            if *(u_type.unwrap()) != unit_type {
+                return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
             }
-        };
-        let u_type = UNIT_SUFFIX.get(suffix);
-        if u_type.is_none() {
-            return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(),0));
-        }
-        if *(u_type.unwrap()) != unit_type {
-            return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(),0));
         }
-
         let file = match File::open(path) {
             Ok(file) => file,
             Err(_) => {
-                return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(),0));
+                return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
             }
         };
         return Ok(io::BufReader::new(file));
@@ -190,8 +197,20 @@ impl UnitParser {
     ///
     /// @param unit_type 指定Unit类型
     ///
-    /// @return 解析成功则返回Ok(Rc<T>),否则返回Err
-    pub fn parse<T: Unit + Default>(path: &str, unit_type: UnitType) -> Result<Rc<T>, ParseError> {
+    /// @return 解析成功则返回Ok(Arc<T>),否则返回Err
+    pub fn parse<T: Unit + Default + Clone + 'static>(
+        path: &str,
+        unit_type: UnitType,
+    ) -> Result<Arc<T>, ParseError> {
+        let manager = GLOBAL_UNIT_MANAGER.read().unwrap();
+        if manager.contants_path(path) {
+            let unit = manager.get_unit_with_path(path).unwrap();
+            let any = unit.as_any();
+            let ret: Arc<T> = Arc::new(any.downcast_ref::<T>().unwrap().clone());
+            return Ok(ret);
+        }
+        drop(manager);
+
         let mut unit: T = T::default();
         let mut unit_base = BaseUnit::default();
         //设置unit类型标记
@@ -232,7 +251,11 @@ impl UnitParser {
             }
             if segment == Segment::None {
                 //未找到段名则不能继续匹配
-                return Err(ParseError::new(ParseErrorType::ESyntaxError, path.to_string(),i + 1));
+                return Err(ParseError::new(
+                    ParseErrorType::ESyntaxError,
+                    path.to_string(),
+                    i + 1,
+                ));
             }
 
             //下面进行属性匹配
@@ -251,23 +274,28 @@ impl UnitParser {
                 break;
             }
             //=号分割后第一个元素为属性,后面的均为值,若一行出现两个等号则是语法错误
-            let (attr_str,val_str) = match line.find('=') {
-                Some(idx) => {
-                    (line[..idx].trim(), line[idx+1..].trim())
-                }
+            let (attr_str, val_str) = match line.find('=') {
+                Some(idx) => (line[..idx].trim(), line[idx + 1..].trim()),
                 None => {
-                    return Err(ParseError::new(ParseErrorType::ESyntaxError, path.to_string(),i + 1));
+                    return Err(ParseError::new(
+                        ParseErrorType::ESyntaxError,
+                        path.to_string(),
+                        i + 1,
+                    ));
                 }
             };
             //首先匹配所有unit文件都有的unit段和install段
             if BASE_UNIT_ATTR_TABLE.get(attr_str).is_some() {
                 if segment != Segment::Unit {
-                    return Err(ParseError::new(ParseErrorType::EINVAL, path.to_string(),i + 1));
+                    return Err(ParseError::new(
+                        ParseErrorType::EINVAL,
+                        path.to_string(),
+                        i + 1,
+                    ));
                 }
-                if let Err(e) = unit_base.set_unit_part_attr(
-                    BASE_UNIT_ATTR_TABLE.get(attr_str).unwrap(),
-                    val_str,
-                ){
+                if let Err(e) = unit_base
+                    .set_unit_part_attr(BASE_UNIT_ATTR_TABLE.get(attr_str).unwrap(), val_str)
+                {
                     let mut e = e.clone();
                     e.set_file(path);
                     e.set_linenum(i + 1);
@@ -275,19 +303,22 @@ impl UnitParser {
                 }
             } else if INSTALL_UNIT_ATTR_TABLE.get(attr_str).is_some() {
                 if segment != Segment::Install {
-                    return Err(ParseError::new(ParseErrorType::EINVAL, path.to_string(),i + 1));
+                    return Err(ParseError::new(
+                        ParseErrorType::EINVAL,
+                        path.to_string(),
+                        i + 1,
+                    ));
                 }
-                if let Err(e) = unit_base.set_install_part_attr(
-                    INSTALL_UNIT_ATTR_TABLE.get(attr_str).unwrap(),
-                    val_str,
-                ){
+                if let Err(e) = unit_base
+                    .set_install_part_attr(INSTALL_UNIT_ATTR_TABLE.get(attr_str).unwrap(), val_str)
+                {
                     let mut e = e.clone();
                     e.set_file(path);
                     e.set_linenum(i + 1);
                     return Err(e);
                 }
             } else {
-                if let Err(e) = unit.set_attr(segment, attr_str, val_str){
+                if let Err(e) = unit.set_attr(segment, attr_str, val_str) {
                     let mut e = e.clone();
                     e.set_file(path);
                     e.set_linenum(i + 1);
@@ -297,6 +328,14 @@ impl UnitParser {
             i += 1;
         }
         unit.set_unit_base(unit_base);
-        return Ok(Rc::new(unit));
+        unit.set_unit_id();
+        let dret: Arc<dyn Unit> = Arc::new(unit.clone());
+
+        let mut manager = GLOBAL_UNIT_MANAGER.write().unwrap();
+        manager.id_to_unit.insert(dret.unit_id(), dret.clone());
+        manager.insert_into_path_table(path, dret);
+
+        let ret = Arc::new(unit);
+        return Ok(ret);
     }
 }

+ 20 - 6
src/parse/parse_service/mod.rs

@@ -1,11 +1,16 @@
 use super::UnitParser;
-use crate::error::ParseError;
-use crate::unit::service::ServiceUnit;
+use super::graph::Graph;
+use super::parse_util::UnitParseUtil;
+use crate::error::parse_error::ParseError;
+use crate::manager::GLOBAL_UNIT_MANAGER;
+use crate::unit::service::{ServiceUnit, self};
 
 #[cfg(target_os = "dragonos")]
 use drstd as std;
 
+use std::any::Any;
 use std::rc::Rc;
+use std::sync::Arc;
 pub struct ServiceParser;
 
 impl ServiceParser {
@@ -16,9 +21,18 @@ impl ServiceParser {
     /// @param path 需解析的文件路径
     ///
     /// @return 成功则返回Ok(Rc<ServiceUnit>),否则返回Err
-    pub fn parse(path: &str) -> Result<Rc<ServiceUnit>, ParseError> {
-        //交付总解析器
-        let service = UnitParser::parse::<ServiceUnit>(path, crate::unit::UnitType::Service)?;
-        return Ok(service);
+    pub fn parse(path: & str) -> Result<Arc<ServiceUnit>, ParseError> {
+        //预先检查是否存在循环依赖
+        let mut graph = Graph::construct_graph(path.to_string())?;
+        let ret = graph.topological_sort()?;
+        for p in ret {
+            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 : ServiceUnit = result.as_any().downcast_ref::<ServiceUnit>().unwrap().clone();
+        return Ok(Arc::new(result));
     }
 }

+ 18 - 5
src/parse/parse_target/mod.rs

@@ -1,11 +1,15 @@
 use super::UnitParser;
-use crate::error::ParseError;
+use super::graph::Graph;
+use super::parse_util::UnitParseUtil;
+use crate::error::parse_error::ParseError;
+use crate::manager::GLOBAL_UNIT_MANAGER;
 use crate::unit::target::TargetUnit;
 
 #[cfg(target_os = "dragonos")]
 use drstd as std;
 
 use std::rc::Rc;
+use std::sync::Arc;
 
 pub struct TargetParser;
 
@@ -17,9 +21,18 @@ impl TargetParser {
     /// @param path 需解析的文件路径
     ///
     /// @return 成功则返回Ok(Rc<ServiceUnit>),否则返回Err
-    pub fn parse(path: &str) -> Result<Rc<TargetUnit>, ParseError> {
-        //交付总解析器
-        let service = UnitParser::parse::<TargetUnit>(path, crate::unit::UnitType::Service)?;
-        return Ok(service);
+    pub fn parse(path: &str) -> Result<Arc<TargetUnit>, ParseError> {
+        //预先检查是否存在循环依赖
+        let mut graph = Graph::construct_graph(path.to_string())?;
+        let ret = graph.topological_sort()?;
+        for p in ret {
+            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));
     }
 }

+ 28 - 28
src/parse/parse_util/mod.rs

@@ -1,8 +1,8 @@
 use crate::{
     contants::{AF_INET, AF_INET6, IPV4_MIN_MTU, IPV6_MIN_MTU, PRIO_MAX, PRIO_MIN},
-    error::{ParseError, ParseErrorType},
+    error::{parse_error::ParseError, parse_error::ParseErrorType},
     task::cmdtask::CmdTask,
-    unit::{Unit, Url},
+    unit::{Unit, Url, service::ServiceUnit, UnitType, target::TargetUnit},
     FileDescriptor,
 };
 
@@ -10,13 +10,11 @@ use crate::{
 use drstd as std;
 
 use std::{
-    format, fs, path::Path, print, println, rc::Rc, string::String, string::ToString, vec, vec::Vec, os::unix::prelude::PermissionsExt,
+    format, fs, path::Path, print, println, string::String, string::ToString, vec, vec::Vec, os::unix::prelude::PermissionsExt, sync::Arc, any::Any,
 };
 
-use std::os::unix::fs::MetadataExt;
-
 use super::{
-    parse_service::ServiceParser, parse_target::TargetParser, BASE_IEC, BASE_SI, SEC_UNIT_TABLE,
+    parse_service::ServiceParser, parse_target::TargetParser, BASE_IEC, BASE_SI, SEC_UNIT_TABLE, UnitParser,
 };
 
 #[derive(PartialEq)]
@@ -430,19 +428,19 @@ impl UnitParseUtil {
     ///
     /// @param path 需解析的文件
     ///
-    /// @return 解析成功则返回Ok(Rc<dyn Unit>),否则返回Err
-    pub fn parse_unit<T: Unit>(path: &str) -> Result<Rc<T>, ParseError> {
+    /// @return 解析成功则返回Ok(Arc<dyn Unit>),否则返回Err
+    pub fn parse_unit<T: Unit>(path: &str) -> Result<Arc<T>, ParseError> {
         return T::from_path(path);
     }
 
-    /// @brief 将对应的str解析为Rc<dyn Unit>
+    /// @brief 将对应的str解析为Arc<dyn Unit>
     ///
-    /// 将传入的字符串解析为Rc<dyn Unit>,解析失败返回错误
+    /// 将传入的字符串解析为Arc<dyn Unit>,解析失败返回错误
     ///
     /// @param path 需解析的文件
     ///
-    /// @return 解析成功则返回Ok(Rc<dyn Unit>),否则返回Err
-    pub fn parse_unit_no_type(path: &str) -> Result<Rc<dyn Unit>, ParseError> {
+    /// @return 解析成功则返回Ok(Arc<dyn Unit>),否则返回Err
+    pub fn parse_unit_no_type(path: &str) -> Result<Arc<dyn Unit>, ParseError> {
         let idx = match path.rfind('.') {
             Some(val) => val,
             None => {
@@ -458,10 +456,14 @@ impl UnitParseUtil {
         let suffix = &path[idx + 1..];
 
         //通过文件后缀分发给不同类型的Unit解析器解析
-        let unit: Rc<dyn Unit> = match suffix {
+        let unit: Arc<dyn Unit> = match suffix {
             //TODO: 目前为递归,后续应考虑从DragonReach管理的Unit表中寻找是否有该Unit,并且通过记录消除递归
-            "service" => ServiceParser::parse(path)?,
-            "target" => TargetParser::parse(path)?,
+            "service" => {
+                UnitParser::parse::<ServiceUnit>(path, UnitType::Service)?
+            },
+            "target" => {
+                UnitParser::parse::<TargetUnit>(path, UnitType::Target)?
+            },
             _ => {
                 return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
             }
@@ -485,37 +487,37 @@ impl UnitParseUtil {
         while i < cmds.len() {
             let mut cmd_task = CmdTask {
                 path: String::new(),
-                cmd: String::new(),
+                cmd: Vec::new(),
                 ignore: false,
             };
             //匹配到这里时,这个单词肯定是路径,若路径以-开头则设置ignore
             cmd_task.ignore = cmds[i].starts_with('-');
 
             //获取到一个CmdTask的路径部分
-            let mut path = "";
+            let mut path = String::new();
             if cmd_task.ignore {
-                path = &cmds[i][1..];
+                path = String::from(&cmds[i][1..]);
             } else {
-                path = &cmds[i];
+                path = String::from(cmds[i]);
             }
 
             //得到的非绝对路径则不符合语法要求,报错
-            if !UnitParseUtil::is_valid_exec_path(path) {
+            if !UnitParseUtil::is_valid_exec_path(path.as_str()) {
                 return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
 
-            cmd_task.path = String::from(path);
+            cmd_task.path = path;
 
             //i += 1,继续匹配下一个单词
             i += 1;
-            let mut cmd_str = String::new();
+            let mut cmd_vec = Vec::new();
             while i < cmds.len() && !UnitParseUtil::is_valid_exec_path(cmds[i]) {
                 //命令可能会有多个单词,将多个命令整理成一个
                 let cmd = cmds[i];
-                cmd_str = format!("{} {}", cmd_str, cmd);
+                cmd_vec.push(String::from(cmd));
                 i += 1;
             }
-            cmd_task.cmd = cmd_str;
+            cmd_task.cmd = cmd_vec;
             tasks.push(cmd_task);
             //经过while到这里之后,cmds[i]对应的单词一点是路径,i不需要加一
         }
@@ -530,10 +532,8 @@ impl UnitParseUtil {
     ///
     /// @return 解析成功则返回true,否则返回false
     pub fn is_valid_exec_path(path: &str) -> bool {
-        if !path.starts_with("/"){
-            return false;
-        }
-        return true;
+        let path = Path::new(path);
+        return path.is_absolute()
 
         //TODO: 后续应判断该文件是否为合法文件
         //let path = Path::new(path);

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

@@ -1,11 +1,35 @@
 #[cfg(target_os = "dragonos")]
 use drstd as std;
 
-use std::string::String;
+use std::{process::Command, string::String};
 
-#[derive(Debug)]
+use crate::error::runtime_error::{RuntimeError, RuntimeErrorType};
+
+#[derive(Debug, Clone, Default)]
 pub struct CmdTask {
     pub path: String,
-    pub cmd: String,
+    pub cmd: Vec<String>,
     pub ignore: bool, //表示忽略这个命令的错误,即使它运行失败也不影响unit正常运作
 }
+
+impl CmdTask {
+    pub fn exec(&self) -> Result<(), RuntimeError> {
+        let result = Command::new(&self.path).args(&self.cmd).output();
+        match result {
+            Ok(output) => {
+                if !output.status.success() && !self.ignore {
+                    let stderr = String::from_utf8_lossy(&output.stderr);
+                    eprintln!("{}: Command failed: {}", self.path, stderr);
+                    return Err(RuntimeError::new(RuntimeErrorType::ExecFailed));
+                }
+            }
+            Err(err) => {
+                if !self.ignore {
+                    eprintln!("{}: Command failed: {}", self.path, err);
+                    return Err(RuntimeError::new(RuntimeErrorType::ExecFailed));
+                }
+            }
+        }
+        Ok(())
+    }
+}

+ 91 - 34
src/unit/mod.rs

@@ -1,36 +1,47 @@
-use crate::error::ParseError;
-use crate::error::ParseErrorType;
+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::parse::parse_util::UnitParseUtil;
 use crate::parse::Segment;
 
 #[cfg(target_os = "dragonos")]
 use drstd as std;
+use hashbrown::HashMap;
 
 use std::any::Any;
-use std::boxed::Box;
 use std::default::Default;
-use std::rc::Rc;
+use std::fmt::Debug;
 use std::result::Result;
 use std::result::Result::Err;
 use std::result::Result::Ok;
 use std::string::String;
+use std::sync::atomic::AtomicUsize;
+use std::sync::atomic::Ordering;
+use std::sync::Arc;
 use std::vec::Vec;
 
 pub mod service;
 pub mod target;
 
 use self::target::TargetUnit;
+use lazy_static::lazy_static;
+
+pub fn generate_unit_id() -> usize {
+    static UNIT_ID: AtomicUsize = AtomicUsize::new(1);
+    return UNIT_ID.fetch_add(1, Ordering::SeqCst);
+}
 
 //所有可解析的Unit都应该实现该trait
-pub trait Unit {
+pub trait Unit: Sync + Send + Debug {
     /// @brief 从文件获取到Unit,该函数是解析Unit文件的入口函数
     ///
     /// 从path解析Unit属性
     ///
     /// @param path 需解析的文件
     ///
-    /// @return 解析成功则返回对应Unit的Rc指针,否则返回Err
-    fn from_path(path: &str) -> Result<Rc<Self>, ParseError>
+    /// @return 解析成功则返回对应Unit的Arc指针,否则返回Err
+    fn from_path(path: &str) -> Result<Arc<Self>, ParseError>
     where
         Self: Sized;
 
@@ -60,11 +71,44 @@ pub trait Unit {
     ///
     /// ## return UnitType
     fn unit_type(&self) -> UnitType;
+
+    fn unit_base(&self) -> &BaseUnit;
+
+    fn mut_unit_base(&mut self) -> &mut BaseUnit;
+
+    fn unit_id(&self) -> usize;
+
+    /// ## Unit的工作逻辑
+    ///
+    /// ### return OK(())/Err
+    fn run(&self) -> Result<(), RuntimeError>;
+
+    /// ## 设置unit_id
+    ///
+    /// ### return OK(())/Err
+    fn set_unit_id(&mut self) {
+        self.mut_unit_base().set_id(generate_unit_id());
+    }
+}
+
+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状态
-#[derive(Clone, Copy, Debug)]
-enum UnitState {
+#[derive(Clone, Copy, Debug,PartialEq)]
+pub enum UnitState {
     Enabled,
     Disabled,
     Static,
@@ -90,11 +134,13 @@ pub enum UnitType {
 }
 
 //记录unit文件基本信息,这个结构体里面的信息是所有Unit文件都可以有的属性
+#[derive(Debug, Clone)]
 pub struct BaseUnit {
     unit_part: UnitPart,
     install_part: InstallPart,
     state: UnitState,
     unit_type: UnitType,
+    unit_id: usize,
 }
 
 impl Default for BaseUnit {
@@ -104,6 +150,7 @@ impl Default for BaseUnit {
             install_part: InstallPart::default(),
             state: UnitState::Disabled,
             unit_type: UnitType::Unknown,
+            unit_id: 0,
         }
     }
 }
@@ -152,9 +199,13 @@ impl BaseUnit {
     pub fn unit_type(&self) -> &UnitType {
         &self.unit_type
     }
+
+    pub fn set_id(&mut self, id: usize) {
+        self.unit_id = id;
+    }
 }
 
-#[derive(Default,Debug)]
+#[derive(Default, Debug, Clone)]
 pub struct Url {
     pub url_string: String, // pub protocol: String,
                             // pub host: String,
@@ -165,17 +216,18 @@ pub struct Url {
 }
 
 //对应Unit文件的Unit段
+#[derive(Debug, Clone)]
 pub struct UnitPart {
     description: String,
     documentation: Vec<Url>,
-    requires: Vec<Rc<dyn Unit>>,
-    wants: Vec<Rc<dyn Unit>>,
-    after: Vec<Rc<dyn Unit>>,
-    before: Vec<Rc<dyn Unit>>,
-    binds_to: Vec<Rc<dyn Unit>>,
-    part_of: Vec<Rc<dyn Unit>>,
-    on_failure: Vec<Rc<dyn Unit>>,
-    conflicts: Vec<Rc<dyn Unit>>,
+    requires: Vec<Arc<dyn Unit>>,
+    wants: Vec<Arc<dyn Unit>>,
+    after: Vec<Arc<dyn Unit>>,
+    before: Vec<Arc<dyn Unit>>,
+    binds_to: Vec<Arc<dyn Unit>>,
+    part_of: Vec<Arc<dyn Unit>>,
+    on_failure: Vec<Arc<dyn Unit>>,
+    conflicts: Vec<Arc<dyn Unit>>,
 }
 
 impl Default for UnitPart {
@@ -199,7 +251,11 @@ impl UnitPart {
     pub fn set_attr(&mut self, attr: &BaseUnitAttr, val: &str) -> Result<(), ParseError> {
         match attr {
             BaseUnitAttr::None => {
-                return Err(ParseError::new(ParseErrorType::ESyntaxError,String::new(),0));
+                return Err(ParseError::new(
+                    ParseErrorType::ESyntaxError,
+                    String::new(),
+                    0,
+                ));
             }
             BaseUnitAttr::Description => self.description = String::from(val),
             BaseUnitAttr::Documentation => {
@@ -281,44 +337,45 @@ impl UnitPart {
         &self.documentation
     }
 
-    pub fn requires(&self) -> &[Rc<dyn Unit>] {
+    pub fn requires(&self) -> &[Arc<dyn Unit>] {
         &self.requires
     }
 
-    pub fn wants(&self) -> &[Rc<dyn Unit>] {
+    pub fn wants(&self) -> &[Arc<dyn Unit>] {
         &self.wants
     }
 
-    pub fn after(&self) -> &[Rc<dyn Unit>] {
+    pub fn after(&self) -> &[Arc<dyn Unit>] {
         &self.after
     }
 
-    pub fn before(&self) -> &[Rc<dyn Unit>] {
+    pub fn before(&self) -> &[Arc<dyn Unit>] {
         &self.before
     }
 
-    pub fn binds_to(&self) -> &[Rc<dyn Unit>] {
+    pub fn binds_to(&self) -> &[Arc<dyn Unit>] {
         &self.binds_to
     }
 
-    pub fn part_of(&self) -> &[Rc<dyn Unit>] {
+    pub fn part_of(&self) -> &[Arc<dyn Unit>] {
         &self.part_of
     }
 
-    pub fn on_failure(&self) -> &[Rc<dyn Unit>] {
+    pub fn on_failure(&self) -> &[Arc<dyn Unit>] {
         &self.on_failure
     }
 
-    pub fn conflicts(&self) -> &[Rc<dyn Unit>] {
+    pub fn conflicts(&self) -> &[Arc<dyn Unit>] {
         &self.conflicts
     }
 }
 
 //对应Unit文件的Install段
+#[derive(Debug, Clone)]
 pub struct InstallPart {
-    wanted_by: Vec<Rc<TargetUnit>>,
-    requires_by: Vec<Rc<TargetUnit>>,
-    also: Vec<Rc<dyn Unit>>,
+    wanted_by: Vec<Arc<TargetUnit>>,
+    requires_by: Vec<Arc<TargetUnit>>,
+    also: Vec<Arc<dyn Unit>>,
     alias: String,
 }
 
@@ -364,21 +421,21 @@ impl InstallPart {
                 self.alias = String::from(val);
             }
             InstallUnitAttr::None => {
-                return Err(ParseError::new(ParseErrorType::EINVAL,String::new(),0));
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         }
         return Ok(());
     }
 
-    pub fn wanted_by(&self) -> &[Rc<TargetUnit>] {
+    pub fn wanted_by(&self) -> &[Arc<TargetUnit>] {
         &self.wanted_by
     }
 
-    pub fn requires_by(&self) -> &[Rc<TargetUnit>] {
+    pub fn requires_by(&self) -> &[Arc<TargetUnit>] {
         &self.requires_by
     }
 
-    pub fn also(&self) -> &[Rc<dyn Unit>] {
+    pub fn also(&self) -> &[Arc<dyn Unit>] {
         &self.also
     }
 

+ 55 - 20
src/unit/service/mod.rs

@@ -1,22 +1,29 @@
 use super::{BaseUnit, Unit};
-use crate::error::{ParseError, ParseErrorType};
+use crate::error::runtime_error::{RuntimeError, RuntimeErrorType};
+use crate::error::{parse_error::ParseError, parse_error::ParseErrorType};
+use crate::executor::service_executor::ServiceExecutor;
+use crate::manager::GLOBAL_UNIT_MANAGER;
+use crate::parse::graph::Graph;
 use crate::parse::parse_service::ServiceParser;
 use crate::parse::parse_util::UnitParseUtil;
-use crate::parse::{Segment, SERVICE_UNIT_ATTR_TABLE};
+use crate::parse::{Segment, UnitParser, SERVICE_UNIT_ATTR_TABLE};
 use crate::task::cmdtask::CmdTask;
 
 #[cfg(target_os = "dragonos")]
 use drstd as std;
+use std::mem::MaybeUninit;
+use std::process::{Child, Command};
 use std::rc::Rc;
 use std::string::String;
+use std::sync::Arc;
 use std::vec::Vec;
-#[derive(Default)]
+#[derive(Clone, Debug,Default)]
 pub struct ServiceUnit {
     unit_base: BaseUnit,
     service_part: ServicePart,
 }
 
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy)]
 pub enum ServiceType {
     Simple,
     Forking,
@@ -32,7 +39,7 @@ impl Default for ServiceType {
     }
 }
 
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy)]
 pub enum RestartOption {
     AlwaysRestart,
     OnSuccess,
@@ -49,7 +56,7 @@ impl Default for RestartOption {
     }
 }
 
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy)]
 pub enum MountFlag {
     Shared,
     Slave,
@@ -62,13 +69,13 @@ impl Default for MountFlag {
     }
 }
 
-#[derive(Default, Debug)]
+#[derive(Default, Debug, Clone)]
 pub struct ServicePart {
     //生命周期相关
     service_type: ServiceType,
     ///
     remain_after_exit: bool,
-    exec_start: Vec<CmdTask>,
+    exec_start: CmdTask,
     exec_start_pre: Vec<CmdTask>,
     exec_start_pos: Vec<CmdTask>,
     exec_reload: Vec<CmdTask>,
@@ -95,7 +102,7 @@ impl Unit for ServiceUnit {
         self
     }
 
-    fn from_path(path: &str) -> Result<Rc<Self>, ParseError>
+    fn from_path(path: &str) -> Result<Arc<Self>, ParseError>
     where
         Self: Sized,
     {
@@ -104,9 +111,13 @@ impl Unit for ServiceUnit {
 
     fn set_attr(&mut self, segment: Segment, attr: &str, val: &str) -> Result<(), ParseError> {
         if segment != Segment::Service {
-            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(),0));
+            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
         }
-        let attr_type = SERVICE_UNIT_ATTR_TABLE.get(attr).ok_or(ParseError::new(ParseErrorType::EINVAL, String::new(),0));
+        let attr_type = SERVICE_UNIT_ATTR_TABLE.get(attr).ok_or(ParseError::new(
+            ParseErrorType::EINVAL,
+            String::new(),
+            0,
+        ));
         return self.service_part.set_attr(attr_type.unwrap(), val);
     }
 
@@ -117,6 +128,22 @@ impl Unit for ServiceUnit {
     fn unit_type(&self) -> super::UnitType {
         return self.unit_base.unit_type;
     }
+
+    fn unit_base(&self) -> &BaseUnit {
+        return &self.unit_base;
+    }
+
+    fn unit_id(&self) -> usize {
+        return self.unit_base.unit_id;
+    }
+
+    fn run(&self) -> Result<(), RuntimeError> {
+        self.exec()
+    }
+
+    fn mut_unit_base(&mut self) -> &mut BaseUnit {
+        return &mut self.unit_base;
+    }
 }
 
 impl ServiceUnit {
@@ -127,8 +154,16 @@ impl ServiceUnit {
     pub fn service_part(&self) -> &ServicePart {
         return &self.service_part;
     }
+
+    fn exec(&self) -> Result<(), RuntimeError> {
+        ServiceExecutor::exec(self)
+    }
 }
 
+unsafe impl Sync for ServiceUnit {}
+
+unsafe impl Send for ServiceUnit {}
+
 pub enum ServiceUnitAttr {
     None,
     //Service段
@@ -175,7 +210,7 @@ pub enum ServiceUnitAttr {
 }
 
 impl ServicePart {
-    pub fn set_attr(&mut self, attr: &ServiceUnitAttr, val: &str) -> Result<(), ParseError> {
+    pub fn set_attr(&'_ mut self, attr: &ServiceUnitAttr, val: &str) -> Result<(), ParseError> {
         match attr {
             ServiceUnitAttr::Type => match val {
                 "simple" => self.service_type = ServiceType::Simple,
@@ -185,14 +220,14 @@ impl ServicePart {
                 "notify" => self.service_type = ServiceType::Notify,
                 "idle" => self.service_type = ServiceType::Idle,
                 _ => {
-                    return Err(ParseError::new(ParseErrorType::EINVAL, String::new(),0));
+                    return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
                 }
             },
             ServiceUnitAttr::RemainAfterExit => {
                 self.remain_after_exit = UnitParseUtil::parse_boolean(val)?
             }
             ServiceUnitAttr::ExecStart => {
-                self.exec_start.extend(UnitParseUtil::parse_cmd_task(val)?);
+                self.exec_start = UnitParseUtil::parse_cmd_task(val)?[0].clone();
             }
             ServiceUnitAttr::ExecStartPre => {
                 self.exec_start_pre
@@ -221,7 +256,7 @@ impl ServicePart {
                 "on-abort" => self.restart = RestartOption::OnAbort,
                 "on-watchdog" => self.restart = RestartOption::OnWatchdog,
                 _ => {
-                    return Err(ParseError::new(ParseErrorType::EINVAL,String::new(),0));
+                    return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
                 }
             },
             ServiceUnitAttr::TimeoutStartSec => {
@@ -235,7 +270,7 @@ impl ServicePart {
             }
             ServiceUnitAttr::EnvironmentFile => {
                 if !UnitParseUtil::is_valid_file(val) {
-                    return Err(ParseError::new(ParseErrorType::EFILE,String::new(),0));
+                    return Err(ParseError::new(ParseErrorType::EFILE, String::new(), 0));
                 }
                 self.environment_file = String::from(val);
             }
@@ -244,7 +279,7 @@ impl ServicePart {
             }
             ServiceUnitAttr::WorkingDirectory => {
                 if !UnitParseUtil::is_dir(val) {
-                    return Err(ParseError::new(ParseErrorType::ENODIR,String::new(),0));
+                    return Err(ParseError::new(ParseErrorType::ENODIR, String::new(), 0));
                 }
                 self.working_directory = String::from(val);
             }
@@ -261,11 +296,11 @@ impl ServicePart {
                 "slave" => self.mount_flags = MountFlag::Slave,
                 "private" => self.mount_flags = MountFlag::Private,
                 _ => {
-                    return Err(ParseError::new(ParseErrorType::EINVAL,String::new(),0));
+                    return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
                 }
             },
             _ => {
-                return Err(ParseError::new(ParseErrorType::EINVAL,String::new(),0));
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         }
         return Ok(());
@@ -280,7 +315,7 @@ impl ServicePart {
         self.remain_after_exit
     }
 
-    pub fn exec_start(&self) -> &Vec<CmdTask> {
+    pub fn exec_start(&self) -> &CmdTask {
         &self.exec_start
     }
 

+ 24 - 10
src/unit/target/mod.rs

@@ -1,8 +1,9 @@
 use super::{BaseUnit, Unit};
-use crate::error::ParseError;
+use crate::error::parse_error::ParseError;
 use crate::parse::Segment;
 use crate::parse::parse_target::TargetParser;
 use core::ops::Deref;
+use std::sync::Arc;
 use cfg_if::cfg_if;
 
 cfg_if!{
@@ -16,25 +17,18 @@ cfg_if!{
     }
 }
 
-#[derive(Default)]
+#[derive(Debug,Clone,Default)]
 pub struct TargetUnit {
     unit_base: BaseUnit,
     //targets: Vec<Rc<dyn Unit>>,
 }
 
-impl Deref for TargetUnit {
-    type Target = TargetUnit;
-    fn deref(&self) -> &Self::Target {
-        &self
-    }
-}
-
 impl Unit for TargetUnit {
     fn as_any(&self) -> &dyn core::any::Any {
         self
     }
 
-    fn from_path(path: &str) -> Result<Rc<Self>, ParseError>
+    fn from_path(path: &str) -> Result<Arc<Self>, ParseError>
     where
         Self: Sized,
     {
@@ -52,4 +46,24 @@ impl Unit for TargetUnit {
     fn unit_type(&self) -> super::UnitType {
         return self.unit_base.unit_type;
     }
+
+    fn unit_base(&self) -> &BaseUnit {
+        return &self.unit_base;
+    }
+
+    fn unit_id(&self) -> usize {
+        return self.unit_base.unit_id;
+    }
+
+    fn run(&self) -> Result<(),crate::error::runtime_error::RuntimeError> {
+        Ok(())
+    }
+
+    fn mut_unit_base(&mut self) -> &mut BaseUnit {
+        return &mut self.unit_base;
+    }
 }
+
+unsafe impl Sync for TargetUnit {}
+
+unsafe impl Send for TargetUnit {}

+ 4 - 2
target.json

@@ -5,6 +5,9 @@
     "os": "dragonos",
     "target-endian": "little",
     "target-pointer-width": "64",
+    "target-family": [
+        "unix"
+    ],
     "target-c-int-width": "32",
     "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
     "disable-redzone": true,
@@ -27,6 +30,5 @@
     "static-position-independent-executables": true,
     "supported-sanitizers": [
         "kcfi"
-    ],
-    "target-pointer-width": "64"
+    ]
 }