fork.rs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. use alloc::vec::Vec;
  2. use core::{intrinsics::unlikely, sync::atomic::Ordering};
  3. use alloc::{string::ToString, sync::Arc};
  4. use log::error;
  5. use system_error::SystemError;
  6. use crate::{
  7. arch::{interrupt::TrapFrame, ipc::signal::Signal},
  8. filesystem::procfs::procfs_register_pid,
  9. ipc::signal::flush_signal_handlers,
  10. libs::rwlock::RwLock,
  11. mm::VirtAddr,
  12. namespaces::{create_new_namespaces, namespace::USER_NS, pid_namespace::PidStrcut},
  13. process::ProcessFlags,
  14. sched::{sched_cgroup_fork, sched_fork},
  15. smp::core::smp_get_processor_id,
  16. syscall::user_access::UserBufferWriter,
  17. };
  18. use super::{
  19. kthread::{KernelThreadPcbPrivate, WorkerPrivate},
  20. KernelStack, Pgid, Pid, ProcessControlBlock, ProcessManager, Sid,
  21. };
  22. const MAX_PID_NS_LEVEL: usize = 32;
  23. bitflags! {
  24. /// 进程克隆标志
  25. pub struct CloneFlags: u64 {
  26. /// 在进程间共享虚拟内存空间
  27. const CLONE_VM = 0x00000100;
  28. /// 在进程间共享文件系统信息
  29. const CLONE_FS = 0x00000200;
  30. /// 共享打开的文件
  31. const CLONE_FILES = 0x00000400;
  32. /// 克隆时,与父进程共享信号处理结构体
  33. const CLONE_SIGHAND = 0x00000800;
  34. /// 返回进程的文件描述符
  35. const CLONE_PIDFD = 0x00001000;
  36. /// 使克隆对象成为父进程的跟踪对象
  37. const CLONE_PTRACE = 0x00002000;
  38. /// 在执行 exec() 或 _exit() 之前挂起父进程的执行
  39. const CLONE_VFORK = 0x00004000;
  40. /// 使克隆对象的父进程为调用进程的父进程
  41. const CLONE_PARENT = 0x00008000;
  42. /// 拷贝线程
  43. const CLONE_THREAD = 0x00010000;
  44. /// 创建一个新的命名空间,其中包含独立的文件系统挂载点层次结构。
  45. const CLONE_NEWNS = 0x00020000;
  46. /// 与父进程共享 System V 信号量。
  47. const CLONE_SYSVSEM = 0x00040000;
  48. /// 设置其线程本地存储
  49. const CLONE_SETTLS = 0x00080000;
  50. /// 设置partent_tid地址为子进程线程 ID
  51. const CLONE_PARENT_SETTID = 0x00100000;
  52. /// 在子进程中设置一个清除线程 ID 的用户空间地址
  53. const CLONE_CHILD_CLEARTID = 0x00200000;
  54. /// 创建一个新线程,将其设置为分离状态
  55. const CLONE_DETACHED = 0x00400000;
  56. /// 使其在创建者进程或线程视角下成为无法跟踪的。
  57. const CLONE_UNTRACED = 0x00800000;
  58. /// 设置其子进程线程 ID
  59. const CLONE_CHILD_SETTID = 0x01000000;
  60. /// 将其放置在一个新的 cgroup 命名空间中
  61. const CLONE_NEWCGROUP = 0x02000000;
  62. /// 将其放置在一个新的 UTS 命名空间中
  63. const CLONE_NEWUTS = 0x04000000;
  64. /// 将其放置在一个新的 IPC 命名空间中
  65. const CLONE_NEWIPC = 0x08000000;
  66. /// 将其放置在一个新的用户命名空间中
  67. const CLONE_NEWUSER = 0x10000000;
  68. /// 将其放置在一个新的 PID 命名空间中
  69. const CLONE_NEWPID = 0x20000000;
  70. /// 将其放置在一个新的网络命名空间中
  71. const CLONE_NEWNET = 0x40000000;
  72. /// 在新的 I/O 上下文中运行它
  73. const CLONE_IO = 0x80000000;
  74. /// 克隆时,将原本被设置为SIG_IGNORE的信号,设置回SIG_DEFAULT
  75. const CLONE_CLEAR_SIGHAND = 0x100000000;
  76. }
  77. }
  78. /// ## clone与clone3系统调用的参数载体
  79. ///
  80. /// 因为这两个系统调用的参数很多,所以有这样一个载体更灵活
  81. ///
  82. /// 仅仅作为参数传递
  83. #[allow(dead_code)]
  84. #[derive(Debug, Clone)]
  85. pub struct KernelCloneArgs {
  86. pub flags: CloneFlags,
  87. // 下列属性均来自用户空间
  88. pub pidfd: VirtAddr,
  89. pub child_tid: VirtAddr,
  90. pub parent_tid: VirtAddr,
  91. pub set_tid: Vec<usize>,
  92. /// 进程退出时发送的信号
  93. pub exit_signal: Signal,
  94. pub stack: usize,
  95. // clone3用到
  96. pub stack_size: usize,
  97. pub tls: usize,
  98. pub set_tid_size: usize,
  99. pub cgroup: i32,
  100. pub io_thread: bool,
  101. pub kthread: bool,
  102. pub idle: bool,
  103. pub func: VirtAddr,
  104. pub fn_arg: VirtAddr,
  105. // cgrp 和 cset?
  106. }
  107. impl KernelCloneArgs {
  108. pub fn new() -> Self {
  109. let null_addr = VirtAddr::new(0);
  110. Self {
  111. flags: unsafe { CloneFlags::from_bits_unchecked(0) },
  112. pidfd: null_addr,
  113. child_tid: null_addr,
  114. parent_tid: null_addr,
  115. set_tid: Vec::with_capacity(MAX_PID_NS_LEVEL),
  116. exit_signal: Signal::SIGCHLD,
  117. stack: 0,
  118. stack_size: 0,
  119. tls: 0,
  120. set_tid_size: 0,
  121. cgroup: 0,
  122. io_thread: false,
  123. kthread: false,
  124. idle: false,
  125. func: null_addr,
  126. fn_arg: null_addr,
  127. }
  128. }
  129. }
  130. impl ProcessManager {
  131. /// 创建一个新进程
  132. ///
  133. /// ## 参数
  134. ///
  135. /// - `current_trapframe`: 当前进程的trapframe
  136. /// - `clone_flags`: 进程克隆标志
  137. ///
  138. /// ## 返回值
  139. ///
  140. /// - 成功:返回新进程的pid
  141. /// - 失败:返回Err(SystemError),fork失败的话,子线程不会执行。
  142. ///
  143. /// ## Safety
  144. ///
  145. /// - fork失败的话,子线程不会执行。
  146. pub fn fork(
  147. current_trapframe: &TrapFrame,
  148. clone_flags: CloneFlags,
  149. ) -> Result<Pid, SystemError> {
  150. let current_pcb = ProcessManager::current_pcb();
  151. let new_kstack: KernelStack = KernelStack::new()?;
  152. let name = current_pcb.basic().name().to_string();
  153. let pcb = ProcessControlBlock::new(name, new_kstack);
  154. let mut args = KernelCloneArgs::new();
  155. args.flags = clone_flags;
  156. args.exit_signal = Signal::SIGCHLD;
  157. Self::copy_process(&current_pcb, &pcb, args, current_trapframe).map_err(|e| {
  158. error!(
  159. "fork: Failed to copy process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  160. current_pcb.pid(),
  161. pcb.pid(),
  162. e
  163. );
  164. e
  165. })?;
  166. // 向procfs注册进程
  167. procfs_register_pid(pcb.pid()).unwrap_or_else(|e| {
  168. panic!(
  169. "fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}",
  170. pcb.pid(),
  171. e
  172. )
  173. });
  174. pcb.sched_info().set_on_cpu(Some(smp_get_processor_id()));
  175. ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
  176. panic!(
  177. "fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}",
  178. pcb.pid(),
  179. e
  180. )
  181. });
  182. return Ok(pcb.pid());
  183. }
  184. fn copy_flags(
  185. clone_flags: &CloneFlags,
  186. new_pcb: &Arc<ProcessControlBlock>,
  187. ) -> Result<(), SystemError> {
  188. if clone_flags.contains(CloneFlags::CLONE_VM) {
  189. new_pcb.flags().insert(ProcessFlags::VFORK);
  190. }
  191. *new_pcb.flags.get_mut() = *ProcessManager::current_pcb().flags();
  192. return Ok(());
  193. }
  194. /// 拷贝进程的地址空间
  195. ///
  196. /// ## 参数
  197. ///
  198. /// - `clone_vm`: 是否与父进程共享地址空间。true表示共享
  199. /// - `new_pcb`: 新进程的pcb
  200. ///
  201. /// ## 返回值
  202. ///
  203. /// - 成功:返回Ok(())
  204. /// - 失败:返回Err(SystemError)
  205. ///
  206. /// ## Panic
  207. ///
  208. /// - 如果当前进程没有用户地址空间,则panic
  209. #[inline(never)]
  210. fn copy_mm(
  211. clone_flags: &CloneFlags,
  212. current_pcb: &Arc<ProcessControlBlock>,
  213. new_pcb: &Arc<ProcessControlBlock>,
  214. ) -> Result<(), SystemError> {
  215. let old_address_space = current_pcb.basic().user_vm().unwrap_or_else(|| {
  216. panic!(
  217. "copy_mm: Failed to get address space of current process, current pid: [{:?}]",
  218. current_pcb.pid()
  219. )
  220. });
  221. if clone_flags.contains(CloneFlags::CLONE_VM) {
  222. unsafe { new_pcb.basic_mut().set_user_vm(Some(old_address_space)) };
  223. return Ok(());
  224. }
  225. let new_address_space = old_address_space.write_irqsave().try_clone().unwrap_or_else(|e| {
  226. panic!(
  227. "copy_mm: Failed to clone address space of current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  228. current_pcb.pid(), new_pcb.pid(), e
  229. )
  230. });
  231. unsafe { new_pcb.basic_mut().set_user_vm(Some(new_address_space)) };
  232. return Ok(());
  233. }
  234. #[inline(never)]
  235. fn copy_namespaces(
  236. clone_flags: &CloneFlags,
  237. current_pcb: &Arc<ProcessControlBlock>,
  238. new_pcb: &Arc<ProcessControlBlock>,
  239. ) -> Result<(), SystemError> {
  240. if !clone_flags.contains(CloneFlags::CLONE_NEWNS)
  241. && !clone_flags.contains(CloneFlags::CLONE_NEWUTS)
  242. && !clone_flags.contains(CloneFlags::CLONE_NEWIPC)
  243. && !clone_flags.contains(CloneFlags::CLONE_NEWPID)
  244. && !clone_flags.contains(CloneFlags::CLONE_NEWNET)
  245. && !clone_flags.contains(CloneFlags::CLONE_NEWCGROUP)
  246. {
  247. new_pcb.set_nsproxy(current_pcb.get_nsproxy().read().clone());
  248. return Ok(());
  249. }
  250. if clone_flags.contains(CloneFlags::CLONE_NEWIPC)
  251. && clone_flags.contains(CloneFlags::CLONE_SYSVSEM)
  252. {
  253. return Err(SystemError::EINVAL);
  254. }
  255. let new_nsproxy = create_new_namespaces(clone_flags.bits(), current_pcb, USER_NS.clone())?;
  256. *new_pcb.nsproxy.write() = new_nsproxy;
  257. Ok(())
  258. }
  259. #[inline(never)]
  260. fn copy_files(
  261. clone_flags: &CloneFlags,
  262. current_pcb: &Arc<ProcessControlBlock>,
  263. new_pcb: &Arc<ProcessControlBlock>,
  264. ) -> Result<(), SystemError> {
  265. // 如果不共享文件描述符表,则拷贝文件描述符表
  266. if !clone_flags.contains(CloneFlags::CLONE_FILES) {
  267. let new_fd_table = current_pcb.basic().fd_table().unwrap().read().clone();
  268. let new_fd_table = Arc::new(RwLock::new(new_fd_table));
  269. new_pcb.basic_mut().set_fd_table(Some(new_fd_table));
  270. } else {
  271. // 如果共享文件描述符表,则直接拷贝指针
  272. new_pcb
  273. .basic_mut()
  274. .set_fd_table(current_pcb.basic().fd_table().clone());
  275. }
  276. return Ok(());
  277. }
  278. #[allow(dead_code)]
  279. fn copy_sighand(
  280. clone_flags: &CloneFlags,
  281. current_pcb: &Arc<ProcessControlBlock>,
  282. new_pcb: &Arc<ProcessControlBlock>,
  283. ) -> Result<(), SystemError> {
  284. // todo SignalStruct结构需要更改,属于线程组逻辑
  285. if clone_flags.contains(CloneFlags::CLONE_SIGHAND) {
  286. // log::debug!("copy_sighand: CLONE_SIGHAND");
  287. current_pcb
  288. .sig_struct_irqsave()
  289. .cnt
  290. .fetch_add(1, Ordering::SeqCst);
  291. return Ok(());
  292. }
  293. // log::debug!("Just copy sighand");
  294. new_pcb.sig_struct_irqsave().handlers = current_pcb.sig_struct_irqsave().handlers;
  295. if clone_flags.contains(CloneFlags::CLONE_CLEAR_SIGHAND) {
  296. flush_signal_handlers(new_pcb.clone(), false);
  297. }
  298. return Ok(());
  299. }
  300. /// 拷贝进程信息
  301. ///
  302. /// ## panic:
  303. /// 某一步拷贝失败时会引发panic
  304. /// 例如:copy_mm等失败时会触发panic
  305. ///
  306. /// ## 参数
  307. ///
  308. /// - clone_flags 标志位
  309. /// - current_pcb 拷贝源pcb
  310. /// - pcb 目标pcb
  311. ///
  312. /// ## return
  313. /// - 发生错误时返回Err(SystemError)
  314. #[inline(never)]
  315. pub fn copy_process(
  316. current_pcb: &Arc<ProcessControlBlock>,
  317. pcb: &Arc<ProcessControlBlock>,
  318. clone_args: KernelCloneArgs,
  319. current_trapframe: &TrapFrame,
  320. ) -> Result<(), SystemError> {
  321. // log::debug!("fork: clone_flags: {:?}", clone_args.flags);
  322. let clone_flags = clone_args.flags;
  323. // 不允许与不同namespace的进程共享根目录
  324. if (clone_flags & (CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_FS)
  325. == (CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_FS))
  326. || (clone_flags & (CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_FS))
  327. == (CloneFlags::CLONE_NEWUSER | CloneFlags::CLONE_FS)
  328. {
  329. return Err(SystemError::EINVAL);
  330. }
  331. // 线程组必须共享信号,分离线程只能在线程组内启动。
  332. if clone_flags.contains(CloneFlags::CLONE_THREAD)
  333. && !clone_flags.contains(CloneFlags::CLONE_SIGHAND)
  334. {
  335. return Err(SystemError::EINVAL);
  336. }
  337. // 共享信号处理器意味着共享vm。
  338. // 线程组也意味着共享vm。阻止这种情况可以简化其他代码。
  339. if clone_flags.contains(CloneFlags::CLONE_SIGHAND)
  340. && !clone_flags.contains(CloneFlags::CLONE_VM)
  341. {
  342. return Err(SystemError::EINVAL);
  343. }
  344. // TODO: 处理CLONE_PARENT 与 SIGNAL_UNKILLABLE的情况
  345. // 如果新进程使用不同的 pid 或 namespace,
  346. // 则不允许它与分叉任务共享线程组。
  347. if clone_flags.contains(CloneFlags::CLONE_THREAD)
  348. && !((clone_flags & (CloneFlags::CLONE_NEWUSER | CloneFlags::CLONE_NEWPID)).is_empty())
  349. {
  350. return Err(SystemError::EINVAL);
  351. // TODO: 判断新进程与当前进程namespace是否相同,不同则返回错误
  352. }
  353. // 如果新进程将处于不同的time namespace,
  354. // 则不能让它共享vm或线程组。
  355. if !((clone_flags & (CloneFlags::CLONE_THREAD | CloneFlags::CLONE_VM)).is_empty()) {
  356. // TODO: 判断time namespace,不同则返回错误
  357. }
  358. if clone_flags.contains(CloneFlags::CLONE_PIDFD)
  359. && !((clone_flags & (CloneFlags::CLONE_DETACHED | CloneFlags::CLONE_THREAD)).is_empty())
  360. {
  361. return Err(SystemError::EINVAL);
  362. }
  363. // TODO: 克隆前应该锁信号处理,等待克隆完成后再处理
  364. // 克隆架构相关
  365. let guard = current_pcb.arch_info_irqsave();
  366. unsafe { pcb.arch_info().clone_from(&guard) };
  367. drop(guard);
  368. // 为内核线程设置WorkerPrivate
  369. if current_pcb.flags().contains(ProcessFlags::KTHREAD) {
  370. *pcb.worker_private() =
  371. Some(WorkerPrivate::KernelThread(KernelThreadPcbPrivate::new()));
  372. }
  373. // 设置clear_child_tid,在线程结束时将其置0以通知父进程
  374. if clone_flags.contains(CloneFlags::CLONE_CHILD_CLEARTID) {
  375. pcb.thread.write_irqsave().clear_child_tid = Some(clone_args.child_tid);
  376. }
  377. // 设置child_tid,意味着子线程能够知道自己的id
  378. if clone_flags.contains(CloneFlags::CLONE_CHILD_SETTID) {
  379. pcb.thread.write_irqsave().set_child_tid = Some(clone_args.child_tid);
  380. }
  381. // 将子进程/线程的id存储在用户态传进的地址中
  382. if clone_flags.contains(CloneFlags::CLONE_PARENT_SETTID) {
  383. let mut writer = UserBufferWriter::new(
  384. clone_args.parent_tid.data() as *mut i32,
  385. core::mem::size_of::<i32>(),
  386. true,
  387. )?;
  388. writer.copy_one_to_user(&(pcb.pid().0 as i32), 0)?;
  389. }
  390. sched_fork(pcb).unwrap_or_else(|e| {
  391. panic!(
  392. "fork: Failed to set sched info from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  393. current_pcb.pid(), pcb.pid(), e
  394. )
  395. });
  396. // 拷贝标志位
  397. Self::copy_flags(&clone_flags, pcb).unwrap_or_else(|e| {
  398. panic!(
  399. "fork: Failed to copy flags from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  400. current_pcb.pid(), pcb.pid(), e
  401. )
  402. });
  403. // 拷贝用户地址空间
  404. Self::copy_mm(&clone_flags, current_pcb, pcb).unwrap_or_else(|e| {
  405. panic!(
  406. "fork: Failed to copy mm from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  407. current_pcb.pid(), pcb.pid(), e
  408. )
  409. });
  410. Self::copy_namespaces(&clone_flags, current_pcb, pcb).unwrap_or_else(|e|{
  411. panic!("fork: Failed to copy namespace form current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  412. current_pcb.pid(), pcb.pid(), e)
  413. });
  414. // 拷贝文件描述符表
  415. Self::copy_files(&clone_flags, current_pcb, pcb).unwrap_or_else(|e| {
  416. panic!(
  417. "fork: Failed to copy files from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  418. current_pcb.pid(), pcb.pid(), e
  419. )
  420. });
  421. // 拷贝信号相关数据
  422. Self::copy_sighand(&clone_flags, current_pcb, pcb).unwrap_or_else(|e| {
  423. panic!(
  424. "fork: Failed to copy sighand from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  425. current_pcb.pid(), pcb.pid(), e
  426. )
  427. });
  428. // 拷贝线程
  429. Self::copy_thread(current_pcb, pcb, &clone_args, current_trapframe).unwrap_or_else(|e| {
  430. panic!(
  431. "fork: Failed to copy thread from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  432. current_pcb.pid(), pcb.pid(), e
  433. )
  434. });
  435. if current_pcb.pid() != Pid(0) {
  436. let new_pid = PidStrcut::alloc_pid(
  437. pcb.get_nsproxy().read().pid_namespace.clone(), // 获取命名空间
  438. clone_args.set_tid.clone(),
  439. )?;
  440. *pcb.thread_pid.write() = new_pid;
  441. }
  442. // log::debug!("fork: clone_flags: {:?}", clone_flags);
  443. // 设置线程组id、组长
  444. if clone_flags.contains(CloneFlags::CLONE_THREAD) {
  445. pcb.thread.write_irqsave().group_leader =
  446. current_pcb.thread.read_irqsave().group_leader.clone();
  447. unsafe {
  448. let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
  449. (*ptr).tgid = current_pcb.tgid;
  450. }
  451. } else {
  452. pcb.thread.write_irqsave().group_leader = Arc::downgrade(pcb);
  453. let ptr: *mut ProcessControlBlock =
  454. pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
  455. unsafe {
  456. (*ptr).tgid = pcb.pid;
  457. }
  458. }
  459. // CLONE_PARENT re-uses the old parent
  460. if !((clone_flags & (CloneFlags::CLONE_PARENT | CloneFlags::CLONE_THREAD)).is_empty()) {
  461. *pcb.real_parent_pcb.write_irqsave() =
  462. current_pcb.real_parent_pcb.read_irqsave().clone();
  463. if clone_flags.contains(CloneFlags::CLONE_THREAD) {
  464. pcb.exit_signal.store(Signal::INVALID, Ordering::SeqCst);
  465. } else {
  466. let leader = current_pcb.thread.read_irqsave().group_leader();
  467. if unlikely(leader.is_none()) {
  468. panic!(
  469. "fork: Failed to get leader of current process, current pid: [{:?}]",
  470. current_pcb.pid()
  471. );
  472. }
  473. pcb.exit_signal.store(
  474. leader.unwrap().exit_signal.load(Ordering::SeqCst),
  475. Ordering::SeqCst,
  476. );
  477. }
  478. } else {
  479. // 新创建的进程,设置其父进程为当前进程
  480. *pcb.real_parent_pcb.write_irqsave() = Arc::downgrade(current_pcb);
  481. pcb.exit_signal
  482. .store(clone_args.exit_signal, Ordering::SeqCst);
  483. }
  484. // todo: 增加线程组相关的逻辑。 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/fork.c#2437
  485. Self::copy_group(current_pcb, pcb).unwrap_or_else(|e| {
  486. panic!(
  487. "fork: Failed to set the process group for the new pcb, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  488. current_pcb.pid(), pcb.pid(), e
  489. )
  490. });
  491. sched_cgroup_fork(pcb);
  492. Ok(())
  493. }
  494. /// 拷贝进程组信息
  495. ///
  496. /// ## 参数
  497. ///
  498. /// `parent_pcb` - 父进程
  499. /// `child_pcb` - 子进程
  500. /// ## 返回值
  501. ///
  502. /// 无
  503. fn copy_group(
  504. parent_pcb: &Arc<ProcessControlBlock>,
  505. child_pcb: &Arc<ProcessControlBlock>,
  506. ) -> Result<(), SystemError> {
  507. if parent_pcb.process_group().is_none() && parent_pcb.pid() == Pid(0) {
  508. return Ok(());
  509. }
  510. let pg = parent_pcb.process_group().unwrap();
  511. let mut pg_inner = pg.process_group_inner.lock();
  512. let mut children_writelock = parent_pcb.children.write();
  513. children_writelock.push(child_pcb.pid());
  514. pg_inner
  515. .processes
  516. .insert(child_pcb.pid(), child_pcb.clone());
  517. // 检查是否已经存在pgid和sid
  518. let pgid = Pgid::new(child_pcb.pid().0);
  519. let sid = Sid::new(pgid.into());
  520. if ProcessManager::find_process_group(pgid).is_some() {
  521. ProcessManager::remove_process_group(pgid);
  522. }
  523. if ProcessManager::find_session(sid).is_some() {
  524. ProcessManager::remove_session(sid);
  525. }
  526. child_pcb.set_process_group(&pg);
  527. Ok(())
  528. }
  529. }