فهرست منبع

添加定时器任务,细化定时器相关生命周期 (#19)

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

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

* update

* 简要的启动逻辑

* 简要的启动逻辑

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

* 启动shell(不完善)

* 细化service各生命周期操作

* 细化service生命周期,能够从DragonOS中读取服务配置文件

* 部署到DragonOS启动shell

* 部署到DragonOS启动shell

* Makefile添加clean

* 添加计时任务,更新计时器相关生命周期

* update
GnoCiYeH 1 سال پیش
والد
کامیت
b40b6b4d2f

+ 1 - 1
Cargo.toml

@@ -14,7 +14,7 @@ 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 = "d96c322da5"}
+drstd = {git = "https://git.mirrors.dragonos.org/DragonOS-Community/drstd.git", revision = "a5a37880a8"}
 
 lazy_static = { version = "1.4.0", default-features = false, features = ["spin_no_std"] }
 

+ 8 - 8
parse_test/test.service

@@ -2,23 +2,23 @@
 Description=My Service
 Documentation=https://example.com/docs/my-service.html
 #After=/home/heyicong/DragonReach/parse_test/test1.service
+#OnFailure=/home/heyicong/DragonReach/parse_test/test1.service
 
 [Service]
 Type=simple
 ExecStart=/bin/gdb
-ExecStartPos=/bin/echo start_pos
-ExecStartPre=/bin/echo start_pre
-ExecStopPost=/bin/echo stop_pos
-ExecReload=/bin/echo reload
+#ExecStartPos=/bin/echo start_pos
+#ExecStartPre=/bin/echo start_pre
+#ExecStopPost=/bin/echo stop_pos
+#ExecReload=/bin/echo reload
 WorkingDirectory=/home/heyicong/
 User=myuser
 Group=mygroup
 Environment=VAR1=value1
 Environment=VAR2=value2
-Restart=on-success
-RestartSec=5s
+Restart=always
+RestartSec=1s
 TimeoutStartSec=10s
-TimeoutStopSec=10s
-
+TimeoutStopSec=5s
 [Install]
 #WantedBy=multi-user.target

+ 1 - 1
parse_test/test1.service

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

+ 2 - 3
src/executor/dep_graph/mod.rs

@@ -1,12 +1,11 @@
 #[cfg(target_os = "dragonos")]
 use drstd as std;
 
-use core::slice::SlicePattern;
 use std::sync::Arc;
+use std::sync::Mutex;
 use std::vec::Vec;
-use std::{cmp::PartialEq, sync::Mutex};
 
