1 use crate::error::parse_error::ParseError; 2 use crate::error::parse_error::ParseErrorType; 3 use crate::error::runtime_error::RuntimeError; 4 5 use crate::executor::ExitStatus; 6 use crate::parse::parse_util::UnitParseUtil; 7 use crate::parse::Segment; 8 9 #[cfg(target_os = "dragonos")] 10 use drstd as std; 11 12 use std::any::Any; 13 use std::default::Default; 14 use std::fmt::Debug; 15 use std::marker::{Send, Sized, Sync}; 16 17 use std::result::Result; 18 use std::result::Result::Err; 19 use std::result::Result::Ok; 20 use std::string::String; 21 use std::sync::atomic::AtomicUsize; 22 use std::sync::atomic::Ordering; 23 24 use std::vec::Vec; 25 26 pub mod service; 27 pub mod target; 28 29 use self::target::TargetUnit; 30 31 pub fn generate_unit_id() -> usize { 32 static UNIT_ID: AtomicUsize = AtomicUsize::new(1); 33 return UNIT_ID.fetch_add(1, Ordering::SeqCst); 34 } 35 36 //所有可解析的Unit都应该实现该trait 37 pub trait Unit: Sync + Send + Debug { 38 /// @brief 从文件获取到Unit,该函数是解析Unit文件的入口函数 39 /// 40 /// 从path解析Unit属性 41 /// 42 /// @param path 需解析的文件 43 /// 44 /// @return 解析成功则返回对应Unit的id,否则返回Err 45 fn from_path(path: &str) -> Result<usize, ParseError> 46 where 47 Self: Sized; 48 49 fn as_any(&self) -> &dyn Any; 50 51 fn as_mut_any(&mut self) -> &mut dyn Any; 52 53 /// @brief 设置Unit属性 54 /// 55 /// 设置对应Unit属性 56 /// 57 /// @param segment 属性段类型 58 /// 59 /// @param attr 属性名 60 /// 61 /// @param val 属性值 62 /// 63 /// @return 设置成功则返回Ok(()),否则返回Err 64 fn set_attr(&mut self, segment: Segment, attr: &str, val: &str) -> Result<(), ParseError>; 65 66 /// # 设置每个Unit都应该有的属性 67 /// 68 /// 设置BaseUnit 69 /// 70 /// ## param unit_base 设置值 71 fn set_unit_base(&mut self, unit_base: BaseUnit); 72 73 /// # 获取UnitType 74 /// 75 /// ## return UnitType 76 fn unit_type(&self) -> UnitType; 77 78 fn unit_base(&self) -> &BaseUnit; 79 80 fn mut_unit_base(&mut self) -> &mut BaseUnit; 81 82 fn unit_id(&self) -> usize; 83 84 /// ## Unit的工作逻辑 85 /// 86 /// ### return OK(())/Err 87 fn run(&mut self) -> Result<(), RuntimeError>; 88 89 /// ## 设置unit_id 90 /// 91 /// ### return OK(())/Err 92 fn set_unit_id(&mut self) -> usize { 93 let ret = generate_unit_id(); 94 self.mut_unit_base().set_id(ret); 95 ret 96 } 97 98 /// ## Unit退出后逻辑 99 /// 100 /// 一般只有可运行的Unit(如Service)需要重写此函数 101 fn after_exit(&mut self, _exit_status: ExitStatus) {} 102 103 /// ## 初始化Unit内任务的一些参数,各个Unit所需处理的不相同,故放在总的Unit trait 104 fn init(&mut self) {} 105 106 /// ## Unit的显式退出逻辑 107 fn exit(&mut self); 108 } 109 110 //Unit状态 111 #[derive(Clone, Copy, Debug, PartialEq)] 112 pub enum UnitState { 113 Enabled, 114 Disabled, 115 Static, 116 Masked, 117 } 118 119 //Unit类型 120 #[derive(Clone, Copy, PartialEq, Debug)] 121 pub enum UnitType { 122 Automount, 123 Device, 124 Mount, 125 Path, 126 Scope, 127 Service, 128 Slice, 129 Snapshot, 130 Socket, 131 Swap, 132 Target, 133 Timer, 134 Unknown, 135 } 136 137 //记录unit文件基本信息,这个结构体里面的信息是所有Unit文件都可以有的属性 138 #[derive(Debug, Clone)] 139 pub struct BaseUnit { 140 unit_part: UnitPart, 141 install_part: InstallPart, 142 state: UnitState, 143 unit_type: UnitType, 144 unit_id: usize, 145 } 146 147 impl Default for BaseUnit { 148 fn default() -> Self { 149 BaseUnit { 150 unit_part: UnitPart::default(), 151 install_part: InstallPart::default(), 152 state: UnitState::Disabled, 153 unit_type: UnitType::Unknown, 154 unit_id: 0, 155 } 156 } 157 } 158 159 impl BaseUnit { 160 pub fn set_state(&mut self, state: UnitState) { 161 self.state = state; 162 } 163 164 pub fn set_unit_type(&mut self, utype: UnitType) { 165 self.unit_type = utype; 166 } 167 168 pub fn set_unit_part_attr( 169 &mut self, 170 attr_type: &BaseUnitAttr, 171 val: &str, 172 ) -> Result<(), ParseError> { 173 return self.unit_part.set_attr(attr_type, val); 174 } 175 176 pub fn set_install_part_attr( 177 &mut self, 178 attr_type: &InstallUnitAttr, 179 val: &str, 180 ) -> Result<(), ParseError> { 181 return self.install_part.set_attr(attr_type, val); 182 } 183 184 pub fn parse_and_set_attribute(&self) -> Result<(), ParseError> { 185 return Ok(()); 186 } 187 188 pub fn unit_part(&self) -> &UnitPart { 189 &self.unit_part 190 } 191 192 pub fn mut_unit_part(&mut self) -> &mut UnitPart { 193 &mut self.unit_part 194 } 195 196 pub fn install_part(&self) -> &InstallPart { 197 &self.install_part 198 } 199 200 pub fn state(&self) -> &UnitState { 201 &self.state 202 } 203 204 pub fn unit_type(&self) -> &UnitType { 205 &self.unit_type 206 } 207 208 pub fn set_id(&mut self, id: usize) { 209 self.unit_id = id; 210 } 211 } 212 213 #[derive(Default, Debug, Clone)] 214 pub struct Url { 215 pub url_string: String, // pub protocol: String, 216 // pub host: String, 217 // pub port: Option<u16>, 218 // pub path: String, 219 // pub query: Option<String>, 220 // pub fragment: Option<String>, 221 } 222 223 //对应Unit文件的Unit段 224 #[derive(Debug, Clone)] 225 pub struct UnitPart { 226 // Unit描述 227 description: String, 228 // Unit文档 229 documentation: Vec<Url>, 230 // 依赖项,同时与当前Unit启动,任意一个失败,终止该Unit的启动 231 requires: Vec<usize>, 232 // 依赖项,同时与当前Unit启动,不需要考虑其成功与否 233 wants: Vec<usize>, 234 // 该Unit在下列Units启动完成之后才能启动 235 after: Vec<usize>, 236 // after相反的语义 237 before: Vec<usize>, 238 // 与requires类似,但是这些模块任意一个意外结束或者重启时,该Unit也会终止或重启 239 binds_to: Vec<usize>, 240 // 与binds_to类似,但是不会随着当前Unit启动而启动 241 part_of: Vec<usize>, 242 // 启动失败时,需启动的项 243 on_failure: Vec<usize>, 244 // 与当前Unit冲突项 245 conflicts: Vec<usize>, 246 // 与当前Unit绑定的项,当前Unit失败或者重启时这些项也会跟着终止或重启 247 be_binded_by: Vec<usize>, 248 } 249 250 impl Default for UnitPart { 251 fn default() -> Self { 252 UnitPart { 253 description: String::new(), 254 documentation: Vec::new(), 255 requires: Vec::new(), 256 wants: Vec::new(), 257 after: Vec::new(), 258 before: Vec::new(), 259 binds_to: Vec::new(), 260 part_of: Vec::new(), 261 on_failure: Vec::new(), 262 conflicts: Vec::new(), 263 be_binded_by: Vec::new(), 264 } 265 } 266 } 267 268 impl UnitPart { 269 pub fn set_attr(&mut self, attr: &BaseUnitAttr, val: &str) -> Result<(), ParseError> { 270 match attr { 271 BaseUnitAttr::None => { 272 return Err(ParseError::new( 273 ParseErrorType::ESyntaxError, 274 String::new(), 275 0, 276 )); 277 } 278 BaseUnitAttr::Description => self.description = String::from(val), 279 BaseUnitAttr::Documentation => { 280 self.documentation.extend(UnitParseUtil::parse_url(val)?) 281 } 282 BaseUnitAttr::Requires => { 283 let units = val.split_whitespace().collect::<Vec<&str>>(); 284 //TODO:目前先加入requires列表,可能会出现循环依赖问题,后续应解决循环依赖问题 285 for unit_path in units { 286 self.requires 287 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 288 } 289 } 290 BaseUnitAttr::Wants => { 291 let units = val.split_whitespace().collect::<Vec<&str>>(); 292 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 293 for unit_path in units { 294 self.wants 295 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 296 } 297 } 298 BaseUnitAttr::After => { 299 let units = val.split_whitespace().collect::<Vec<&str>>(); 300 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 301 for unit_path in units { 302 self.after 303 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 304 } 305 } 306 BaseUnitAttr::Before => { 307 let units = val.split_whitespace().collect::<Vec<&str>>(); 308 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 309 for unit_path in units { 310 self.before 311 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 312 } 313 } 314 BaseUnitAttr::BindsTo => { 315 let units = val.split_whitespace().collect::<Vec<&str>>(); 316 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 317 for unit_path in units { 318 self.binds_to 319 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 320 } 321 } 322 BaseUnitAttr::PartOf => { 323 let units = val.split_whitespace().collect::<Vec<&str>>(); 324 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 325 for unit_path in units { 326 self.part_of 327 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 328 } 329 } 330 BaseUnitAttr::OnFailure => { 331 let units = val.split_whitespace().collect::<Vec<&str>>(); 332 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 333 for unit_path in units { 334 self.on_failure 335 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 336 } 337 } 338 BaseUnitAttr::Conflicts => { 339 let units = val.split_whitespace().collect::<Vec<&str>>(); 340 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 341 for unit_path in units { 342 let unit = UnitParseUtil::parse_unit_no_type(unit_path)?; 343 self.conflicts.push(unit); 344 } 345 } 346 } 347 return Ok(()); 348 } 349 350 pub fn description(&self) -> &str { 351 &self.description 352 } 353 354 pub fn documentation(&self) -> &[Url] { 355 &self.documentation 356 } 357 358 pub fn requires(&self) -> &[usize] { 359 &self.requires 360 } 361 362 pub fn wants(&self) -> &[usize] { 363 &self.wants 364 } 365 366 pub fn after(&self) -> &[usize] { 367 &self.after 368 } 369 370 pub fn before(&self) -> &[usize] { 371 &self.before 372 } 373 374 pub fn binds_to(&self) -> &[usize] { 375 &self.binds_to 376 } 377 378 pub fn part_of(&self) -> &[usize] { 379 &self.part_of 380 } 381 382 pub fn on_failure(&self) -> &[usize] { 383 &self.on_failure 384 } 385 386 pub fn conflicts(&self) -> &[usize] { 387 &self.conflicts 388 } 389 390 pub fn be_binded_by(&self) -> &[usize] { 391 &self.be_binded_by 392 } 393 394 pub fn push_be_binded_by(&mut self, id: usize) { 395 if !self.be_binded_by.contains(&id) { 396 self.be_binded_by.push(id); 397 } 398 } 399 400 pub fn push_after_unit(&mut self, id: usize) { 401 if !self.after.contains(&id) { 402 self.after.push(id); 403 } 404 } 405 } 406 407 //对应Unit文件的Install段 408 #[derive(Debug, Clone)] 409 pub struct InstallPart { 410 wanted_by: Vec<usize>, 411 requires_by: Vec<usize>, 412 also: Vec<usize>, 413 alias: String, 414 } 415 416 impl Default for InstallPart { 417 fn default() -> Self { 418 InstallPart { 419 wanted_by: Vec::new(), 420 requires_by: Vec::new(), 421 also: Vec::new(), 422 alias: String::new(), 423 } 424 } 425 } 426 427 impl InstallPart { 428 pub fn set_attr(&mut self, attr: &InstallUnitAttr, val: &str) -> Result<(), ParseError> { 429 match attr { 430 InstallUnitAttr::RequiredBy => { 431 let units = val.split_whitespace().collect::<Vec<&str>>(); 432 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 433 for unit_path in units { 434 let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?; 435 self.requires_by.push(unit); 436 } 437 } 438 InstallUnitAttr::Also => { 439 let units = val.split_whitespace().collect::<Vec<&str>>(); 440 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 441 for unit_path in units { 442 let unit = UnitParseUtil::parse_unit_no_type(unit_path)?; 443 self.also.push(unit); 444 } 445 } 446 InstallUnitAttr::WantedBy => { 447 let units = val.split_whitespace().collect::<Vec<&str>>(); 448 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 449 for unit_path in units { 450 let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?; 451 self.wanted_by.push(unit); 452 } 453 } 454 InstallUnitAttr::Alias => { 455 self.alias = String::from(val); 456 } 457 InstallUnitAttr::None => { 458 return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0)); 459 } 460 } 461 return Ok(()); 462 } 463 464 pub fn wanted_by(&self) -> &[usize] { 465 &self.wanted_by 466 } 467 468 pub fn requires_by(&self) -> &[usize] { 469 &self.requires_by 470 } 471 472 pub fn also(&self) -> &[usize] { 473 &self.also 474 } 475 476 pub fn alias(&self) -> &str { 477 &self.alias 478 } 479 } 480 //对应Unit文件的各种属性 481 pub enum BaseUnitAttr { 482 None, 483 484 //Unit段 485 //描述该Unit文件的信息 486 Description, 487 //指定服务文档 488 Documentation, 489 //依赖的其它 Unit 列表 490 Requires, 491 //这个 Unit 启动时,触发启动列出的每个 Unit 模块,而不去考虑这些模板启动是否成功 492 Wants, 493 //后面列出的所有模块全部启动完成以后,才会启动当前的服务 494 After, 495 //在启动指定的任务一个模块之间,都会首先确证当前服务已经运行 496 Before, 497 //这些Unit启动失败时该任务失败,都成功时该任务成功,在这些模板中有任意一个出现意外结束或重启时,这个服务也会跟着终止或重启 498 BindsTo, 499 //仅在列出的任务模块失败或重启时,终止或重启当前服务,而不会随列出模板的启动而启动 500 PartOf, 501 //当这个模板启动失败时,就会自动启动列出的每个模块 502 OnFailure, 503 //与这个模块有冲突的模块,如果列出的模块中有已经在运行的,这个服务就不能启动,反之亦然 504 Conflicts, 505 } 506 507 pub enum InstallUnitAttr { 508 None, 509 //Install段 510 //依赖当前服务的模块。当前 Unit 激活时(enable)符号链接会放入 /etc/systemd/system 目录下面以 <Target 名> + .wants 后缀构成的子目录中 511 WantedBy, 512 //依赖当前服务的模块。当前 Unit 激活时(enable)符号链接会放入 /etc/systemd/system 目录下面以 <Target 名> + .required 后缀构成的子目录中 513 RequiredBy, 514 //当前 Unit enable/disable 时,同时 enable/disable 的其他 Unit 515 Also, 516 //别名 517 Alias, 518 } 519