xref: /DragonOS/kernel/src/process/fork.rs (revision 3c82aa56d1b784ea7371100b3e906365be8332fd)
11496ba7bSLoGin use alloc::{string::ToString, sync::Arc};
2c8025a88Slogin 
3c8025a88Slogin use crate::{
4*3c82aa56SChiichen     arch::interrupt::TrapFrame, filesystem::procfs::procfs_register_pid,
5*3c82aa56SChiichen     ipc::signal::flush_signal_handlers, libs::rwlock::RwLock, process::ProcessFlags,
6*3c82aa56SChiichen     syscall::SystemError,
7c8025a88Slogin };
866f67c6aSlogin 
91496ba7bSLoGin use super::{
101496ba7bSLoGin     kthread::{KernelThreadPcbPrivate, WorkerPrivate},
111496ba7bSLoGin     KernelStack, Pid, ProcessControlBlock, ProcessManager,
121496ba7bSLoGin };
131a2eaa40Slogin 
141496ba7bSLoGin bitflags! {
151496ba7bSLoGin     /// 进程克隆标志
161496ba7bSLoGin     pub struct CloneFlags: u32 {
171496ba7bSLoGin         /// 在进程间共享文件系统信息
181496ba7bSLoGin         const CLONE_FS = (1 << 0);
191496ba7bSLoGin         /// 克隆时,与父进程共享信号结构体
201496ba7bSLoGin         const CLONE_SIGNAL = (1 << 1);
211496ba7bSLoGin         /// 克隆时,与父进程共享信号处理结构体
221496ba7bSLoGin         const CLONE_SIGHAND = (1 << 2);
231496ba7bSLoGin         /// 克隆时,将原本被设置为SIG_IGNORE的信号,设置回SIG_DEFAULT
241496ba7bSLoGin         const CLONE_CLEAR_SIGHAND = (1 << 3);
251496ba7bSLoGin         /// 在进程间共享虚拟内存空间
261496ba7bSLoGin         const CLONE_VM = (1 << 4);
271496ba7bSLoGin         /// 拷贝线程
281496ba7bSLoGin         const CLONE_THREAD = (1 << 5);
291496ba7bSLoGin         /// 共享打开的文件
301496ba7bSLoGin         const CLONE_FILES = (1 << 6);
31c8025a88Slogin     }
3266f67c6aSlogin }
3366f67c6aSlogin 
341496ba7bSLoGin impl ProcessManager {
351496ba7bSLoGin     /// 创建一个新进程
361496ba7bSLoGin     ///
371496ba7bSLoGin     /// ## 参数
381496ba7bSLoGin     ///
391496ba7bSLoGin     /// - `current_trapframe`: 当前进程的trapframe
401496ba7bSLoGin     /// - `clone_flags`: 进程克隆标志
411496ba7bSLoGin     ///
421496ba7bSLoGin     /// ## 返回值
431496ba7bSLoGin     ///
441496ba7bSLoGin     /// - 成功:返回新进程的pid
451496ba7bSLoGin     /// - 失败:返回Err(SystemError),fork失败的话,子线程不会执行。
461496ba7bSLoGin     ///
471496ba7bSLoGin     /// ## Safety
481496ba7bSLoGin     ///
491496ba7bSLoGin     /// - fork失败的话,子线程不会执行。
501496ba7bSLoGin     pub fn fork(
511496ba7bSLoGin         current_trapframe: &mut TrapFrame,
521496ba7bSLoGin         clone_flags: CloneFlags,
531496ba7bSLoGin     ) -> Result<Pid, SystemError> {
541496ba7bSLoGin         let current_pcb = ProcessManager::current_pcb();
551496ba7bSLoGin         let new_kstack = KernelStack::new()?;
561496ba7bSLoGin         let name = current_pcb.basic().name().to_string();
571496ba7bSLoGin         let pcb = ProcessControlBlock::new(name, new_kstack);
581496ba7bSLoGin 
591496ba7bSLoGin         // 克隆架构相关信息
601496ba7bSLoGin         *pcb.arch_info() = current_pcb.arch_info_irqsave().clone();
611496ba7bSLoGin 
621496ba7bSLoGin         // 为内核线程设置worker private字段。(也许由内核线程机制去做会更好?)
631496ba7bSLoGin         if current_pcb.flags().contains(ProcessFlags::KTHREAD) {
641496ba7bSLoGin             *pcb.worker_private() = Some(WorkerPrivate::KernelThread(KernelThreadPcbPrivate::new()))
65c8025a88Slogin         }
661496ba7bSLoGin 
671496ba7bSLoGin         // 拷贝标志位
681496ba7bSLoGin         ProcessManager::copy_flags(&clone_flags, &pcb).unwrap_or_else(|e| {
691496ba7bSLoGin             panic!(
701496ba7bSLoGin                 "fork: Failed to copy flags from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
711496ba7bSLoGin                 current_pcb.pid(), pcb.pid(), e
721496ba7bSLoGin             )
731496ba7bSLoGin         });
741496ba7bSLoGin 
751496ba7bSLoGin         // 拷贝用户地址空间
761496ba7bSLoGin         ProcessManager::copy_mm(&clone_flags, &current_pcb, &pcb).unwrap_or_else(|e| {
771496ba7bSLoGin             panic!(
781496ba7bSLoGin                 "fork: Failed to copy mm from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
791496ba7bSLoGin                 current_pcb.pid(), pcb.pid(), e
801496ba7bSLoGin             )
811496ba7bSLoGin         });
821496ba7bSLoGin 
831496ba7bSLoGin         // 拷贝文件描述符表
841496ba7bSLoGin         ProcessManager::copy_files(&clone_flags, &current_pcb, &pcb).unwrap_or_else(|e| {
851496ba7bSLoGin             panic!(
861496ba7bSLoGin                 "fork: Failed to copy files from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
871496ba7bSLoGin                 current_pcb.pid(), pcb.pid(), e
881496ba7bSLoGin             )
891496ba7bSLoGin         });
901496ba7bSLoGin 
91*3c82aa56SChiichen         //拷贝信号相关数据
92*3c82aa56SChiichen         ProcessManager::copy_sighand(&clone_flags, &current_pcb, &pcb).unwrap_or_else(|e| {
93*3c82aa56SChiichen             panic!(
94*3c82aa56SChiichen                 "fork: Failed to copy sighands from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
95*3c82aa56SChiichen                 current_pcb.pid(), pcb.pid(), e
96*3c82aa56SChiichen             )
97*3c82aa56SChiichen         });
981496ba7bSLoGin 
991496ba7bSLoGin         // 拷贝线程
1001496ba7bSLoGin         ProcessManager::copy_thread(&clone_flags, &current_pcb, &pcb, &current_trapframe).unwrap_or_else(|e| {
1011496ba7bSLoGin             panic!(
1021496ba7bSLoGin                 "fork: Failed to copy thread from current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
1031496ba7bSLoGin                 current_pcb.pid(), pcb.pid(), e
1041496ba7bSLoGin             )
1051496ba7bSLoGin         });
1061496ba7bSLoGin 
1071496ba7bSLoGin         ProcessManager::add_pcb(pcb.clone());
1081496ba7bSLoGin 
1091496ba7bSLoGin         // 向procfs注册进程
1101496ba7bSLoGin         procfs_register_pid(pcb.pid()).unwrap_or_else(|e| {
1111496ba7bSLoGin             panic!(
1121496ba7bSLoGin                 "fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}",
1131496ba7bSLoGin                 pcb.pid(),
1141496ba7bSLoGin                 e
1151496ba7bSLoGin             )
1161496ba7bSLoGin         });
1171496ba7bSLoGin 
1181496ba7bSLoGin         ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
1191496ba7bSLoGin             panic!(
1201496ba7bSLoGin                 "fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}",
1211496ba7bSLoGin                 pcb.pid(),
1221496ba7bSLoGin                 e
1231496ba7bSLoGin             )
1241496ba7bSLoGin         });
1251496ba7bSLoGin 
1261496ba7bSLoGin         return Ok(pcb.pid());
1271496ba7bSLoGin     }
1281496ba7bSLoGin 
1291496ba7bSLoGin     fn copy_flags(
1301496ba7bSLoGin         clone_flags: &CloneFlags,
1311496ba7bSLoGin         new_pcb: &Arc<ProcessControlBlock>,
1321496ba7bSLoGin     ) -> Result<(), SystemError> {
1331496ba7bSLoGin         if clone_flags.contains(CloneFlags::CLONE_VM) {
1341496ba7bSLoGin             new_pcb.flags().insert(ProcessFlags::VFORK);
1351496ba7bSLoGin         }
1361496ba7bSLoGin         *new_pcb.flags.lock() = ProcessManager::current_pcb().flags().clone();
1371496ba7bSLoGin         return Ok(());
13866f67c6aSlogin     }
13940fe15e0SLoGin 
14040fe15e0SLoGin     /// 拷贝进程的地址空间
14140fe15e0SLoGin     ///
14240fe15e0SLoGin     /// ## 参数
14340fe15e0SLoGin     ///
14440fe15e0SLoGin     /// - `clone_vm`: 是否与父进程共享地址空间。true表示共享
14540fe15e0SLoGin     /// - `new_pcb`: 新进程的pcb
14640fe15e0SLoGin     ///
14740fe15e0SLoGin     /// ## 返回值
14840fe15e0SLoGin     ///
14940fe15e0SLoGin     /// - 成功:返回Ok(())
15040fe15e0SLoGin     /// - 失败:返回Err(SystemError)
15140fe15e0SLoGin     ///
15240fe15e0SLoGin     /// ## Panic
15340fe15e0SLoGin     ///
15440fe15e0SLoGin     /// - 如果当前进程没有用户地址空间,则panic
1551496ba7bSLoGin     fn copy_mm(
1561496ba7bSLoGin         clone_flags: &CloneFlags,
1571496ba7bSLoGin         current_pcb: &Arc<ProcessControlBlock>,
1581496ba7bSLoGin         new_pcb: &Arc<ProcessControlBlock>,
1591496ba7bSLoGin     ) -> Result<(), SystemError> {
1601496ba7bSLoGin         let old_address_space = current_pcb.basic().user_vm().unwrap_or_else(|| {
1611496ba7bSLoGin             panic!(
1621496ba7bSLoGin                 "copy_mm: Failed to get address space of current process, current pid: [{:?}]",
1631496ba7bSLoGin                 current_pcb.pid()
1641496ba7bSLoGin             )
1651496ba7bSLoGin         });
16640fe15e0SLoGin 
1671496ba7bSLoGin         if clone_flags.contains(CloneFlags::CLONE_VM) {
1681496ba7bSLoGin             unsafe { new_pcb.basic_mut().set_user_vm(Some(old_address_space)) };
16940fe15e0SLoGin             return Ok(());
17040fe15e0SLoGin         }
17140fe15e0SLoGin 
17240fe15e0SLoGin         let new_address_space = old_address_space.write().try_clone().unwrap_or_else(|e| {
17340fe15e0SLoGin             panic!(
1741496ba7bSLoGin                 "copy_mm: Failed to clone address space of current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
1751496ba7bSLoGin                 current_pcb.pid(), new_pcb.pid(), e
17640fe15e0SLoGin             )
17740fe15e0SLoGin         });
1781496ba7bSLoGin         unsafe { new_pcb.basic_mut().set_user_vm(Some(new_address_space)) };
17940fe15e0SLoGin         return Ok(());
18040fe15e0SLoGin     }
1811496ba7bSLoGin 
1821496ba7bSLoGin     fn copy_files(
1831496ba7bSLoGin         clone_flags: &CloneFlags,
1841496ba7bSLoGin         current_pcb: &Arc<ProcessControlBlock>,
1851496ba7bSLoGin         new_pcb: &Arc<ProcessControlBlock>,
1861496ba7bSLoGin     ) -> Result<(), SystemError> {
1871496ba7bSLoGin         // 如果不共享文件描述符表,则拷贝文件描述符表
1881496ba7bSLoGin         if !clone_flags.contains(CloneFlags::CLONE_FILES) {
1891496ba7bSLoGin             let new_fd_table = current_pcb.basic().fd_table().unwrap().read().clone();
1901496ba7bSLoGin             let new_fd_table = Arc::new(RwLock::new(new_fd_table));
1911496ba7bSLoGin             new_pcb.basic_mut().set_fd_table(Some(new_fd_table));
192bb0e4d41SGnoCiYeH         } else {
1931496ba7bSLoGin             // 如果共享文件描述符表,则直接拷贝指针
1941496ba7bSLoGin             new_pcb
1951496ba7bSLoGin                 .basic_mut()
1961496ba7bSLoGin                 .set_fd_table(current_pcb.basic().fd_table().clone());
197bb0e4d41SGnoCiYeH         }
1981496ba7bSLoGin 
1991496ba7bSLoGin         return Ok(());
2001496ba7bSLoGin     }
2011496ba7bSLoGin 
2021496ba7bSLoGin     #[allow(dead_code)]
2031496ba7bSLoGin     fn copy_sighand(
204*3c82aa56SChiichen         clone_flags: &CloneFlags,
205*3c82aa56SChiichen         current_pcb: &Arc<ProcessControlBlock>,
206*3c82aa56SChiichen         new_pcb: &Arc<ProcessControlBlock>,
2071496ba7bSLoGin     ) -> Result<(), SystemError> {
208*3c82aa56SChiichen         // // 将信号的处理函数设置为default(除了那些被手动屏蔽的)
209*3c82aa56SChiichen         if clone_flags.contains(CloneFlags::CLONE_CLEAR_SIGHAND) {
210*3c82aa56SChiichen             flush_signal_handlers(new_pcb.clone(), false);
211*3c82aa56SChiichen         }
212*3c82aa56SChiichen 
213*3c82aa56SChiichen         if clone_flags.contains(CloneFlags::CLONE_SIGHAND) {
214*3c82aa56SChiichen             (*new_pcb.sig_struct()).handlers = current_pcb.sig_struct().handlers.clone();
215*3c82aa56SChiichen         }
2161496ba7bSLoGin         return Ok(());
2171496ba7bSLoGin     }
2181496ba7bSLoGin }
219