mod.rs 13 KB

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