From owner-svn-src-all@FreeBSD.ORG Sun Jan 22 20:31:53 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8C02C1065674; Sun, 22 Jan 2012 20:31:53 +0000 (UTC) (envelope-from to.my.trociny@gmail.com) Received: from mail-bk0-f54.google.com (mail-bk0-f54.google.com [209.85.214.54]) by mx1.freebsd.org (Postfix) with ESMTP id 748018FC08; Sun, 22 Jan 2012 20:31:52 +0000 (UTC) Received: by bkbc12 with SMTP id c12so2462170bkb.13 for ; Sun, 22 Jan 2012 12:31:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:references:x-comment-to:sender:date:in-reply-to :message-id:user-agent:mime-version:content-type; bh=bSMuAPSOc40hG5o35WDRUJK5PZL1rgxHaxyrqkL4r9o=; b=cZmXN7CcFT08pQ866TxcTTIvPTsEKJ1CnXcOl1I4zSeThU2F6MuTXp9rOeKsigq52u e9R3rGfyrgQxGUmGCQ6o2FcOWsRzejIzuBDBKRlaVY5jzuGnBh7zjmE0SEd+kODojDgf tvvQh6R5Qmo8Snank0z59LIRdLtydM3S9QjD4= Received: by 10.204.129.18 with SMTP id m18mr2089013bks.115.1327264310256; Sun, 22 Jan 2012 12:31:50 -0800 (PST) Received: from localhost ([95.69.173.122]) by mx.google.com with ESMTPS id fg16sm22991338bkb.16.2012.01.22.12.31.47 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 22 Jan 2012 12:31:49 -0800 (PST) From: Mikolaj Golub To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org References: <201201222025.q0MKP0Ix091451@svn.freebsd.org> X-Comment-To: Mikolaj Golub Sender: Mikolaj Golub Date: Sun, 22 Jan 2012 22:31:45 +0200 In-Reply-To: <201201222025.q0MKP0Ix091451@svn.freebsd.org> (Mikolaj Golub's message of "Sun, 22 Jan 2012 20:25:00 +0000 (UTC)") Message-ID: <86d3abtr66.fsf@kopusha.home.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (berkeley-unix) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Cc: Andrey Zonov , Kostik Belousov Subject: Re: svn commit: r230470 - in head/sys: kern sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 22 Jan 2012 20:31:53 -0000 --=-=-= 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 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 ' without the list of limits is specified it returns the limits for this process. - If '-P ' with the list of limits is specified it changes these limits for the process. - If '-P ' 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 , but core dump is disabled, it could run: eval `limits -P -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 #include #include +#include #include #include #include @@ -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); +} --=-=-=--