1 #[cfg(target_os = "dragonos")] 2 use drstd as std; 3 4 use crate::{ 5 error::{ 6 runtime_error::{RuntimeError, RuntimeErrorType}, 7 ErrorFormat, 8 }, 9 manager::{RunningUnit, UnitManager}, 10 parse::{parse_util::UnitParseUtil, Segment, UnitParser}, 11 task::cmdtask::CmdTask, 12 unit::{ 13 service::RestartOption, 14 service::{ServiceType, ServiceUnit}, 15 Unit, UnitState, UnitType, 16 }, 17 }; 18 use std::os::unix::process::CommandExt; 19 use std::sync::Mutex; 20 use std::vec::Vec; 21 use std::{ 22 borrow::BorrowMut, 23 cell::RefCell, 24 eprint, eprintln, 25 io::{Error, ErrorKind}, 26 print, println, 27 }; 28 use std::{io::BufRead, process::Command, sync::Arc}; 29 use std::{process::Stdio, string::ToString}; 30 31 use super::ExitStatus; 32 33 pub struct ServiceExecutor; 34 35 impl ServiceExecutor { 36 pub fn exec(service: &mut ServiceUnit) -> Result<(), RuntimeError> { 37 match *service.service_part().service_type() { 38 ServiceType::Simple => { 39 return Self::exec_simple(service); 40 } 41 ServiceType::Forking => { 42 return Self::exec_forking(service); 43 } 44 ServiceType::Dbus => { 45 return Self::exec_dbus(service); 46 } 47 ServiceType::Notify => { 48 return Self::exec_notify(service); 49 } 50 ServiceType::Idle => { 51 return Self::exec_idle(service); 52 } 53 ServiceType::OneShot => { 54 return Self::exec_one_shot(service); 55 } 56 } 57 } 58 pub fn exec_simple(service: &mut ServiceUnit) -> Result<(), RuntimeError> { 59 //处理conflict 60 let conflicts = service.unit_base().unit_part().conflicts(); 61 for u in conflicts { 62 // 如果有冲突项enable的时候,该unit不能启动 63 let mutex = UnitManager::get_unit_with_id(u).unwrap(); 64 let unit = mutex.lock().unwrap(); 65 if *unit.unit_base().state() == UnitState::Enabled { 66 eprintln!( 67 "{}: Service startup failed: conflict unit", 68 unit.unit_base().unit_part().description() 69 ); 70 return Err(RuntimeError::new(RuntimeErrorType::ExecFailed)); 71 } 72 } 73 74 //获取环境变量 75 //先获取指定的环境变量 76 let mut envs = Vec::from(service.service_part().environment()); 77 78 //若指定了环境变量文件,则解析环境变量文件 79 let env_file = service.service_part().environment_file(); 80 if env_file.len() > 0 { 81 let env_reader = match UnitParser::get_reader(env_file, UnitType::Unknown) { 82 Ok(reader) => reader, 83 Err(_) => { 84 return Err(RuntimeError::new(RuntimeErrorType::Custom( 85 "Incorrect environment variable configuration file".to_string(), 86 ))); 87 } 88 }; 89 for line in env_reader.lines() { 90 if let Ok(line) = line { 91 let x = match UnitParseUtil::parse_env(line.as_str()) { 92 Ok(v) => v, 93 Err(_) => { 94 return Err(RuntimeError::new(RuntimeErrorType::Custom( 95 "Failed to parse environment variable configuration file" 96 .to_string(), 97 ))); 98 } 99 }; 100 envs.push(x); 101 } 102 } 103 } 104 105 //服务配置环境变量,配置工作目录 106 //获取工作目录 107 let mut dir = service.service_part().working_directory(); 108 if dir.is_empty() { 109 dir = "/"; 110 } 111 //获取启动命令 112 let exec_start = service.service_part().exec_start(); 113 println!("exec:{}", exec_start.path); 114 //处理ExecStartsPre,准备在服务启动前执行的命令 115 //TODO:设置uid与gid 116 let cmds = service.service_part().exec_start_pre().clone(); 117 let proc = unsafe { 118 Command::new(&exec_start.path) 119 .args(&exec_start.cmd) 120 .current_dir(dir) 121 .envs(envs) 122 .stderr(Stdio::inherit()) 123 .stdout(Stdio::inherit()) 124 .stdin(Stdio::inherit()) 125 .pre_exec(move || { 126 for cmdtask in cmds.clone() { 127 match cmdtask.exec() { 128 Ok(_) => (), 129 Err(e) => { 130 eprintln!("{}", e.error_format()); 131 return Err(Error::new( 132 ErrorKind::Interrupted, 133 "ExecStartPreFailed", 134 )); 135 } 136 }; 137 } 138 Ok(()) 139 }) 140 .spawn() 141 }; 142 143 match proc { 144 Ok(p) => { 145 println!("Service running..."); 146 //修改service状态 147 service.mut_unit_base().set_state(UnitState::Enabled); 148 //启动成功后将Child加入全局管理的进程表 149 UnitManager::push_running(RunningUnit::new(p, service.unit_id())); 150 //执行启动后命令 151 Self::exec_start_pos(service)?; 152 } 153 Err(err) => { 154 eprintln!("{}: Service startup failed: {}", exec_start.path, err); 155 return Err(RuntimeError::new(RuntimeErrorType::ExecFailed)); 156 } 157 } 158 Ok(()) 159 } 160 161 fn exec_dbus(service: &ServiceUnit) -> Result<(), RuntimeError> { 162 Ok(()) 163 } 164 165 fn exec_forking(service: &ServiceUnit) -> Result<(), RuntimeError> { 166 Ok(()) 167 } 168 169 // 此方法会改变service的启动模式为simple 170 fn exec_idle(service: &mut ServiceUnit) -> Result<(), RuntimeError> { 171 // 将该service加入等待运行队列 172 let _ = service.set_attr(Segment::Service, "Type", "simple"); 173 UnitManager::push_a_idle_service(service.unit_id()); 174 Ok(()) 175 } 176 177 fn exec_notify(service: &ServiceUnit) -> Result<(), RuntimeError> { 178 Ok(()) 179 } 180 181 fn exec_one_shot(service: &ServiceUnit) -> Result<(), RuntimeError> { 182 Ok(()) 183 } 184 185 fn exec_start_pos(service: &ServiceUnit) -> Result<(), RuntimeError> { 186 let cmds = service.service_part().exec_start_pos(); 187 for cmd in cmds { 188 cmd.exec()?; 189 } 190 Ok(()) 191 } 192 193 //显式停止时执行的命令 194 fn exec_stop(service: &mut ServiceUnit) -> Result<(), RuntimeError> { 195 let cmds = service.service_part().exec_stop(); 196 for cmd in cmds { 197 cmd.exec()?; 198 } 199 Ok(()) 200 } 201 202 //停止后执行的命令 203 fn exec_stop_post(service: &mut ServiceUnit) -> Result<(), RuntimeError> { 204 let cmds = service.service_part().exec_stop_post(); 205 for cmd in cmds { 206 cmd.exec()?; 207 } 208 Ok(()) 209 } 210 211 //服务退出执行的逻辑(包括自然退出及显式退出) 212 pub fn after_exit(service: &mut ServiceUnit, exit_status: ExitStatus) { 213 //TODO: 需要考虑是否需要在此处执行退出后代码,还是只需要显式退出时才执行 214 let _ = Self::exec_stop_post(service); 215 216 //判断是否需要restart,需要则再次启动服务 217 if service.service_part().restart().is_restart(&exit_status) { 218 let _ = service.run(); 219 return; 220 } 221 222 //如果该进程标记了RemainAfterExit,则将其加入特殊标记表 223 if service.service_part().remain_after_exit() { 224 UnitManager::push_flag_running(service.unit_id()); 225 } 226 } 227 } 228