summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authortrociny <trociny@FreeBSD.org>2012-01-22 20:25:00 +0000
committertrociny <trociny@FreeBSD.org>2012-01-22 20:25:00 +0000
commitfcd1c3665658a259422a5ab83d754099b36bbd46 (patch)
tree87e37d6d78b8a9e78c36d0fc7dbca8411f650152 /sys/kern
parentfc1df62a26053d47f27ceb29ae7488c5b0ed82fb (diff)
downloadFreeBSD-src-fcd1c3665658a259422a5ab83d754099b36bbd46.zip
FreeBSD-src-fcd1c3665658a259422a5ab83d754099b36bbd46.tar.gz
Change kern.proc.rlimit sysctl to:
- retrive only one, specified limit for a process, not the whole array, as it was previously (the sysctl has been added recently and has not been backported to stable yet, so this change is ok); - allow to set a resource limit for another process. Submitted by: Andrey Zonov <andrey at zonov.org> Discussed with: kib Reviewed by: kib MFC after: 2 weeks
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_proc.c56
-rw-r--r--sys/kern/kern_resource.c15
2 files changed, 49 insertions, 22 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 38bc438..11ef29f 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -2372,7 +2372,7 @@ sysctl_kern_proc_groups(SYSCTL_HANDLER_ARGS)
}
/*
- * This sysctl allows a process to retrieve the resource limits for
+ * This sysctl allows a process to retrieve or/and set the resource limit for
* another process.
*/
static int
@@ -2380,30 +2380,53 @@ sysctl_kern_proc_rlimit(SYSCTL_HANDLER_ARGS)
{
int *name = (int *)arg1;
u_int namelen = arg2;
- struct plimit *limp;
+ struct rlimit rlim;
struct proc *p;
- int error = 0;
+ u_int which;
+ int flags, error;
- if (namelen != 1)
+ if (namelen != 2)
return (EINVAL);
- error = pget((pid_t)name[0], PGET_CANSEE, &p);
+ which = (u_int)name[1];
+ if (which >= RLIM_NLIMITS)
+ return (EINVAL);
+
+ if (req->newptr != NULL && req->newlen != sizeof(rlim))
+ return (EINVAL);
+
+ flags = PGET_HOLD | PGET_NOTWEXIT;
+ if (req->newptr != NULL)
+ flags |= PGET_CANDEBUG;
+ else
+ flags |= PGET_CANSEE;
+ error = pget((pid_t)name[0], flags, &p);
if (error != 0)
return (error);
+
/*
- * Check the request size. We alow sizes smaller rlimit array for
- * backward binary compatibility: the number of resource limits may
- * grow.
+ * Retrieve limit.
*/
- if (sizeof(limp->pl_rlimit) < req->oldlen) {
+ if (req->oldptr != NULL) {
+ PROC_LOCK(p);
+ lim_rlimit(p, which, &rlim);
PROC_UNLOCK(p);
- return (EINVAL);
}
+ error = SYSCTL_OUT(req, &rlim, sizeof(rlim));
+ if (error != 0)
+ goto errout;
- limp = lim_hold(p->p_limit);
- PROC_UNLOCK(p);
- error = SYSCTL_OUT(req, limp->pl_rlimit, req->oldlen);
- lim_free(limp);
+ /*
+ * Set limit.
+ */
+ if (req->newptr != NULL) {
+ error = SYSCTL_IN(req, &rlim, sizeof(rlim));
+ if (error == 0)
+ error = kern_proc_setrlimit(curthread, p, which, &rlim);
+ }
+
+errout:
+ PRELE(p);
return (error);
}
@@ -2544,8 +2567,9 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_KSTACK, kstack, CTLFLAG_RD |
static SYSCTL_NODE(_kern_proc, KERN_PROC_GROUPS, groups, CTLFLAG_RD |
CTLFLAG_MPSAFE, sysctl_kern_proc_groups, "Process groups");
-static SYSCTL_NODE(_kern_proc, KERN_PROC_RLIMIT, rlimit, CTLFLAG_RD |
- CTLFLAG_MPSAFE, sysctl_kern_proc_rlimit, "Process resource limits");
+static SYSCTL_NODE(_kern_proc, KERN_PROC_RLIMIT, rlimit, CTLFLAG_RW |
+ CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_rlimit,
+ "Process resource limits");
static SYSCTL_NODE(_kern_proc, KERN_PROC_PS_STRINGS, ps_strings,
CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE,
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index bccabc8..590cfcb 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -649,13 +649,17 @@ lim_cb(void *arg)
}
int
-kern_setrlimit(td, which, limp)
- struct thread *td;
- u_int which;
- struct rlimit *limp;
+kern_setrlimit(struct thread *td, u_int which, struct rlimit *limp)
+{
+
+ return (kern_proc_setrlimit(td, td->td_proc, which, limp));
+}
+
+int
+kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
+ struct rlimit *limp)
{
struct plimit *newlim, *oldlim;
- struct proc *p;
register struct rlimit *alimp;
struct rlimit oldssiz;
int error;
@@ -672,7 +676,6 @@ kern_setrlimit(td, which, limp)
limp->rlim_max = RLIM_INFINITY;
oldssiz.rlim_cur = 0;
- p = td->td_proc;
newlim = lim_alloc();
PROC_LOCK(p);
oldlim = p->p_limit;
OpenPOWER on IntegriCloud