添加prlimit64系统调用 (#438)

注意: 目前仅支持读取默认的rlimit值,尚不支持设置rlimit值.
This commit is contained in:
LoGin 2023-11-12 18:44:15 +08:00 committed by GitHub
parent 4a2d7191a3
commit 0d9b7d9240
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 165 additions and 8 deletions

View File

@ -13,6 +13,8 @@ use alloc::string::String;
use super::{interrupt::TrapFrame, mm::barrier::mfence};
pub const SYS_PRLIMIT64: usize = 302;
/// ### 存储PCB系统调用栈以及在syscall过程中暂存用户态rsp的结构体
///
/// 在syscall指令中将会从该结构体中读取系统调用栈和暂存rsp,
@ -65,7 +67,7 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) -> () {
];
mfence();
// 由于进程管理未完成重构,有些系统调用需要在这里临时处理,以后这里的特殊处理要删掉。
// Arch specific syscall
match syscall_num {
SYS_RT_SIGRETURN => {
syscall_return!(X86_64SignalArch::sys_rt_sigreturn(frame) as usize, frame);

View File

@ -417,7 +417,7 @@ pub struct FileDescriptorVec {
}
impl FileDescriptorVec {
pub const PROCESS_MAX_FD: usize = 32;
pub const PROCESS_MAX_FD: usize = 1024;
pub fn new() -> FileDescriptorVec {
// 先声明一个未初始化的数组

View File

@ -1,3 +1,5 @@
use num_traits::FromPrimitive;
use crate::{syscall::SystemError, time::TimeSpec};
use super::ProcessControlBlock;
@ -71,6 +73,69 @@ impl TryFrom<i32> for RUsageWho {
}
}
/// Resource limit
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(C)]
pub struct RLimit64 {
/// The current (soft) limit
pub rlim_cur: u64,
/// The hard limit
pub rlim_max: u64,
}
/// Resource limit IDs
///
/// ## Note
///
/// 有些架构中,这里[5,9]的值是不同的,我们将来需要在这里增加条件编译
#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive)]
pub enum RLimitID {
/// CPU time in sec
Cpu = 0,
/// Maximum file size
Fsize = 1,
/// Max data size
Data = 2,
/// Max stack size
Stack = 3,
/// Max core file size
Core = 4,
/// Max resident set size
Rss = 5,
/// Max number of processes
Nproc = 6,
/// Max number of open files
Nofile = 7,
/// Max locked-in-memory address space
Memlock = 8,
/// Address space limit
As = 9,
/// Max number of file locks held
Locks = 10,
/// Max number of pending signals
Sigpending = 11,
/// Max bytes in POSIX mqueues
Msgqueue = 12,
/// Max nice prio allowed to raise to
/// 0-39 for nice level 19 .. -20
Nice = 13,
/// Max realtime priority
Rtprio = 14,
/// Timeout for RT tasks in us
Rttime = 15,
Nlimits = 16,
}
impl TryFrom<usize> for RLimitID {
type Error = SystemError;
fn try_from(value: usize) -> Result<Self, Self::Error> {
<Self as FromPrimitive>::from_usize(value).ok_or(SystemError::EINVAL)
}
}
impl ProcessControlBlock {
/// 获取进程资源使用情况
///

View File

@ -9,15 +9,18 @@ use alloc::{
use super::{
abi::WaitOption,
fork::{CloneFlags, KernelCloneArgs},
resource::{RUsage, RUsageWho},
resource::{RLimit64, RLimitID, RUsage, RUsageWho},
KernelStack, Pid, ProcessManager, ProcessState,
};
use crate::{
arch::{interrupt::TrapFrame, sched::sched, CurrentIrqArch},
arch::{interrupt::TrapFrame, sched::sched, CurrentIrqArch, MMArch},
exception::InterruptArch,
filesystem::{procfs::procfs_register_pid, vfs::MAX_PATHLEN},
filesystem::{
procfs::procfs_register_pid,
vfs::{file::FileDescriptorVec, MAX_PATHLEN},
},
include::bindings::bindings::verify_area,
mm::VirtAddr,
mm::{ucontext::UserStack, MemoryManagementArch, VirtAddr},
process::ProcessControlBlock,
sched::completion::Completion,
syscall::{
@ -333,4 +336,77 @@ impl Syscall {
return Ok(0);
}
/// # 设置资源限制
///
/// TODO: 目前暂时不支持设置资源限制,只提供读取默认值的功能
///
/// ## 参数
///
/// - pid: 进程号
/// - resource: 资源类型
/// - new_limit: 新的资源限制
/// - old_limit: 旧的资源限制
///
/// ## 返回值
///
/// - 成功0
/// - 如果old_limit不为NULL则返回旧的资源限制到old_limit
///
pub fn prlimit64(
_pid: Pid,
resource: usize,
new_limit: *const RLimit64,
old_limit: *mut RLimit64,
) -> Result<usize, SystemError> {
let resource = RLimitID::try_from(resource)?;
let mut writer = None;
if new_limit.is_null() {
return Err(SystemError::EINVAL);
}
if !old_limit.is_null() {
writer = Some(UserBufferWriter::new(
old_limit,
core::mem::size_of::<RLimit64>(),
true,
)?);
}
let _reader = UserBufferReader::new(new_limit, core::mem::size_of::<RLimit64>(), true)?;
match resource {
RLimitID::Stack => {
if let Some(mut writer) = writer {
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
rlimit.rlim_cur = UserStack::DEFAULT_USER_STACK_SIZE as u64;
rlimit.rlim_max = UserStack::DEFAULT_USER_STACK_SIZE as u64;
}
return Ok(0);
}
RLimitID::Nofile => {
if let Some(mut writer) = writer {
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
rlimit.rlim_cur = FileDescriptorVec::PROCESS_MAX_FD as u64;
rlimit.rlim_max = FileDescriptorVec::PROCESS_MAX_FD as u64;
}
return Ok(0);
}
RLimitID::As | RLimitID::Rss => {
if let Some(mut writer) = writer {
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
rlimit.rlim_cur = MMArch::USER_END_VADDR.data() as u64;
rlimit.rlim_max = MMArch::USER_END_VADDR.data() as u64;
}
return Ok(0);
}
_ => {
return Err(SystemError::ENOSYS);
}
}
}
}

View File

@ -4,8 +4,12 @@ use core::{
};
use crate::{
arch::syscall::SYS_PRLIMIT64,
libs::{futex::constant::FutexFlag, rand::GRandFlags},
process::{fork::KernelCloneArgs, resource::RUsage},
process::{
fork::KernelCloneArgs,
resource::{RLimit64, RUsage},
},
};
use num_traits::{FromPrimitive, ToPrimitive};
@ -1190,6 +1194,16 @@ impl Syscall {
Self::readlink_at(dirfd, pathname, buf, bufsiz)
}
SYS_PRLIMIT64 => {
let pid = args[0];
let pid = Pid::new(pid);
let resource = args[1];
let new_limit = args[2] as *const RLimit64;
let old_limit = args[3] as *mut RLimit64;
Self::prlimit64(pid, resource, new_limit, old_limit)
}
_ => panic!("Unsupported syscall ID: {}", syscall_num),
};
return r;

View File

@ -521,7 +521,7 @@ int shell_cmd_exec(int argc, char **argv)
char *file_path = get_target_filepath(argv[1], &path_len);
// printf("before execv, path=%s, argc=%d\n", file_path, argc);
char **real_argv;
char **real_argv = NULL;
if (argc > 1)
{
real_argv = &argv[1];