Date: Sun, 22 Jan 2012 20:25:00 +0000 (UTC) From: Mikolaj Golub <trociny@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r230470 - in head/sys: kern sys Message-ID: <201201222025.q0MKP0Ix091451@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: trociny Date: Sun Jan 22 20:25:00 2012 New Revision: 230470 URL: http://svn.freebsd.org/changeset/base/230470 Log: 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 Modified: head/sys/kern/kern_proc.c head/sys/kern/kern_resource.c head/sys/sys/resourcevar.h Modified: head/sys/kern/kern_proc.c ============================================================================== --- head/sys/kern/kern_proc.c Sun Jan 22 19:49:43 2012 (r230469) +++ head/sys/kern/kern_proc.c Sun Jan 22 20:25:00 2012 (r230470) @@ -2372,7 +2372,7 @@ sysctl_kern_proc_groups(SYSCTL_HANDLER_A } /* - * 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_A { 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); + + which = (u_int)name[1]; + if (which >= RLIM_NLIMITS) return (EINVAL); - error = pget((pid_t)name[0], PGET_CANSEE, &p); + 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 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, Modified: head/sys/kern/kern_resource.c ============================================================================== --- head/sys/kern/kern_resource.c Sun Jan 22 19:49:43 2012 (r230469) +++ head/sys/kern/kern_resource.c Sun Jan 22 20:25:00 2012 (r230470) @@ -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; Modified: head/sys/sys/resourcevar.h ============================================================================== --- head/sys/sys/resourcevar.h Sun Jan 22 19:49:43 2012 (r230469) +++ head/sys/sys/resourcevar.h Sun Jan 22 20:25:00 2012 (r230470) @@ -120,6 +120,8 @@ int chgsbsize(struct uidinfo *uip, u_in rlim_t maxval); int chgptscnt(struct uidinfo *uip, int diff, rlim_t maxval); int fuswintr(void *base); +int kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which, + struct rlimit *limp); struct plimit *lim_alloc(void); void lim_copy(struct plimit *dst, struct plimit *src);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201222025.q0MKP0Ix091451>