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