mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-10 20:36:48 +00:00
parent
4a2d7191a3
commit
0d9b7d9240
@ -13,6 +13,8 @@ use alloc::string::String;
|
|||||||
|
|
||||||
use super::{interrupt::TrapFrame, mm::barrier::mfence};
|
use super::{interrupt::TrapFrame, mm::barrier::mfence};
|
||||||
|
|
||||||
|
pub const SYS_PRLIMIT64: usize = 302;
|
||||||
|
|
||||||
/// ### 存储PCB系统调用栈以及在syscall过程中暂存用户态rsp的结构体
|
/// ### 存储PCB系统调用栈以及在syscall过程中暂存用户态rsp的结构体
|
||||||
///
|
///
|
||||||
/// 在syscall指令中将会从该结构体中读取系统调用栈和暂存rsp,
|
/// 在syscall指令中将会从该结构体中读取系统调用栈和暂存rsp,
|
||||||
@ -65,7 +67,7 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) -> () {
|
|||||||
];
|
];
|
||||||
mfence();
|
mfence();
|
||||||
|
|
||||||
// 由于进程管理未完成重构,有些系统调用需要在这里临时处理,以后这里的特殊处理要删掉。
|
// Arch specific syscall
|
||||||
match syscall_num {
|
match syscall_num {
|
||||||
SYS_RT_SIGRETURN => {
|
SYS_RT_SIGRETURN => {
|
||||||
syscall_return!(X86_64SignalArch::sys_rt_sigreturn(frame) as usize, frame);
|
syscall_return!(X86_64SignalArch::sys_rt_sigreturn(frame) as usize, frame);
|
||||||
|
@ -417,7 +417,7 @@ pub struct FileDescriptorVec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FileDescriptorVec {
|
impl FileDescriptorVec {
|
||||||
pub const PROCESS_MAX_FD: usize = 32;
|
pub const PROCESS_MAX_FD: usize = 1024;
|
||||||
|
|
||||||
pub fn new() -> FileDescriptorVec {
|
pub fn new() -> FileDescriptorVec {
|
||||||
// 先声明一个未初始化的数组
|
// 先声明一个未初始化的数组
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use num_traits::FromPrimitive;
|
||||||
|
|
||||||
use crate::{syscall::SystemError, time::TimeSpec};
|
use crate::{syscall::SystemError, time::TimeSpec};
|
||||||
|
|
||||||
use super::ProcessControlBlock;
|
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 {
|
impl ProcessControlBlock {
|
||||||
/// 获取进程资源使用情况
|
/// 获取进程资源使用情况
|
||||||
///
|
///
|
||||||
|
@ -9,15 +9,18 @@ use alloc::{
|
|||||||
use super::{
|
use super::{
|
||||||
abi::WaitOption,
|
abi::WaitOption,
|
||||||
fork::{CloneFlags, KernelCloneArgs},
|
fork::{CloneFlags, KernelCloneArgs},
|
||||||
resource::{RUsage, RUsageWho},
|
resource::{RLimit64, RLimitID, RUsage, RUsageWho},
|
||||||
KernelStack, Pid, ProcessManager, ProcessState,
|
KernelStack, Pid, ProcessManager, ProcessState,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{interrupt::TrapFrame, sched::sched, CurrentIrqArch},
|
arch::{interrupt::TrapFrame, sched::sched, CurrentIrqArch, MMArch},
|
||||||
exception::InterruptArch,
|
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,
|
include::bindings::bindings::verify_area,
|
||||||
mm::VirtAddr,
|
mm::{ucontext::UserStack, MemoryManagementArch, VirtAddr},
|
||||||
process::ProcessControlBlock,
|
process::ProcessControlBlock,
|
||||||
sched::completion::Completion,
|
sched::completion::Completion,
|
||||||
syscall::{
|
syscall::{
|
||||||
@ -333,4 +336,77 @@ impl Syscall {
|
|||||||
|
|
||||||
return Ok(0);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,12 @@ use core::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
arch::syscall::SYS_PRLIMIT64,
|
||||||
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
||||||
process::{fork::KernelCloneArgs, resource::RUsage},
|
process::{
|
||||||
|
fork::KernelCloneArgs,
|
||||||
|
resource::{RLimit64, RUsage},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use num_traits::{FromPrimitive, ToPrimitive};
|
use num_traits::{FromPrimitive, ToPrimitive};
|
||||||
@ -1190,6 +1194,16 @@ impl Syscall {
|
|||||||
Self::readlink_at(dirfd, pathname, buf, bufsiz)
|
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),
|
_ => panic!("Unsupported syscall ID: {}", syscall_num),
|
||||||
};
|
};
|
||||||
return r;
|
return r;
|
||||||
|
@ -521,7 +521,7 @@ int shell_cmd_exec(int argc, char **argv)
|
|||||||
char *file_path = get_target_filepath(argv[1], &path_len);
|
char *file_path = get_target_filepath(argv[1], &path_len);
|
||||||
// printf("before execv, path=%s, argc=%d\n", file_path, argc);
|
// printf("before execv, path=%s, argc=%d\n", file_path, argc);
|
||||||
|
|
||||||
char **real_argv;
|
char **real_argv = NULL;
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
{
|
{
|
||||||
real_argv = &argv[1];
|
real_argv = &argv[1];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user