From be4ee4f0acd13c2f598bbffd357229e8dcc63d58 Mon Sep 17 00:00:00 2001 From: JingXuan_Wei Date: Mon, 10 Nov 2025 13:31:10 +0800 Subject: [PATCH] fix:Fix related issues with kexec (pr # 1303) code (#1339) - Fix some legacy issues of PR 1303 - Supplement the error handling of PR 1303 Signed-off-by: JensenWei007 --- .gitignore | 7 +- env.mk | 1 + kernel/.gitignore | 4 - kernel/build.rs | 11 ++- kernel/initram/create_initram.sh | 3 - kernel/src/Makefile | 2 +- kernel/src/arch/loongarch64/init/mod.rs | 2 - kernel/src/arch/loongarch64/ipc/signal.rs | 25 +++++ kernel/src/arch/loongarch64/kexec.rs | 13 ++- kernel/src/arch/loongarch64/mod.rs | 1 + kernel/src/arch/riscv64/init/dragonstub.rs | 4 +- kernel/src/arch/riscv64/init/mod.rs | 2 - kernel/src/arch/riscv64/ipc/signal.rs | 25 +++++ kernel/src/arch/riscv64/kexec.rs | 13 ++- kernel/src/arch/riscv64/mod.rs | 1 + kernel/src/arch/x86_64/init/multiboot2.rs | 2 +- kernel/src/arch/x86_64/init/pvh/mod.rs | 3 +- kernel/src/arch/x86_64/ipc/signal.rs | 20 +++- kernel/src/arch/x86_64/kexec.rs | 15 +-- kernel/src/arch/x86_64/mod.rs | 2 + kernel/src/filesystem/ramfs/mod.rs | 62 ------------- kernel/src/filesystem/vfs/mod.rs | 58 ------------ kernel/src/filesystem/vfs/mount.rs | 18 ---- kernel/src/init/boot.rs | 2 +- kernel/src/init/initial_kthread.rs | 8 +- kernel/src/init/initram.rs | 91 +++++++------------ kernel/src/init/kexec/kexec_core.rs | 66 ++++++++------ kernel/src/init/mod.rs | 2 +- kernel/src/ipc/signal_types.rs | 25 ----- .../src/ipc/syscall/sys_pidfd_sendsignal.rs | 2 +- kernel/src/libs/decompress.rs | 5 +- kernel/src/mm/ident_map.rs | 37 ++++++-- kernel/src/mm/sysfs.rs | 2 +- kernel/src/process/fork.rs | 7 +- kernel/src/process/mod.rs | 12 +-- kernel/src/process/syscall/sys_execve.rs | 25 +++-- kernel/src/process/syscall/sys_pidfdopen.rs | 19 ++-- 37 files changed, 259 insertions(+), 338 deletions(-) delete mode 100644 kernel/initram/create_initram.sh diff --git a/.gitignore b/.gitignore index 03eae8469..3080ca0b8 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,9 @@ compile_commands.json /.direnv/ /flake.nix flake.lock -/default.nix \ No newline at end of file +/default.nix + +# initram +*.cpio +*.cpio.xz +*.cpio* diff --git a/env.mk b/env.mk index e499d50b4..8284f2f25 100644 --- a/env.mk +++ b/env.mk @@ -10,5 +10,6 @@ ifeq ($(EMULATOR), ) export EMULATOR=__NO_EMULATION__ endif +export INITRAM_PATH?=$(ROOT_PATH)/x86.cpio.xz export DADK?=$(shell which dadk) diff --git a/kernel/.gitignore b/kernel/.gitignore index 40437acb2..b76171a61 100644 --- a/kernel/.gitignore +++ b/kernel/.gitignore @@ -10,7 +10,3 @@ src/include/bindings/bindings.h # Build counter .build_count - -# initram -initram/*.cpio -initram/*.cpio.xz diff --git a/kernel/build.rs b/kernel/build.rs index dce0dbfd6..ad2dc3615 100644 --- a/kernel/build.rs +++ b/kernel/build.rs @@ -2,10 +2,13 @@ use std::env; use std::path::Path; fn main() { - let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); - let path = format!("{}/initram/x86.cpio.xz", manifest_dir); - if Path::new(&path).exists() { - println!("cargo:rustc-cfg=has_initram_x86"); + if let Ok(initram_path) = env::var("INITRAM_PATH") { + if Path::new(&initram_path).exists() { + println!("cargo:rustc-cfg=has_initram"); + // 将路径传递给编译时常量 + println!("cargo:rustc-env=INITRAM_PATH={}", initram_path); + println!("cargo:rerun-if-env-changed=INITRAM_PATH"); + } } kernel_build::run(); diff --git a/kernel/initram/create_initram.sh b/kernel/initram/create_initram.sh deleted file mode 100644 index 27a70dc41..000000000 --- a/kernel/initram/create_initram.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -echo "此脚本暂时废置, 请使用 DragonBoot 仓库进行构建" diff --git a/kernel/src/Makefile b/kernel/src/Makefile index 6dd238e17..044146079 100644 --- a/kernel/src/Makefile +++ b/kernel/src/Makefile @@ -42,7 +42,7 @@ kernel_subdirs := debug TOOLCHAIN := +nightly-2025-08-10 kernel_rust: - DRAGONOS_ACTUAL_BUILD=1 RUSTFLAGS="$(RUSTFLAGS)" cargo $(TOOLCHAIN) $(CARGO_ZBUILD) build --release --target $(TARGET_JSON) + DRAGONOS_ACTUAL_BUILD=1 RUSTFLAGS="$(RUSTFLAGS)" INITRAM_PATH="$(INITRAM_PATH)" cargo $(TOOLCHAIN) $(CARGO_ZBUILD) build --release --target $(TARGET_JSON) all: kernel diff --git a/kernel/src/arch/loongarch64/init/mod.rs b/kernel/src/arch/loongarch64/init/mod.rs index 6aa1289c4..0cb6d190e 100644 --- a/kernel/src/arch/loongarch64/init/mod.rs +++ b/kernel/src/arch/loongarch64/init/mod.rs @@ -13,8 +13,6 @@ impl ArchBootParams { pub fn set_scratch(&mut self, _scratch: u32) {} - pub fn add_e820_entry(&mut self, _addr: u64, _size: u64, _mtype: u32) {} - pub fn init_setupheader(&mut self) {} pub fn convert_to_buf(&self) -> &[u8] { diff --git a/kernel/src/arch/loongarch64/ipc/signal.rs b/kernel/src/arch/loongarch64/ipc/signal.rs index 2a006ba4b..429eaec6a 100644 --- a/kernel/src/arch/loongarch64/ipc/signal.rs +++ b/kernel/src/arch/loongarch64/ipc/signal.rs @@ -24,3 +24,28 @@ impl SignalArch for LoongArch64SignalArch { todo!("la64:sys_rt_sigreturn") } } + +/// @brief 信号处理备用栈的信息 +#[allow(dead_code)] +#[derive(Debug, Clone, Copy)] +pub struct LoongArch64SigStack { + pub sp: usize, + pub flags: u32, + pub size: u32, +} + +impl LoongArch64SigStack { + pub fn new() -> Self { + Self { + sp: 0, + flags: 0, + size: 0, + } + } +} + +impl Default for LoongArch64SigStack { + fn default() -> Self { + Self::new() + } +} diff --git a/kernel/src/arch/loongarch64/kexec.rs b/kernel/src/arch/loongarch64/kexec.rs index b43f7fea3..f979a1ecc 100644 --- a/kernel/src/arch/loongarch64/kexec.rs +++ b/kernel/src/arch/loongarch64/kexec.rs @@ -1,11 +1,16 @@ use crate::init::kexec::Kimage; use crate::libs::spinlock::SpinLock; use alloc::rc::Rc; +use system_error::SystemError; -pub fn machine_kexec_prepare(kimage: Rc>) -> bool { - false +pub fn machine_kexec_prepare(kimage: Rc>) -> Result<(), SystemError> { + Ok(()) } -pub fn init_pgtable(kimage: Rc>) {} +pub fn init_pgtable(kimage: Rc>) -> Result<(), SystemError> { + Ok(()) +} -pub fn machine_kexec(kimage: Rc>) {} +pub fn machine_kexec(kimage: Rc>) -> Result<(), SystemError> { + Ok(()) +} diff --git a/kernel/src/arch/loongarch64/mod.rs b/kernel/src/arch/loongarch64/mod.rs index 019170aa3..d916245bb 100644 --- a/kernel/src/arch/loongarch64/mod.rs +++ b/kernel/src/arch/loongarch64/mod.rs @@ -21,6 +21,7 @@ pub mod time; pub use self::elf::LoongArch64ElfArch as CurrentElfArch; pub use self::interrupt::LoongArch64InterruptArch as CurrentIrqArch; +pub use self::ipc::signal::LoongArch64SigStack as SigStackArch; pub use self::ipc::signal::LoongArch64SignalArch as CurrentSignalArch; pub use self::mm::LoongArch64MMArch as MMArch; pub use self::pci::LoongArch64PciArch as PciArch; diff --git a/kernel/src/arch/riscv64/init/dragonstub.rs b/kernel/src/arch/riscv64/init/dragonstub.rs index 6bc04d688..07ae01a1a 100644 --- a/kernel/src/arch/riscv64/init/dragonstub.rs +++ b/kernel/src/arch/riscv64/init/dragonstub.rs @@ -39,8 +39,8 @@ impl BootCallbacks for DragonStubCallBack { Ok(()) } - fn early_init_memmap_sysfs(&self) -> Result<(), SystemError> { - log::error!("riscv64, early_init_memmap_sysfs is not impled"); + fn init_memmap_sysfs(&self) -> Result<(), SystemError> { + log::error!("riscv64, init_memmap_sysfs is not impled"); Ok(()) } diff --git a/kernel/src/arch/riscv64/init/mod.rs b/kernel/src/arch/riscv64/init/mod.rs index 65701a23f..a13686145 100644 --- a/kernel/src/arch/riscv64/init/mod.rs +++ b/kernel/src/arch/riscv64/init/mod.rs @@ -50,8 +50,6 @@ impl ArchBootParams { pub fn set_scratch(&mut self, _scratch: u32) {} - pub fn add_e820_entry(&mut self, _addr: u64, _size: u64, _mtype: u32) {} - pub fn init_setupheader(&mut self) {} pub fn convert_to_buf(&self) -> &[u8] { diff --git a/kernel/src/arch/riscv64/ipc/signal.rs b/kernel/src/arch/riscv64/ipc/signal.rs index e7ee2c90c..cf4f37aac 100644 --- a/kernel/src/arch/riscv64/ipc/signal.rs +++ b/kernel/src/arch/riscv64/ipc/signal.rs @@ -40,3 +40,28 @@ bitflags! { } } + +/// @brief 信号处理备用栈的信息 +#[allow(dead_code)] +#[derive(Debug, Clone, Copy)] +pub struct RiscV64SigStack { + pub sp: usize, + pub flags: u32, + pub size: u32, +} + +impl RiscV64SigStack { + pub fn new() -> Self { + Self { + sp: 0, + flags: 0, + size: 0, + } + } +} + +impl Default for RiscV64SigStack { + fn default() -> Self { + Self::new() + } +} diff --git a/kernel/src/arch/riscv64/kexec.rs b/kernel/src/arch/riscv64/kexec.rs index b43f7fea3..f979a1ecc 100644 --- a/kernel/src/arch/riscv64/kexec.rs +++ b/kernel/src/arch/riscv64/kexec.rs @@ -1,11 +1,16 @@ use crate::init::kexec::Kimage; use crate::libs::spinlock::SpinLock; use alloc::rc::Rc; +use system_error::SystemError; -pub fn machine_kexec_prepare(kimage: Rc>) -> bool { - false +pub fn machine_kexec_prepare(kimage: Rc>) -> Result<(), SystemError> { + Ok(()) } -pub fn init_pgtable(kimage: Rc>) {} +pub fn init_pgtable(kimage: Rc>) -> Result<(), SystemError> { + Ok(()) +} -pub fn machine_kexec(kimage: Rc>) {} +pub fn machine_kexec(kimage: Rc>) -> Result<(), SystemError> { + Ok(()) +} diff --git a/kernel/src/arch/riscv64/mod.rs b/kernel/src/arch/riscv64/mod.rs index 583fb3bbc..7b7c5d9e2 100644 --- a/kernel/src/arch/riscv64/mod.rs +++ b/kernel/src/arch/riscv64/mod.rs @@ -30,6 +30,7 @@ pub use self::time::RiscV64TimeArch as CurrentTimeArch; pub use self::elf::RiscV64ElfArch as CurrentElfArch; +pub use self::ipc::signal::RiscV64SigStack as SigStackArch; pub use self::ipc::signal::RiscV64SignalArch as CurrentSignalArch; pub use crate::arch::smp::RiscV64SMPArch as CurrentSMPArch; diff --git a/kernel/src/arch/x86_64/init/multiboot2.rs b/kernel/src/arch/x86_64/init/multiboot2.rs index e757838d0..af6a0c4b4 100644 --- a/kernel/src/arch/x86_64/init/multiboot2.rs +++ b/kernel/src/arch/x86_64/init/multiboot2.rs @@ -217,7 +217,7 @@ impl BootCallbacks for Mb2Callback { Ok(()) } - fn early_init_memmap_sysfs(&self) -> Result<(), SystemError> { + fn init_memmap_sysfs(&self) -> Result<(), SystemError> { // 没测试过, 可能有问题 crate::mm::sysfs::early_memmap_init(); diff --git a/kernel/src/arch/x86_64/init/pvh/mod.rs b/kernel/src/arch/x86_64/init/pvh/mod.rs index 085c14116..fa6ece8c9 100644 --- a/kernel/src/arch/x86_64/init/pvh/mod.rs +++ b/kernel/src/arch/x86_64/init/pvh/mod.rs @@ -56,7 +56,6 @@ impl BootCallbacks for PvhBootCallback { } fn init_initramfs(&self) -> Result<(), SystemError> { - log::error!("x86 pvh, init_initramfs is not impled"); Ok(()) } @@ -125,7 +124,7 @@ impl BootCallbacks for PvhBootCallback { Ok(()) } - fn early_init_memmap_sysfs(&self) -> Result<(), SystemError> { + fn init_memmap_sysfs(&self) -> Result<(), SystemError> { crate::mm::sysfs::early_memmap_init(); let start_info = START_INFO.get(); diff --git a/kernel/src/arch/x86_64/ipc/signal.rs b/kernel/src/arch/x86_64/ipc/signal.rs index 99fbcf2c4..40c920e15 100644 --- a/kernel/src/arch/x86_64/ipc/signal.rs +++ b/kernel/src/arch/x86_64/ipc/signal.rs @@ -131,16 +131,34 @@ impl SigContext { return true; } } + /// @brief 信号处理备用栈的信息 #[allow(dead_code)] #[derive(Debug, Clone, Copy)] pub struct X86SigStack { - pub sp: *mut c_void, + pub sp: usize, pub flags: u32, pub size: u32, pub fpstate: FpState, } +impl X86SigStack { + pub fn new() -> Self { + Self { + sp: 0, + flags: 0, + size: 0, + fpstate: FpState::new(), + } + } +} + +impl Default for X86SigStack { + fn default() -> Self { + Self::new() + } +} + unsafe fn do_signal(frame: &mut TrapFrame, got_signal: &mut bool) { let pcb = ProcessManager::current_pcb(); diff --git a/kernel/src/arch/x86_64/kexec.rs b/kernel/src/arch/x86_64/kexec.rs index 94507e971..f3289a8a9 100644 --- a/kernel/src/arch/x86_64/kexec.rs +++ b/kernel/src/arch/x86_64/kexec.rs @@ -8,11 +8,12 @@ use crate::mm::MemoryManagementArch; use crate::mm::{page::EntryFlags, PhysAddr}; use alloc::rc::Rc; use core::mem::transmute; +use system_error::SystemError; type RelocateKernelFn = unsafe extern "C" fn(indirection_page: usize, start_address: usize, stack_page_address: usize); -pub fn machine_kexec_prepare(kimage: Rc>) -> bool { +pub fn machine_kexec_prepare(kimage: Rc>) -> Result<(), SystemError> { unsafe { unsafe extern "C" { unsafe fn __relocate_kernel_start(); @@ -69,10 +70,10 @@ pub fn machine_kexec_prepare(kimage: Rc>) -> bool { mess_buf.resize(2048, 0); slice.copy_from_slice(&mess_buf); } - true + Ok(()) } -pub fn init_pgtable(kimage: Rc>) { +pub fn init_pgtable(kimage: Rc>) -> Result<(), SystemError> { let pgd = ident_pt_alloc(); kimage.lock().pgd = pgd; @@ -92,7 +93,7 @@ pub fn init_pgtable(kimage: Rc>) { let size = kimage.lock().segment[i].memsz; // TODO:处理可能不是页面整数的情况, 但是目前, 传入的参数都是在用户层页面对其和取整了 let pages_nums = size / MMArch::PAGE_SIZE; - ident_map_pages(pgd, addr, addr, pages_nums); + ident_map_pages(pgd, addr, addr, pages_nums)?; } // pages @@ -106,7 +107,7 @@ pub fn init_pgtable(kimage: Rc>) { for i in 0..len { let page = kimage.lock().pages[i].clone(); let addr = page.phys_address().data(); - ident_map_page(pgd, addr, addr); + ident_map_page(pgd, addr, addr)?; } // efi @@ -126,11 +127,11 @@ pub fn init_pgtable(kimage: Rc>) { pgd, unsafe { MMArch::phys_2_virt(control_page_pa).unwrap().data() }, control_page_pa.data(), - ); + )?; // cmdline let cmdline_ptr = boot_params().read().arch.hdr.cmd_line_ptr as usize; - ident_map_page(pgd, cmdline_ptr, cmdline_ptr); + ident_map_page(pgd, cmdline_ptr, cmdline_ptr) } pub fn machine_kexec(kimage: Rc>) { diff --git a/kernel/src/arch/x86_64/mod.rs b/kernel/src/arch/x86_64/mod.rs index 8e5a78c9f..6378c4295 100644 --- a/kernel/src/arch/x86_64/mod.rs +++ b/kernel/src/arch/x86_64/mod.rs @@ -37,6 +37,8 @@ pub use crate::arch::asm::pio::X86_64PortIOArch as CurrentPortIOArch; pub use crate::arch::ipc::signal::X86_64SignalArch as CurrentSignalArch; pub use crate::arch::time::X86_64TimeArch as CurrentTimeArch; +pub use crate::arch::ipc::signal::X86SigStack as SigStackArch; + pub use crate::arch::elf::X86_64ElfArch as CurrentElfArch; pub use crate::arch::smp::X86_64SMPArch as CurrentSMPArch; diff --git a/kernel/src/filesystem/ramfs/mod.rs b/kernel/src/filesystem/ramfs/mod.rs index 2264a0a3d..feafb906b 100644 --- a/kernel/src/filesystem/ramfs/mod.rs +++ b/kernel/src/filesystem/ramfs/mod.rs @@ -59,8 +59,6 @@ pub struct RamFSInode { self_ref: Weak, /// 子Inode的B树 children: BTreeMap>, - /// 子Syms的B树, 记录符号到符号的链接 - syms: BTreeMap, /// 当前inode的数据部分 data: Vec, /// 当前inode的元数据 @@ -79,7 +77,6 @@ impl RamFSInode { parent: Weak::default(), self_ref: Weak::default(), children: BTreeMap::new(), - syms: BTreeMap::new(), data: Vec::new(), metadata: Metadata { dev_id: 0, @@ -331,7 +328,6 @@ impl IndexNode for LockedRamFSInode { parent: inode.self_ref.clone(), self_ref: Weak::default(), children: BTreeMap::new(), - syms: BTreeMap::new(), data: Vec::new(), metadata: Metadata { dev_id: 0, @@ -420,63 +416,6 @@ impl IndexNode for LockedRamFSInode { return Ok(()); } - fn symlink( - &self, - name1: &str, - name2: &str, - other: &Arc, - ) -> Result<(), SystemError> { - // TODO: 判断是否指向的other为一个符号链接 - // 也就是需要判断 test1 -> echo -> busybox 的情况下, other的name是busybox,但是name2是echo - let other: &LockedRamFSInode = other - .downcast_ref::() - .ok_or(SystemError::EPERM)?; - let name = DName::from(name1); - let other_name = DName::from(name2); - let mut inode: SpinLockGuard = self.0.lock(); - let other_locked: SpinLockGuard = other.0.lock(); - - // 如果当前inode不是文件夹,那么报错 - if inode.metadata.file_type != FileType::Dir { - return Err(SystemError::ENOTDIR); - } - - // 如果另一个inode是文件夹,那么也报错 - if other_locked.metadata.file_type == FileType::Dir { - return Err(SystemError::EISDIR); - } - - // 如果当前文件夹下已经有同名文件,也报错。 - if inode.children.contains_key(&name) { - return Err(SystemError::EEXIST); - } - - // 将子name插入父syms的B树中 - inode.syms.insert(name.clone(), other_name.clone()); - - inode - .children - .insert(name, other_locked.self_ref.upgrade().unwrap()); - - return Ok(()); - } - - fn symunlink(&self, _name: &str) -> Result<(), SystemError> { - // 若文件系统没有实现此方法,则返回“不支持” - return Err(SystemError::ENOSYS); - } - - fn get_nextsym(&self, name: &str) -> Result { - let name = DName::from(name); - let inode: SpinLockGuard = self.0.lock(); - - if let Some(r) = inode.syms.get(&name) { - return Ok(r.0.to_string()); - } - - return Ok(name.to_string()); - } - fn rmdir(&self, name: &str) -> Result<(), SystemError> { let name = DName::from(name); let mut inode: SpinLockGuard = self.0.lock(); @@ -661,7 +600,6 @@ impl IndexNode for LockedRamFSInode { parent: inode.self_ref.clone(), self_ref: Weak::default(), children: BTreeMap::new(), - syms: BTreeMap::new(), data: Vec::new(), metadata: Metadata { dev_id: 0, diff --git a/kernel/src/filesystem/vfs/mod.rs b/kernel/src/filesystem/vfs/mod.rs index 96fc04527..a569d27af 100644 --- a/kernel/src/filesystem/vfs/mod.rs +++ b/kernel/src/filesystem/vfs/mod.rs @@ -8,7 +8,6 @@ pub mod syscall; pub mod utils; pub mod vcore; -use self::utils::rsplit_path; use ::core::{any::Any, fmt::Debug, sync::atomic::AtomicUsize}; use alloc::{string::String, sync::Arc, vec::Vec}; use derive_builder::Builder; @@ -386,46 +385,6 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync { return Err(SystemError::ENOSYS); } - /// @brief 在当前目录下,创建一个名为Name的符号链接(软链接),指向另一个IndexNode,支持链接向一个符号链接 - /// - /// @param name1 符号链接的名称, 将会在此目录下创建名为name的inode - /// @param name1 要被指向的 name 名称, 会根据此name与other的name区分是否指向一个符号链接 - /// @param other 要被指向的IndexNode的Arc指针 - /// - /// @return 成功:Ok(新的inode的Arc指针) - /// 失败:Err(错误码) - fn symlink( - &self, - _name1: &str, - _name2: &str, - _other: &Arc, - ) -> Result<(), SystemError> { - // 若文件系统没有实现此方法,则返回“不支持” - return Err(SystemError::ENOSYS); - } - - /// @brief 在当前目录下,删除一个名为Name的符号链接(软链接) - /// - /// @param name 符号链接的名称 - /// - /// @return 成功:Ok() - /// 失败:Err(错误码) - fn symunlink(&self, _name: &str) -> Result<(), SystemError> { - // 若文件系统没有实现此方法,则返回“不支持” - return Err(SystemError::ENOSYS); - } - - /// @brief 在当前目录下,获取名为Name的符号链接(软链接)的执行的文件名称 - /// - /// @param name 符号链接的名称 - /// - /// @return 成功:Ok() - /// 失败:Err(错误码) - fn get_nextsym(&self, _name: &str) -> Result { - // 若文件系统没有实现此方法,则返回“不支持” - return Err(SystemError::ENOSYS); - } - /// @brief 删除文件夹 /// /// @param name 文件夹名称 @@ -1334,20 +1293,3 @@ impl<'a> FilldirContext<'a> { return Ok(()); } } - -/// 查找链接文件的最底层链接, 目的是解决循环嵌套链接 -/// 如 test -> echo, echo -> busybox, 需要解析 test 的链接情况 -/// 返回 name 指向的文件的名称(可能为绝对路径, 具体值为symlink传入的参数值) -/// 如果返回其本身(最底层文件名, 经过路径处理后的), 说明此文件不是链接文件 -#[allow(dead_code)] -pub fn get_link_true_file(name: String) -> Result { - let (filename, parent_path) = rsplit_path(&name); - let parent_inode = match parent_path { - None => ProcessManager::current_mntns().root_inode(), - Some(path) => ProcessManager::current_mntns() - .root_inode() - .lookup(path) - .unwrap(), - }; - parent_inode.get_nextsym(filename) -} diff --git a/kernel/src/filesystem/vfs/mount.rs b/kernel/src/filesystem/vfs/mount.rs index e73c9b482..d324bce19 100644 --- a/kernel/src/filesystem/vfs/mount.rs +++ b/kernel/src/filesystem/vfs/mount.rs @@ -709,24 +709,6 @@ impl IndexNode for MountFSInode { return self.inner_inode.unlink(name); } - fn symlink( - &self, - name1: &str, - name2: &str, - other: &Arc, - ) -> Result<(), SystemError> { - return self.inner_inode.symlink(name1, name2, other); - } - - fn symunlink(&self, _name: &str) -> Result<(), SystemError> { - // 若文件系统没有实现此方法,则返回“不支持” - return Err(SystemError::ENOSYS); - } - - fn get_nextsym(&self, name: &str) -> Result { - return self.inner_inode.get_nextsym(name); - } - #[inline] fn rmdir(&self, name: &str) -> Result<(), SystemError> { let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id; diff --git a/kernel/src/init/boot.rs b/kernel/src/init/boot.rs index eec3e6f90..68432ff1b 100644 --- a/kernel/src/init/boot.rs +++ b/kernel/src/init/boot.rs @@ -173,7 +173,7 @@ pub trait BootCallbacks: Send + Sync { /// 初始化内存块 fn early_init_memory_blocks(&self) -> Result<(), SystemError>; /// 初始化内存 memmap 信息到 sysfs - fn early_init_memmap_sysfs(&self) -> Result<(), SystemError>; + fn init_memmap_sysfs(&self) -> Result<(), SystemError>; /// 初始化内存 memmap 信息到 boot_params fn init_memmap_bp(&self) -> Result<(), SystemError>; } diff --git a/kernel/src/init/initial_kthread.rs b/kernel/src/init/initial_kthread.rs index e6c9c0986..165fc96ff 100644 --- a/kernel/src/init/initial_kthread.rs +++ b/kernel/src/init/initial_kthread.rs @@ -12,7 +12,7 @@ use crate::filesystem::vfs::vcore::change_root_fs; use crate::{ arch::{interrupt::TrapFrame, process::arch_switch_to_user}, driver::net::e1000e::e1000e::e1000e_init, - filesystem::vfs::vcore::mount_root_fs, + filesystem::vfs::{vcore::mount_root_fs, VFS_MAX_FOLLOW_SYMLINK_TIMES}, net::net_core::net_init, process::{ exec::ProcInitInfo, execve::do_execve, kthread::KernelThreadMechanism, stdio::stdio_init, @@ -75,7 +75,7 @@ fn kernel_init() -> Result<(), SystemError> { .inspect_err(|e| log::error!("ahci_init failed: {:?}", e)) .ok(); - if super::enable_initramfs() { + if super::initramfs_enabled() { // 使用 initramfs, 迁移文件系统 #[cfg(feature = "initram")] change_root_fs().expect("Failed to mount root fs"); @@ -127,7 +127,7 @@ fn switch_to_user() -> ! { let mut trap_frame = TrapFrame::new(); - if super::enable_initramfs() { + if super::initramfs_enabled() { // 使用 initramfs, 启动 /init log::info!("Initramfs, Boot with specified init process: /init"); @@ -212,7 +212,7 @@ fn run_init_process( let path = proc_init_info.proc_name.to_str().unwrap(); let pwd = ProcessManager::current_pcb().pwd_inode(); - let inode = pwd.lookup(path)?; + let inode = pwd.lookup_follow_symlink(path, VFS_MAX_FOLLOW_SYMLINK_TIMES)?; do_execve( inode, proc_init_info.args.clone(), diff --git a/kernel/src/init/initram.rs b/kernel/src/init/initram.rs index b96bd6279..42cf922fa 100644 --- a/kernel/src/init/initram.rs +++ b/kernel/src/init/initram.rs @@ -5,6 +5,7 @@ use alloc::vec::Vec; use crate::filesystem::ramfs::RamFS; use crate::filesystem::vfs::mount::MountFlags; +use crate::filesystem::vfs::FilePrivateData; use crate::filesystem::vfs::FileSystem; use crate::filesystem::vfs::MountFS; use crate::init::boot::boot_callbacks; @@ -31,49 +32,14 @@ pub fn INIT_ROOT_INODE() -> Arc { } } -#[cfg(target_arch = "x86_64")] #[allow(non_upper_case_globals, unexpected_cfgs)] #[used] pub static INITRAM_DATA: &[u8] = { - #[cfg(has_initram_x86)] + #[cfg(has_initram)] { - include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/initram/x86.cpio.xz")) + include_bytes!(env!("INITRAM_PATH")) } - #[cfg(not(has_initram_x86))] - { - &[] - } -}; - -#[cfg(target_arch = "riscv64")] -#[allow(non_upper_case_globals, unexpected_cfgs)] -#[used] -pub static INITRAM_DATA: &[u8] = { - #[cfg(has_initram_riscv64)] - { - include_bytes!(concat!( - env!("CARGO_MANIFEST_DIR"), - "/initram/riscv64.cpio.xz" - )) - } - #[cfg(not(has_initram_riscv64))] - { - &[] - } -}; - -#[cfg(target_arch = "loongarch64")] -#[allow(non_upper_case_globals, unexpected_cfgs)] -#[used] -pub static INITRAM_DATA: &[u8] = { - #[cfg(has_initram_loongarch64)] - { - include_bytes!(concat!( - env!("CARGO_MANIFEST_DIR"), - "/initram/loongarch64.cpio.xz" - )) - } - #[cfg(not(has_initram_loongarch64))] + #[cfg(not(has_initram))] { &[] } @@ -154,7 +120,7 @@ pub fn initramfs_init() -> Result<(), SystemError> { return Err(SystemError::ENOENT); } - let cpio_data = xz_decompress(get_initram()).unwrap(); + let cpio_data = xz_decompress(get_initram())?; let collected_entries_vec = cpio_reader::iter_files(&cpio_data) .map(|entry| CpioEntryInfo { @@ -180,7 +146,10 @@ pub fn initramfs_init() -> Result<(), SystemError> { for (index, entry) in collected_entries_vec.iter().enumerate() { // x86 的有 4 种文件:Dir, File, CharDevice, SymLink let name = entry.name.clone(); - let mode = ModeType::from_bits(entry.mode.bits()).unwrap(); + let mode = ModeType::from_bits(entry.mode.bits()).ok_or_else(|| { + log::error!("initramfs: failed to get mode!"); + SystemError::EINVAL + })?; let file_type = FileType::from(mode); log::info!( "Find cpio entry, Name:{}, ModeType:{:?}, FileType:{:?}", @@ -191,24 +160,22 @@ pub fn initramfs_init() -> Result<(), SystemError> { let (filename, parent_path) = rsplit_path(&name); let parent_inode = match parent_path { None => INIT_ROOT_INODE(), - Some(path) => INIT_ROOT_INODE().lookup(path).unwrap(), + Some(path) => INIT_ROOT_INODE().lookup(path)?, }; match file_type { FileType::Dir => { // 直接插入, 无需处理数据 - parent_inode.create(filename, file_type, mode).unwrap(); + parent_inode.create(filename, file_type, mode)?; } FileType::File => { // 插入, 随后写入文件数据 - let inode = parent_inode.create(filename, file_type, mode).unwrap(); - inode - .write_at( - 0, - entry.file.len(), - &entry.file, - SpinLock::new(crate::filesystem::vfs::FilePrivateData::Unused).lock(), - ) - .unwrap(); + let inode = parent_inode.create(filename, file_type, mode)?; + inode.write_at( + 0, + entry.file.len(), + &entry.file, + SpinLock::new(crate::filesystem::vfs::FilePrivateData::Unused).lock(), + )?; } FileType::CharDevice => { // 不处理, 如果使用 initramfs 那么直接从已经初始化好的根文件系统迁移到此文件系统 @@ -223,20 +190,28 @@ pub fn initramfs_init() -> Result<(), SystemError> { }; } - // 处理链接文件 - // TODO: 正常来说必须使用软链接(符号链接), 但是现在内核没有实现软链接 - // 这里使用硬链接在一层符号嵌套访问上不会出问题, 但是执行多层符号嵌套会出问题, 这个使用了一个小暂时的方法 + // 处理链接文件, 使用符号链接 for i in 0..links.len() { let entry = &collected_entries_vec[links[i]]; let name = entry.name.clone(); let (filename, parent_path) = rsplit_path(&name); let parent_inode = match parent_path { None => INIT_ROOT_INODE(), - Some(path) => INIT_ROOT_INODE().lookup(path).unwrap(), + Some(path) => INIT_ROOT_INODE().lookup(path)?, }; - let other_name = String::from_utf8(entry.file.clone()).unwrap(); - let other = parent_inode.lookup(&other_name).unwrap(); - parent_inode.symlink(filename, &other_name, &other).unwrap(); + let other_name = String::from_utf8(entry.file.clone()).map_err(|err| { + log::error!("initramfs: failed to get utf8_name, err is {}", err); + SystemError::EINVAL + })?; + let new_inode = parent_inode.create_with_data( + filename, + FileType::SymLink, + ModeType::from_bits_truncate(0o777), + 0, + )?; + let buf = other_name.as_bytes(); + let len = buf.len(); + new_inode.write_at(0, len, buf, SpinLock::new(FilePrivateData::Unused).lock())?; } // 下面的方式是查看外置 initramfs, 例如使用 qemu 的 -initrd 参数加载的 diff --git a/kernel/src/init/kexec/kexec_core.rs b/kernel/src/init/kexec/kexec_core.rs index bc10aea68..a92c6a395 100644 --- a/kernel/src/init/kexec/kexec_core.rs +++ b/kernel/src/init/kexec/kexec_core.rs @@ -32,20 +32,18 @@ pub fn do_kexec_load( return Ok(0); } - let image = kimage_alloc_init(entry, nr_segments, ksegments, flags).unwrap(); + let image = kimage_alloc_init(entry, nr_segments, ksegments, flags)?; // load segment 的解析: https://zhuanlan.zhihu.com/p/105284305 for i in 0..nr_segments { - kimage_load_normal_segment(image.clone(), i); + kimage_load_normal_segment(image.clone(), i)?; } kimage_terminate(image.clone()); - KexecArch::init_pgtable(image.clone()); + KexecArch::init_pgtable(image.clone())?; - if !KexecArch::machine_kexec_prepare(image.clone()) { - return Err(SystemError::EADV); - } + KexecArch::machine_kexec_prepare(image.clone())?; unsafe { KEXEC_IMAGE = Some(image.clone()); @@ -91,10 +89,10 @@ pub fn kimage_alloc_init( image.lock().segment[..ksegments.len()].copy_from_slice(ksegments); - let temp_c = kimage_alloc_pages(image.clone(), 0, false); + let temp_c = kimage_alloc_pages(image.clone(), 0, false)?; image.lock().control_code_page = temp_c.clone(); - let temp_st = kimage_alloc_pages(image.clone(), 0, true); + let temp_st = kimage_alloc_pages(image.clone(), 0, true)?; image.lock().stack_page = temp_st.clone(); Ok(image) @@ -104,7 +102,7 @@ pub fn kimage_alloc_pages( kimage: Rc>, order: usize, store: bool, -) -> Option> { +) -> Result>, SystemError> { let mut _page = None; let mut extra_pages: Vec> = Vec::new(); let mut alloc = page_manager_lock_irqsave(); @@ -113,13 +111,11 @@ pub fn kimage_alloc_pages( // 目前只分配一个页面, 后面改成多个, 使用 order 控制 loop { - let p = alloc - .create_one_page( - PageType::Normal, - PageFlags::PG_RESERVED | PageFlags::PG_PRIVATE, - &mut LockedFrameAllocator, - ) - .unwrap(); + let p = alloc.create_one_page( + PageType::Normal, + PageFlags::PG_RESERVED | PageFlags::PG_PRIVATE, + &mut LockedFrameAllocator, + )?; if check_isdst(kimage.clone(), p.clone()) { extra_pages.push(p); @@ -136,7 +132,7 @@ pub fn kimage_alloc_pages( alloc.remove_page(&p.phys_address()); } - _page + Ok(_page) } pub fn check_isdst(kimage: Rc>, page: Arc) -> bool { @@ -170,7 +166,10 @@ pub fn kernel_kexec() { } } -pub fn kimage_add_entry(kimage: Rc>, entry: KimageEntry) { +pub fn kimage_add_entry( + kimage: Rc>, + entry: KimageEntry, +) -> Result<(), SystemError> { unsafe { if *kimage.lock().entry != 0 { let t = kimage.lock().entry.add(1); @@ -180,7 +179,7 @@ pub fn kimage_add_entry(kimage: Rc>, entry: KimageEntry) { let k_entry = kimage.lock().entry; let k_last_entry = kimage.lock().last_entry; if k_entry == k_last_entry { - let page = kimage_alloc_pages(kimage.clone(), 0, true).unwrap(); + let page = kimage_alloc_pages(kimage.clone(), 0, true)?.unwrap(); let ind_page = MMArch::phys_2_virt(page.phys_address()).unwrap().data() as *mut KimageEntry; @@ -198,19 +197,26 @@ pub fn kimage_add_entry(kimage: Rc>, entry: KimageEntry) { kimage.lock().entry = t; *kimage.lock().entry = 0; } + Ok(()) } -pub fn kimage_set_destination(kimage: Rc>, destination: usize) { +pub fn kimage_set_destination( + kimage: Rc>, + destination: usize, +) -> Result<(), SystemError> { let d = destination & MMArch::PAGE_MASK; - kimage_add_entry(kimage.clone(), d | IND_DESTINATION); + kimage_add_entry(kimage.clone(), d | IND_DESTINATION) } -pub fn kimage_add_page(kimage: Rc>, page: usize) { +pub fn kimage_add_page(kimage: Rc>, page: usize) -> Result<(), SystemError> { let p = page & MMArch::PAGE_MASK; - kimage_add_entry(kimage.clone(), p | IND_SOURCE); + kimage_add_entry(kimage.clone(), p | IND_SOURCE) } -pub fn kimage_load_normal_segment(kimage: Rc>, index: usize) { +pub fn kimage_load_normal_segment( + kimage: Rc>, + index: usize, +) -> Result<(), SystemError> { let segment = kimage.lock().segment[index]; let mut maddr = segment.mem; @@ -218,11 +224,11 @@ pub fn kimage_load_normal_segment(kimage: Rc>, index: usize) { let mut buf = unsafe { segment.buffer.buf } as *mut u8; let mut ubytes = segment.bufsz; - kimage_set_destination(kimage.clone(), maddr); + kimage_set_destination(kimage.clone(), maddr)?; loop { - let page = kimage_alloc_pages(kimage.clone(), 0, true).unwrap(); - kimage_add_page(kimage.clone(), page.phys_address().data()); + let page = (kimage_alloc_pages(kimage.clone(), 0, true)?).unwrap(); + kimage_add_page(kimage.clone(), page.phys_address().data())?; let mut virt_data = unsafe { MMArch::phys_2_virt(page.phys_address()).unwrap().data() }; virt_data += maddr & !(MMArch::PAGE_MASK); @@ -233,8 +239,8 @@ pub fn kimage_load_normal_segment(kimage: Rc>, index: usize) { let uchunk = min(ubytes, mchunk); if uchunk != 0 { - let usegments_buf = UserBufferReader::new::(buf, uchunk, true).unwrap(); - let ksegment: &[u8] = usegments_buf.read_from_user(0).unwrap(); + let usegments_buf = UserBufferReader::new::(buf, uchunk, true)?; + let ksegment: &[u8] = usegments_buf.read_from_user(0)?; unsafe { core::ptr::copy(ksegment.as_ptr(), virt_data as *mut u8, uchunk) }; ubytes -= uchunk; @@ -245,7 +251,7 @@ pub fn kimage_load_normal_segment(kimage: Rc>, index: usize) { mbytes -= mchunk as isize; if mbytes <= 0 { - return; + return Ok(()); } } } diff --git a/kernel/src/init/mod.rs b/kernel/src/init/mod.rs index f16aba129..bf33075c8 100644 --- a/kernel/src/init/mod.rs +++ b/kernel/src/init/mod.rs @@ -26,7 +26,7 @@ fn init_intertrait() { intertrait::init_caster_map(); } -pub fn enable_initramfs() -> bool { +pub fn initramfs_enabled() -> bool { #[cfg(feature = "initram")] unsafe { self::initram::__INIT_ROOT_ENABLED diff --git a/kernel/src/ipc/signal_types.rs b/kernel/src/ipc/signal_types.rs index 01d794f41..b2246fa18 100644 --- a/kernel/src/ipc/signal_types.rs +++ b/kernel/src/ipc/signal_types.rs @@ -587,31 +587,6 @@ impl SigPending { } } -/// @brief 信号处理备用栈的信息 -#[allow(dead_code)] -#[derive(Debug, Clone, Copy)] -pub struct SigStack { - pub sp: usize, - pub flags: u32, - pub size: u32, -} - -impl SigStack { - pub fn new() -> Self { - Self { - sp: 0, - flags: 0, - size: 0, - } - } -} - -impl Default for SigStack { - fn default() -> Self { - Self::new() - } -} - /// @brief 进程接收到的信号的队列 #[derive(Debug, Clone, Default)] pub struct SigQueue { diff --git a/kernel/src/ipc/syscall/sys_pidfd_sendsignal.rs b/kernel/src/ipc/syscall/sys_pidfd_sendsignal.rs index e03728144..214bf19c7 100644 --- a/kernel/src/ipc/syscall/sys_pidfd_sendsignal.rs +++ b/kernel/src/ipc/syscall/sys_pidfd_sendsignal.rs @@ -50,7 +50,7 @@ impl Syscall for SysPidfdSendSignalHandle { .fd_table() .read() .get_file_by_fd(pidfd) - .unwrap(); + .ok_or(SystemError::EBADF)?; if file.private_data.lock().is_pid() { pid = file.private_data.lock().get_pid(); } diff --git a/kernel/src/libs/decompress.rs b/kernel/src/libs/decompress.rs index c30170b04..26e77b2c6 100644 --- a/kernel/src/libs/decompress.rs +++ b/kernel/src/libs/decompress.rs @@ -22,7 +22,10 @@ pub fn xz_decompress(compressed_data: &[u8]) -> Result, SystemError> { decompressed_data.extend_from_slice(&temp_buffer[..output_produced]); break; } - Err(err) => panic!("Decompression failed {}", err), + Err(err) => { + log::error!("Decompression failed {}", err); + return Err(SystemError::E2BIG); + } }; } diff --git a/kernel/src/mm/ident_map.rs b/kernel/src/mm/ident_map.rs index 134942562..68566e369 100644 --- a/kernel/src/mm/ident_map.rs +++ b/kernel/src/mm/ident_map.rs @@ -8,6 +8,7 @@ use crate::mm::{ use core::marker::PhantomData; use core::sync::atomic::compiler_fence; use core::sync::atomic::Ordering; +use system_error::SystemError; /// 恒等页表映射器( paddr == vaddr ) #[derive(Hash)] @@ -55,7 +56,7 @@ impl IdentPageMapper { virt: VirtAddr, phys: PhysAddr, mut allocator: F, - ) -> Option> { + ) -> Result>, SystemError> { // 验证虚拟地址和物理地址是否对齐 if !(virt.check_aligned(Arch::PAGE_SIZE) && phys.check_aligned(Arch::PAGE_SIZE)) { log::error!( @@ -63,7 +64,7 @@ impl IdentPageMapper { virt, phys ); - return None; + return Err(SystemError::EFAULT); } let virt = VirtAddr::new(virt.data() & (!Arch::PAGE_NEGATIVE_MASK)); @@ -80,7 +81,10 @@ impl IdentPageMapper { let entry = PageEntry::new(phys, flags); let mut table = PageTable::new(VirtAddr::new(0), table_paddr, Arch::PAGE_LEVELS - 1); loop { - let i = table.index_of(virt).unwrap(); + let i = table.index_of(virt).ok_or_else(|| { + log::error!("ident_mapper, map_phys: failed to get index of addr!"); + SystemError::EINVAL + })?; assert!(i < Arch::PAGE_ENTRY_NUM); if table.level() == 0 { @@ -88,14 +92,17 @@ impl IdentPageMapper { table.set_entry(i, entry); compiler_fence(Ordering::SeqCst); - return Some(PageFlush::new(virt)); + return Ok(Some(PageFlush::new(virt))); } else { let next_table = table.next_level_table(i); if let Some(next_table) = next_table { table = next_table; } else { // 分配下一级页表 - let frame = allocator.allocate_one().unwrap(); + let frame = allocator.allocate_one().ok_or_else(|| { + log::error!("ident_mapper, map_phys: allocate table failed"); + SystemError::ENOMEM + })?; // 清空这个页帧 MMArch::write_bytes(MMArch::phys_2_virt(frame).unwrap(), 0, MMArch::PAGE_SIZE); @@ -106,7 +113,10 @@ impl IdentPageMapper { table.set_entry(i, PageEntry::new(frame, flags)); // 获取新分配的页表 - table = table.next_level_table(i).unwrap(); + table = table.next_level_table(i).ok_or_else(|| { + log::error!("ident_mapper, map_phys: get next_level_table failed"); + SystemError::EPERM + })?; } } } @@ -119,21 +129,27 @@ pub fn ident_pt_alloc() -> usize { new_imapper.paddr().data() } -pub fn ident_map_page(table_paddr: usize, virt: usize, phys: usize) { +pub fn ident_map_page(table_paddr: usize, virt: usize, phys: usize) -> Result<(), SystemError> { unsafe { IdentPageMapper::::map_phys( PhysAddr::new(table_paddr), VirtAddr::new(virt), PhysAddr::new(phys), LockedFrameAllocator, - ) + )? .unwrap() .flush(); }; + Ok(()) } /// 需要对齐 -pub fn ident_map_pages(table_paddr: usize, virt: usize, phys: usize, nums: usize) { +pub fn ident_map_pages( + table_paddr: usize, + virt: usize, + phys: usize, + nums: usize, +) -> Result<(), SystemError> { for i in 0..nums { let virt = virt + i * MMArch::PAGE_SIZE; let phys = phys + i * MMArch::PAGE_SIZE; @@ -143,9 +159,10 @@ pub fn ident_map_pages(table_paddr: usize, virt: usize, phys: usize, nums: usize VirtAddr::new(virt), PhysAddr::new(phys), LockedFrameAllocator, - ) + )? .unwrap() .flush() }; } + Ok(()) } diff --git a/kernel/src/mm/sysfs.rs b/kernel/src/mm/sysfs.rs index 98810f521..e1e22223f 100644 --- a/kernel/src/mm/sysfs.rs +++ b/kernel/src/mm/sysfs.rs @@ -313,7 +313,7 @@ fn memmap_sysfs_init() -> Result<(), SystemError> { .init_memmap_bp() .expect("init bp memmap failed"); boot_callbacks() - .early_init_memmap_sysfs() + .init_memmap_sysfs() .expect("init sysfs memmap failed"); let memmap_kobj = CommonKobj::new("memmap".to_string()); diff --git a/kernel/src/process/fork.rs b/kernel/src/process/fork.rs index 1f49db0a8..99965c327 100644 --- a/kernel/src/process/fork.rs +++ b/kernel/src/process/fork.rs @@ -444,10 +444,9 @@ impl ProcessManager { ProcessManager::current_pcb().raw_pid().data(), pid ); - let new_inode = root_inode - .create(&name, FileType::File, ModeType::from_bits_truncate(0o777)) - .unwrap(); - let file = File::new(new_inode, FileMode::O_RDWR | FileMode::O_CLOEXEC).unwrap(); + let new_inode = + root_inode.create(&name, FileType::File, ModeType::from_bits_truncate(0o777))?; + let file = File::new(new_inode, FileMode::O_RDWR | FileMode::O_CLOEXEC)?; { let mut guard = file.private_data.lock(); *guard = FilePrivateData::Pid(PidPrivateData::new(pid)); diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index 3e62e0cb4..3b08b2b57 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -24,7 +24,7 @@ use crate::{ cpu::current_cpu_id, ipc::signal::{AtomicSignal, SigSet, Signal}, process::ArchPCBInfo, - CurrentIrqArch, + CurrentIrqArch, SigStackArch, }, driver::tty::tty_core::TtyCore, exception::InterruptArch, @@ -36,7 +36,7 @@ use crate::{ ipc::{ sighand::SigHand, signal::RestartBlock, - signal_types::{SigInfo, SigPending, SigStack}, + signal_types::{SigInfo, SigPending}, }, libs::{ align::AlignedBox, @@ -757,7 +757,7 @@ pub struct ProcessControlBlock { sig_info: RwLock, sighand: RwLock>, /// 备用信号栈 - sig_altstack: RwLock, + sig_altstack: RwLock, /// 退出信号S exit_signal: AtomicSignal, @@ -900,7 +900,7 @@ impl ProcessControlBlock { arch_info, sig_info: RwLock::new(ProcessSignalInfo::default()), sighand: RwLock::new(SigHand::new()), - sig_altstack: RwLock::new(SigStack::new()), + sig_altstack: RwLock::new(SigStackArch::new()), exit_signal: AtomicSignal::new(Signal::SIGCHLD), parent_pcb: RwLock::new(ppcb.clone()), real_parent_pcb: RwLock::new(ppcb), @@ -1161,11 +1161,11 @@ impl ProcessControlBlock { return &self.sched_info; } - pub fn sig_altstack(&self) -> RwLockReadGuard<'_, SigStack> { + pub fn sig_altstack(&self) -> RwLockReadGuard<'_, SigStackArch> { self.sig_altstack.read_irqsave() } - pub fn sig_altstack_mut(&self) -> RwLockWriteGuard<'_, SigStack> { + pub fn sig_altstack_mut(&self) -> RwLockWriteGuard<'_, SigStackArch> { self.sig_altstack.write_irqsave() } diff --git a/kernel/src/process/syscall/sys_execve.rs b/kernel/src/process/syscall/sys_execve.rs index aab586ba3..fd9e8028c 100644 --- a/kernel/src/process/syscall/sys_execve.rs +++ b/kernel/src/process/syscall/sys_execve.rs @@ -5,7 +5,7 @@ use alloc::sync::Arc; use crate::arch::interrupt::TrapFrame; use crate::arch::syscall::nr::SYS_EXECVE; -use crate::filesystem::vfs::{IndexNode, MAX_PATHLEN}; +use crate::filesystem::vfs::{IndexNode, MAX_PATHLEN, VFS_MAX_FOLLOW_SYMLINK_TIMES}; use crate::mm::page::PAGE_4K_SIZE; use crate::mm::{verify_area, VirtAddr}; use crate::process::execve::do_execve; @@ -61,20 +61,19 @@ impl SysExecve { envp: *const *const u8, ) -> Result<(CString, Vec, Vec), SystemError> { let path: CString = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; - #[cfg(not(feature = "initram"))] - let argv: Vec = check_and_clone_cstr_array(argv)?; - #[cfg(feature = "initram")] let mut argv: Vec = check_and_clone_cstr_array(argv)?; let envp: Vec = check_and_clone_cstr_array(envp)?; - // 这里需要处理符号链接, 目前内核没有完整实现, 这里是个简易的替代 - // 例如执行/bin/echo, 必须拿到echo这个名字, 目前内核只有硬链接, 会执行/bin/busybox, 导致无法识别命令 - #[cfg(feature = "initram")] - { - let real = - crate::filesystem::vfs::get_link_true_file(argv[0].to_string_lossy().to_string()) - .unwrap(); - argv[0] = CString::new(real).unwrap(); + // 这里需要处理符号链接, 应用程序一般不支持嵌套符号链接 + // 如 test -> echo -> busybox, 需要内核代为解析到 echo, 传入 test 则不会让程序执行 echo 命令 + let root = ProcessManager::current_mntns().root_inode(); + if let Ok(real_inode) = root.lookup_follow_symlink2( + argv[0].to_string_lossy().as_ref(), + VFS_MAX_FOLLOW_SYMLINK_TIMES, + false, + ) { + let real_path = real_inode.absolute_path()?; + argv[0] = CString::new(real_path).unwrap(); } Ok((path, argv, envp)) @@ -127,7 +126,7 @@ impl Syscall for SysExecve { let path = path.into_string().map_err(|_| SystemError::EINVAL)?; let pwd = ProcessManager::current_pcb().pwd_inode(); - let inode = pwd.lookup(&path)?; + let inode = pwd.lookup_follow_symlink(&path, VFS_MAX_FOLLOW_SYMLINK_TIMES)?; Self::execve(inode, path, argv, envp, frame)?; return Ok(0); diff --git a/kernel/src/process/syscall/sys_pidfdopen.rs b/kernel/src/process/syscall/sys_pidfdopen.rs index bdbb752d3..ab766a2b3 100644 --- a/kernel/src/process/syscall/sys_pidfdopen.rs +++ b/kernel/src/process/syscall/sys_pidfdopen.rs @@ -37,9 +37,15 @@ impl Syscall for SysPidFdOpen { let pid = Self::pid(args); let flags = Self::flags(args); - let mode = ModeType::from_bits(flags).unwrap(); + let mode = ModeType::from_bits(flags).ok_or_else(|| { + log::error!("SysPidFdOpen: failed to get mode!"); + SystemError::EINVAL + })?; let file_type = FileType::from(mode); - let file_mode = FileMode::from_bits(flags).unwrap(); + let file_mode = FileMode::from_bits(flags).ok_or_else(|| { + log::error!("SysPidFdOpen: failed to get file_mode!"); + SystemError::EINVAL + })?; let root_inode = ProcessManager::current_mntns().root_inode(); let name = format!( @@ -47,20 +53,19 @@ impl Syscall for SysPidFdOpen { ProcessManager::current_pcb().raw_pid().data(), pid ); - let new_inode = root_inode.create(&name, file_type, mode).unwrap(); - let file = File::new(new_inode, file_mode).unwrap(); + let new_inode = root_inode.create(&name, file_type, mode)?; + let file = File::new(new_inode, file_mode)?; { let mut guard = file.private_data.lock(); *guard = FilePrivateData::Pid(PidPrivateData::new(pid)); } // 存入pcb - let r = ProcessManager::current_pcb() + ProcessManager::current_pcb() .fd_table() .write() .alloc_fd(file, None) - .map(|fd| fd as usize); - r + .map(|fd| fd as usize) } fn entry_format(&self, args: &[usize]) -> Vec {