util-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 07/15] prlimit: fix case when getting missing limit is needed and PID is given later
@ 2011-11-14  1:48 Bernhard Voelker
  2011-11-16 12:48 ` Karel Zak
  0 siblings, 1 reply; 2+ messages in thread
From: Bernhard Voelker @ 2011-11-14  1:48 UTC (permalink / raw)
  To: util-linux

[PATCH 07/15] prlimit: fix case when getting missing limit is needed and 
PID is given later

When the PID is given later than a partially given limit, then
prlimit used the current PID for getting the missing part
(hard, soft) of the limit. Example:
$ ps
   PID TTY          TIME CMD
   555 pts/6    00:00:00 bash
   ...
$ prlimit -p555 -n --noheadings
NOFILE   max amount of open files 1024 8192
$ sleep 100000&
[1] 650
$ prlimit -p555 -n:5000
$ prlimit -n4000: -p650
$ prlimit -p650 -n --noheadings
NOFILE   max amount of open files 4000 5000

Factored out the retrieval of the unknown limit from parse_prlim()
to new get_unknown_hardsoft() which is to be called by do_prlimit()
based on the new struct prlimit member 'found' set by add_prlim().

Signed-off-by: Bernhard Voelker <mail@bernhard-voelker.de>
---
  sys-utils/prlimit.c |   57 
++++++++++++++++++++++++++++++--------------------
  1 files changed, 34 insertions(+), 23 deletions(-)

diff --git a/sys-utils/prlimit.c b/sys-utils/prlimit.c
index 611f3e8..622a318 100644
--- a/sys-utils/prlimit.c
+++ b/sys-utils/prlimit.c
@@ -85,6 +85,7 @@ static struct prlimit_desc prlimit_desc[] =

  struct prlimit {
  	struct rlimit rlim;
+	int found;
  	struct prlimit_desc *desc;
  	int modify;
  };
@@ -294,6 +295,26 @@ done:
  	return 0;
  }

+static void get_unknown_hardsoft(struct prlimit *lim)
+{
+	/*
+	 * If one of the limits is unknown (default value for not being
+	 * passed), we need to get the current limit and use it.
+	 * I see no other way other than using prlimit(2).
+	 */
+	if (lim->found != (PRLIMIT_HARD | PRLIMIT_SOFT)) {
+		struct rlimit old;
+
+		if (prlimit(pid, lim->desc->resource, NULL, &old) == -1)
+			errx(EXIT_FAILURE, _("failed to get old %s limit"),
+				lim->desc->resource);
+
+		if (!(lim->found & PRLIMIT_SOFT))
+			lim->rlim.rlim_cur = old.rlim_cur;
+		else if (!(lim->found & PRLIMIT_HARD))
+			lim->rlim.rlim_max = old.rlim_max;
+	}
+}

  static void do_prlimit(struct prlimit lims[], size_t n, int tt_flags)
  {
@@ -305,6 +326,17 @@ static void do_prlimit(struct prlimit lims[], 
size_t n, int tt_flags)
  		if (lims[i].modify) {
  			if (!pid)
  				warnx(_("setting limits of the prlimit process is pointless"));
+
+			get_unknown_hardsoft(&lims[i]);
+
+			/* final soft vs. hard limit check to have a
+			 * better diagnostic than "invalid argument".
+			 */
+			if ((lims[i].rlim.rlim_cur > lims[i].rlim.rlim_max) &&
+				(lims[i].rlim.rlim_cur != RLIM_INFINITY ||
+				 lims[i].rlim.rlim_max != RLIM_INFINITY))
+				errx(EXIT_FAILURE, _("the soft limit cannot exceed the ceiling 
value"));
+
  			new = &lims[i].rlim;
  		} else {
  			nshows++;
@@ -420,31 +452,10 @@ static int parse_prlim(struct rlimit *lim, char 
*ops, size_t id)
  		errx(EXIT_FAILURE, _("failed to parse %s limit"),
  		     prlimit_desc[id].name);

-	/*
-	 * If one of the limits is unknown (default value for not being 
passed), we need
-	 * to get the current limit and use it.
-	 * I see no other way other than using prlimit(2).
-	 */
-	if (found != (PRLIMIT_HARD | PRLIMIT_SOFT)) {
-		struct rlimit old;
-
-		if (prlimit(pid, prlimit_desc[id].resource, NULL, &old) == -1)
-			errx(EXIT_FAILURE, _("failed to get old %s limit"),
-			     prlimit_desc[id].name);
-
-		if (!(found & PRLIMIT_SOFT))
-			soft = old.rlim_cur;
-		else if (!(found & PRLIMIT_HARD))
-			hard = old.rlim_max;
-	}
-
-	if (soft > hard && (soft != RLIM_INFINITY || hard != RLIM_INFINITY))
-		errx(EXIT_FAILURE, _("the soft limit cannot exceed the ceiling value"));
-
  	lim->rlim_cur = soft;
  	lim->rlim_max = hard;

-	return 0;
+	return found;
  }

  /*
@@ -456,7 +467,7 @@ static int add_prlim(char *ops, struct prlimit *lim, 
size_t id)

  	if (ops) { /* planning on modifying a limit? */
  		lim->modify = 1;
-		parse_prlim(&lim->rlim, ops, id);
+		lim->found = parse_prlim(&lim->rlim, ops, id);
  	}

  	return 0;

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH 07/15] prlimit: fix case when getting missing limit is needed and PID is given later
  2011-11-14  1:48 [PATCH 07/15] prlimit: fix case when getting missing limit is needed and PID is given later Bernhard Voelker
@ 2011-11-16 12:48 ` Karel Zak
  0 siblings, 0 replies; 2+ messages in thread
From: Karel Zak @ 2011-11-16 12:48 UTC (permalink / raw)
  To: Bernhard Voelker; +Cc: util-linux

On Mon, Nov 14, 2011 at 02:48:23AM +0100, Bernhard Voelker wrote:
> [PATCH 07/15] prlimit: fix case when getting missing limit is needed and  
> PID is given later

 Applied with some minor changes, thanks.

>  struct prlimit {
>  	struct rlimit rlim;
> +	int found;
>  	struct prlimit_desc *desc;
>  	int modify;
>  };

 I think 'modify' is good enough for everything ;-)

    Karel

-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-11-16 12:48 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-14  1:48 [PATCH 07/15] prlimit: fix case when getting missing limit is needed and PID is given later Bernhard Voelker
2011-11-16 12:48 ` Karel Zak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).