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