-use crate::manager::{self, UnitManager};
+use crate::manager::UnitManager;
 use crate::{
     error::runtime_error::{RuntimeError, RuntimeErrorType},
     unit::Unit,

+ 77 - 17
src/executor/mod.rs

@@ -4,24 +4,19 @@ use drstd as std;
 pub mod dep_graph;
 pub mod service_executor;
 
-use std::sync::Arc;
-use std::{process::Child, sync::Mutex};
-
 use crate::{
     error::runtime_error::{RuntimeError, RuntimeErrorType},
     manager::UnitManager,
     unit::Unit,
 };
 
-use self::dep_graph::DepGraph;
-
 #[derive(Debug, Clone, Copy)]
 pub enum ExitStatus {
-    Success,
-    Failure,
-    Abnormal,
-    Abort,
-    Watchdog,
+    Success,  // 成功退出
+    Failure,  // 启动失败
+    Abnormal, // 异常退出
+    Abort,    // 显式退出
+    Watchdog, // 超时检测
 }
 
 impl ExitStatus {
@@ -43,22 +38,87 @@ impl ExitStatus {
 pub struct Executor;
 
 impl Executor {
-    pub fn exec(unit: &Arc<Mutex<dyn Unit>>) -> Result<(), RuntimeError> {
+    /// ## 全局执行器入口,将会进行启动检测以及循环依赖检测
+    pub fn exec(unit_id: usize) -> Result<(), RuntimeError> {
+        // TODO: 添加超时检测,这个工作应该在线程执行
+
+        match Self::exec_(unit_id) {
+            Ok(_) => Ok(()),
+            Err(e) => {
+                let mutex = UnitManager::get_unit_with_id(&unit_id).unwrap();
+                let mut unit = mutex.lock().unwrap();
+
+                // 启动失败时启动onfailure项目
+                for id in unit.unit_base().unit_part().on_failure() {
+                    // TODO: 待日志库开发后,这里的错误处理应该是打印日志
+                    let _ = Executor::exec(*id);
+                }
+
+                unit.after_exit(ExitStatus::Failure);
+                return Err(e);
+            }
+        }
+    }
+    pub fn exec_(unit_id: usize) -> Result<(), RuntimeError> {
+        // TODO: 目前的启动逻辑还是串行启动,后续需更改为并行启动某些项
+
+        let unit = match UnitManager::get_unit_with_id(&unit_id) {
+            Some(s) => s,
+            None => {
+                return Err(RuntimeError::new(RuntimeErrorType::FileNotFound));
+            }
+        };
+
+        let mut unit = unit.lock().unwrap();
+
         //TODO: 优化此处,解析时也用到了拓扑排序,尝试使用那次拓扑排序的结果
-        let mut graph = DepGraph::construct_graph(unit);
+        // 此处不需要再次拓扑排序,在parse时已经确定不会出现循环依赖,现在仅需按照启动流程启动即可
+        // let mut graph = DepGraph::construct_graph(&unit);
+        // let sort_ret = graph.topological_sort()?;
 
-        let sort_ret = graph.topological_sort()?;
-        for u in sort_ret {
+        // 优先启动After
+        for u in unit.unit_base().unit_part().after() {
             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);
+            let mut after = mutex.lock().unwrap();
+            after.run()?;
+        }
+
+        // 启动Requires
+        for u in unit.unit_base().unit_part().requires() {
+            if UnitManager::is_running_unit(&u) {
+                continue;
+            }
+            let mutex = UnitManager::get_unit_with_id(&u).unwrap();
+            let mut after = mutex.lock().unwrap();
+            after.run()?;
+        }
+
+        // 启动binds
+        for u in unit.unit_base().unit_part().binds_to() {
+            if UnitManager::is_running_unit(&u) {
+                continue;
             }
+            let mutex = UnitManager::get_unit_with_id(&u).unwrap();
+            let mut after = mutex.lock().unwrap();
+            after.run()?;
+        }
+
+        // 启动Wants
+        for u in unit.unit_base().unit_part().wants() {
+            if UnitManager::is_running_unit(&u) {
+                continue;
+            }
+            let mutex = UnitManager::get_unit_with_id(&u).unwrap();
+            let mut after = mutex.lock().unwrap();
+            let _ = after.run();
         }
+
+        // 启动自身
+        unit.run()?;
         return Ok(());
     }
 }

+ 99 - 70
src/executor/service_executor/mod.rs

@@ -2,59 +2,39 @@
 use drstd as std;
 
 use crate::{
-    error::{
-        runtime_error::{RuntimeError, RuntimeErrorType},
-        ErrorFormat,
-    },
-    manager::{RunningUnit, UnitManager},
-    parse::{parse_util::UnitParseUtil, Segment, UnitParser},
-    task::cmdtask::CmdTask,
+    error::runtime_error::{RuntimeError, RuntimeErrorType},
+    manager::{timer_manager::TimerManager, UnitManager},
+    parse::Segment,
     unit::{
-        service::RestartOption,
         service::{ServiceType, ServiceUnit},
-        Unit, UnitState, UnitType,
+        Unit, UnitState,
     },
 };
-use std::os::unix::process::CommandExt;
-use std::sync::Mutex;
+
+use std::process::Command;
+use std::process::Stdio;
+use std::time::Duration;
 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 std::{eprint, eprintln, print, println};
 
-use super::ExitStatus;
+use super::{Executor, ExitStatus};
 
 pub struct ServiceExecutor;
 
 impl ServiceExecutor {
+    /// ## Service执行器
     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);
-            }
-        }
+            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();
@@ -73,7 +53,6 @@ impl ServiceExecutor {
 
         //获取启动命令
         let exec_start = service.service_part().exec_start();
-        println!("exec:{}", exec_start.path);
 
         //TODO:设置uid与gid
 
@@ -97,7 +76,7 @@ impl ServiceExecutor {
                 //修改service状态
                 service.mut_unit_base().set_state(UnitState::Enabled);
                 //启动成功后将Child加入全局管理的进程表
-                UnitManager::push_running(RunningUnit::new(p, service.unit_id()));
+                UnitManager::push_running(service.unit_id(), p);
                 //执行启动后命令
                 Self::exec_start_pos(service)?;
             }
@@ -109,11 +88,11 @@ impl ServiceExecutor {
         Ok(())
     }
 
-    fn exec_dbus(service: &ServiceUnit) -> Result<(), RuntimeError> {
+    fn exec_dbus(_service: &ServiceUnit) -> Result<(), RuntimeError> {
         Ok(())
     }
 
-    fn exec_forking(service: &ServiceUnit) -> Result<(), RuntimeError> {
+    fn exec_forking(_service: &ServiceUnit) -> Result<(), RuntimeError> {
         Ok(())
     }
 
@@ -125,21 +104,18 @@ impl ServiceExecutor {
         Ok(())
     }
 
-    fn exec_notify(service: &ServiceUnit) -> Result<(), RuntimeError> {
+    fn exec_notify(_service: &ServiceUnit) -> Result<(), RuntimeError> {
         Ok(())
     }
 
-    fn exec_one_shot(service: &ServiceUnit) -> Result<(), RuntimeError> {
+    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.spawn(
-                service.service_part().working_directory().to_string(),
-                service.service_part().environment(),
-            )?;
+            cmd.spawn()?;
         }
         Ok(())
     }
@@ -147,10 +123,7 @@ impl ServiceExecutor {
     fn exec_start_pre(service: &ServiceUnit) -> Result<(), RuntimeError> {
         let cmds = service.service_part().exec_start_pre();
         for cmd in cmds {
-            cmd.spawn(
-                service.service_part().working_directory().to_string(),
-                service.service_part().environment(),
-            )?;
+            cmd.spawn()?;
         }
         Ok(())
     }
@@ -159,22 +132,16 @@ impl ServiceExecutor {
     fn exec_stop(service: &mut ServiceUnit) -> Result<(), RuntimeError> {
         let cmds = service.service_part().exec_stop();
         for cmd in cmds {
-            cmd.no_spawn(
-                service.service_part().working_directory().to_string(),
-                service.service_part().environment(),
-            )?;
+            cmd.no_spawn()?;
         }
         Ok(())
     }
 
     //停止后执行的命令
     fn exec_stop_post(service: &mut ServiceUnit) -> Result<(), RuntimeError> {
-        let cmds = service.service_part().exec_stop_post();
+        let cmds = service.mut_service_part().mut_exec_stop_post();
         for cmd in cmds {
-            cmd.no_spawn(
-                service.service_part().working_directory().to_string(),
-                service.service_part().environment(),
-            )?;
+            cmd.no_spawn()?;
         }
         Ok(())
     }
@@ -182,29 +149,91 @@ impl ServiceExecutor {
     fn exec_reload(service: &mut ServiceUnit) -> Result<(), RuntimeError> {
         let cmds = service.service_part().exec_reload();
         for cmd in cmds {
-            cmd.no_spawn(
-                service.service_part().working_directory().to_string(),
-                service.service_part().environment(),
-            )?;
+            cmd.no_spawn()?;
         }
         Ok(())
     }
 
-    //服务退出执行的逻辑(包括自然退出及显式退出)
+    /// ## 服务退出执行的逻辑(包括自然退出及显式退出)
     pub fn after_exit(service: &mut ServiceUnit, exit_status: ExitStatus) {
         //TODO: 需要考虑是否需要在此处执行退出后代码,还是只需要显式退出时才执行
         let _ = Self::exec_stop_post(service);
 
+        // 停止被spawn的命令
+        let s_part = service.mut_service_part();
+        for cmd in s_part.mut_exec_start_pos() {
+            cmd.stop()
+        }
+        for cmd in s_part.mut_exec_start_pre() {
+            cmd.stop()
+        }
+
+        // 取消未进行的定时器任务
+        TimerManager::cancel_timer(service.unit_id());
+
+        // 关闭和此服务绑定的项目
+        for bind in service.unit_base().unit_part().be_binded_by() {
+            UnitManager::kill_running(*bind);
+        }
+
         //判断是否需要restart,需要则再次启动服务
         if service.service_part().restart().is_restart(&exit_status) {
-            let _ = Self::exec_reload(service);
-            let _ = service.run();
+            let ns = service.service_part().restart_sec();
+            let binds = service.unit_base().unit_part().be_binded_by();
+            let binds = Vec::from(binds);
+            let id = service.unit_id();
+            if ns > 0 {
+                let cmds = service.service_part().exec_reload().clone();
+                TimerManager::push_timer(
+                    Duration::from_nanos(ns),
+                    move || {
+                        for cmd in &cmds {
+                            cmd.no_spawn()?;
+                        }
+                        Executor::exec(id)?;
+                        for bind in &binds {
+                            Executor::exec(*bind)?
+                        }
+                        Ok(())
+                    },
+                    service.unit_id(),
+                )
+            } else {
+                let _ = Self::exec_reload(service);
+                let _ = Executor::exec(id);
+            }
             return;
         }
 
         //如果该进程标记了RemainAfterExit,则将其加入特殊标记表
         if service.service_part().remain_after_exit() {
             UnitManager::push_flag_running(service.unit_id());
+            return;
+        }
+
+        //停止服务后设置Unit状态
+        service.mut_unit_base().set_state(UnitState::Disabled);
+    }
+
+    /// ## 显示退出Service
+    pub fn exit(service: &mut ServiceUnit) {
+        // TODO: 打印日志
+        let _ = Self::exec_stop(service);
+
+        let ns = service.service_part().timeout_stop_sec();
+        let id = service.unit_id();
+        if ns != 0 {
+            // 计时器触发后若服务还未停止,则kill掉进程
+            TimerManager::push_timer(
+                Duration::from_nanos(ns),
+                move || {
+                    if UnitManager::is_running_unit(&id) {
+                        UnitManager::kill_running(id);
+                    }
+                    Ok(())
+                },
+                service.unit_id(),
+            )
         }
     }
 }

+ 22 - 23
src/main.rs

@@ -1,6 +1,7 @@
 #![no_std]
 #![no_main]
 #![feature(slice_pattern)]
+#![feature(fn_traits)]
 
 use cfg_if::cfg_if;
 
@@ -19,19 +20,15 @@ mod executor;
 mod manager;
 mod parse;
 mod task;
+mod time;
 mod unit;
 
-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::{eprint, eprintln, print, println};
+
+use std::string::ToString;
 use std::vec::Vec;
-use unit::service::ServiceUnit;
 
-use self::unit::Unit;
 use error::ErrorFormat;
 
 pub struct FileDescriptor(usize);
@@ -41,6 +38,7 @@ const DRAGON_REACH_UNIT_DIR: &'static str = "/etc/reach/system/";
 #[cfg(target_os = "dragonos")]
 #[no_mangle]
 fn main() {
+    use manager::timer_manager::TimerManager;
     use parse::UnitParser;
 
     use crate::{
@@ -76,8 +74,7 @@ fn main() {
         };
 
         if id != 0 {
-            let unit = UnitManager::get_unit_with_id(&id).unwrap();
-            if let Err(e) = Executor::exec(&unit) {
+            if let Err(e) = Executor::exec(id) {
                 eprintln!("Err:{}", e.error_format());
             } else {
                 println!("Service {} startup success...", id);
@@ -89,19 +86,20 @@ fn main() {
     loop {
         // 检查各服务运行状态
         Manager::check_running_status();
+        // 检查cmd进程状态
+        Manager::check_cmd_proc();
+        // 检查计时器任务
+        TimerManager::check_timer();
     }
 }
 
 #[cfg(not(target_os = "dragonos"))]
 fn main() {
-    use std::time::Instant;
-
     use parse::UnitParser;
 
     use crate::{
         executor::Executor,
-        manager::{Manager, UnitManager},
-        parse::parse_util::UnitParseUtil,
+        manager::{timer_manager::TimerManager, Manager, UnitManager},
     };
 
     let mut units_file_name = Vec::new();
@@ -112,16 +110,19 @@ fn main() {
                 if let Ok(file_type) = entry.file_type() {
                     if file_type.is_file() {
                         let filename = entry.file_name();
-                        let filename = filename.to_str().unwrap();
+                        let _filename = filename.to_str().unwrap();
                         //units_file_name.push(filename.to_string());
                     }
                 }
             }
         }
     }
-  
+
     units_file_name.push("/home/heyicong/DragonReach/parse_test/test.service".to_string());
 
+    // 完善unit之间依赖关系
+    UnitManager::init_units_dependencies();
+
     //启动服务
     for path in units_file_name {
         let id = match UnitParser::from_path(&path) {
@@ -133,8 +134,8 @@ fn main() {
         };
 
         if id != 0 {
-            let unit = UnitManager::get_unit_with_id(&id).unwrap();
-            if let Err(e) = Executor::exec(&unit) {
+            let _unit = UnitManager::get_unit_with_id(&id).unwrap();
+            if let Err(e) = Executor::exec(id) {
                 eprintln!("Err:{}", e.error_format());
             }
         }
@@ -142,13 +143,11 @@ fn main() {
 
     // 启动完服务后进入主循环
     loop {
-        let time = Instant::now();
-
         // 检查各服务运行状态
         Manager::check_running_status();
-        //println!(".");
 
-        let t = time.elapsed().as_micros();
-        //println!("{}",t);
+        Manager::check_cmd_proc();
+
+        TimerManager::check_timer();
     }
 }

+ 46 - 28
src/manager/mod.rs

@@ -1,48 +1,41 @@
 #[cfg(target_os = "dragonos")]
 use drstd as std;
-use std::fs::File;
-use std::{eprint, eprintln, os::fd::AsFd, print, println, process::Child, vec::Vec};
 
+use std::{eprint, eprintln, print, println, vec::Vec};
+
+pub mod timer_manager;
 pub mod unit_manager;
-use std::io::Read;
-use std::os::unix::io::{AsRawFd, FromRawFd};
+
 pub use unit_manager::*;
 
 use crate::executor::ExitStatus;
 
+use self::timer_manager::TimerManager;
+
 pub struct Manager;
 
 impl Manager {
-    /// ## 检查处于运行状态的unit状态
+    /// ## 检查当前DragonReach运行的项目状态,并对其分发处理
     pub fn check_running_status() {
+        // 检查正在运行的Unit
         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();
+        for unit in running_manager.mut_running_table() {
+            let proc = unit.1;
             match proc.try_wait() {
                 //进程正常退出
                 Ok(Some(status)) => {
                     //TODO:交付给相应类型的Unit类型去执行退出后的逻辑
                     println!("Service exited success");
 
-                    exited_unit.push((
-                        *unit.id(),
-                        ExitStatus::from_exit_code(status.code().unwrap()),
-                    ));
-
-                    //退出后从表中去除该任务
-                    dead_unit.push(*unit.id());
+                    exited_unit.push((*unit.0, ExitStatus::from_exit_code(status.code().unwrap())));
                 }
                 //进程错误退出(或启动失败)
                 Err(e) => {
                     eprintln!("unit error: {}", e);
 
                     //test
-                    exited_unit.push((*unit.id(), ExitStatus::from_exit_code(!0)));
-
-                    //从表中去除该任务
-                    dead_unit.push(*unit.id());
+                    exited_unit.push((*unit.0, ExitStatus::from_exit_code(!0)));
                 }
                 //进程处于正常运行状态
                 _ => {}
@@ -51,11 +44,20 @@ impl Manager {
         //释放锁,以便后续删除操作能拿到锁
         drop(running_manager);
 
-        //从表中清除数据
-        for id in dead_unit {
-            UnitManager::remove_running(id);
+        // 处理退出的Unit
+        for tmp in exited_unit {
+            // 从运行表中擦除该unit
+            UnitManager::remove_running(tmp.0);
+
+            // 取消该任务的定时器任务
+            TimerManager::cancel_timer(tmp.0);
+
+            // 交付处理子进程退出逻辑
+            let unit = UnitManager::get_unit_with_id(&tmp.0).unwrap();
+            unit.lock().unwrap().after_exit(tmp.1);
         }
 
+        // 若无运行中任务,则取出IDLE任务运行
         if UnitManager::running_count() == 0 {
             let unit = UnitManager::pop_a_idle_service();
             match unit {
@@ -65,12 +67,28 @@ impl Manager {
                 None => {}
             }
         }
+    }
 
-        // 交付处理子进程退出逻辑
-        // TODO:先不做此处理,因为DragonOS的fork进程管道问题尚未解决
-        // for tmp in exited_unit {
-        //     let unit = UnitManager::get_unit_with_id(&tmp.0).unwrap();
-        //     unit.lock().unwrap().after_exit(tmp.1);
-        // }
+    /// ## 检查当前所有cmd进程的运行状态
+    pub fn check_cmd_proc() {
+        let mut exited = Vec::new();
+        let mut table = CMD_PROCESS_TABLE.write().unwrap();
+        for tuple in table.iter_mut() {
+            let mut proc = tuple.1.lock().unwrap();
+            match proc.try_wait() {
+                // 正常运行
+                Ok(None) => {}
+                // 停止运行,从表中删除数据
+                _ => {
+                    // TODO: 应该添加错误处理,有一些命令执行失败会影响服务正常运行
+                    // 后续应该添加机制来执行服务相关命令启动失败的回调
+                    exited.push(*tuple.0);
+                }
+            }
+        }
+
+        for id in exited {
+            table.remove(&id);
+        }
     }
 }

+ 63 - 0
src/manager/timer_manager/mod.rs

@@ -0,0 +1,63 @@
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+
+use crate::{error::runtime_error::RuntimeError, time::timer::Timer};
+use lazy_static::lazy_static;
+use std::{boxed::Box, sync::RwLock, time::Duration, vec::Vec};
+
+lazy_static! {
+    // 管理全局计时器任务
+    static ref TIMER_TASK_MANAGER: RwLock<TimerManager> = RwLock::new(TimerManager {
+        inner_timers: Vec::new()
+    });
+}
+
+pub struct TimerManager {
+    inner_timers: Vec<Timer>,
+}
+
+impl<'a> IntoIterator for &'a mut TimerManager {
+    type Item = &'a mut Timer;
+
+    type IntoIter = std::slice::IterMut<'a, Timer>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.inner_timers.iter_mut()
+    }
+}
+
+impl TimerManager {
+    /// ## 添加定时器任务
+    ///
+    /// 只有通过这个方式创建的Timer对象才会真正的实现计时
+    pub fn push_timer<F>(duration: Duration, callback: F, parent: usize)
+    where
+        F: FnMut() -> Result<(), RuntimeError> + Send + Sync + 'static,
+    {
+        TIMER_TASK_MANAGER
+            .write()
+            .unwrap()
+            .inner_timers
+            .push(Timer::new(duration, Box::new(callback), parent));
+    }
+
+    /// ## 检测定时器是否到时,到时则触发
+    ///
+    /// 该方法在主循环中每循环一次检测一次,是伪计时器的主运行函数
+    pub fn check_timer() {
+        let mut writer = TIMER_TASK_MANAGER.write().unwrap();
+        //此处触发定时器,若定时器被触发,则移除
+        writer.inner_timers.retain_mut(|x| !x.check());
+    }
+
+    /// ## 取消掉一个unit的所有定时任务,
+    ///
+    /// 一般在unit启动失败或者退出unit时进行该操作
+    pub fn cancel_timer(unit_id: usize) {
+        TIMER_TASK_MANAGER
+            .write()
+            .unwrap()
+            .inner_timers
+            .retain(|x| x.parent() == unit_id)
+    }
+}

+ 92 - 45
src/manager/unit_manager/mod.rs

@@ -4,13 +4,13 @@ use std::hash::{Hash, Hasher};
 use std::{
     collections::hash_map::DefaultHasher,
     collections::vec_deque::VecDeque,
+    print, println,
     process::Child,
     sync::{Arc, Mutex, RwLock},
     vec::Vec,
 };
 
-use crate::unit::service::ServiceUnit;
-use crate::unit::{service, Unit};
+use crate::unit::Unit;
 use hashbrown::HashMap;
 use lazy_static::lazy_static;
 
@@ -28,43 +28,23 @@ lazy_static! {
     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(super) static ref RUNNING_TABLE: RwLock<RunningTableManager> = RwLock::new(RunningTableManager { running_table: HashMap::new() });
 
     // CMD进程表,用于处理Unit的CMD派生进程(ExecStartPre等命令派生进程)
     pub(super) static ref CMD_PROCESS_TABLE: RwLock<HashMap<u32,Mutex<Child>>> = RwLock::new(HashMap::new());
 }
 
 pub struct RunningTableManager {
-    running_table: Vec<RunningUnit>,
+    running_table: HashMap<usize, Child>,
 }
 
-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
+impl RunningTableManager {
+    pub fn running_table(&self) -> &HashMap<usize, Child> {
+        &self.running_table
     }
 
-    pub fn id(&self) -> &usize {
-        &self.unit_id
+    pub fn mut_running_table(&mut self) -> &mut HashMap<usize, Child> {
+        &mut self.running_table
     }
 }
 
@@ -73,6 +53,7 @@ pub struct UnitManager;
 unsafe impl Sync for UnitManager {}
 
 impl UnitManager {
+    /// 插入一条path到unit_id的映射
     pub fn insert_into_path_table(path: &str, unit: usize) {
         let mut hasher = DefaultHasher::new();
         path.hash(&mut hasher);
@@ -80,6 +61,7 @@ impl UnitManager {
         PATH_TO_UNIT_MAP.write().unwrap().insert(hash, unit);
     }
 
+    // 判断当前是否已经有了对应path的Unit
     pub fn contains_path(path: &str) -> bool {
         let mut hasher = DefaultHasher::new();
         path.hash(&mut hasher);
@@ -87,6 +69,7 @@ impl UnitManager {
         PATH_TO_UNIT_MAP.read().unwrap().contains_key(&hash)
     }
 
+    // 通过path获取到Unit
     pub fn get_unit_with_path(path: &str) -> Option<Arc<Mutex<dyn Unit>>> {
         let mut hasher = DefaultHasher::new();
         path.hash(&mut hasher);
@@ -104,12 +87,14 @@ impl UnitManager {
         ret
     }
 
+    // 通过unit_id获取Unit
     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
     }
 
+    // 通过id获取到path
     pub fn get_id_with_path(path: &str) -> Option<usize> {
         let mut hasher = DefaultHasher::new();
         path.hash(&mut hasher);
@@ -117,31 +102,34 @@ impl UnitManager {
         PATH_TO_UNIT_MAP.read().unwrap().get(&hash).cloned()
     }
 
+    // 判断该Unit是否正在运行中
     pub fn is_running_unit(id: &usize) -> bool {
-        !RUNNING_TABLE
-            .read()
+        RUNNING_TABLE.read().unwrap().running_table.contains_key(id)
+            || !FLAG_RUNNING
+                .read()
+                .unwrap()
+                .iter()
+                .filter(|x| **x == *id)
+                .collect::<Vec<_>>()
+                .is_empty()
+    }
+
+    // 向运行表中添加运行的Unit
+    pub fn push_running(unit_id: usize, p: Child) {
+        RUNNING_TABLE
+            .write()
             .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);
+            .insert(unit_id, p);
     }
 
+    // 删除运行表中的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);
-            }
-            _ => (),
-        }
+        table.running_table.remove(&id);
     }
 
+    // 向id到Unit映射表中插入数据
     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) {
@@ -149,10 +137,12 @@ impl UnitManager {
         }
     }
 
+    // 判断当前DragonReach是否拥有目标id的Unit
     pub fn contains_id(id: &usize) -> bool {
         ID_TO_UNIT_MAP.read().unwrap().contains_key(id)
     }
 
+    // 弹出一个处于IDLE状态的Service
     pub fn pop_a_idle_service() -> Option<Arc<Mutex<dyn Unit>>> {
         let id = IDLE_SERVIEC_DEQUE.lock().unwrap().pop_front();
         match id {
@@ -165,6 +155,7 @@ impl UnitManager {
         }
     }
 
+    // 添加IDLE状态的Service,将在后续调度
     pub fn push_a_idle_service(id: usize) {
         if !Self::contains_id(&id) {
             return;
@@ -172,6 +163,7 @@ impl UnitManager {
         IDLE_SERVIEC_DEQUE.lock().unwrap().push_back(id);
     }
 
+    // 将该Unit标记为运行状态,并且后续不会对其进行运行检查
     pub fn push_flag_running(id: usize) {
         let mut t = FLAG_RUNNING.write().unwrap();
         if t.contains(&id) {
@@ -180,10 +172,12 @@ impl UnitManager {
         t.push(id);
     }
 
+    // 当前运行的Unit数
     pub fn running_count() -> usize {
         return RUNNING_TABLE.read().unwrap().running_table.len();
     }
 
+    // 向Cmd运行表中添加
     pub fn push_cmd_proc(proc: Child) {
         CMD_PROCESS_TABLE
             .write()
@@ -191,7 +185,60 @@ impl UnitManager {
             .insert(proc.id(), Mutex::new(proc));
     }
 
+    // 删除对应cmd的进程
     pub fn remove_cmd_proc(id: u32) {
         CMD_PROCESS_TABLE.write().unwrap().remove(&id);
     }
+
+    // 弹出指定id的cmd进程
+    pub fn pop_cmd_proc(id: u32) -> Option<Mutex<Child>> {
+        CMD_PROCESS_TABLE.write().unwrap().remove(&id)
+    }
+
+    // 初始化各Unit的依赖关系,此方法只需在解析完系统Unit文件后调用一次
+    pub fn init_units_dependencies() {
+        let manager = ID_TO_UNIT_MAP.write().unwrap();
+
+        // 处理before段,将before段的Unit添加此Unit为After
+        for (id, unit) in manager.iter() {
+            let mut unit = unit.lock().unwrap();
+            let before = unit.mut_unit_base().unit_part().before();
+            for rid in before {
+                let req = UnitManager::get_unit_with_id(rid).unwrap();
+                let mut req = req.lock().unwrap();
+                req.mut_unit_base().mut_unit_part().push_after_unit(*id);
+            }
+        }
+
+        for (id, unit) in manager.iter() {
+            let mut unit = unit.lock().unwrap();
+
+            // 处理binds_to段
+            let binds_to = unit.mut_unit_base().unit_part().binds_to();
+            for rid in binds_to {
+                let req = UnitManager::get_unit_with_id(rid).unwrap();
+                let mut req = req.lock().unwrap();
+                req.mut_unit_base().mut_unit_part().push_be_binded_by(*id);
+            }
+
+            // 处理part_of段
+            let part_of = unit.mut_unit_base().unit_part().part_of();
+            for rid in part_of {
+                let req = UnitManager::get_unit_with_id(rid).unwrap();
+                let mut req = req.lock().unwrap();
+                req.mut_unit_base().mut_unit_part().push_be_binded_by(*id);
+            }
+        }
+    }
+
+    /// ## 杀死Unit进程
+    pub fn kill_running(id: usize) {
+        if Self::is_running_unit(&id) {
+            let mut running_manager = RUNNING_TABLE.write().unwrap();
+            let unit = running_manager.running_table.get_mut(&id).unwrap();
+            let _ = unit.kill();
+            println!("kill:{}", id);
+            running_manager.running_table.remove(&id);
+        }
+    }
 }

+ 5 - 7
src/parse/graph/mod.rs

@@ -2,17 +2,14 @@ use crate::{
     error::parse_error::{ParseError, ParseErrorType},
     unit::UnitType,
 };
-use core::slice::SlicePattern;
+
 #[cfg(target_os = "dragonos")]
 use drstd as std;
+use std::io::BufRead;
 use std::string::{String, ToString};
 use std::vec::Vec;
-use std::{
-    fs::File,
-    io::{BufRead, BufReader},
-};
 
-use super::{parse_util::UnitParseUtil, UnitParser};
+use super::UnitParser;
 
 pub struct GraphNode {
     value: String,
@@ -107,11 +104,12 @@ impl Graph {
         }
     }
 
+    // TODO: 完善这里,目前还是可能会有循环依赖的问题,因为目前只判断了After字段,其他字段也有可能导致循环依赖问题
     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);
+        Self::get_node_num(&unit, &mut dep, &mut node_num)?;
 
         let mut graph: Graph = Graph::new();
         graph.max_edge = node_num * (node_num - 1);

+ 4 - 3
src/parse/mod.rs

@@ -1,5 +1,5 @@
 use crate::error::parse_error::ParseErrorType;
-use crate::manager::{self, UnitManager};
+use crate::manager::UnitManager;
 use crate::unit::{BaseUnit, Unit};
 use crate::DRAGON_REACH_UNIT_DIR;
 use crate::{
@@ -236,7 +236,7 @@ impl UnitParser {
         //用于记录当前段的类型
         let mut segment = Segment::None;
         //用于处理多行对应一个属性的情况
-        let mut last_attr = ServiceUnitAttr::None;
+        let _last_attr = ServiceUnitAttr::None;
 
         //一行一行向下解析
         let lines = reader
@@ -288,7 +288,7 @@ impl UnitParser {
                 i += 1;
                 break;
             }
-            //=号分割后第一个元素为属性,后面的均为值,若一行出现两个等号则是语法错误
+            //=号分割后第一个元素为属性,后面的均为值
             let (attr_str, val_str) = match line.find('=') {
                 Some(idx) => (line[..idx].trim(), line[idx + 1..].trim()),
                 None => {
@@ -344,6 +344,7 @@ impl UnitParser {
         }
         unit.set_unit_base(unit_base);
         let id = unit.set_unit_id();
+        unit.init();
         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);

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

@@ -1,17 +1,14 @@
 use super::graph::Graph;
 use super::parse_util::UnitParseUtil;
-use super::UnitParser;
+
 use crate::error::parse_error::ParseError;
 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;
 
 impl ServiceParser {
@@ -27,7 +24,7 @@ impl ServiceParser {
         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)?;
+            UnitParseUtil::parse_unit_no_type(&p)?;
         }
 
         let result = UnitManager::get_id_with_path(path).unwrap();

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

@@ -1,16 +1,13 @@
 use super::graph::Graph;
 use super::parse_util::UnitParseUtil;
-use super::UnitParser;
+
 use crate::error::parse_error::ParseError;
 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;
 
@@ -27,7 +24,7 @@ impl TargetParser {
         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 _temp_unit = UnitParseUtil::parse_unit_no_type(&p)?;
         }
 
         let result = UnitManager::get_id_with_path(path).unwrap();

+ 7 - 12
src/parse/parse_util/mod.rs

@@ -10,14 +10,11 @@ use crate::{
 use drstd as std;
 
 use std::{
-    any::Any, format, fs, io::BufRead, os::unix::prelude::PermissionsExt, path::Path, print,
-    println, string::String, string::ToString, sync::Arc, vec, vec::Vec,
+    fs, io::BufRead, os::unix::prelude::PermissionsExt, path::Path, string::String,
+    string::ToString, vec, vec::Vec,
 };
 
-use super::{
-    parse_service::ServiceParser, parse_target::TargetParser, UnitParser, BASE_IEC, BASE_SI,
-    SEC_UNIT_TABLE,
-};
+use super::{UnitParser, BASE_IEC, BASE_SI, SEC_UNIT_TABLE};
 
 #[derive(PartialEq)]
 pub enum SizeBase {
@@ -413,7 +410,7 @@ impl UnitParseUtil {
     ///
     /// @return 解析成功则返回Ok(Url),否则返回Err
     pub fn parse_url(s: &str) -> Result<Vec<Url>, ParseError> {
-        let mut url = Url::default();
+        let _url = Url::default();
         let url_strs = s.split_whitespace().collect::<Vec<&str>>();
         let mut urls = Vec::new();
         for s in url_strs {
@@ -492,11 +489,7 @@ impl UnitParseUtil {
         let mut tasks = Vec::new();
         let mut i = 0;
         while i < cmds.len() {
-            let mut cmd_task = CmdTask {
-                path: String::new(),
-                cmd: Vec::new(),
-                ignore: false,
-            };
+            let mut cmd_task = CmdTask::default();
             //匹配到这里时,这个单词肯定是路径,若路径以-开头则设置ignore
             cmd_task.ignore = cmds[i].starts_with('-');
 
@@ -695,6 +688,7 @@ impl UnitParseUtil {
         return false;
     }
 
+    ///// ## 通过文件名解析该Unit的类型
     pub fn parse_type(path: &str) -> UnitType {
         if let Some(index) = path.rfind('.') {
             let result = &path[index + 1..];
@@ -708,6 +702,7 @@ impl UnitParseUtil {
         UnitType::Unknown
     }
 
+    /// ## 将读取环境变量文件解析为环境变量集合
     pub fn parse_environment_file(env_file: &str) -> Result<Vec<(String, String)>, ParseError> {
         let mut envs = Vec::new();
         if env_file.len() > 0 {

+ 30 - 12
src/task/cmdtask/mod.rs

@@ -1,12 +1,7 @@
 #[cfg(target_os = "dragonos")]
 use drstd as std;
 
-use std::{
-    eprint, eprintln, print, println,
-    process::{Child, Command},
-    string::String,
-    vec::Vec,
-};
+use std::{eprint, eprintln, print, process::Command, string::String, vec::Vec};
 
 use crate::{
     error::runtime_error::{RuntimeError, RuntimeErrorType},
@@ -18,14 +13,18 @@ pub struct CmdTask {
     pub path: String,
     pub cmd: Vec<String>,
     pub ignore: bool, //表示忽略这个命令的错误,即使它运行失败也不影响unit正常运作
+    pub dir: String,
+    pub envs: Vec<(String, String)>,
+    pub pid: u32,
 }
 
 impl CmdTask {
-    pub fn spawn(&self, dir: String, envs: &[(String, String)]) -> Result<(), RuntimeError> {
+    /// ## 以新建进程的方式运行这个cmd
+    pub fn spawn(&self) -> Result<(), RuntimeError> {
         let result = Command::new(&self.path)
             .args(&self.cmd)
-            .current_dir(dir)
-            .envs(Vec::from(envs))
+            .current_dir(self.dir.clone())
+            .envs(self.envs.clone())
             .spawn();
         match result {
             Ok(proc) => {
@@ -41,11 +40,12 @@ impl CmdTask {
         Ok(())
     }
 
-    pub fn no_spawn(&self, dir: String, envs: &[(String, String)]) -> Result<(), RuntimeError> {
+    /// ## 阻塞式运行
+    pub fn no_spawn(&self) -> Result<(), RuntimeError> {
         let result = Command::new(&self.path)
             .args(&self.cmd)
-            .current_dir(dir)
-            .envs(Vec::from(envs))
+            .current_dir(self.dir.clone())
+            .envs(self.envs.clone())
             .output();
         match result {
             Ok(output) => {
@@ -64,4 +64,22 @@ impl CmdTask {
         }
         Ok(())
     }
+
+    /// ## 若这个cmd任务spawn了,则kill这个cmd进程
+    pub fn stop(&mut self) {
+        if self.pid != 0 {
+            let res = UnitManager::pop_cmd_proc(self.pid).unwrap();
+
+            let mut proc = res.lock().unwrap();
+
+            match proc.try_wait() {
+                //进程正常退出
+                Ok(Some(_status)) => {}
+                //进程错误退出(或启动失败)
+                _ => {
+                    proc.kill().expect("Cannot kill cmd task");
+                }
+            };
+        }
+    }
 }

+ 4 - 0
src/time/mod.rs

@@ -0,0 +1,4 @@
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+pub mod timer;
+pub mod watchdog;

+ 57 - 0
src/time/timer/mod.rs

@@ -0,0 +1,57 @@
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+
+use std::boxed::Box;
+use std::time::{Duration, Instant};
+use std::{print, println};
+
+use crate::error::runtime_error::RuntimeError;
+
+/// 伪定时器,结合主循环来实现计时,在计时器触发时,会执行相应的cmd命令
+/// 后续实现线程后,应使用线程实现
+pub struct Timer {
+    // 在创建计时器时记录当前时间
+    instant: Instant,
+    // 计时器触发时执行的闭包
+    callback: Box<dyn FnMut() -> Result<(), RuntimeError> + Send + Sync + 'static>,
+    // 计时时长
+    duration: Duration,
+    // 此计时器的拥有者(Unit)
+    parent: usize,
+}
+
+impl Timer {
+    /// ## 创建计时任务
+    pub fn new(
+        duration: Duration,
+        callback: Box<dyn FnMut() -> Result<(), RuntimeError> + Send + Sync + 'static>,
+        parent: usize,
+    ) -> Self {
+        Timer {
+            instant: Instant::now(),
+            callback: callback,
+            duration: duration,
+            parent: parent,
+        }
+    }
+
+    /// ## 判断当前是否到时,若执行该函数时已到时,将会执行定时任务
+    ///
+    /// ### return 到时返回true,否则返回false
+    pub fn check(&mut self) -> bool {
+        //println!("{},{}",self.instant.elapsed().as_micros(),self.duration.as_micros());
+        if self.instant.elapsed().saturating_sub(self.duration) > Duration::ZERO {
+            // TODO: 未进行错误处理
+            if let Err(_e) = (self.callback)() {
+                println!("task error");
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /// ## 获取此计时器的拥有者Unit
+    pub fn parent(&self) -> usize {
+        self.parent
+    }
+}

+ 2 - 0
src/time/watchdog/mod.rs

@@ -0,0 +1,2 @@
+#[cfg(target_os = "dragonos")]
+use drstd as std;

+ 45 - 6
src/unit/mod.rs

@@ -1,34 +1,32 @@
 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;
 
 #[cfg(target_os = "dragonos")]
 use drstd as std;
-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;
 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);
@@ -50,6 +48,8 @@ pub trait Unit: Sync + Send + Debug {
 
     fn as_any(&self) -> &dyn Any;
 
+    fn as_mut_any(&mut self) -> &mut dyn Any;
+
     /// @brief 设置Unit属性
     ///
     /// 设置对应Unit属性
@@ -98,7 +98,13 @@ pub trait Unit: Sync + Send + Debug {
     /// ## Unit退出后逻辑
     ///
     /// 一般只有可运行的Unit(如Service)需要重写此函数
-    fn after_exit(&mut self, exit_status: ExitStatus) {}
+    fn after_exit(&mut self, _exit_status: ExitStatus) {}
+
+    /// ## 初始化Unit内任务的一些参数,各个Unit所需处理的不相同,故放在总的Unit trait
+    fn init(&mut self) {}
+
+    /// ## Unit的显式退出逻辑
+    fn exit(&mut self);
 }
 
 //Unit状态
@@ -183,6 +189,10 @@ impl BaseUnit {
         &self.unit_part
     }
 
+    pub fn mut_unit_part(&mut self) -> &mut UnitPart {
+        &mut self.unit_part
+    }
+
     pub fn install_part(&self) -> &InstallPart {
         &self.install_part
     }
@@ -213,16 +223,28 @@ pub struct Url {
 //对应Unit文件的Unit段
 #[derive(Debug, Clone)]
 pub struct UnitPart {
+    // Unit描述
     description: String,
+    // Unit文档
     documentation: Vec<Url>,
+    // 依赖项,同时与当前Unit启动,任意一个失败,终止该Unit的启动
     requires: Vec<usize>,
+    // 依赖项,同时与当前Unit启动,不需要考虑其成功与否
     wants: Vec<usize>,
+    // 该Unit在下列Units启动完成之后才能启动
     after: Vec<usize>,
+    // after相反的语义
     before: Vec<usize>,
+    // 与requires类似,但是这些模块任意一个意外结束或者重启时,该Unit也会终止或重启
     binds_to: Vec<usize>,
+    // 与binds_to类似,但是不会随着当前Unit启动而启动
     part_of: Vec<usize>,
+    // 启动失败时,需启动的项
     on_failure: Vec<usize>,
+    // 与当前Unit冲突项
     conflicts: Vec<usize>,
+    // 与当前Unit绑定的项,当前Unit失败或者重启时这些项也会跟着终止或重启
+    be_binded_by: Vec<usize>,
 }
 
 impl Default for UnitPart {
@@ -238,6 +260,7 @@ impl Default for UnitPart {
             part_of: Vec::new(),
             on_failure: Vec::new(),
             conflicts: Vec::new(),
+            be_binded_by: Vec::new(),
         }
     }
 }
@@ -363,6 +386,22 @@ impl UnitPart {
     pub fn conflicts(&self) -> &[usize] {
         &self.conflicts
     }
+
+    pub fn be_binded_by(&self) -> &[usize] {
+        &self.be_binded_by
+    }
+
+    pub fn push_be_binded_by(&mut self, id: usize) {
+        if !self.be_binded_by.contains(&id) {
+            self.be_binded_by.push(id);
+        }
+    }
+
+    pub fn push_after_unit(&mut self, id: usize) {
+        if !self.after.contains(&id) {
+            self.after.push(id);
+        }
+    }
 }
 
 //对应Unit文件的Install段

+ 67 - 12
src/unit/service/mod.rs

@@ -1,22 +1,19 @@
 use super::{BaseUnit, Unit};
-use crate::error::runtime_error::{RuntimeError, RuntimeErrorType};
+use crate::error::runtime_error::RuntimeError;
 use crate::error::{parse_error::ParseError, parse_error::ParseErrorType};
-use crate::executor::ExitStatus;
 use crate::executor::service_executor::ServiceExecutor;
-use crate::manager::UnitManager;
-use crate::parse::graph::Graph;
+use crate::executor::ExitStatus;
+
 use crate::parse::parse_service::ServiceParser;
 use crate::parse::parse_util::UnitParseUtil;
-use crate::parse::{Segment, UnitParser, SERVICE_UNIT_ATTR_TABLE};
+use crate::parse::{Segment, 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::string::{String, ToString};
+
 use std::vec::Vec;
 #[derive(Clone, Debug)]
 pub struct ServiceUnit {
@@ -188,6 +185,40 @@ impl Unit for ServiceUnit {
     fn after_exit(&mut self, exit_status: ExitStatus) {
         ServiceExecutor::after_exit(self, exit_status);
     }
+
+    fn init(&mut self) {
+        let part = &mut self.service_part;
+        for cmd in part.exec_reload.iter_mut() {
+            cmd.dir = part.working_directory.to_string();
+            cmd.envs = part.environment.clone();
+        }
+        part.exec_start.dir = part.working_directory.to_string();
+        part.exec_start.envs = part.environment.clone();
+        for cmd in part.exec_start_pos.iter_mut() {
+            cmd.dir = part.working_directory.to_string();
+            cmd.envs = part.environment.clone();
+        }
+        for cmd in part.exec_start_pre.iter_mut() {
+            cmd.dir = part.working_directory.to_string();
+            cmd.envs = part.environment.clone();
+        }
+        for cmd in part.exec_stop.iter_mut() {
+            cmd.dir = part.working_directory.to_string();
+            cmd.envs = part.environment.clone();
+        }
+        for cmd in part.exec_stop_post.iter_mut() {
+            cmd.dir = part.working_directory.to_string();
+            cmd.envs = part.environment.clone();
+        }
+    }
+
+    fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
+        self
+    }
+
+    fn exit(&mut self) {
+        ServiceExecutor::exit(self);
+    }
 }
 
 impl ServiceUnit {
@@ -199,6 +230,10 @@ impl ServiceUnit {
         return &self.service_part;
     }
 
+    pub fn mut_service_part(&mut self) -> &mut ServicePart {
+        return &mut self.service_part;
+    }
+
     fn exec(&mut self) -> Result<(), RuntimeError> {
         ServiceExecutor::exec(self)
     }
@@ -380,8 +415,28 @@ impl ServicePart {
         &self.exec_stop
     }
 
-    pub fn exec_stop_post(&self) -> &Vec<CmdTask> {
-        &self.exec_stop_post
+    pub fn exec_stop_post(&mut self) -> &mut Vec<CmdTask> {
+        &mut self.exec_stop_post
+    }
+
+    pub fn mut_exec_start_pre(&mut self) -> &mut Vec<CmdTask> {
+        &mut self.exec_start_pre
+    }
+
+    pub fn mut_exec_start_pos(&mut self) -> &mut Vec<CmdTask> {
+        &mut self.exec_start_pos
+    }
+
+    pub fn mut_exec_reload(&mut self) -> &mut Vec<CmdTask> {
+        &mut self.exec_reload
+    }
+
+    pub fn mut_exec_stop(&mut self) -> &mut Vec<CmdTask> {
+        &mut self.exec_stop
+    }
+
+    pub fn mut_exec_stop_post(&mut self) -> &mut Vec<CmdTask> {
+        &mut self.exec_stop_post
     }
 
     pub fn restart_sec(&self) -> u64 {

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

@@ -2,15 +2,11 @@ use super::{BaseUnit, Unit};
 use crate::error::parse_error::ParseError;
 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};
+
+use core::result::Result::{self, Ok};
 #[cfg(target_os = "dragonos")]
 use drstd as std;
 use std::marker::{Send, Sized, Sync};
-use std::rc::Rc;
-use std::sync::Arc;
-use std::vec::Vec;
 
 #[derive(Debug, Clone, Default)]
 pub struct TargetUnit {
@@ -30,7 +26,7 @@ impl Unit for TargetUnit {
         return TargetParser::parse(path);
     }
 
-    fn set_attr(&mut self, segement: Segment, attr: &str, val: &str) -> Result<(), ParseError> {
+    fn set_attr(&mut self, _segement: Segment, _attr: &str, _val: &str) -> Result<(), ParseError> {
         Ok(())
     }
 
@@ -57,6 +53,14 @@ impl Unit for TargetUnit {
     fn mut_unit_base(&mut self) -> &mut BaseUnit {
         return &mut self.unit_base;
     }
+
+    fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
+        self
+    }
+
+    fn exit(&mut self) {
+        todo!()
+    }
 }
 
 unsafe impl Sync for TargetUnit {}