fork.rs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  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, signal_types::SignalFlags},
  10. libs::rwlock::RwLock,
  11. mm::VirtAddr,
  12. process::ProcessFlags,
  13. sched::{sched_cgroup_fork, sched_fork},
  14. smp::core::smp_get_processor_id,
  15. syscall::user_access::UserBufferWriter,
  16. };
  17. use super::{
  18. alloc_pid,
  19. kthread::{KernelThreadPcbPrivate, WorkerPrivate},
  20. pid::{Pid, PidType},
  21. KernelStack, ProcessControlBlock, ProcessManager, RawPid,
  22. };
  23. const MAX_PID_NS_LEVEL: usize = 32;
  24. bitflags! {
  25. /// 进程克隆标志
  26. pub struct CloneFlags: u64 {
  27. const CLONE_NEWTIME = 0x00000080;
  28. /// 在进程间共享虚拟内存空间
  29. const CLONE_VM = 0x00000100;
  30. /// 在进程间共享文件系统信息
  31. const CLONE_FS = 0x00000200;
  32. /// 共享打开的文件
  33. const CLONE_FILES = 0x00000400;
  34. /// 克隆时,与父进程共享信号处理结构体
  35. const CLONE_SIGHAND = 0x00000800;
  36. /// 返回进程的文件描述符
  37. const CLONE_PIDFD = 0x00001000;
  38. /// 使克隆对象成为父进程的跟踪对象
  39. const CLONE_PTRACE = 0x00002000;
  40. /// 在执行 exec() 或 _exit() 之前挂起父进程的执行
  41. const CLONE_VFORK = 0x00004000;
  42. /// 使克隆对象的父进程为调用进程的父进程
  43. const CLONE_PARENT = 0x00008000;
  44. /// 拷贝线程
  45. const CLONE_THREAD = 0x00010000;
  46. /// 创建一个新的命名空间,其中包含独立的文件系统挂载点层次结构。
  47. const CLONE_NEWNS = 0x00020000;
  48. /// 与父进程共享 System V 信号量。
  49. const CLONE_SYSVSEM = 0x00040000;
  50. /// 设置其线程本地存储
  51. const CLONE_SETTLS = 0x00080000;
  52. /// 设置partent_tid地址为子进程线程 ID
  53. const CLONE_PARENT_SETTID = 0x00100000;
  54. /// 在子进程中设置一个清除线程 ID 的用户空间地址
  55. const CLONE_CHILD_CLEARTID = 0x00200000;
  56. /// 创建一个新线程,将其设置为分离状态
  57. const CLONE_DETACHED = 0x00400000;
  58. /// 使其在创建者进程或线程视角下成为无法跟踪的。
  59. const CLONE_UNTRACED = 0x00800000;
  60. /// 设置其子进程线程 ID
  61. const CLONE_CHILD_SETTID = 0x01000000;
  62. /// 将其放置在一个新的 cgroup 命名空间中
  63. const CLONE_NEWCGROUP = 0x02000000;
  64. /// 将其放置在一个新的 UTS 命名空间中
  65. const CLONE_NEWUTS = 0x04000000;
  66. /// 将其放置在一个新的 IPC 命名空间中
  67. const CLONE_NEWIPC = 0x08000000;
  68. /// 将其放置在一个新的用户命名空间中
  69. const CLONE_NEWUSER = 0x10000000;
  70. /// 将其放置在一个新的 PID 命名空间中
  71. const CLONE_NEWPID = 0x20000000;
  72. /// 将其放置在一个新的网络命名空间中
  73. const CLONE_NEWNET = 0x40000000;
  74. /// 在新的 I/O 上下文中运行它
  75. const CLONE_IO = 0x80000000;
  76. /// 克隆时,将原本被设置为SIG_IGNORE的信号,设置回SIG_DEFAULT
  77. const CLONE_CLEAR_SIGHAND = 0x100000000;
  78. }
  79. }
  80. /// ## clone与clone3系统调用的参数载体
  81. ///
  82. /// 因为这两个系统调用的参数很多,所以有这样一个载体更灵活
  83. ///
  84. /// 仅仅作为参数传递
  85. #[allow(dead_code)]
  86. #[derive(Debug, Clone)]
  87. pub struct KernelCloneArgs {
  88. pub flags: CloneFlags,
  89. // 下列属性均来自用户空间
  90. pub pidfd: VirtAddr,
  91. pub child_tid: VirtAddr,
  92. pub parent_tid: VirtAddr,
  93. pub set_tid: Vec<usize>,
  94. /// 进程退出时发送的信号
  95. pub exit_signal: Signal,
  96. pub stack: usize,
  97. // clone3用到
  98. pub stack_size: usize,
  99. pub tls: usize,
  100. pub set_tid_size: usize,
  101. pub cgroup: i32,
  102. pub io_thread: bool,
  103. pub kthread: bool,
  104. pub idle: bool,
  105. pub func: VirtAddr,
  106. pub fn_arg: VirtAddr,
  107. // cgrp 和 cset?
  108. }
  109. impl KernelCloneArgs {
  110. pub fn new() -> Self {
  111. let null_addr = VirtAddr::new(0);
  112. Self {
  113. flags: unsafe { CloneFlags::from_bits_unchecked(0) },
  114. pidfd: null_addr,
  115. child_tid: null_addr,
  116. parent_tid: null_addr,
  117. set_tid: Vec::with_capacity(MAX_PID_NS_LEVEL),
  118. exit_signal: Signal::SIGCHLD,
  119. stack: 0,
  120. stack_size: 0,
  121. tls: 0,
  122. set_tid_size: 0,
  123. cgroup: 0,
  124. io_thread: false,
  125. kthread: false,
  126. idle: false,
  127. func: null_addr,
  128. fn_arg: null_addr,
  129. }
  130. }
  131. }
  132. impl ProcessManager {
  133. /// 创建一个新进程
  134. ///
  135. /// ## 参数
  136. ///
  137. /// - `current_trapframe`: 当前进程的trapframe
  138. /// - `clone_flags`: 进程克隆标志
  139. ///
  140. /// ## 返回值
  141. ///
  142. /// - 成功:返回新进程的pid
  143. /// - 失败:返回Err(SystemError),fork失败的话,子线程不会执行。
  144. ///
  145. /// ## Safety
  146. ///
  147. /// - fork失败的话,子线程不会执行。
  148. pub fn fork(
  149. current_trapframe: &TrapFrame,
  150. clone_flags: CloneFlags,
  151. ) -> Result<RawPid, SystemError> {
  152. let current_pcb = ProcessManager::current_pcb();
  153. let new_kstack: KernelStack = KernelStack::new()?;
  154. let name = current_pcb.basic().name().to_string();
  155. let pcb = ProcessControlBlock::new(name, new_kstack);
  156. let mut args = KernelCloneArgs::new();
  157. args.flags = clone_flags;
  158. args.exit_signal = Signal::SIGCHLD;
  159. Self::copy_process(&current_pcb, &pcb, args, current_trapframe).map_err(|e| {
  160. error!(
  161. "fork: Failed to copy process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  162. current_pcb.raw_pid(),
  163. pcb.raw_pid(),
  164. e
  165. );
  166. e
  167. })?;
  168. // if pcb.raw_pid().data() > 1 {
  169. // log::debug!(
  170. // "fork done, pid: {}, pgid: {:?}, tgid: {:?}, sid: {}",
  171. // pcb.raw_pid(),
  172. // pcb.task_pgrp().map(|x| x.pid_vnr().data()),
  173. // pcb.task_tgid_vnr(),
  174. // pcb.task_session().map_or(0, |s| s.pid_vnr().data())
  175. // );
  176. // }
  177. // 向procfs注册进程
  178. procfs_register_pid(pcb.raw_pid()).unwrap_or_else(|e| {
  179. panic!(
  180. "fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}",
  181. pcb.raw_pid(),
  182. e
  183. )
  184. });
  185. pcb.sched_info().set_on_cpu(Some(smp_get_processor_id()));
  186. ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
  187. panic!(
  188. "fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}",
  189. pcb.raw_pid(),
  190. e
  191. )
  192. });
  193. if ProcessManager::current_pid().data() == 0 {
  194. return Ok(pcb.raw_pid());
  195. }
  196. return Ok(pcb.pid().pid_vnr());
  197. }
  198. fn copy_flags(
  199. clone_flags: &CloneFlags,
  200. new_pcb: &Arc<ProcessControlBlock>,
  201. ) -> Result<(), SystemError> {
  202. if clone_flags.contains(CloneFlags::CLONE_VM) {
  203. new_pcb.flags().insert(ProcessFlags::VFORK);
  204. }
  205. *new_pcb.flags.get_mut() = *ProcessManager::current_pcb().flags();
  206. return Ok(());
  207. }
  208. /// 拷贝进程的地址空间
  209. ///
  210. /// ## 参数
  211. ///
  212. /// - `clone_vm`: 是否与父进程共享地址空间。true表示共享
  213. /// - `new_pcb`: 新进程的pcb
  214. ///
  215. /// ## 返回值
  216. ///
  217. /// - 成功:返回Ok(())
  218. /// - 失败:返回Err(SystemError)
  219. ///
  220. /// ## Panic
  221. ///
  222. /// - 如果当前进程没有用户地址空间,则panic
  223. #[inline(never)]
  224. fn copy_mm(
  225. clone_flags: &CloneFlags,
  226. current_pcb: &Arc<ProcessControlBlock>,
  227. new_pcb: &Arc<ProcessControlBlock>,
  228. ) -> Result<(), SystemError> {
  229. let old_address_space = current_pcb.basic().user_vm().unwrap_or_else(|| {
  230. panic!(
  231. "copy_mm: Failed to get address space of current process, current pid: [{:?}]",
  232. current_pcb.raw_pid()
  233. )
  234. });
  235. if clone_flags.contains(CloneFlags::CLONE_VM) {
  236. unsafe { new_pcb.basic_mut().set_user_vm(Some(old_address_space)) };
  237. return Ok(());
  238. }
  239. let new_address_space = old_address_space.write_irqsave().try_clone().unwrap_or_else(|e| {
  240. panic!(
  241. "copy_mm: Failed to clone address space of current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  242. current_pcb.raw_pid(), new_pcb.raw_pid(), e
  243. )
  244. });
  245. unsafe { new_pcb.basic_mut().set_user_vm(Some(new_address_space)) };
  246. return Ok(());
  247. }
  248. #[inline(never)]
  249. fn copy_files(
  250. clone_flags: &CloneFlags,
  251. current_pcb: &Arc<ProcessControlBlock>,
  252. new_pcb: &Arc<ProcessControlBlock>,
  253. ) -> Result<(), SystemError> {
  254. // 如果不共享文件描述符表,则拷贝文件描述符表
  255. if !clone_flags.contains(CloneFlags::CLONE_FILES) {
  256. let new_fd_table = current_pcb.basic().try_fd_table().unwrap().read().clone();
  257. let new_fd_table = Arc::new(RwLock::new(new_fd_table));
  258. new_pcb.basic_mut().set_fd_table(Some(new_fd_table));
  259. } else {
  260. // 如果共享文件描述符表,则直接拷贝指针
  261. new_pcb
  262. .basic_mut()
  263. .set_fd_table(current_pcb.basic().try_fd_table().clone());
  264. }
  265. return Ok(());
  266. }
  267. #[allow(dead_code)]
  268. fn copy_sighand(
  269. clone_flags: &CloneFlags,
  270. current_pcb: &Arc<ProcessControlBlock>,
  271. new_pcb: &Arc<ProcessControlBlock>,
  272. ) -> Result<(), SystemError> {
  273. // todo SignalStruct结构需要更改,属于线程组逻辑
  274. if clone_flags.contains(CloneFlags::CLONE_SIGHAND) {
  275. // log::debug!("copy_sighand: CLONE_SIGHAND");
  276. current_pcb
  277. .sig_struct_irqsave()
  278. .cnt
  279. .fetch_add(1, Ordering::SeqCst);
  280. // todo: sighand结构体应该是个arc,这里要做arc赋值。下面要做创建新的arc。(现在的实现有问题)
  281. return Ok(());
  282. }
  283. // log::debug!("Just copy sighand");
  284. new_pcb.sig_struct_irqsave().handlers = current_pcb.sig_struct_irqsave().handlers.clone();
  285. if clone_flags.contains(CloneFlags::CLONE_CLEAR_SIGHAND) {
  286. flush_signal_handlers(new_pcb.clone(), false);
  287. }
  288. return Ok(());
  289. }
  290. /// 拷贝进程信息
  291. ///
  292. /// ## panic:
  293. /// 某一步拷贝失败时会引发panic
  294. /// 例如:copy_mm等失败时会触发panic
  295. ///
  296. /// ## 参数
  297. ///
  298. /// - clone_flags 标志位
  299. /// - current_pcb 拷贝源pcb
  300. /// - pcb 目标pcb
  301. ///
  302. /// ## return
  303. /// - 发生错误时返回Err(SystemError)
  304. #[inline(never)]
  305. pub fn copy_process(
  306. current_pcb: &Arc<ProcessControlBlock>,
  307. pcb: &Arc<ProcessControlBlock>,
  308. clone_args: KernelCloneArgs,
  309. current_trapframe: &TrapFrame,
  310. ) -> Result<(), SystemError> {
  311. // log::debug!("fork: clone_flags: {:?}", clone_args.flags);
  312. let clone_flags = clone_args.flags;
  313. // 不允许与不同namespace的进程共享根目录
  314. if (clone_flags & (CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_FS)
  315. == (CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_FS))
  316. || (clone_flags & (CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_FS))
  317. == (CloneFlags::CLONE_NEWUSER | CloneFlags::CLONE_FS)
  318. {
  319. return Err(SystemError::EINVAL);
  320. }
  321. // 线程组必须共享信号,分离线程只能在线程组内启动。
  322. if clone_flags.contains(CloneFlags::CLONE_THREAD)
  323. && !clone_flags.contains(CloneFlags::CLONE_SIGHAND)
  324. {
  325. return Err(SystemError::EINVAL);
  326. }
  327. // 共享信号处理器意味着共享vm。
  328. // 线程组也意味着共享vm。阻止这种情况可以简化其他代码。
  329. if clone_flags.contains(CloneFlags::CLONE_SIGHAND)
  330. && !clone_flags.contains(CloneFlags::CLONE_VM)
  331. {
  332. return Err(SystemError::EINVAL);
  333. }
  334. // 当全局init进程或其容器内init进程的兄弟进程退出时,由于它们的父进程(swapper)不会回收它们,
  335. // 这些进程会保持僵尸状态。为了避免这种情况以及防止出现多根进程树,
  336. // 需要阻止全局init和容器内init进程创建兄弟进程。
  337. if clone_flags.contains(CloneFlags::CLONE_PARENT)
  338. && current_pcb
  339. .sig_info_irqsave()
  340. .flags
  341. .contains(SignalFlags::UNKILLABLE)
  342. {
  343. return Err(SystemError::EINVAL);
  344. }
  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. // 标记当前线程还未被执行exec
  382. pcb.flags().insert(ProcessFlags::FORKNOEXEC);
  383. // 将子进程/线程的id存储在用户态传进的地址中
  384. if clone_flags.contains(CloneFlags::CLONE_PARENT_SETTID) {
  385. let mut writer = UserBufferWriter::new(
  386. clone_args.parent_tid.data() as *mut i32,
  387. core::mem::size_of::<i32>(),
  388. true,
  389. )?;
  390. writer.copy_one_to_user(&(pcb.raw_pid().0 as i32), 0)?;
  391. }
  392. sched_fork(pcb).unwrap_or_else(|e| {
  393. panic!(
  394. "fork: Failed to set sched info from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  395. current_pcb.raw_pid(), pcb.raw_pid(), e
  396. )
  397. });
  398. // 拷贝标志位
  399. Self::copy_flags(&clone_flags, pcb).unwrap_or_else(|e| {
  400. panic!(
  401. "fork: Failed to copy flags from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  402. current_pcb.raw_pid(), pcb.raw_pid(), e
  403. )
  404. });
  405. // 拷贝用户地址空间
  406. Self::copy_mm(&clone_flags, current_pcb, pcb).unwrap_or_else(|e| {
  407. panic!(
  408. "fork: Failed to copy mm from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  409. current_pcb.raw_pid(), pcb.raw_pid(), e
  410. )
  411. });
  412. // 拷贝文件描述符表
  413. Self::copy_files(&clone_flags, current_pcb, pcb).unwrap_or_else(|e| {
  414. panic!(
  415. "fork: Failed to copy files from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  416. current_pcb.raw_pid(), pcb.raw_pid(), e
  417. )
  418. });
  419. // 拷贝信号相关数据
  420. Self::copy_sighand(&clone_flags, current_pcb, pcb).unwrap_or_else(|e| {
  421. panic!(
  422. "fork: Failed to copy sighand from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  423. current_pcb.raw_pid(), pcb.raw_pid(), e
  424. )
  425. });
  426. // 拷贝namespace
  427. Self::copy_namespaces(&clone_flags, current_pcb, pcb).unwrap_or_else(|e| {
  428. panic!(
  429. "fork: Failed to copy namespaces from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  430. current_pcb.raw_pid(), pcb.raw_pid(), e
  431. )
  432. });
  433. // 拷贝线程
  434. Self::copy_thread(current_pcb, pcb, &clone_args, current_trapframe).unwrap_or_else(|e| {
  435. panic!(
  436. "fork: Failed to copy thread from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  437. current_pcb.raw_pid(), pcb.raw_pid(), e
  438. )
  439. });
  440. // log::debug!("fork: clone_flags: {:?}", clone_flags);
  441. // 设置线程组id、组长
  442. if clone_flags.contains(CloneFlags::CLONE_THREAD) {
  443. pcb.thread.write_irqsave().group_leader =
  444. current_pcb.thread.read_irqsave().group_leader.clone();
  445. unsafe {
  446. let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
  447. (*ptr).tgid = current_pcb.tgid;
  448. }
  449. } else {
  450. pcb.thread.write_irqsave().group_leader = Arc::downgrade(pcb);
  451. let ptr: *mut ProcessControlBlock =
  452. pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
  453. unsafe {
  454. (*ptr).tgid = pcb.pid;
  455. }
  456. }
  457. // CLONE_PARENT re-uses the old parent
  458. if !((clone_flags & (CloneFlags::CLONE_PARENT | CloneFlags::CLONE_THREAD)).is_empty()) {
  459. *pcb.real_parent_pcb.write_irqsave() =
  460. current_pcb.real_parent_pcb.read_irqsave().clone();
  461. if clone_flags.contains(CloneFlags::CLONE_THREAD) {
  462. pcb.exit_signal.store(Signal::INVALID, Ordering::SeqCst);
  463. } else {
  464. let leader = current_pcb.thread.read_irqsave().group_leader();
  465. if unlikely(leader.is_none()) {
  466. panic!(
  467. "fork: Failed to get leader of current process, current pid: [{:?}]",
  468. current_pcb.raw_pid()
  469. );
  470. }
  471. pcb.exit_signal.store(
  472. leader.unwrap().exit_signal.load(Ordering::SeqCst),
  473. Ordering::SeqCst,
  474. );
  475. }
  476. } else {
  477. // 新创建的进程,设置其父进程为当前进程
  478. *pcb.real_parent_pcb.write_irqsave() = Arc::downgrade(current_pcb);
  479. pcb.exit_signal
  480. .store(clone_args.exit_signal, Ordering::SeqCst);
  481. }
  482. Self::copy_fs(&clone_flags, current_pcb, pcb).unwrap_or_else(|e| {
  483. panic!(
  484. "fork: Failed to copy fs from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  485. current_pcb.raw_pid(), pcb.raw_pid(), e
  486. )
  487. });
  488. if pcb.raw_pid() == RawPid::UNASSIGNED {
  489. // 分层PID分配:在父进程的子PID namespace中为新任务分配PID
  490. let ns = pcb.nsproxy().pid_namespace_for_children().clone();
  491. let main_pid_arc = alloc_pid(&ns).expect("alloc_pid failed");
  492. // 根namespace中的PID号作为RawPid
  493. let root_pid_nr = main_pid_arc
  494. .first_upid()
  495. .expect("UPid list empty")
  496. .nr
  497. .data();
  498. // log::debug!("fork: root_pid_nr: {}", root_pid_nr);
  499. unsafe {
  500. pcb.force_set_raw_pid(RawPid(root_pid_nr));
  501. }
  502. pcb.init_task_pid(PidType::PID, main_pid_arc);
  503. }
  504. // 将当前pcb加入父进程的子进程哈希表中
  505. if pcb.raw_pid() > RawPid(1) {
  506. if let Some(ppcb_arc) = pcb.parent_pcb.read_irqsave().upgrade() {
  507. let mut children = ppcb_arc.children.write_irqsave();
  508. children.push(pcb.raw_pid());
  509. } else {
  510. panic!("parent pcb is None");
  511. }
  512. }
  513. if pcb.raw_pid() > RawPid(0) {
  514. ProcessManager::add_pcb(pcb.clone());
  515. }
  516. let pid = pcb.pid();
  517. if pcb.is_thread_group_leader() {
  518. if pcb.raw_pid() == RawPid(1) {
  519. pcb.init_task_pid(PidType::TGID, pid.clone());
  520. pcb.init_task_pid(PidType::PGID, pid.clone());
  521. pcb.init_task_pid(PidType::SID, pid.clone());
  522. } else {
  523. pcb.init_task_pid(PidType::TGID, pid.clone());
  524. pcb.init_task_pid(PidType::PGID, current_pcb.task_pgrp().unwrap());
  525. pcb.init_task_pid(PidType::SID, current_pcb.task_session().unwrap());
  526. }
  527. if pid.is_child_reaper() {
  528. pid.ns_of_pid().set_child_reaper(Arc::downgrade(pcb));
  529. pcb.sig_info_mut().flags.insert(SignalFlags::UNKILLABLE);
  530. }
  531. let parent_siginfo = current_pcb.sig_info_irqsave();
  532. let parent_tty = parent_siginfo.tty();
  533. let parent_has_child_subreaper = parent_siginfo.has_child_subreaper();
  534. let parent_is_child_reaper = parent_siginfo.is_child_subreaper();
  535. drop(parent_siginfo);
  536. let mut sig_info_guard = pcb.sig_info_mut();
  537. // log::debug!("set tty: {:?}", parent_tty);
  538. sig_info_guard.set_tty(parent_tty);
  539. /*
  540. * Inherit has_child_subreaper flag under the same
  541. * tasklist_lock with adding child to the process tree
  542. * for propagate_has_child_subreaper optimization.
  543. */
  544. sig_info_guard
  545. .set_has_child_subreaper(parent_has_child_subreaper || parent_is_child_reaper);
  546. drop(sig_info_guard);
  547. pcb.attach_pid(PidType::TGID);
  548. pcb.attach_pid(PidType::PGID);
  549. pcb.attach_pid(PidType::SID);
  550. } else {
  551. pcb.task_join_group_stop();
  552. let group_leader = pcb.threads_read_irqsave().group_leader().unwrap();
  553. group_leader
  554. .threads_write_irqsave()
  555. .group_tasks
  556. .push(Arc::downgrade(pcb));
  557. }
  558. pcb.attach_pid(PidType::PID);
  559. sched_cgroup_fork(pcb);
  560. Ok(())
  561. }
  562. fn copy_fs(
  563. clone_flags: &CloneFlags,
  564. parent_pcb: &Arc<ProcessControlBlock>,
  565. child_pcb: &Arc<ProcessControlBlock>,
  566. ) -> Result<(), SystemError> {
  567. let fs = parent_pcb.fs_struct();
  568. let mut guard = child_pcb.fs_struct_mut();
  569. if clone_flags.contains(CloneFlags::CLONE_FS) {
  570. *guard = fs.clone();
  571. } else {
  572. let new_fs = (*fs).clone();
  573. *guard = Arc::new(new_fs);
  574. }
  575. Ok(())
  576. }
  577. }
  578. impl ProcessControlBlock {
  579. /// https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/fork.c#1959
  580. pub(super) fn init_task_pid(&self, pid_type: PidType, pid: Arc<Pid>) {
  581. // log::debug!(
  582. // "init_task_pid: pid_type: {:?}, raw_pid:{}",
  583. // pid_type,
  584. // self.raw_pid().data()
  585. // );
  586. if pid_type == PidType::PID {
  587. self.thread_pid.write().replace(pid);
  588. } else {
  589. self.sig_struct().pids[pid_type as usize] = Some(pid);
  590. }
  591. }
  592. }