fork.rs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. use alloc::{string::ToString, sync::Arc};
  2. use crate::{
  3. arch::interrupt::TrapFrame, filesystem::procfs::procfs_register_pid, libs::rwlock::RwLock,
  4. process::ProcessFlags, syscall::SystemError,
  5. };
  6. use super::{
  7. kthread::{KernelThreadPcbPrivate, WorkerPrivate},
  8. KernelStack, Pid, ProcessControlBlock, ProcessManager,
  9. };
  10. bitflags! {
  11. /// 进程克隆标志
  12. pub struct CloneFlags: u32 {
  13. /// 在进程间共享文件系统信息
  14. const CLONE_FS = (1 << 0);
  15. /// 克隆时,与父进程共享信号结构体
  16. const CLONE_SIGNAL = (1 << 1);
  17. /// 克隆时,与父进程共享信号处理结构体
  18. const CLONE_SIGHAND = (1 << 2);
  19. /// 克隆时,将原本被设置为SIG_IGNORE的信号,设置回SIG_DEFAULT
  20. const CLONE_CLEAR_SIGHAND = (1 << 3);
  21. /// 在进程间共享虚拟内存空间
  22. const CLONE_VM = (1 << 4);
  23. /// 拷贝线程
  24. const CLONE_THREAD = (1 << 5);
  25. /// 共享打开的文件
  26. const CLONE_FILES = (1 << 6);
  27. }
  28. }
  29. impl ProcessManager {
  30. /// 创建一个新进程
  31. ///
  32. /// ## 参数
  33. ///
  34. /// - `current_trapframe`: 当前进程的trapframe
  35. /// - `clone_flags`: 进程克隆标志
  36. ///
  37. /// ## 返回值
  38. ///
  39. /// - 成功:返回新进程的pid
  40. /// - 失败:返回Err(SystemError),fork失败的话,子线程不会执行。
  41. ///
  42. /// ## Safety
  43. ///
  44. /// - fork失败的话,子线程不会执行。
  45. pub fn fork(
  46. current_trapframe: &mut TrapFrame,
  47. clone_flags: CloneFlags,
  48. ) -> Result<Pid, SystemError> {
  49. let current_pcb = ProcessManager::current_pcb();
  50. let new_kstack = KernelStack::new()?;
  51. let name = current_pcb.basic().name().to_string();
  52. let pcb = ProcessControlBlock::new(name, new_kstack);
  53. // 克隆架构相关信息
  54. *pcb.arch_info() = current_pcb.arch_info_irqsave().clone();
  55. // 为内核线程设置worker private字段。(也许由内核线程机制去做会更好?)
  56. if current_pcb.flags().contains(ProcessFlags::KTHREAD) {
  57. *pcb.worker_private() = Some(WorkerPrivate::KernelThread(KernelThreadPcbPrivate::new()))
  58. }
  59. // 拷贝标志位
  60. ProcessManager::copy_flags(&clone_flags, &pcb).unwrap_or_else(|e| {
  61. panic!(
  62. "fork: Failed to copy flags from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  63. current_pcb.pid(), pcb.pid(), e
  64. )
  65. });
  66. // 拷贝用户地址空间
  67. ProcessManager::copy_mm(&clone_flags, &current_pcb, &pcb).unwrap_or_else(|e| {
  68. panic!(
  69. "fork: Failed to copy mm from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  70. current_pcb.pid(), pcb.pid(), e
  71. )
  72. });
  73. // 拷贝文件描述符表
  74. ProcessManager::copy_files(&clone_flags, &current_pcb, &pcb).unwrap_or_else(|e| {
  75. panic!(
  76. "fork: Failed to copy files from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  77. current_pcb.pid(), pcb.pid(), e
  78. )
  79. });
  80. // todo: 拷贝信号相关数据
  81. // 拷贝线程
  82. ProcessManager::copy_thread(&clone_flags, &current_pcb, &pcb, &current_trapframe).unwrap_or_else(|e| {
  83. panic!(
  84. "fork: Failed to copy thread from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  85. current_pcb.pid(), pcb.pid(), e
  86. )
  87. });
  88. ProcessManager::add_pcb(pcb.clone());
  89. // 向procfs注册进程
  90. procfs_register_pid(pcb.pid()).unwrap_or_else(|e| {
  91. panic!(
  92. "fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}",
  93. pcb.pid(),
  94. e
  95. )
  96. });
  97. ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
  98. panic!(
  99. "fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}",
  100. pcb.pid(),
  101. e
  102. )
  103. });
  104. return Ok(pcb.pid());
  105. }
  106. fn copy_flags(
  107. clone_flags: &CloneFlags,
  108. new_pcb: &Arc<ProcessControlBlock>,
  109. ) -> Result<(), SystemError> {
  110. if clone_flags.contains(CloneFlags::CLONE_VM) {
  111. new_pcb.flags().insert(ProcessFlags::VFORK);
  112. }
  113. *new_pcb.flags.lock() = ProcessManager::current_pcb().flags().clone();
  114. return Ok(());
  115. }
  116. /// 拷贝进程的地址空间
  117. ///
  118. /// ## 参数
  119. ///
  120. /// - `clone_vm`: 是否与父进程共享地址空间。true表示共享
  121. /// - `new_pcb`: 新进程的pcb
  122. ///
  123. /// ## 返回值
  124. ///
  125. /// - 成功:返回Ok(())
  126. /// - 失败:返回Err(SystemError)
  127. ///
  128. /// ## Panic
  129. ///
  130. /// - 如果当前进程没有用户地址空间,则panic
  131. fn copy_mm(
  132. clone_flags: &CloneFlags,
  133. current_pcb: &Arc<ProcessControlBlock>,
  134. new_pcb: &Arc<ProcessControlBlock>,
  135. ) -> Result<(), SystemError> {
  136. let old_address_space = current_pcb.basic().user_vm().unwrap_or_else(|| {
  137. panic!(
  138. "copy_mm: Failed to get address space of current process, current pid: [{:?}]",
  139. current_pcb.pid()
  140. )
  141. });
  142. if clone_flags.contains(CloneFlags::CLONE_VM) {
  143. unsafe { new_pcb.basic_mut().set_user_vm(Some(old_address_space)) };
  144. return Ok(());
  145. }
  146. let new_address_space = old_address_space.write().try_clone().unwrap_or_else(|e| {
  147. panic!(
  148. "copy_mm: Failed to clone address space of current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
  149. current_pcb.pid(), new_pcb.pid(), e
  150. )
  151. });
  152. unsafe { new_pcb.basic_mut().set_user_vm(Some(new_address_space)) };
  153. return Ok(());
  154. }
  155. fn copy_files(
  156. clone_flags: &CloneFlags,
  157. current_pcb: &Arc<ProcessControlBlock>,
  158. new_pcb: &Arc<ProcessControlBlock>,
  159. ) -> Result<(), SystemError> {
  160. // 如果不共享文件描述符表,则拷贝文件描述符表
  161. if !clone_flags.contains(CloneFlags::CLONE_FILES) {
  162. let new_fd_table = current_pcb.basic().fd_table().unwrap().read().clone();
  163. let new_fd_table = Arc::new(RwLock::new(new_fd_table));
  164. new_pcb.basic_mut().set_fd_table(Some(new_fd_table));
  165. } else {
  166. // 如果共享文件描述符表,则直接拷贝指针
  167. new_pcb
  168. .basic_mut()
  169. .set_fd_table(current_pcb.basic().fd_table().clone());
  170. }
  171. return Ok(());
  172. }
  173. #[allow(dead_code)]
  174. fn copy_sighand(
  175. _clone_flags: &CloneFlags,
  176. _current_pcb: &Arc<ProcessControlBlock>,
  177. _new_pcb: &Arc<ProcessControlBlock>,
  178. ) -> Result<(), SystemError> {
  179. // todo: 由于信号原来写的太烂,移植到新的进程管理的话,需要改动很多。因此决定重写。这里先空着
  180. return Ok(());
  181. }
  182. }