Просмотр исходного кода

fix(process): 修复copy_process的一些bug & 支持默认init进程传参 (#1083)

- 修复`copy_process`函数对标志位处理不正确的bug
- init进程搜索列表中,支持为默认init程序传入参数

Signed-off-by: longjin <[email protected]>
LoGin 1 месяц назад
Родитель
Сommit
55d7280a51

+ 25 - 6
kernel/src/init/initial_kthread.rs

@@ -22,7 +22,12 @@ use crate::{
 
 use super::{cmdline::kenrel_cmdline_param_manager, initcall::do_initcalls};
 
-const INIT_PROC_TRYLIST: [&str; 3] = ["/bin/dragonreach", "/bin/init", "/bin/sh"];
+const INIT_PROC_TRYLIST: [(&str, Option<&str>); 4] = [
+    ("/bin/dragonreach", None),
+    ("/bin/init", None),
+    ("/bin/sh", None),
+    ("/bin/busybox", Some("init")),
+];
 
 pub fn initial_kernel_thread() -> i32 {
     kernel_init().unwrap_or_else(|err| {
@@ -88,6 +93,7 @@ fn switch_to_user() -> ! {
         try_to_run_init_process(
             path.as_c_str().to_str().unwrap(),
             &mut proc_init_info,
+            &None,
             &mut trap_frame,
         )
         .unwrap_or_else(|e| {
@@ -98,8 +104,9 @@ fn switch_to_user() -> ! {
         });
     } else {
         let mut ok = false;
-        for path in INIT_PROC_TRYLIST.iter() {
-            if try_to_run_init_process(path, &mut proc_init_info, &mut trap_frame).is_ok() {
+        for (path, ext_args) in INIT_PROC_TRYLIST.iter() {
+            if try_to_run_init_process(path, &mut proc_init_info, ext_args, &mut trap_frame).is_ok()
+            {
                 ok = true;
                 break;
             }
@@ -118,10 +125,22 @@ fn switch_to_user() -> ! {
 fn try_to_run_init_process(
     path: &str,
     proc_init_info: &mut ProcInitInfo,
+    ext_args: &Option<&str>,
     trap_frame: &mut TrapFrame,
 ) -> Result<(), SystemError> {
+    let mut args_to_insert = alloc::vec::Vec::new();
+    args_to_insert.push(CString::new(path).unwrap());
+
+    if let Some(ext_args) = ext_args {
+        // Split ext_args by whitespace and trim each part
+        for arg in ext_args.split_whitespace() {
+            args_to_insert.push(CString::new(arg.trim()).unwrap());
+        }
+    }
     proc_init_info.proc_name = CString::new(path).unwrap();
-    proc_init_info.args.insert(0, CString::new(path).unwrap());
+    let elements_to_remove = args_to_insert.len();
+    let old_args = core::mem::replace(&mut proc_init_info.args, args_to_insert);
+    proc_init_info.args.extend(old_args);
     if let Err(e) = run_init_process(proc_init_info, trap_frame) {
         if e != SystemError::ENOENT {
             error!(
@@ -130,12 +149,12 @@ fn try_to_run_init_process(
             );
         }
 
-        proc_init_info.args.remove(0);
+        proc_init_info.args.drain(0..elements_to_remove);
         return Err(e);
     }
+
     Ok(())
 }
-
 fn run_init_process(
     proc_init_info: &ProcInitInfo,
     trap_frame: &mut TrapFrame,

+ 6 - 1
kernel/src/ipc/signal.rs

@@ -69,6 +69,11 @@ impl Signal {
             warn!("Kill operation not support: pid={:?}", pid);
             return Err(SystemError::ENOSYS);
         }
+
+        // 暂时不支持发送信号给进程组
+        if pid.data() == 0 {
+            return Err(SystemError::ENOSYS);
+        }
         compiler_fence(core::sync::atomic::Ordering::SeqCst);
         // 检查sig是否符合要求,如果不符合要求,则退出。
         if !self.is_valid() {
@@ -78,7 +83,7 @@ impl Signal {
         let pcb = ProcessManager::find(pid);
 
         if pcb.is_none() {
-            warn!("No such process.");
+            warn!("No such process: pid={:?}", pid);
             return retval;
         }
 

+ 14 - 10
kernel/src/process/fork.rs

@@ -75,8 +75,6 @@ bitflags! {
         const CLONE_NEWNET = 0x40000000;
         /// 在新的 I/O 上下文中运行它
         const CLONE_IO = 0x80000000;
-        /// 克隆时,与父进程共享信号结构体
-        const CLONE_SIGNAL = 0x00010000 | 0x00000800;
         /// 克隆时,将原本被设置为SIG_IGNORE的信号,设置回SIG_DEFAULT
         const CLONE_CLEAR_SIGHAND = 0x100000000;
     }
@@ -347,8 +345,11 @@ impl ProcessManager {
     ) -> Result<(), SystemError> {
         let clone_flags = clone_args.flags;
         // 不允许与不同namespace的进程共享根目录
-        if (clone_flags == (CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_FS))
-            || clone_flags == (CloneFlags::CLONE_NEWUSER | CloneFlags::CLONE_FS)
+
+        if (clone_flags & (CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_FS)
+            == (CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_FS))
+            || (clone_flags & (CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_FS))
+                == (CloneFlags::CLONE_NEWUSER | CloneFlags::CLONE_FS)
         {
             return Err(SystemError::EINVAL);
         }
@@ -373,7 +374,7 @@ impl ProcessManager {
         // 如果新进程使用不同的 pid 或 namespace,
         // 则不允许它与分叉任务共享线程组。
         if clone_flags.contains(CloneFlags::CLONE_THREAD)
-            && clone_flags.contains(CloneFlags::CLONE_NEWUSER | CloneFlags::CLONE_NEWPID)
+            && !((clone_flags & (CloneFlags::CLONE_NEWUSER | CloneFlags::CLONE_NEWPID)).is_empty())
         {
             return Err(SystemError::EINVAL);
             // TODO: 判断新进程与当前进程namespace是否相同,不同则返回错误
@@ -381,12 +382,12 @@ impl ProcessManager {
 
         // 如果新进程将处于不同的time namespace,
         // 则不能让它共享vm或线程组。
-        if clone_flags.contains(CloneFlags::CLONE_THREAD | CloneFlags::CLONE_VM) {
+        if !((clone_flags & (CloneFlags::CLONE_THREAD | CloneFlags::CLONE_VM)).is_empty()) {
             // TODO: 判断time namespace,不同则返回错误
         }
 
         if clone_flags.contains(CloneFlags::CLONE_PIDFD)
-            && clone_flags.contains(CloneFlags::CLONE_DETACHED | CloneFlags::CLONE_THREAD)
+            && !((clone_flags & (CloneFlags::CLONE_DETACHED | CloneFlags::CLONE_THREAD)).is_empty())
         {
             return Err(SystemError::EINVAL);
         }
@@ -483,6 +484,8 @@ impl ProcessManager {
             )?;
             *pcb.thread_pid.write() = new_pid;
         }
+
+        // log::debug!("fork: clone_flags: {:?}", clone_flags);
         // 设置线程组id、组长
         if clone_flags.contains(CloneFlags::CLONE_THREAD) {
             pcb.thread.write_irqsave().group_leader =
@@ -493,14 +496,15 @@ impl ProcessManager {
             }
         } else {
             pcb.thread.write_irqsave().group_leader = Arc::downgrade(pcb);
+
+            let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
             unsafe {
-                let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
-                (*ptr).tgid = pcb.tgid;
+                (*ptr).tgid = pcb.pid;
             }
         }
 
         // CLONE_PARENT re-uses the old parent
-        if clone_flags.contains(CloneFlags::CLONE_PARENT | CloneFlags::CLONE_THREAD) {
+        if !((clone_flags & (CloneFlags::CLONE_PARENT | CloneFlags::CLONE_THREAD)).is_empty()) {
             *pcb.real_parent_pcb.write_irqsave() =
                 current_pcb.real_parent_pcb.read_irqsave().clone();
 

+ 3 - 3
kernel/src/process/kthread.rs

@@ -286,7 +286,7 @@ impl KernelThreadMechanism {
 
         KernelThreadMechanism::__inner_create(
             &create_info,
-            CloneFlags::CLONE_VM | CloneFlags::CLONE_SIGNAL,
+            CloneFlags::CLONE_VM | CloneFlags::CLONE_SIGHAND,
         )
         .unwrap_or_else(|e| panic!("Failed to create initial kernel thread, error: {:?}", e));
 
@@ -313,7 +313,7 @@ impl KernelThreadMechanism {
                 .expect("kthreadadd should be run first");
             let kthreadd_pid: Pid = Self::__inner_create(
                 &info,
-                CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
+                CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGHAND,
             )
             .expect("Failed to create kthread daemon");
             let pcb = ProcessManager::find(kthreadd_pid).unwrap();
@@ -466,7 +466,7 @@ impl KernelThreadMechanism {
                 // create a new kernel thread
                 let result: Result<Pid, SystemError> = Self::__inner_create(
                     &info,
-                    CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
+                    CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGHAND,
                 );
                 if result.is_err() {
                     // 创建失败

+ 1 - 0
kernel/src/syscall/mod.rs

@@ -1255,6 +1255,7 @@ impl Syscall {
     }
 
     pub fn reboot() -> Result<usize, SystemError> {
+        log::info!("reboot");
         unsafe { cpu_reset() };
     }
 }