Date: Sun, 22 Jan 2012 22:31:45 +0200 From: Mikolaj Golub <trociny@freebsd.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Cc: Andrey Zonov <andrey@zonov.org>, Kostik Belousov <kib@FreeBSD.org> Subject: Re: svn commit: r230470 - in head/sys: kern sys Message-ID: <86d3abtr66.fsf@kopusha.home.net> In-Reply-To: <201201222025.q0MKP0Ix091451@svn.freebsd.org> (Mikolaj Golub's message of "Sun, 22 Jan 2012 20:25:00 %2B0000 (UTC)") References: <201201222025.q0MKP0Ix091451@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
--=-=-= On Sun, 22 Jan 2012 20:25:00 +0000 (UTC) Mikolaj Golub wrote: MG> Author: trociny MG> Date: Sun Jan 22 20:25:00 2012 MG> New Revision: 230470 MG> URL: http://svn.freebsd.org/changeset/base/230470 MG> Log: MG> Change kern.proc.rlimit sysctl to: MG> MG> - retrive only one, specified limit for a process, not the whole MG> array, as it was previously (the sysctl has been added recently and MG> has not been backported to stable yet, so this change is ok); MG> MG> - allow to set a resource limit for another process. MG> MG> Submitted by: Andrey Zonov <andrey at zonov.org> MG> Discussed with: kib MG> Reviewed by: kib MG> MFC after: 2 weeks Andrey has also been working on the patch for limits(1), which allows to view/set limits for another process: - If '-P <pid>' without the list of limits is specified it returns the limits for this process. - If '-P <pid>' with the list of limits is specified it changes these limits for the process. - If '-P <pid>' with list of limits is specified but also -a option is present it outputs all limits for the process updated by the command line setting. So if one want, for example, to set for a current shell all limits as they are for a process <pid>, but core dump is disabled, it could run: eval `limits -P <pid> -aBec 0` The latest version of the patch is attached. I am going to commit it if there are no objections or suggestions. -- Mikolaj Golub --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=limits.patch Index: usr.bin/limits/limits.1 =================================================================== --- usr.bin/limits/limits.1 (revision 230394) +++ usr.bin/limits/limits.1 (working copy) @@ -19,7 +19,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 10, 2011 +.Dd January 18, 2011 .Dt LIMITS 1 .Os .Sh NAME @@ -28,11 +28,13 @@ .Sh SYNOPSIS .Nm .Op Fl C Ar class | Fl U Ar user +.Op Fl P Ar pid .Op Fl SHB .Op Fl ea .Op Fl bcdflmnstuvpw Op Ar val .Nm .Op Fl C Ar class | Fl U Ar user +.Op Fl P Ar pid .Op Fl SHB .Op Fl bcdflmnstuvpw Op Ar val .Op Fl E @@ -143,6 +145,9 @@ for the class are used, if it exists, or the .Dq Li root class if the user is a superuser account. +.It Fl P Ar pid +Select or set limits for the process identified by the +.Ar pid . .It Fl S Select display or setting of .Dq soft Index: usr.bin/limits/limits.c =================================================================== --- usr.bin/limits/limits.c (revision 230394) +++ usr.bin/limits/limits.c (working copy) @@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <sys/types.h> #include <sys/stat.h> +#include <sys/sysctl.h> #include <sys/param.h> #include <stdlib.h> #include <unistd.h> @@ -249,6 +250,8 @@ static void usage(void); static int getshelltype(void); static void print_limit(rlim_t limit, unsigned divisor, const char *inf, const char *pfx, const char *sfx, const char *which); +static void getrlimit_proc(pid_t pid, int resource, struct rlimit *rlp); +static void setrlimit_proc(pid_t pid, int resource, const struct rlimit *rlp); extern char **environ; static const char rcs_string[] = RCS_STRING; @@ -262,24 +265,24 @@ main(int argc, char *argv[]) int rcswhich, shelltype; int i, num_limits = 0; int ch, doeval = 0, doall = 0; - int rtrn; + int rtrn, setproc; login_cap_t * lc = NULL; enum { ANY=0, SOFT=1, HARD=2, BOTH=3, DISPLAYONLY=4 } type = ANY; enum { RCSUNKNOWN=0, RCSSET=1, RCSSEL=2 } todo = RCSUNKNOWN; int which_limits[RLIM_NLIMITS]; rlim_t set_limits[RLIM_NLIMITS]; struct rlimit limits[RLIM_NLIMITS]; + pid_t pid; /* init resource tables */ for (i = 0; i < RLIM_NLIMITS; i++) { which_limits[i] = 0; /* Don't set/display any */ set_limits[i] = RLIM_INFINITY; - /* Get current resource values */ - getrlimit(i, &limits[i]); } + pid = -1; optarg = NULL; - while ((ch = getopt(argc, argv, ":EeC:U:BSHab:c:d:f:l:m:n:s:t:u:v:p:w:")) != -1) { + while ((ch = getopt(argc, argv, ":EeC:U:BSHP:ab:c:d:f:l:m:n:s:t:u:v:p:w:")) != -1) { switch(ch) { case 'a': doall = 1; @@ -312,6 +315,12 @@ main(int argc, char *argv[]) case 'B': type = SOFT|HARD; break; + case 'P': + if (!isdigit(*optarg) || (pid = atoi(optarg)) < 0) { + warnx("invalid pid `%s'", optarg); + usage(); + } + break; default: case ':': /* Without arg */ if ((p = strchr(rcs_string, optopt)) != NULL) { @@ -335,6 +344,30 @@ main(int argc, char *argv[]) optarg = NULL; } + if (pid != -1) { + if (cls != NULL) { + warnx("-C cannot be used with -P option"); + usage(); + } + if (pwd != NULL) { + warnx("-U cannot be used with -P option"); + usage(); + } + } + + /* Get current resource values */ + setproc = 0; + for (i = 0; i < RLIM_NLIMITS; i++) { + if (pid == -1) { + getrlimit(i, &limits[i]); + } else if (doall || num_limits == 0) { + getrlimit_proc(pid, i, &limits[i]); + } else if (which_limits[i] != 0) { + getrlimit_proc(pid, i, &limits[i]); + setproc = 1; + } + } + /* If user was specified, get class from that */ if (pwd != NULL) lc = login_getpwclass(pwd); @@ -414,6 +447,10 @@ main(int argc, char *argv[]) warnx("-e cannot be used with `cmd' option"); usage(); } + if (pid != -1) { + warnx("-P cannot be used with `cmd' option"); + usage(); + } login_close(lc); @@ -440,6 +477,14 @@ main(int argc, char *argv[]) err(1, "%s", *argv); } + if (setproc) { + for (rcswhich = 0; rcswhich < RLIM_NLIMITS; rcswhich++) { + if (which_limits[rcswhich] != 0) + setrlimit_proc(pid, rcswhich, &limits[rcswhich]); + } + exit(EXIT_SUCCESS); + } + shelltype = doeval ? getshelltype() : SH_NONE; if (type == ANY) /* Default to soft limits */ @@ -493,7 +538,8 @@ static void usage(void) { (void)fprintf(stderr, -"usage: limits [-C class|-U user] [-eaSHBE] [-bcdflmnstuvpw [val]] [[name=val ...] cmd]\n"); + "usage: limits [-C class|-U user|-P pid] [-eaSHBE] " + "[-bcdflmnstuvpw [val]] [[name=val ...] cmd]\n"); exit(EXIT_FAILURE); } @@ -677,3 +723,38 @@ getshelltype(void) return SH_SH; } +static void +getrlimit_proc(pid_t pid, int resource, struct rlimit *rlp) +{ + int error; + int name[5]; + size_t len; + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_RLIMIT; + name[3] = pid; + name[4] = resource; + len = sizeof(*rlp); + error = sysctl(name, 5, rlp, &len, NULL, 0); + if (error == -1) + err(EXIT_FAILURE, "sysctl: kern.proc.rlimit: %d", pid); + if (len != sizeof(*rlp)) + errx(EXIT_FAILURE, "sysctl() returns wrong size"); +} + +static void +setrlimit_proc(pid_t pid, int resource, const struct rlimit *rlp) +{ + int error; + int name[5]; + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_RLIMIT; + name[3] = pid; + name[4] = resource; + error = sysctl(name, 5, NULL, 0, rlp, sizeof(*rlp)); + if (error == -1) + err(EXIT_FAILURE, "sysctl: kern.proc.rlimit: %d", pid); +} --=-=-=--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?86d3abtr66.fsf>