|
| 1 | +# prlimit64分析 |
| 2 | + |
| 3 | +- Starry-Old实现 |
| 4 | +``` |
| 5 | +pub fn syscall_prlimit64(args: [usize; 6]) -> SyscallResult { |
| 6 | + let pid = args[0]; |
| 7 | + let resource = args[1] as i32; |
| 8 | + let new_limit = args[2] as *const RLimit; |
| 9 | + let old_limit = args[3] as *mut RLimit; |
| 10 | + // 当pid不为0,其实没有权利去修改其他的进程的资源限制 |
| 11 | + let curr_process = current_process(); |
| 12 | + if pid == 0 || pid == curr_process.pid() as usize { |
| 13 | + match resource { |
| 14 | + // TODO: 改变了新创建的任务栈大小,但未实现当前任务的栈扩展 |
| 15 | + RLIMIT_STACK => { |
| 16 | + let mut stack_limit: u64 = curr_process.get_stack_limit(); |
| 17 | + if old_limit as usize != 0 { |
| 18 | + unsafe { |
| 19 | + *old_limit = RLimit { |
| 20 | + rlim_cur: stack_limit, |
| 21 | + rlim_max: stack_limit, |
| 22 | + }; |
| 23 | + } |
| 24 | + } |
| 25 | + if new_limit as usize != 0 { |
| 26 | + let new_size = unsafe { (*new_limit).rlim_cur }; |
| 27 | + if new_size > axconfig::TASK_STACK_SIZE as u64 { |
| 28 | + stack_limit = new_size; |
| 29 | + curr_process.set_stack_limit(stack_limit); |
| 30 | + } |
| 31 | + } |
| 32 | + } |
| 33 | + RLIMIT_NOFILE => { |
| 34 | + // 仅支持修改最大文件数 |
| 35 | + if old_limit as usize != 0 { |
| 36 | + let limit = curr_process.fd_manager.get_limit(); |
| 37 | + unsafe { |
| 38 | + *old_limit = RLimit { |
| 39 | + rlim_cur: limit as u64, |
| 40 | + rlim_max: limit as u64, |
| 41 | + }; |
| 42 | + } |
| 43 | + } |
| 44 | + if new_limit as usize != 0 { |
| 45 | + let new_limit = unsafe { (*new_limit).rlim_cur }; |
| 46 | + curr_process.fd_manager.set_limit(new_limit); |
| 47 | + } |
| 48 | + } |
| 49 | + RLIMIT_AS => { |
| 50 | + const USER_MEMORY_LIMIT: usize = 0xffff_ffff; |
| 51 | + if old_limit as usize != 0 { |
| 52 | + unsafe { |
| 53 | + *old_limit = RLimit { |
| 54 | + rlim_cur: USER_MEMORY_LIMIT as u64, |
| 55 | + rlim_max: USER_MEMORY_LIMIT as u64, |
| 56 | + }; |
| 57 | + } |
| 58 | + } |
| 59 | + } |
| 60 | + _ => {} |
| 61 | + } |
| 62 | + } |
| 63 | + Ok(0) |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +- 使用方式 |
| 68 | + - 测例:argv |
| 69 | + - prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0 |
| 70 | + // 获取当前进程的栈资源限制。 |
| 71 | + - prlimit64(0, RLIMIT_STACK, {rlim_cur=100*1024, rlim_max=100*1024}, NULL) = 0 |
| 72 | + //设置当前进程的栈资源限制为 100KB。 |
| 73 | + |
| 74 | +- 官方文档信息 |
| 75 | + - int prlimit(pid_t pid, int resource, |
| 76 | + const struct rlimit *_Nullable new_limit, |
| 77 | + struct rlimit *_Nullable old_limit); |
| 78 | + - 功能 |
| 79 | + - new_limit不为NULL:为软硬限制设置新值 |
| 80 | + - old_limit不为NULL:读取资源限制到old_limit中 |
| 81 | + - pid:进程ID。pid=0,系统调用作用于调用者。设置或获取除自身以外的进程的资源,调用者必须在其资源限制正被更改的那个进程所在的用户命名空间中具备CAP_SYS_RESOURCE(系统资源管理)能力 |
| 82 | + - ``` |
| 83 | + struct rlimit { |
| 84 | +
|
| 85 | +
|
| 86 | + rlim_t rlim_cur; /* Soft limit */ |
| 87 | +
|
| 88 | +
|
| 89 | + rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur) */ |
| 90 | + }; |
| 91 | + ``` |
| 92 | + - 软限制是内核针对相应资源所强制执行的值。 |
| 93 | + - 硬限制则作为软限制的上限:一个无特权的进程只能将其软限制设置为介于 0 到硬限制之间的某个值,并且可以(不可逆地)降低其硬限制。 |
| 94 | + - 一个有特权的进程(在 Linux 系统中,指的是在初始用户命名空间中具备 CAP_SYS_RESOURCE 能力的进程)可以对这两种限制值进行任意修改。 |
| 95 | +RLIM_INFINITY 这个值表示对资源没有限制(在 getrlimit() 函数返回的结构体中,以及传递给 setrlimit() 函数的结构体中都是如此)。 |
| 96 | + - 返回值 |
| 97 | + - 成功:0 |
| 98 | + - 失败:-1,设置errno |
| 99 | +
|
| 100 | + |
0 commit comments