diff --git a/kernel/src/init/initial_kthread.rs b/kernel/src/init/initial_kthread.rs index 25fb2191..a79c59da 100644 --- a/kernel/src/init/initial_kthread.rs +++ b/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, diff --git a/kernel/src/ipc/signal.rs b/kernel/src/ipc/signal.rs index 8c85182d..f5304878 100644 --- a/kernel/src/ipc/signal.rs +++ b/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; } diff --git a/kernel/src/process/fork.rs b/kernel/src/process/fork.rs index 41265d13..ca4e6015 100644 --- a/kernel/src/process/fork.rs +++ b/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(); diff --git a/kernel/src/process/kthread.rs b/kernel/src/process/kthread.rs index 6f4d113d..6ee7d13a 100644 --- a/kernel/src/process/kthread.rs +++ b/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 = 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() { // 创建失败 diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 03087e15..8b2a8118 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -1255,6 +1255,7 @@ impl Syscall { } pub fn reboot() -> Result { + log::info!("reboot"); unsafe { cpu_reset() }; } }