More complete implementation of /proc/self/limits.

Fix the way the code accesses process limits struct - pointed out by mjg@.

PR:		207386
Reviewed by:	no objection form des@
MFC after:	3 weeks
This commit is contained in:
Dmitry Chagin 2016-04-10 07:11:29 +00:00
parent 307734b6d4
commit 5743aa47f5
2 changed files with 76 additions and 42 deletions

View File

@ -1370,65 +1370,92 @@ linprocfs_dofdescfs(PFS_FILL_ARGS)
/*
* Filler function for proc/pid/limits
*/
#define RLIM_NONE -1
static const struct limit_info {
static const struct linux_rlimit_ident {
const char *desc;
const char *unit;
unsigned long long rlim_id;
} limits_info[] = {
{ "Max cpu time", "seconds", RLIMIT_CPU },
{ "Max file size", "bytes", RLIMIT_FSIZE },
{ "Max data size", "bytes", RLIMIT_DATA },
{ "Max stack size", "bytes", RLIMIT_STACK },
{ "Max core file size", "bytes", RLIMIT_CORE },
{ "Max resident set", "bytes", RLIMIT_RSS },
{ "Max processes", "processes", RLIMIT_NPROC },
{ "Max open files", "files", RLIMIT_NOFILE },
{ "Max locked memory", "bytes", RLIMIT_MEMLOCK },
{ "Max address space", "bytes", RLIMIT_AS },
{ "Max file locks", "locks", RLIM_INFINITY },
{ "Max pending signals", "signals", RLIM_INFINITY },
{ "Max msgqueue size", "bytes", RLIM_NONE },
{ "Max nice priority", "", RLIM_NONE },
{ "Max realtime priority", "", RLIM_NONE },
{ "Max realtime timeout", "us", RLIM_INFINITY },
unsigned int rlim_id;
} linux_rlimits_ident[] = {
{ "Max cpu time", "seconds", RLIMIT_CPU },
{ "Max file size", "bytes", RLIMIT_FSIZE },
{ "Max data size", "bytes", RLIMIT_DATA },
{ "Max stack size", "bytes", RLIMIT_STACK },
{ "Max core file size", "bytes", RLIMIT_CORE },
{ "Max resident set", "bytes", RLIMIT_RSS },
{ "Max processes", "processes", RLIMIT_NPROC },
{ "Max open files", "files", RLIMIT_NOFILE },
{ "Max locked memory", "bytes", RLIMIT_MEMLOCK },
{ "Max address space", "bytes", RLIMIT_AS },
{ "Max file locks", "locks", LINUX_RLIMIT_LOCKS },
{ "Max pending signals", "signals", LINUX_RLIMIT_SIGPENDING },
{ "Max msgqueue size", "bytes", LINUX_RLIMIT_MSGQUEUE },
{ "Max nice priority", "", LINUX_RLIMIT_NICE },
{ "Max realtime priority", "", LINUX_RLIMIT_RTPRIO },
{ "Max realtime timeout", "us", LINUX_RLIMIT_RTTIME },
{ 0, 0, 0 }
};
static int
linprocfs_doproclimits(PFS_FILL_ARGS)
{
const struct limit_info *li;
struct rlimit li_rlimits;
struct plimit *cur_proc_lim;
const struct linux_rlimit_ident *li;
struct plimit *limp;
struct rlimit rl;
ssize_t size;
int res, error;
cur_proc_lim = lim_alloc();
lim_copy(cur_proc_lim, p->p_limit);
sbuf_printf(sb, "%-26s%-21s%-21s%-10s\n", "Limit", "Soft Limit",
PROC_LOCK(p);
limp = lim_hold(p->p_limit);
PROC_UNLOCK(p);
size = sizeof(res);
sbuf_printf(sb, "%-26s%-21s%-21s%-21s\n", "Limit", "Soft Limit",
"Hard Limit", "Units");
for (li = limits_info; li->desc != NULL; ++li) {
if (li->rlim_id != RLIM_INFINITY && li->rlim_id != RLIM_NONE)
li_rlimits = cur_proc_lim->pl_rlimit[li->rlim_id];
else {
li_rlimits.rlim_cur = 0;
li_rlimits.rlim_max = 0;
for (li = linux_rlimits_ident; li->desc != NULL; ++li) {
switch (li->rlim_id)
{
case LINUX_RLIMIT_LOCKS:
/* FALLTHROUGH */
case LINUX_RLIMIT_RTTIME:
rl.rlim_cur = RLIM_INFINITY;
break;
case LINUX_RLIMIT_SIGPENDING:
error = kernel_sysctlbyname(td,
"kern.sigqueue.max_pending_per_proc",
&res, &size, 0, 0, 0, 0);
if (error != 0)
break;
rl.rlim_cur = res;
rl.rlim_max = res;
break;
case LINUX_RLIMIT_MSGQUEUE:
error = kernel_sysctlbyname(td,
"kern.ipc.msgmnb", &res, &size, 0, 0, 0, 0);
if (error != 0)
break;
rl.rlim_cur = res;
rl.rlim_max = res;
break;
case LINUX_RLIMIT_NICE:
/* FALLTHROUGH */
case LINUX_RLIMIT_RTPRIO:
rl.rlim_cur = 0;
rl.rlim_max = 0;
break;
default:
rl = limp->pl_rlimit[li->rlim_id];
break;
}
if (li->rlim_id == RLIM_INFINITY ||
li_rlimits.rlim_cur == RLIM_INFINITY)
if (rl.rlim_cur == RLIM_INFINITY)
sbuf_printf(sb, "%-26s%-21s%-21s%-10s\n",
li->desc, "unlimited", "unlimited", li->unit);
else
sbuf_printf(sb, "%-26s%-21ld%-21ld%-10s\n",
li->desc, (long)li_rlimits.rlim_cur,
(long)li_rlimits.rlim_max, li->unit);
sbuf_printf(sb, "%-26s%-21llu%-21llu%-10s\n",
li->desc, (unsigned long long)rl.rlim_cur,
(unsigned long long)rl.rlim_max, li->unit);
}
lim_free(cur_proc_lim);
return (0);
lim_free(limp);
return (error);
}
/*
* Filler function for proc/sys/kernel/random/uuid
*/

View File

@ -143,6 +143,13 @@ extern int stclohz;
#define LINUX_P_PID 1
#define LINUX_P_PGID 2
#define LINUX_RLIMIT_LOCKS RLIM_NLIMITS + 1
#define LINUX_RLIMIT_SIGPENDING RLIM_NLIMITS + 2
#define LINUX_RLIMIT_MSGQUEUE RLIM_NLIMITS + 3
#define LINUX_RLIMIT_NICE RLIM_NLIMITS + 4
#define LINUX_RLIMIT_RTPRIO RLIM_NLIMITS + 5
#define LINUX_RLIMIT_RTTIME RLIM_NLIMITS + 6
#define LINUX_RLIM_INFINITY (~0UL)
int linux_common_wait(struct thread *td, int pid, int *status,