1 use super::{BaseUnit, Unit}; 2 use crate::error::runtime_error::{RuntimeError, RuntimeErrorType}; 3 use crate::error::{parse_error::ParseError, parse_error::ParseErrorType}; 4 use crate::executor::service_executor::ServiceExecutor; 5 use crate::manager::GLOBAL_UNIT_MANAGER; 6 use crate::parse::graph::Graph; 7 use crate::parse::parse_service::ServiceParser; 8 use crate::parse::parse_util::UnitParseUtil; 9 use crate::parse::{Segment, UnitParser, SERVICE_UNIT_ATTR_TABLE}; 10 use crate::task::cmdtask::CmdTask; 11 12 #[cfg(target_os = "dragonos")] 13 use drstd as std; 14 use std::mem::MaybeUninit; 15 use std::process::{Child, Command}; 16 use std::rc::Rc; 17 use std::string::String; 18 use std::sync::Arc; 19 use std::vec::Vec; 20 #[derive(Clone, Debug,Default)] 21 pub struct ServiceUnit { 22 unit_base: BaseUnit, 23 service_part: ServicePart, 24 } 25 26 #[derive(Debug, Clone, Copy)] 27 pub enum ServiceType { 28 Simple, 29 Forking, 30 OneShot, 31 Dbus, 32 Notify, 33 Idle, 34 } 35 36 impl Default for ServiceType { 37 fn default() -> Self { 38 ServiceType::Simple 39 } 40 } 41 42 #[derive(Debug, Clone, Copy)] 43 pub enum RestartOption { 44 AlwaysRestart, 45 OnSuccess, 46 OnFailure, 47 OnAbnormal, 48 OnAbort, 49 OnWatchdog, 50 None, 51 } 52 53 impl Default for RestartOption { 54 fn default() -> Self { 55 Self::None 56 } 57 } 58 59 #[derive(Debug, Clone, Copy)] 60 pub enum MountFlag { 61 Shared, 62 Slave, 63 Private, 64 } 65 66 impl Default for MountFlag { 67 fn default() -> Self { 68 Self::Private 69 } 70 } 71 72 #[derive(Default, Debug, Clone)] 73 pub struct ServicePart { 74 //生命周期相关 75 service_type: ServiceType, 76 /// 77 remain_after_exit: bool, 78 exec_start: CmdTask, 79 exec_start_pre: Vec<CmdTask>, 80 exec_start_pos: Vec<CmdTask>, 81 exec_reload: Vec<CmdTask>, 82 exec_stop: Vec<CmdTask>, 83 exec_stop_post: Vec<CmdTask>, 84 restart_sec: u64, 85 restart: RestartOption, 86 timeout_start_sec: u64, 87 timeout_stop_sec: u64, 88 //上下文配置相关 89 environment: Vec<String>, 90 environment_file: String, 91 nice: i8, 92 working_directory: String, 93 root_directory: String, 94 user: String, 95 group: String, 96 mount_flags: MountFlag, 97 //LimitCPU / LimitSTACK / LimitNOFILE / LimitNPROC 等,后续支持再添加 98 } 99 100 impl Unit for ServiceUnit { 101 fn as_any(&self) -> &dyn core::any::Any { 102 self 103 } 104 105 fn from_path(path: &str) -> Result<Arc<Self>, ParseError> 106 where 107 Self: Sized, 108 { 109 return ServiceParser::parse(path); 110 } 111 112 fn set_attr(&mut self, segment: Segment, attr: &str, val: &str) -> Result<(), ParseError> { 113 if segment != Segment::Service { 114 return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0)); 115 } 116 let attr_type = SERVICE_UNIT_ATTR_TABLE.get(attr).ok_or(ParseError::new( 117 ParseErrorType::EINVAL, 118 String::new(), 119 0, 120 )); 121 return self.service_part.set_attr(attr_type.unwrap(), val); 122 } 123 124 fn set_unit_base(&mut self, base: BaseUnit) { 125 self.unit_base = base; 126 } 127 128 fn unit_type(&self) -> super::UnitType { 129 return self.unit_base.unit_type; 130 } 131 132 fn unit_base(&self) -> &BaseUnit { 133 return &self.unit_base; 134 } 135 136 fn unit_id(&self) -> usize { 137 return self.unit_base.unit_id; 138 } 139 140 fn run(&self) -> Result<(), RuntimeError> { 141 self.exec() 142 } 143 144 fn mut_unit_base(&mut self) -> &mut BaseUnit { 145 return &mut self.unit_base; 146 } 147 } 148 149 impl ServiceUnit { 150 pub fn unit_base(&self) -> &BaseUnit { 151 return &self.unit_base; 152 } 153 154 pub fn service_part(&self) -> &ServicePart { 155 return &self.service_part; 156 } 157 158 fn exec(&self) -> Result<(), RuntimeError> { 159 ServiceExecutor::exec(self) 160 } 161 } 162 163 unsafe impl Sync for ServiceUnit {} 164 165 unsafe impl Send for ServiceUnit {} 166 167 pub enum ServiceUnitAttr { 168 None, 169 //Service段 170 //定义启动时的进程行为 171 Type, 172 // 173 RemainAfterExit, 174 //启动命令 175 ExecStart, 176 //启动当前服务之前执行的命令 177 ExecStartPre, 178 //启动当前服务之后执行的命令 179 ExecStartPos, 180 //重启当前服务时执行的命令 181 ExecReload, 182 //停止当前服务时执行的命令 183 ExecStop, 184 //停止当其服务之后执行的命令 185 ExecStopPost, 186 //自动重启当前服务间隔的秒数 187 RestartSec, 188 //定义何种情况 Systemd 会自动重启当前服务 189 Restart, 190 //启动服务时等待的秒数 191 TimeoutStartSec, 192 //停止服务时的等待秒数,如果超过这个时间仍然没有停止,应该使用 SIGKILL 信号强行杀死服务的进程 193 TimeoutStopSec, 194 //为服务指定环境变量 195 Environment, 196 //指定加载一个包含服务所需的环境变量的列表的文件,文件中的每一行都是一个环境变量的定义 197 EnvironmentFile, 198 //服务的进程优先级,值越小优先级越高,默认为 0。其中 -20 为最高优先级,19 为最低优先级 199 Nice, 200 //指定服务的工作目录 201 WorkingDirectory, 202 //指定服务进程的根目录(/ 目录)。如果配置了这个参数,服务将无法访问指定目录以外的任何文件 203 RootDirectory, 204 //指定运行服务的用户 205 User, 206 //指定运行服务的用户组 207 Group, 208 //服务的 Mount Namespace 配置,会影响进程上下文中挂载点的信息 209 MountFlags, 210 } 211 212 impl ServicePart { 213 pub fn set_attr(&'_ mut self, attr: &ServiceUnitAttr, val: &str) -> Result<(), ParseError> { 214 match attr { 215 ServiceUnitAttr::Type => match val { 216 "simple" => self.service_type = ServiceType::Simple, 217 "forking" => self.service_type = ServiceType::Forking, 218 "oneshot" => self.service_type = ServiceType::OneShot, 219 "dbus" => self.service_type = ServiceType::Dbus, 220 "notify" => self.service_type = ServiceType::Notify, 221 "idle" => self.service_type = ServiceType::Idle, 222 _ => { 223 return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0)); 224 } 225 }, 226 ServiceUnitAttr::RemainAfterExit => { 227 self.remain_after_exit = UnitParseUtil::parse_boolean(val)? 228 } 229 ServiceUnitAttr::ExecStart => { 230 self.exec_start = UnitParseUtil::parse_cmd_task(val)?[0].clone(); 231 } 232 ServiceUnitAttr::ExecStartPre => { 233 self.exec_start_pre 234 .extend(UnitParseUtil::parse_cmd_task(val)?); 235 } 236 ServiceUnitAttr::ExecStartPos => { 237 self.exec_start_pos 238 .extend(UnitParseUtil::parse_cmd_task(val)?); 239 } 240 ServiceUnitAttr::ExecReload => { 241 self.exec_reload.extend(UnitParseUtil::parse_cmd_task(val)?); 242 } 243 ServiceUnitAttr::ExecStopPost => { 244 self.exec_stop_post 245 .extend(UnitParseUtil::parse_cmd_task(val)?); 246 } 247 ServiceUnitAttr::ExecStop => { 248 self.exec_stop.extend(UnitParseUtil::parse_cmd_task(val)?); 249 } 250 ServiceUnitAttr::RestartSec => self.restart_sec = UnitParseUtil::parse_sec(val)?, 251 ServiceUnitAttr::Restart => match val { 252 "always" => self.restart = RestartOption::AlwaysRestart, 253 "on-success" => self.restart = RestartOption::OnSuccess, 254 "on-failure" => self.restart = RestartOption::OnFailure, 255 "on-abnormal" => self.restart = RestartOption::OnAbnormal, 256 "on-abort" => self.restart = RestartOption::OnAbort, 257 "on-watchdog" => self.restart = RestartOption::OnWatchdog, 258 _ => { 259 return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0)); 260 } 261 }, 262 ServiceUnitAttr::TimeoutStartSec => { 263 self.timeout_start_sec = UnitParseUtil::parse_sec(val)? 264 } 265 ServiceUnitAttr::TimeoutStopSec => { 266 self.timeout_stop_sec = UnitParseUtil::parse_sec(val)? 267 } 268 ServiceUnitAttr::Environment => { 269 self.environment.push(String::from(val)); 270 } 271 ServiceUnitAttr::EnvironmentFile => { 272 if !UnitParseUtil::is_valid_file(val) { 273 return Err(ParseError::new(ParseErrorType::EFILE, String::new(), 0)); 274 } 275 self.environment_file = String::from(val); 276 } 277 ServiceUnitAttr::Nice => { 278 self.nice = UnitParseUtil::parse_nice(val)?; 279 } 280 ServiceUnitAttr::WorkingDirectory => { 281 if !UnitParseUtil::is_dir(val) { 282 return Err(ParseError::new(ParseErrorType::ENODIR, String::new(), 0)); 283 } 284 self.working_directory = String::from(val); 285 } 286 ServiceUnitAttr::User => { 287 //TODO: 检查系统是否存在这个用户 288 self.user = String::from(val); 289 } 290 ServiceUnitAttr::Group => { 291 //TODO: 检查系统是否存在该用户组 292 self.group = String::from(val); 293 } 294 ServiceUnitAttr::MountFlags => match val { 295 "shared" => self.mount_flags = MountFlag::Shared, 296 "slave" => self.mount_flags = MountFlag::Slave, 297 "private" => self.mount_flags = MountFlag::Private, 298 _ => { 299 return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0)); 300 } 301 }, 302 _ => { 303 return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0)); 304 } 305 } 306 return Ok(()); 307 } 308 309 // 生命周期相关 310 pub fn service_type(&self) -> &ServiceType { 311 &self.service_type 312 } 313 314 pub fn remain_after_exit(&self) -> bool { 315 self.remain_after_exit 316 } 317 318 pub fn exec_start(&self) -> &CmdTask { 319 &self.exec_start 320 } 321 322 pub fn exec_start_pre(&self) -> &Vec<CmdTask> { 323 &self.exec_start_pre 324 } 325 326 pub fn exec_start_pos(&self) -> &Vec<CmdTask> { 327 &self.exec_start_pos 328 } 329 330 pub fn exec_reload(&self) -> &Vec<CmdTask> { 331 &self.exec_reload 332 } 333 334 pub fn exec_stop(&self) -> &Vec<CmdTask> { 335 &self.exec_stop 336 } 337 338 pub fn exec_stop_post(&self) -> &Vec<CmdTask> { 339 &self.exec_stop_post 340 } 341 342 pub fn restart_sec(&self) -> u64 { 343 self.restart_sec 344 } 345 346 pub fn restart(&self) -> &RestartOption { 347 &self.restart 348 } 349 350 pub fn timeout_start_sec(&self) -> u64 { 351 self.timeout_start_sec 352 } 353 354 pub fn timeout_stop_sec(&self) -> u64 { 355 self.timeout_stop_sec 356 } 357 358 // 上下文配置相关 359 pub fn environment(&self) -> &[String] { 360 &self.environment 361 } 362 363 pub fn environment_file(&self) -> &str { 364 &self.environment_file 365 } 366 367 pub fn nice(&self) -> i8 { 368 self.nice 369 } 370 371 pub fn working_directory(&self) -> &str { 372 &self.working_directory 373 } 374 375 pub fn root_directory(&self) -> &str { 376 &self.root_directory 377 } 378 379 pub fn user(&self) -> &str { 380 &self.user 381 } 382 383 pub fn group(&self) -> &str { 384 &self.group 385 } 386 387 pub fn mount_flags(&self) -> &MountFlag { 388 &self.mount_flags 389 } 390 } 391