public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
* [LTP] [PATCH] [syscalls] getrusage03: test ru_maxrss
@ 2011-05-16 15:05 Caspar Zhang
  2011-05-16 15:08 ` Caspar Zhang
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Caspar Zhang @ 2011-05-16 15:05 UTC (permalink / raw)
  To: LTP List

[-- Attachment #1: Type: text/plain, Size: 770 bytes --]


getrusage03 - test ru_maxrss behaviors in struct rusage

This test program is backported from upstream commit:
1f10206cf8e945220f7220a809d8bfc15c21f9a5, which fills ru_maxrss
value in struct rusage according to rss hiwater mark. To make sure
this feature works correctly, a series of tests are executed in
this program.

Signed-off-by: Caspar Zhang <czhang@redhat.com>
---
 runtest/syscalls                                  |    1 +
 testcases/kernel/syscalls/getrusage/child.c       |  165 ++++++++++
 testcases/kernel/syscalls/getrusage/getrusage03.c |  341 +++++++++++++++++++++
 3 files changed, 507 insertions(+), 0 deletions(-)
 create mode 100644 testcases/kernel/syscalls/getrusage/child.c
 create mode 100644 testcases/kernel/syscalls/getrusage/getrusage03.c


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-syscalls-getrusage03-test-ru_maxrss.patch --]
[-- Type: text/x-patch; name="0001-syscalls-getrusage03-test-ru_maxrss.patch", Size: 15727 bytes --]

diff --git a/runtest/syscalls b/runtest/syscalls
index 4294d07..7989764 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -399,6 +399,7 @@ get_robust_list01 get_robust_list01
 
 getrusage01 getrusage01
 getrusage02 getrusage02
+getrusage03 getrusage03
 
 getsid01 getsid01
 getsid02 getsid02
diff --git a/testcases/kernel/syscalls/getrusage/child.c b/testcases/kernel/syscalls/getrusage/child.c
new file mode 100644
index 0000000..4f81241
--- /dev/null
+++ b/testcases/kernel/syscalls/getrusage/child.c
@@ -0,0 +1,165 @@
+/*
+ * child.c - a child program executed by getrusage03
+ *
+ * Copyright (C) 2011  Red Hat, Inc.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it
+ * is free of the rightful claim of any third person regarding
+ * infringement or the like.  Any license provided herein, whether
+ * implied or otherwise, applies only to this software file.  Patent
+ * licenses, if any, provided herein do not apply to combinations of
+ * this program with other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "child_proc ";
+int TST_TOTAL = 1;
+
+#define DELTA_MAX	10240
+
+static int opt_consume, opt_grand, opt_show, opt_self, opt_child;
+static char *consume_str, *grand_consume_str, *self_str, *child_str;
+
+option_t child_options[] = {
+	{ "n:", &opt_consume, &consume_str },
+	{ "g:", &opt_grand,   &grand_consume_str },
+	{ "v",  &opt_show,    NULL },
+	{ "s:", &opt_self,    &self_str },
+	{ "l:", &opt_child,   &child_str }
+};
+
+static void usage(void);
+static void consume(int mega);
+static void setup(void);
+static void cleanup(void);
+
+int main(int argc, char *argv[])
+{
+	int lc;
+	pid_t pid;
+	long maxrss_self, maxrss_children, delta;
+	struct rusage ru;
+	char *msg;
+
+	msg = parse_opts(argc, argv, child_options, usage);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		Tst_count = 0;
+
+		if (opt_consume) {
+			tst_resm(TINFO, "child allocate %sMB", consume_str);
+			consume(atol(consume_str));
+		}
+
+		if (opt_grand) {
+			tst_resm(TINFO, "grandchild allocate %sMB",
+				grand_consume_str);
+			switch (pid = fork()) {
+			case -1:
+				tst_brkm(TBROK, cleanup, "fork");
+			case 0:
+				consume(atol(grand_consume_str));
+				exit(0);
+			default:
+				break;
+			}
+			while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
+				if (WEXITSTATUS(pid) != 0)
+					tst_brkm(TBROK|TERRNO, cleanup,
+						"child exit status is not 0");
+		}
+
+		if (opt_show) {
+			if (getrusage(RUSAGE_SELF, &ru) == -1)
+				tst_brkm(TBROK|TERRNO, cleanup,
+					"exec getrusage");
+			maxrss_self = ru.ru_maxrss;
+			if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
+				tst_brkm(TBROK|TERRNO, cleanup,
+					"exec getrusage");
+			maxrss_children = ru.ru_maxrss;
+			tst_resm(TINFO, "exec.self = %ld, exec.children = %ld",
+					maxrss_self, maxrss_children);
+			if (opt_self) {
+				delta = maxrss_self - atol(self_str);
+				if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+					tst_resm(TPASS,
+						"initial.self ~= exec.self");
+				else
+					tst_resm(TFAIL,
+						"initial.self !~= exec.self");
+			}
+			if (opt_child) {
+				delta = maxrss_children - atol(child_str);
+				if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+					tst_resm(TPASS,
+						"initial.children ~= exec.children");
+				else
+					tst_resm(TFAIL,
+						"initial.children !~= exec.children");
+			}
+		}
+	}
+
+	cleanup();
+	tst_exit();
+}
+
+static void usage(void)
+{
+	printf("  -n      consume size (MB)\n");
+	printf("  -g      grandchild consume size (MB)\n");
+	printf("  -v      verbose mode, show rusage info\n");
+	printf("  -s      compare rusage_self.maxrss with given number\n");
+	printf("  -l      compare rusage_children.maxrss with given number\n");
+}
+
+static void consume(int mega)
+{
+	size_t sz;
+	void *ptr;
+
+	sz  = mega * 1024 * 1024;
+	ptr = malloc(sz);
+	memset(ptr, 0, sz);
+}
+
+static void setup()
+{
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	TEST_PAUSE;
+}
+
+static void cleanup()
+{
+	TEST_CLEANUP;
+}
diff --git a/testcases/kernel/syscalls/getrusage/getrusage03.c b/testcases/kernel/syscalls/getrusage/getrusage03.c
new file mode 100644
index 0000000..c1d8108
--- /dev/null
+++ b/testcases/kernel/syscalls/getrusage/getrusage03.c
@@ -0,0 +1,341 @@
+/*
+ * getrusage03 - test ru_maxrss behaviors in struct rusage
+ *
+ * This test program is backported from upstream commit:
+ * 1f10206cf8e945220f7220a809d8bfc15c21f9a5, which fills ru_maxrss
+ * value in struct rusage according to rss hiwater mark. To make sure
+ * this feature works correctly, a series of tests are executed in
+ * this program.
+ *
+ * Copyright (C) 2011  Red Hat, Inc.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it
+ * is free of the rightful claim of any third person regarding
+ * infringement or the like.  Any license provided herein, whether
+ * implied or otherwise, applies only to this software file.  Patent
+ * licenses, if any, provided herein do not apply to combinations of
+ * this program with other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "getrusage03";
+int TST_TOTAL = 7, Tst_count;
+
+#define DELTA_MAX	10240
+#define ERR(x) perror(x), cleanup(), exit(-1);
+
+static struct rusage ru;
+static long maxrss_init;
+
+static void check_return(int status, char *pass_msg, char *fail_msg);
+static void consume(int mega);
+static void setup(void);
+static void cleanup(void);
+
+int main(int argc, char *argv[])
+{
+	int lc;
+	long delta;
+	int retval;
+	pid_t pid;
+	char *msg;
+	long maxrss_self, maxrss_child;
+	char str_maxrss_self[BUFSIZ], str_maxrss_child[BUFSIZ];
+
+	msg = parse_opts(argc, argv, NULL, NULL);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		Tst_count = 0;
+
+		tst_resm(TINFO, "allocate 100MB");
+		consume(100);
+
+		/* Testcase #01: fork inherit
+		 * expect: initial.self ~= child.self */
+		tst_resm(TINFO, "Testcase #01: fork inherit");
+		if (getrusage(RUSAGE_SELF, &ru) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #1");
+		tst_resm(TINFO, "initial.self = %ld", ru.ru_maxrss);
+
+		switch (pid = fork()) {
+		case -1:
+			tst_brkm(TBROK|TERRNO, cleanup, "fork #1");
+		case 0:
+			maxrss_init = ru.ru_maxrss;
+			if (getrusage(RUSAGE_SELF, &ru) == -1)
+				ERR("child: getrusage #1");
+			printf("%-8s %4d  TINFO  :  child.self = %ld\n",
+				"child_proc ", 0, ru.ru_maxrss);
+			delta = maxrss_init - ru.ru_maxrss;
+			retval = (delta >= -DELTA_MAX &&
+				delta <= DELTA_MAX) ? 0 : 1;
+			exit(retval);
+		default:
+			break;
+		}
+		while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
+			check_return(WEXITSTATUS(pid),
+				"initial.self ~= child.self",
+				"initial.self !~= child.self");
+
+		/*
+		 * Testcase #02: fork inherit (cont.)
+		 * expect: initial.children ~= 100MB,
+		 *         child.children = 0
+		 */
+		tst_resm(TINFO, "Testcase #02: fork inherit(cont.)");
+		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #2");
+		tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+		delta = ru.ru_maxrss - 102400;
+		if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+			tst_resm(TPASS, "initial.children ~= 100MB");
+		else
+			tst_resm(TFAIL, "initial.children !~= 100MB");
+
+		switch (pid = fork()) {
+		case -1:
+			tst_brkm(TBROK|TERRNO, cleanup, "fork #2");
+		case 0:
+			if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
+				ERR("child: getrusage #2");
+			printf("%-8s %4d  TINFO  :  child.children = %ld\n",
+				"child_proc ", 0, ru.ru_maxrss);
+			retval = (ru.ru_maxrss == 0) ? 0 : 1;
+			exit(retval);
+		default:
+			break;
+		}
+		while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
+			check_return(WEXITSTATUS(pid),
+				"child.children == 0",
+				"child.children != 0");
+
+		/* Testcase #03: fork + malloc
+		 * expect: initial.self + 50MB ~= child.self */
+		tst_resm(TINFO, "Testcase #03: fork + malloc");
+		if (getrusage(RUSAGE_SELF, &ru) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #3");
+		tst_resm(TINFO, "initial.self = %ld", ru.ru_maxrss);
+
+		switch (pid = fork()) {
+		case -1:
+			tst_brkm(TBROK|TERRNO, cleanup, "fork #3");
+		case 0:
+			maxrss_init = ru.ru_maxrss;
+			printf("%-8s %4d  TINFO  :  child allocate +50MB\n",
+				"child_proc ", 0);
+			consume(50);
+			if (getrusage(RUSAGE_SELF, &ru) == -1)
+				ERR("child getrusage #3");
+			printf("%-8s %4d  TINFO  :  child.self = %ld\n",
+				"child_proc ", 0, ru.ru_maxrss);
+			delta = maxrss_init + 51200 - ru.ru_maxrss;
+			retval = (delta >= -DELTA_MAX &&
+				delta <= DELTA_MAX) ? 0 : 1;
+			exit(retval);
+		default:
+			break;
+		}
+		while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
+			check_return(WEXITSTATUS(pid),
+				"initial.self + 50MB ~= child.self",
+				"initial.self + 50MB !~= child.self");
+
+		/* Testcase #04: grandchild maxrss
+		 * expect: post_wait.children ~= 300MB */
+		tst_resm(TINFO, "Testcase #04: grandchild maxrss");
+		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #4");
+		tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+
+		switch (pid = fork()) {
+		case -1:
+			tst_brkm(TBROK|TERRNO, cleanup, "fork #4");
+		case 0:
+			retval = system("./child -g 300");
+			if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
+				ERR("system");
+			exit(0);
+		default:
+			break;
+		}
+		while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
+			if (WEXITSTATUS(pid) != 0)
+				tst_brkm(TBROK|TERRNO, cleanup,
+					"child exit status is not 0");
+		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup,
+				"post_wait getrusage #4");
+		tst_resm(TINFO, "post_wait.children = %ld",
+			ru.ru_maxrss);
+		delta = ru.ru_maxrss - 307200;
+		if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+			tst_resm(TPASS, "child.children ~= 300MB");
+		else
+			tst_resm(TFAIL, "child.children !~= 300MB");
+
+		/* Testcase #05: zombie
+		 * expect: initial ~= pre_wait, post_wait ~= 400MB */
+		tst_resm(TINFO, "Testcase #05: zombie");
+		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #5");
+		tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+		maxrss_init = ru.ru_maxrss;
+		switch (pid = fork()) {
+		case -1:
+			tst_brkm(TBROK, cleanup, "fork #5");
+		case 0:
+			retval = system("./child -n 400");
+			if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
+				ERR("system");
+			exit(0);
+		default:
+			break;
+		}
+		sleep(1); /* children become zombie */
+		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup,
+				"pre_wait getrusage #5");
+		tst_resm(TINFO, "pre_wait.children = %ld", ru.ru_maxrss);
+		delta = ru.ru_maxrss - maxrss_init;
+		if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+			tst_resm(TPASS,
+				"initial.children ~= pre_wait.children");
+		else
+			tst_resm(TFAIL,
+				"initial.children !~= pre_wait.children");
+		while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
+			if (WEXITSTATUS(pid) != 0)
+				tst_brkm(TBROK|TERRNO, cleanup,
+					"child exit status is not 0");
+		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup,
+				"post_wait getrusage #5");
+		tst_resm(TINFO, "post_wait.children = %ld", ru.ru_maxrss);
+		delta = ru.ru_maxrss - 409600;
+		if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+			tst_resm(TPASS, "post_wait.children ~= 400MB");
+		else
+			tst_resm(TFAIL, "post_wait.children !~= 400MB");
+
+		/* Testcase #06: SIG_IGN
+		 * expect: initial ~= after_zombie */
+		tst_resm(TINFO, "Testcase #06: SIG_IGN");
+		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #6");
+		tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+		signal(SIGCHLD, SIG_IGN);
+		maxrss_init = ru.ru_maxrss;
+		switch (pid = fork()) {
+		case -1:
+			tst_brkm(TBROK, cleanup, "fork #6");
+		case 0:
+			retval = system("./child -n 500");
+			if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
+				ERR("system");
+			exit(0);
+		default:
+			break;
+		}
+		sleep(1); /* children become zombie */
+		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup,
+				"after_zombie getrusage #6");
+		tst_resm(TINFO, "after_zombie.children = %ld",
+			ru.ru_maxrss);
+		delta = ru.ru_maxrss - maxrss_init;
+		if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+			tst_resm(TPASS,
+				"initial.children ~= after_zombie.children");
+		else
+			tst_resm(TFAIL,
+				"initial.children !~= after_zombie.children");
+		signal(SIGCHLD, SIG_DFL);
+
+		/* Testcase #07: exec without fork
+		 * expect: initial ~= fork */
+		tst_resm(TINFO, "Testcase #07: exec without fork");
+		if (getrusage(RUSAGE_SELF, &ru) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #7");
+		maxrss_self = ru.ru_maxrss;
+		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #7");
+		maxrss_child = ru.ru_maxrss;
+		tst_resm(TINFO, "initial.self = %ld, initial.children = %ld",
+				maxrss_self, maxrss_child);
+		sprintf(str_maxrss_self, "%ld", maxrss_self);
+		sprintf(str_maxrss_child, "%ld", maxrss_child);
+		if (execl("./child", "child", "-v",
+				"-s", str_maxrss_self,
+				"-l", str_maxrss_child, NULL) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup, "execl");
+	}
+	cleanup();
+	tst_exit();
+}
+
+static void check_return(int status, char *pass_msg, char *fail_msg)
+{
+	switch (status) {
+	case 0:
+		tst_resm(TPASS, "%s", pass_msg);
+		break;
+	case 1:
+		tst_resm(TFAIL, "%s", fail_msg);
+		break;
+	default:
+		tst_resm(TFAIL, "child exit status is %d", status);
+		break;
+	}
+}
+
+static void consume(int mega)
+{
+	size_t sz;
+	void *ptr;
+
+	sz  = mega * 1024 * 1024;
+	ptr = malloc(sz);
+	memset(ptr, 0, sz);
+}
+
+static void setup(void)
+{
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	TEST_PAUSE;
+}
+
+static void cleanup(void)
+{
+	TEST_CLEANUP;
+}

[-- Attachment #3: Type: text/plain, Size: 350 bytes --]

------------------------------------------------------------------------------
Achieve unprecedented app performance and reliability
What every C/C++ and Fortran developer should know.
Learn how Intel has extended the reach of its next-generation tools
to help boost performance applications - inlcuding clusters.
http://p.sf.net/sfu/intel-dev2devmay

[-- Attachment #4: Type: text/plain, Size: 155 bytes --]

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH] [syscalls] getrusage03: test ru_maxrss
  2011-05-16 15:05 [LTP] [PATCH] [syscalls] getrusage03: test ru_maxrss Caspar Zhang
@ 2011-05-16 15:08 ` Caspar Zhang
  2011-05-19 17:40 ` Cyril Hrubis
  2011-06-13 13:12 ` [LTP] [PATCH v2] " Caspar Zhang
  2 siblings, 0 replies; 10+ messages in thread
From: Caspar Zhang @ 2011-05-16 15:08 UTC (permalink / raw)
  To: LTP List

On 05/16/2011 11:05 PM, Caspar Zhang wrote:
> 
> getrusage03 - test ru_maxrss behaviors in struct rusage
> 
> This test program is backported from upstream commit:
> 1f10206cf8e945220f7220a809d8bfc15c21f9a5, which fills ru_maxrss
> value in struct rusage according to rss hiwater mark. To make sure
> this feature works correctly, a series of tests are executed in
> this program.
> 
> Signed-off-by: Caspar Zhang <czhang@redhat.com>
> ---
>  runtest/syscalls                                  |    1 +
>  testcases/kernel/syscalls/getrusage/child.c       |  165 ++++++++++
>  testcases/kernel/syscalls/getrusage/getrusage03.c |  341 +++++++++++++++++++++
>  3 files changed, 507 insertions(+), 0 deletions(-)
>  create mode 100644 testcases/kernel/syscalls/getrusage/child.c
>  create mode 100644 testcases/kernel/syscalls/getrusage/getrusage03.c
> 

PASS/FAIL Criteria
==================
This test PASS when all sub-tests executed successfully and return code
is 0. The test gets FAIL when any TFAIL/TBROK information occurs on
output or/and the return code is a non-zero value.

EXAMPLE OUTPUT
==============
getrusage03    0  TINFO  :  allocate 100MB
getrusage03    0  TINFO  :  Testcase #01: fork inherit
getrusage03    0  TINFO  :  initial.self = 108456
child_proc     0  TINFO  :  child.self = 103632
getrusage03    1  TPASS  :  initial.self ~= child.self
getrusage03    0  TINFO  :  Testcase #02: fork inherit(cont.)
getrusage03    0  TINFO  :  initial.children = 105244
getrusage03    2  TPASS  :  initial.children ~= 100MB
child_proc     0  TINFO  :  child.children = 0
getrusage03    3  TPASS  :  child.children == 0
getrusage03    0  TINFO  :  Testcase #03: fork + malloc
getrusage03    0  TINFO  :  initial.self = 108716
child_proc     0  TINFO  :  child allocate +50MB
child_proc     0  TINFO  :  child.self = 154744
getrusage03    4  TPASS  :  initial.self + 50MB ~= child.self
getrusage03    0  TINFO  :  Testcase #04: grandchild maxrss
getrusage03    0  TINFO  :  initial.children = 156460
child_proc     0  TINFO  :  grandchild allocate 300MB
getrusage03    0  TINFO  :  post_wait.children = 310028
getrusage03    5  TPASS  :  child.children ~= 300MB
getrusage03    0  TINFO  :  Testcase #05: zombie
getrusage03    0  TINFO  :  initial.children = 310028
child_proc     0  TINFO  :  child allocate 400MB
getrusage03    0  TINFO  :  pre_wait.children = 310028
getrusage03    6  TPASS  :  initial.children ~= pre_wait.children
getrusage03    0  TINFO  :  post_wait.children = 415972
getrusage03    7  TPASS  :  post_wait.children ~= 400MB
getrusage03    0  TINFO  :  Testcase #06: SIG_IGN
getrusage03    0  TINFO  :  initial.children = 415972
child_proc     0  TINFO  :  child allocate 500MB
getrusage03    0  TINFO  :  after_zombie.children = 415972
getrusage03    8  TPASS  :  initial.children ~= after_zombie.children
getrusage03    0  TINFO  :  Testcase #07: exec without fork
getrusage03    0  TINFO  :  initial.self = 108720, initial.children = 415972
child_proc     0  TINFO  :  exec.self = 108732, exec.children = 415972
child_proc     1  TPASS  :  initial.self ~= exec.self
child_proc     2  TPASS  :  initial.children ~= exec.children

# echo $?
0

------------------------------------------------------------------------------
Achieve unprecedented app performance and reliability
What every C/C++ and Fortran developer should know.
Learn how Intel has extended the reach of its next-generation tools
to help boost performance applications - inlcuding clusters.
http://p.sf.net/sfu/intel-dev2devmay
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH] [syscalls] getrusage03: test ru_maxrss
  2011-05-16 15:05 [LTP] [PATCH] [syscalls] getrusage03: test ru_maxrss Caspar Zhang
  2011-05-16 15:08 ` Caspar Zhang
@ 2011-05-19 17:40 ` Cyril Hrubis
       [not found]   ` <BANLkTi=m96RBZeFuRaOA5Sb_QANhgo4yCA@mail.gmail.com>
  2011-06-13 13:12 ` [LTP] [PATCH v2] " Caspar Zhang
  2 siblings, 1 reply; 10+ messages in thread
From: Cyril Hrubis @ 2011-05-19 17:40 UTC (permalink / raw)
  To: Caspar Zhang; +Cc: LTP List

Hi!
> +char *TCID = "child_proc ";

Is this whitespace at the end of child_proc intentional?

> +int TST_TOTAL = 1;
> +
> +#define DELTA_MAX	10240
> +
> +static int opt_consume, opt_grand, opt_show, opt_self, opt_child;
> +static char *consume_str, *grand_consume_str, *self_str, *child_str;
> +
> +option_t child_options[] = {
> +	{ "n:", &opt_consume, &consume_str },
> +	{ "g:", &opt_grand,   &grand_consume_str },
> +	{ "v",  &opt_show,    NULL },
> +	{ "s:", &opt_self,    &self_str },
> +	{ "l:", &opt_child,   &child_str }
> +};
> +
> +static void usage(void);
> +static void consume(int mega);
> +static void setup(void);
> +static void cleanup(void);
> +
> +int main(int argc, char *argv[])
> +{
> +	int lc;
> +	pid_t pid;
> +	long maxrss_self, maxrss_children, delta;
> +	struct rusage ru;
> +	char *msg;
> +
> +	msg = parse_opts(argc, argv, child_options, usage);
> +	if (msg != NULL)
> +		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
> +
> +	setup();
> +
> +	for (lc = 0; TEST_LOOPING(lc); lc++) {
> +		Tst_count = 0;
> +
> +		if (opt_consume) {
> +			tst_resm(TINFO, "child allocate %sMB", consume_str);
> +			consume(atol(consume_str));

I would rather use strtol() here and print errors when invalid
parameters were given.

> +		}
> +
> +		if (opt_grand) {
> +			tst_resm(TINFO, "grandchild allocate %sMB",
> +				grand_consume_str);
> +			switch (pid = fork()) {
> +			case -1:
> +				tst_brkm(TBROK, cleanup, "fork");
> +			case 0:
> +				consume(atol(grand_consume_str));

Here too.

> +				exit(0);
> +			default:
> +				break;
> +			}
> +			while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
> +				if (WEXITSTATUS(pid) != 0)
> +					tst_brkm(TBROK|TERRNO, cleanup,
> +						"child exit status is not 0");
> +		}
> +
> +		if (opt_show) {
> +			if (getrusage(RUSAGE_SELF, &ru) == -1)
> +				tst_brkm(TBROK|TERRNO, cleanup,
> +					"exec getrusage");
> +			maxrss_self = ru.ru_maxrss;
> +			if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
> +				tst_brkm(TBROK|TERRNO, cleanup,
> +					"exec getrusage");
> +			maxrss_children = ru.ru_maxrss;
> +			tst_resm(TINFO, "exec.self = %ld, exec.children = %ld",
> +					maxrss_self, maxrss_children);
> +			if (opt_self) {
> +				delta = maxrss_self - atol(self_str);
> +				if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
> +					tst_resm(TPASS,
> +						"initial.self ~= exec.self");
> +				else
> +					tst_resm(TFAIL,
> +						"initial.self !~= exec.self");
> +			}
> +			if (opt_child) {
> +				delta = maxrss_children - atol(child_str);
> +				if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
> +					tst_resm(TPASS,
> +						"initial.children ~= exec.children");
> +				else
> +					tst_resm(TFAIL,
> +						"initial.children !~= exec.children");
> +			}
> +		}
> +	}
> +
> +	cleanup();
> +	tst_exit();
> +}
> +
> +static void usage(void)
> +{
> +	printf("  -n      consume size (MB)\n");
> +	printf("  -g      grandchild consume size (MB)\n");
> +	printf("  -v      verbose mode, show rusage info\n");
> +	printf("  -s      compare rusage_self.maxrss with given number\n");
> +	printf("  -l      compare rusage_children.maxrss with given number\n");
> +}
> +
> +static void consume(int mega)
> +{
> +	size_t sz;
> +	void *ptr;
> +
> +	sz  = mega * 1024 * 1024;
> +	ptr = malloc(sz);
> +	memset(ptr, 0, sz);
> +}
> +
> +static void setup()
> +{
> +	tst_sig(FORK, DEF_HANDLER, cleanup);
> +
> +	TEST_PAUSE;
> +}
> +
> +static void cleanup()
> +{
> +	TEST_CLEANUP;
> +}

Also naming the file simple child.c is not wise idea as it likely will
collide after installation. I would suggest getrusage03_child.c here.

It seems that there isn't child binary just now, but even then, somebody
will burn because of that sooner or later.

> diff --git a/testcases/kernel/syscalls/getrusage/getrusage03.c b/testcases/kernel/syscalls/getrusage/getrusage03.c
> new file mode 100644
> index 0000000..c1d8108
> --- /dev/null
> +++ b/testcases/kernel/syscalls/getrusage/getrusage03.c
> @@ -0,0 +1,341 @@
> +/*
> + * getrusage03 - test ru_maxrss behaviors in struct rusage
> + *
> + * This test program is backported from upstream commit:
> + * 1f10206cf8e945220f7220a809d8bfc15c21f9a5, which fills ru_maxrss
> + * value in struct rusage according to rss hiwater mark. To make sure
> + * this feature works correctly, a series of tests are executed in
> + * this program.
> + *
> + * Copyright (C) 2011  Red Hat, Inc.
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of version 2 of the GNU General Public
> + * License as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it would be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> + *
> + * Further, this software is distributed without any warranty that it
> + * is free of the rightful claim of any third person regarding
> + * infringement or the like.  Any license provided herein, whether
> + * implied or otherwise, applies only to this software file.  Patent
> + * licenses, if any, provided herein do not apply to combinations of
> + * this program with other software, or any other product whatsoever.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + */
> +#include <sys/types.h>
> +#include <sys/mman.h>
> +#include <sys/resource.h>
> +#include <sys/time.h>
> +#include <sys/wait.h>
> +#include <unistd.h>
> +#include <signal.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include "test.h"
> +#include "usctest.h"
> +
> +char *TCID = "getrusage03";
> +int TST_TOTAL = 7, Tst_count;
> +
> +#define DELTA_MAX	10240
> +#define ERR(x) perror(x), cleanup(), exit(-1);
> +
> +static struct rusage ru;
> +static long maxrss_init;
> +
> +static void check_return(int status, char *pass_msg, char *fail_msg);
> +static void consume(int mega);
> +static void setup(void);
> +static void cleanup(void);
> +
> +int main(int argc, char *argv[])
> +{
> +	int lc;
> +	long delta;
> +	int retval;
> +	pid_t pid;
> +	char *msg;
> +	long maxrss_self, maxrss_child;
> +	char str_maxrss_self[BUFSIZ], str_maxrss_child[BUFSIZ];
> +
> +	msg = parse_opts(argc, argv, NULL, NULL);
> +	if (msg != NULL)
> +		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
> +
> +	setup();
> +
> +	for (lc = 0; TEST_LOOPING(lc); lc++) {
> +		Tst_count = 0;
> +
> +		tst_resm(TINFO, "allocate 100MB");
> +		consume(100);
> +
> +		/* Testcase #01: fork inherit
> +		 * expect: initial.self ~= child.self */
> +		tst_resm(TINFO, "Testcase #01: fork inherit");
> +		if (getrusage(RUSAGE_SELF, &ru) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #1");
> +		tst_resm(TINFO, "initial.self = %ld", ru.ru_maxrss);
> +
> +		switch (pid = fork()) {
> +		case -1:
> +			tst_brkm(TBROK|TERRNO, cleanup, "fork #1");
> +		case 0:
> +			maxrss_init = ru.ru_maxrss;
> +			if (getrusage(RUSAGE_SELF, &ru) == -1)
> +				ERR("child: getrusage #1");
> +			printf("%-8s %4d  TINFO  :  child.self = %ld\n",
> +				"child_proc ", 0, ru.ru_maxrss);
> +			delta = maxrss_init - ru.ru_maxrss;
> +			retval = (delta >= -DELTA_MAX &&
> +				delta <= DELTA_MAX) ? 0 : 1;
> +			exit(retval);
> +		default:
> +			break;
> +		}
> +		while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
> +			check_return(WEXITSTATUS(pid),
> +				"initial.self ~= child.self",
> +				"initial.self !~= child.self");
> +
> +		/*
> +		 * Testcase #02: fork inherit (cont.)
> +		 * expect: initial.children ~= 100MB,
> +		 *         child.children = 0
> +		 */
> +		tst_resm(TINFO, "Testcase #02: fork inherit(cont.)");
> +		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #2");
> +		tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
> +		delta = ru.ru_maxrss - 102400;
> +		if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
> +			tst_resm(TPASS, "initial.children ~= 100MB");
> +		else
> +			tst_resm(TFAIL, "initial.children !~= 100MB");
> +
> +		switch (pid = fork()) {
> +		case -1:
> +			tst_brkm(TBROK|TERRNO, cleanup, "fork #2");
> +		case 0:
> +			if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
> +				ERR("child: getrusage #2");
> +			printf("%-8s %4d  TINFO  :  child.children = %ld\n",
> +				"child_proc ", 0, ru.ru_maxrss);
> +			retval = (ru.ru_maxrss == 0) ? 0 : 1;
> +			exit(retval);
> +		default:
> +			break;
> +		}
> +		while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
> +			check_return(WEXITSTATUS(pid),
> +				"child.children == 0",
> +				"child.children != 0");
> +
> +		/* Testcase #03: fork + malloc
> +		 * expect: initial.self + 50MB ~= child.self */
> +		tst_resm(TINFO, "Testcase #03: fork + malloc");
> +		if (getrusage(RUSAGE_SELF, &ru) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #3");
> +		tst_resm(TINFO, "initial.self = %ld", ru.ru_maxrss);
> +
> +		switch (pid = fork()) {
> +		case -1:
> +			tst_brkm(TBROK|TERRNO, cleanup, "fork #3");
> +		case 0:
> +			maxrss_init = ru.ru_maxrss;
> +			printf("%-8s %4d  TINFO  :  child allocate +50MB\n",
> +				"child_proc ", 0);
> +			consume(50);
> +			if (getrusage(RUSAGE_SELF, &ru) == -1)
> +				ERR("child getrusage #3");
> +			printf("%-8s %4d  TINFO  :  child.self = %ld\n",
> +				"child_proc ", 0, ru.ru_maxrss);
> +			delta = maxrss_init + 51200 - ru.ru_maxrss;
> +			retval = (delta >= -DELTA_MAX &&
> +				delta <= DELTA_MAX) ? 0 : 1;
> +			exit(retval);
> +		default:
> +			break;
> +		}
> +		while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
> +			check_return(WEXITSTATUS(pid),
> +				"initial.self + 50MB ~= child.self",
> +				"initial.self + 50MB !~= child.self");
> +
> +		/* Testcase #04: grandchild maxrss
> +		 * expect: post_wait.children ~= 300MB */
> +		tst_resm(TINFO, "Testcase #04: grandchild maxrss");
> +		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #4");
> +		tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
> +
> +		switch (pid = fork()) {
> +		case -1:
> +			tst_brkm(TBROK|TERRNO, cleanup, "fork #4");
> +		case 0:
> +			retval = system("./child -g 300");
> +			if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
> +				ERR("system");
> +			exit(0);
> +		default:
> +			break;
> +		}
> +		while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
> +			if (WEXITSTATUS(pid) != 0)
> +				tst_brkm(TBROK|TERRNO, cleanup,
> +					"child exit status is not 0");
> +		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup,
> +				"post_wait getrusage #4");
> +		tst_resm(TINFO, "post_wait.children = %ld",
> +			ru.ru_maxrss);
> +		delta = ru.ru_maxrss - 307200;
> +		if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
> +			tst_resm(TPASS, "child.children ~= 300MB");
> +		else
> +			tst_resm(TFAIL, "child.children !~= 300MB");
> +
> +		/* Testcase #05: zombie
> +		 * expect: initial ~= pre_wait, post_wait ~= 400MB */
> +		tst_resm(TINFO, "Testcase #05: zombie");
> +		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #5");
> +		tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
> +		maxrss_init = ru.ru_maxrss;
> +		switch (pid = fork()) {
> +		case -1:
> +			tst_brkm(TBROK, cleanup, "fork #5");
> +		case 0:
> +			retval = system("./child -n 400");
> +			if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
> +				ERR("system");
> +			exit(0);
> +		default:
> +			break;
> +		}
> +		sleep(1); /* children become zombie */
> +		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup,
> +				"pre_wait getrusage #5");
> +		tst_resm(TINFO, "pre_wait.children = %ld", ru.ru_maxrss);
> +		delta = ru.ru_maxrss - maxrss_init;
> +		if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
> +			tst_resm(TPASS,
> +				"initial.children ~= pre_wait.children");
> +		else
> +			tst_resm(TFAIL,
> +				"initial.children !~= pre_wait.children");
> +		while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
> +			if (WEXITSTATUS(pid) != 0)
> +				tst_brkm(TBROK|TERRNO, cleanup,
> +					"child exit status is not 0");
> +		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup,
> +				"post_wait getrusage #5");
> +		tst_resm(TINFO, "post_wait.children = %ld", ru.ru_maxrss);
> +		delta = ru.ru_maxrss - 409600;
> +		if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
> +			tst_resm(TPASS, "post_wait.children ~= 400MB");
> +		else
> +			tst_resm(TFAIL, "post_wait.children !~= 400MB");
> +
> +		/* Testcase #06: SIG_IGN
> +		 * expect: initial ~= after_zombie */
> +		tst_resm(TINFO, "Testcase #06: SIG_IGN");
> +		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #6");
> +		tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
> +		signal(SIGCHLD, SIG_IGN);
> +		maxrss_init = ru.ru_maxrss;
> +		switch (pid = fork()) {
> +		case -1:
> +			tst_brkm(TBROK, cleanup, "fork #6");
> +		case 0:
> +			retval = system("./child -n 500");
> +			if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
> +				ERR("system");
> +			exit(0);
> +		default:
> +			break;
> +		}
> +		sleep(1); /* children become zombie */
> +		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup,
> +				"after_zombie getrusage #6");
> +		tst_resm(TINFO, "after_zombie.children = %ld",
> +			ru.ru_maxrss);
> +		delta = ru.ru_maxrss - maxrss_init;
> +		if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
> +			tst_resm(TPASS,
> +				"initial.children ~= after_zombie.children");
> +		else
> +			tst_resm(TFAIL,
> +				"initial.children !~= after_zombie.children");
> +		signal(SIGCHLD, SIG_DFL);
> +
> +		/* Testcase #07: exec without fork
> +		 * expect: initial ~= fork */
> +		tst_resm(TINFO, "Testcase #07: exec without fork");
> +		if (getrusage(RUSAGE_SELF, &ru) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #7");
> +		maxrss_self = ru.ru_maxrss;
> +		if (getrusage(RUSAGE_CHILDREN, &ru) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup, "getrusage #7");
> +		maxrss_child = ru.ru_maxrss;
> +		tst_resm(TINFO, "initial.self = %ld, initial.children = %ld",
> +				maxrss_self, maxrss_child);
> +		sprintf(str_maxrss_self, "%ld", maxrss_self);
> +		sprintf(str_maxrss_child, "%ld", maxrss_child);
> +		if (execl("./child", "child", "-v",
> +				"-s", str_maxrss_self,
> +				"-l", str_maxrss_child, NULL) == -1)
> +			tst_brkm(TBROK|TERRNO, cleanup, "execl");

Executing binaries from local directory likely won't work after the test
is installed. Do we have some helper fuctions for that; Garrett?

> +	}
> +	cleanup();
> +	tst_exit();
> +}


Aaargh, the main is too long, could you split the testcases into
individual functions.

Also creating SAFE_GETRUSAGE() (as it is done in include/safe_macros.h)
would probably make the code simplier.

And creating function to handle the delta may help too, then you
can just easily write:

if (is_in_delta(ru.ru_maxrss - maxrss_init)) {
...

or:

exit(is_in_delta(maxrss_init - ru.ru_maxrss));


> +static void check_return(int status, char *pass_msg, char *fail_msg)
> +{
> +	switch (status) {
> +	case 0:
> +		tst_resm(TPASS, "%s", pass_msg);
> +		break;
> +	case 1:
> +		tst_resm(TFAIL, "%s", fail_msg);
> +		break;
> +	default:
> +		tst_resm(TFAIL, "child exit status is %d", status);
> +		break;
> +	}
> +}
> +
> +static void consume(int mega)
> +{
> +	size_t sz;
> +	void *ptr;
> +
> +	sz  = mega * 1024 * 1024;
> +	ptr = malloc(sz);
> +	memset(ptr, 0, sz);
> +}

I would rather check the return value here. You know, there may be
strange linux system where this may segfault here. Or even better, use
SAFE_MALLOC() from safe_macros.h.

> +static void setup(void)
> +{
> +	tst_sig(FORK, DEF_HANDLER, cleanup);
> +
> +	TEST_PAUSE;
> +}
> +
> +static void cleanup(void)
> +{
> +	TEST_CLEANUP;
> +}


-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
What Every C/C++ and Fortran developer Should Know!
Read this article and learn how Intel has extended the reach of its 
next-generation tools to help Windows* and Linux* C/C++ and Fortran 
developers boost performance applications - including clusters. 
http://p.sf.net/sfu/intel-dev2devmay
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH] [syscalls] getrusage03: test ru_maxrss
       [not found]   ` <BANLkTi=m96RBZeFuRaOA5Sb_QANhgo4yCA@mail.gmail.com>
@ 2011-05-20 13:29     ` Cyril Hrubis
  0 siblings, 0 replies; 10+ messages in thread
From: Cyril Hrubis @ 2011-05-20 13:29 UTC (permalink / raw)
  To: Garrett Cooper; +Cc: LTP List

Hi!
>     [Un]fortunately we don't (I say that because writing something
> functional would be kind of a pain because we'd need to replicate what
> tar does with that file mode, permissions bits, and other fun security
> attributes in order to be complete).
>     Does this need to be run from the current working directory, or
> can it be picked up from $PATH ? If the latter is ok, then all you
> need to do is add $LTPROOT/testcases/bin to $PATH (which should be
> done already by runltp) and use execvp, or you could play tricks and
> lookup the dirname of the realpath, etc of the testcase (argv[0]), and
> use that in the execle, etc call.

All the child does here is allocating memory, so I would say execvp() is
good enough in this case. (And adding note about this into style-guide
would be great).

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
What Every C/C++ and Fortran developer Should Know!
Read this article and learn how Intel has extended the reach of its 
next-generation tools to help Windows* and Linux* C/C++ and Fortran 
developers boost performance applications - including clusters. 
http://p.sf.net/sfu/intel-dev2devmay
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* [LTP] [PATCH v2] [syscalls] getrusage03: test ru_maxrss
  2011-05-16 15:05 [LTP] [PATCH] [syscalls] getrusage03: test ru_maxrss Caspar Zhang
  2011-05-16 15:08 ` Caspar Zhang
  2011-05-19 17:40 ` Cyril Hrubis
@ 2011-06-13 13:12 ` Caspar Zhang
  2011-06-29 14:14   ` Cyril Hrubis
  2011-06-29 15:36   ` [LTP] [PATCH v3] " Caspar Zhang
  2 siblings, 2 replies; 10+ messages in thread
From: Caspar Zhang @ 2011-06-13 13:12 UTC (permalink / raw)
  To: LTP List

[-- Attachment #1: Type: text/plain, Size: 906 bytes --]


getrusage03 - test ru_maxrss behaviors in struct rusage

This test program is backported from upstream commit:
1f10206cf8e945220f7220a809d8bfc15c21f9a5, which fills ru_maxrss
value in struct rusage according to rss hiwater mark. To make sure
this feature works correctly, a series of tests are executed in
this program.

Signed-off-by: Caspar Zhang <czhang@redhat.com>
---
 include/safe_macros.h                              |    5 +
 lib/safe_macros.c                                  |   15 +
 runtest/syscalls                                   |    1 +
 testcases/kernel/syscalls/getrusage/getrusage03.c  |  359 ++++++++++++++++++++
 .../kernel/syscalls/getrusage/getrusage03_child.c  |  183 ++++++++++
 5 files changed, 563 insertions(+), 0 deletions(-)
 create mode 100644 testcases/kernel/syscalls/getrusage/getrusage03.c
 create mode 100644 testcases/kernel/syscalls/getrusage/getrusage03_child.c


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-syscalls-getrusage03-test-ru_maxrss.patch --]
[-- Type: text/x-patch; name="0001-syscalls-getrusage03-test-ru_maxrss.patch", Size: 17617 bytes --]

diff --git a/include/safe_macros.h b/include/safe_macros.h
index 7c99c66..3753b7f 100644
--- a/include/safe_macros.h
+++ b/include/safe_macros.h
@@ -58,6 +58,11 @@ struct passwd*	safe_getpwnam(const char *file, const int lineno,
 #define SAFE_GETPWNAM(cleanup_fn, name)	\
 	safe_getpwnam(__FILE__, __LINE__, cleanup_fn, (name))
 
+int     safe_getrusage(const char *file, const int lineno,
+	    void (*cleanup_fn)(void), int who, struct rusage *usage);
+#define SAFE_GETRUSAGE(cleanup_fn, who, usage) \
+	safe_getrusage(__FILE__, __LINE__, (cleanup_fn), (who), (usage))
+
 void*	safe_malloc(const char *file, const int lineno,
 	    void (*cleanup_fn)(void), size_t size);
 #define SAFE_MALLOC(cleanup_fn, size)	\
diff --git a/lib/safe_macros.c b/lib/safe_macros.c
index c98376d..11f5fe6 100644
--- a/lib/safe_macros.c
+++ b/lib/safe_macros.c
@@ -1,5 +1,6 @@
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <libgen.h>
@@ -108,6 +109,20 @@ safe_getpwnam(const char *file, const int lineno, void (*cleanup_fn)(void),
 	return (rval);
 }
 
+int
+safe_getrusage(const char *file, const int lineno, void (*cleanup_fn)(void),
+	    int who, struct rusage *usage)
+{
+	int rval;
+
+	rval = getrusage(who, usage);
+	if (rval == -1)
+		tst_brkm(TBROK|TERRNO, cleanup_fn, "getrusage failed at %s:%d",
+		    file, lineno);
+
+	return rval;
+}
+
 void*
 safe_malloc(const char *file, const int lineno, void (*cleanup_fn)(void),
     size_t size)
diff --git a/runtest/syscalls b/runtest/syscalls
index 4294d07..7989764 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -399,6 +399,7 @@ get_robust_list01 get_robust_list01
 
 getrusage01 getrusage01
 getrusage02 getrusage02
+getrusage03 getrusage03
 
 getsid01 getsid01
 getsid02 getsid02
diff --git a/testcases/kernel/syscalls/getrusage/getrusage03.c b/testcases/kernel/syscalls/getrusage/getrusage03.c
new file mode 100644
index 0000000..79c7508
--- /dev/null
+++ b/testcases/kernel/syscalls/getrusage/getrusage03.c
@@ -0,0 +1,359 @@
+/*
+ * getrusage03 - test ru_maxrss behaviors in struct rusage
+ *
+ * This test program is backported from upstream commit:
+ * 1f10206cf8e945220f7220a809d8bfc15c21f9a5, which fills ru_maxrss
+ * value in struct rusage according to rss hiwater mark. To make sure
+ * this feature works correctly, a series of tests are executed in
+ * this program.
+ *
+ * Copyright (C) 2011  Red Hat, Inc.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it
+ * is free of the rightful claim of any third person regarding
+ * infringement or the like.  Any license provided herein, whether
+ * implied or otherwise, applies only to this software file.  Patent
+ * licenses, if any, provided herein do not apply to combinations of
+ * this program with other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+#include "usctest.h"
+#include "safe_macros.h"
+
+char *TCID = "getrusage03";
+int TST_TOTAL = 1;
+
+#define DELTA_MAX	10240
+
+static struct rusage ru;
+static long maxrss_init;
+static int retval, status;
+static pid_t pid;
+
+static void inherit_fork(void);
+static void inherit_fork2(void);
+static void fork_malloc(void);
+static void grandchild_maxrss(void);
+static void zombie(void);
+static void sig_ign(void);
+static void exec_without_fork(void);
+static void check_return(int status, char *pass_msg, char *fail_msg);
+static int is_in_delta(long value);
+static void consume(int mega);
+static void setup(void);
+static void cleanup(void);
+
+int main(int argc, char *argv[])
+{
+	int lc;
+	char *msg;
+
+	msg = parse_opts(argc, argv, NULL, NULL);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		Tst_count = 0;
+
+		tst_resm(TINFO, "allocate 100MB");
+		consume(100);
+
+		inherit_fork();
+		inherit_fork2();
+		fork_malloc();
+		grandchild_maxrss();
+		zombie();
+		sig_ign();
+		exec_without_fork();
+	}
+	cleanup();
+	tst_exit();
+}
+
+/* Testcase #01: fork inherit
+ * expect: initial.self ~= child.self */
+static void inherit_fork(void)
+{
+	tst_resm(TINFO, "Testcase #01: fork inherit");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+	tst_resm(TINFO, "initial.self = %ld", ru.ru_maxrss);
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK|TERRNO, cleanup, "fork #1");
+	case 0:
+		maxrss_init = ru.ru_maxrss;
+		SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+		tst_resm(TINFO, "child.self = %ld", ru.ru_maxrss);
+		exit(is_in_delta(maxrss_init - ru.ru_maxrss));
+	default:
+		break;
+	}
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	check_return(WEXITSTATUS(status), "initial.self ~= child.self",
+		    "initial.self !~= child.self");
+}
+
+/* Testcase #02: fork inherit (cont.)
+ * expect: initial.children ~= 100MB, child.children = 0 */
+static void inherit_fork2(void)
+{
+	tst_resm(TINFO, "Testcase #02: fork inherit(cont.)");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - 102400) == 0)
+		tst_resm(TPASS, "initial.children ~= 100MB");
+	else
+		tst_resm(TFAIL, "initial.children !~= 100MB");
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK|TERRNO, cleanup, "fork #2");
+	case 0:
+		SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+		tst_resm(TINFO, "child.children = %ld", ru.ru_maxrss);
+		exit((ru.ru_maxrss == 0) ? 0 : 1);
+	default:
+		break;
+	}
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	check_return(WEXITSTATUS(status), "child.children == 0",
+		    "child.children != 0");
+}
+
+/* Testcase #03: fork + malloc
+ * expect: initial.self + 50MB ~= child.self */
+static void fork_malloc(void)
+{
+	tst_resm(TINFO, "Testcase #03: fork + malloc");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+	tst_resm(TINFO, "initial.self = %ld", ru.ru_maxrss);
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK|TERRNO, cleanup, "fork #3");
+	case 0:
+		maxrss_init = ru.ru_maxrss;
+		tst_resm(TINFO, "child allocate +50MB");
+		consume(50);
+		SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+		tst_resm(TINFO, "child.self = %ld", ru.ru_maxrss);
+		exit(is_in_delta(maxrss_init + 51200 - ru.ru_maxrss));
+	default:
+		break;
+	}
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	check_return(WEXITSTATUS(status), "initial.self + 50MB ~= child.self",
+		    "initial.self + 50MB !~= child.self");
+}
+
+/* Testcase #04: grandchild maxrss
+ * expect: post_wait.children ~= 300MB */
+static void grandchild_maxrss(void)
+{
+	tst_resm(TINFO, "Testcase #04: grandchild maxrss");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK|TERRNO, cleanup, "fork #4");
+	case 0:
+		retval = system("getrusage03_child -g 300");
+		if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
+			tst_brkm(TBROK|TERRNO, cleanup, "system");
+		exit(0);
+	default:
+		break;
+	}
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	if (WEXITSTATUS(status) != 0)
+		tst_brkm(TBROK|TERRNO, cleanup, "child exit status is not 0");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "post_wait.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - 307200) == 0)
+		tst_resm(TPASS, "child.children ~= 300MB");
+	else
+		tst_resm(TFAIL, "child.children !~= 300MB");
+}
+
+/* Testcase #05: zombie
+ * expect: initial ~= pre_wait, post_wait ~= 400MB */
+static void zombie(void)
+{
+	tst_resm(TINFO, "Testcase #05: zombie");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+	maxrss_init = ru.ru_maxrss;
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK, cleanup, "fork #5");
+	case 0:
+		retval = system("getrusage03_child -n 400");
+		if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
+			tst_brkm(TBROK|TERRNO, cleanup, "system");
+		exit(0);
+	default:
+		break;
+	}
+
+	sleep(1); /* children become zombie */
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "pre_wait.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - maxrss_init) == 0)
+		tst_resm(TPASS, "initial.children ~= pre_wait.children");
+	else
+		tst_resm(TFAIL, "initial.children !~= pre_wait.children");
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	if (WEXITSTATUS(status) != 0)
+		tst_brkm(TBROK|TERRNO, cleanup, "child exit status is not 0");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "post_wait.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - 409600) == 0)
+		tst_resm(TPASS, "post_wait.children ~= 400MB");
+	else
+		tst_resm(TFAIL, "post_wait.children !~= 400MB");
+}
+
+/* Testcase #06: SIG_IGN
+ * expect: initial ~= after_zombie */
+static void sig_ign(void)
+{
+	tst_resm(TINFO, "Testcase #06: SIG_IGN");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+	signal(SIGCHLD, SIG_IGN);
+	maxrss_init = ru.ru_maxrss;
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK, cleanup, "fork #6");
+	case 0:
+		retval = system("getrusage03_child -n 500");
+		if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
+			tst_brkm(TBROK|TERRNO, cleanup, "system");
+		exit(0);
+	default:
+		break;
+	}
+
+	sleep(1); /* children become zombie */
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "after_zombie.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - maxrss_init) == 0)
+		tst_resm(TPASS, "initial.children ~= after_zombie.children");
+	else
+		tst_resm(TFAIL, "initial.children !~= after_zombie.children");
+	signal(SIGCHLD, SIG_DFL);
+}
+
+/* Testcase #07: exec without fork
+ * expect: initial ~= fork */
+static void exec_without_fork(void)
+{
+	char str_maxrss_self[BUFSIZ], str_maxrss_child[BUFSIZ];
+	long maxrss_self, maxrss_child;
+
+	tst_resm(TINFO, "Testcase #07: exec without fork");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+	maxrss_self = ru.ru_maxrss;
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	maxrss_child = ru.ru_maxrss;
+	tst_resm(TINFO, "initial.self = %ld, initial.children = %ld",
+		    maxrss_self, maxrss_child);
+
+	sprintf(str_maxrss_self, "%ld", maxrss_self);
+	sprintf(str_maxrss_child, "%ld", maxrss_child);
+	if (execlp("getrusage03_child", "getrusage03_child", "-v",
+		    "-s", str_maxrss_self,
+		    "-l", str_maxrss_child, NULL) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "execlp");
+}
+
+static int is_in_delta(long value)
+{
+	return ((value >= -DELTA_MAX && value <= DELTA_MAX) ? 0 : 1);
+}
+
+static void check_return(int status, char *pass_msg, char *fail_msg)
+{
+	switch (status) {
+	case 0:
+		tst_resm(TPASS, "%s", pass_msg);
+		break;
+	case 1:
+		tst_resm(TFAIL, "%s", fail_msg);
+		break;
+	default:
+		tst_resm(TFAIL, "child exit status is %d", status);
+		break;
+	}
+}
+
+static void consume(int mega)
+{
+	size_t sz;
+	void *ptr;
+
+	sz  = mega * 1024 * 1024;
+	ptr = SAFE_MALLOC(cleanup, sz);
+	if (memset(ptr, 0, sz) == NULL)
+		tst_brkm(TBROK|TERRNO, cleanup, "memset");
+}
+
+static void setup(void)
+{
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	TEST_PAUSE;
+}
+
+static void cleanup(void)
+{
+	TEST_CLEANUP;
+}
diff --git a/testcases/kernel/syscalls/getrusage/getrusage03_child.c b/testcases/kernel/syscalls/getrusage/getrusage03_child.c
new file mode 100644
index 0000000..6127fd2
--- /dev/null
+++ b/testcases/kernel/syscalls/getrusage/getrusage03_child.c
@@ -0,0 +1,183 @@
+/*
+ * getrusage03_child.c - a child program executed by getrusage03
+ *
+ * Copyright (C) 2011  Red Hat, Inc.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it
+ * is free of the rightful claim of any third person regarding
+ * infringement or the like.  Any license provided herein, whether
+ * implied or otherwise, applies only to this software file.  Patent
+ * licenses, if any, provided herein do not apply to combinations of
+ * this program with other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+#include "usctest.h"
+#include "safe_macros.h"
+
+char *TCID = "getrusage03_child";
+int TST_TOTAL = 1;
+
+#define DELTA_MAX	10240
+
+static int opt_consume, opt_grand, opt_show, opt_self, opt_child;
+static char *consume_str, *grand_consume_str, *self_str, *child_str;
+
+option_t child_options[] = {
+	{ "n:", &opt_consume, &consume_str },
+	{ "g:", &opt_grand,   &grand_consume_str },
+	{ "v",  &opt_show,    NULL },
+	{ "s:", &opt_self,    &self_str },
+	{ "l:", &opt_child,   &child_str }
+};
+
+static void usage(void);
+static void consume(int mega);
+static long get_long(const char *str);
+static void setup(void);
+static void cleanup(void);
+
+int main(int argc, char *argv[])
+{
+	int lc;
+	pid_t pid;
+	long maxrss_self, maxrss_children, delta;
+	long consume_nr, grand_consume_nr, self_nr, child_nr;
+	struct rusage ru;
+	char *msg;
+
+	msg = parse_opts(argc, argv, child_options, usage);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		Tst_count = 0;
+
+		if (opt_consume) {
+			consume_nr = get_long(consume_str);
+			tst_resm(TINFO, "child allocate %ldMB", consume_nr);
+			consume(consume_nr);
+		}
+
+		if (opt_grand) {
+			grand_consume_nr = get_long(grand_consume_str);
+			tst_resm(TINFO, "grandchild allocate %ldMB",
+				    grand_consume_nr);
+			switch (pid = fork()) {
+			case -1:
+				tst_brkm(TBROK, cleanup, "fork");
+			case 0:
+				consume(grand_consume_nr);
+				exit(0);
+			default:
+				break;
+			}
+			while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
+				if (WEXITSTATUS(pid) != 0)
+					tst_brkm(TBROK|TERRNO, cleanup,
+						"child exit status is not 0");
+		}
+
+		if (opt_show) {
+			SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+			maxrss_self = ru.ru_maxrss;
+			SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+			maxrss_children = ru.ru_maxrss;
+			tst_resm(TINFO, "exec.self = %ld, exec.children = %ld",
+				    maxrss_self, maxrss_children);
+			if (opt_self) {
+				self_nr = get_long(self_str);
+				delta = maxrss_self - self_nr;
+				if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+					tst_resm(TPASS,
+						"initial.self ~= exec.self");
+				else
+					tst_resm(TFAIL,
+						"initial.self !~= exec.self");
+			}
+			if (opt_child) {
+				child_nr = get_long(child_str);
+				delta = maxrss_children - child_nr;
+				if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+					tst_resm(TPASS,
+						"initial.children ~= exec.children");
+				else
+					tst_resm(TFAIL,
+						"initial.children !~= exec.children");
+			}
+		}
+	}
+
+	cleanup();
+	tst_exit();
+}
+
+static void usage(void)
+{
+	printf("  -n NUM  consume NUM MB size\n");
+	printf("  -g NUM  grandchild consume NUM MB size\n");
+	printf("  -v      verbose mode, show rusage info\n");
+	printf("  -s NUM  compare rusage_self.maxrss with given NUM\n");
+	printf("  -l NUM  compare rusage_children.maxrss with given NUM\n");
+}
+
+static void consume(int mega)
+{
+	size_t sz;
+	void *ptr;
+
+	sz  = mega * 1024 * 1024;
+	ptr = SAFE_MALLOC(cleanup, sz);
+	if (memset(ptr, 0, sz) == NULL)
+		tst_brkm(TBROK|TERRNO, cleanup, "memset");
+}
+
+static long get_long(const char *str)
+{
+	long val;
+	char *endptr;
+
+	val = strtol(str, &endptr, 10);
+	if (((val == LONG_MAX || val == LONG_MIN) && errno == ERANGE) ||
+		    (errno != 0 && val == 0))
+		tst_brkm(TBROK|TERRNO, cleanup, "strtol");
+	if (endptr == str)
+		tst_brkm(TBROK, cleanup, "No digits were found.");
+
+	return val;
+}
+
+static void setup()
+{
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	TEST_PAUSE;
+}
+
+static void cleanup()
+{
+	TEST_CLEANUP;
+}

[-- Attachment #3: Type: text/plain, Size: 318 bytes --]

------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev

[-- Attachment #4: Type: text/plain, Size: 155 bytes --]

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH v2] [syscalls] getrusage03: test ru_maxrss
  2011-06-13 13:12 ` [LTP] [PATCH v2] " Caspar Zhang
@ 2011-06-29 14:14   ` Cyril Hrubis
  2011-06-29 15:36   ` [LTP] [PATCH v3] " Caspar Zhang
  1 sibling, 0 replies; 10+ messages in thread
From: Cyril Hrubis @ 2011-06-29 14:14 UTC (permalink / raw)
  To: Caspar Zhang; +Cc: LTP List

Hi!
> +int main(int argc, char *argv[])
> +{
> +	int lc;
> +	char *msg;
> +
> +	msg = parse_opts(argc, argv, NULL, NULL);
> +	if (msg != NULL)
> +		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
> +
> +	setup();
> +
> +	for (lc = 0; TEST_LOOPING(lc); lc++) {
> +		Tst_count = 0;
> +
> +		tst_resm(TINFO, "allocate 100MB");
> +		consume(100);
> +
> +		inherit_fork();
> +		inherit_fork2();
> +		fork_malloc();
> +		grandchild_maxrss();
> +		zombie();
> +		sig_ign();
> +		exec_without_fork();
> +	}
> +	cleanup();
> +	tst_exit();
> +}
> +
> +/* Testcase #01: fork inherit
> + * expect: initial.self ~= child.self */
> +static void inherit_fork(void)
> +{
> +	tst_resm(TINFO, "Testcase #01: fork inherit");
> +
> +	SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
> +	tst_resm(TINFO, "initial.self = %ld", ru.ru_maxrss);
> +
> +	switch (pid = fork()) {
> +	case -1:
> +		tst_brkm(TBROK|TERRNO, cleanup, "fork #1");
> +	case 0:
> +		maxrss_init = ru.ru_maxrss;
> +		SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
> +		tst_resm(TINFO, "child.self = %ld", ru.ru_maxrss);
> +		exit(is_in_delta(maxrss_init - ru.ru_maxrss));
> +	default:
> +		break;
> +	}
> +
> +	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
> +		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
> +	check_return(WEXITSTATUS(status), "initial.self ~= child.self",
> +		    "initial.self !~= child.self");
> +}
> +
> +/* Testcase #02: fork inherit (cont.)
> + * expect: initial.children ~= 100MB, child.children = 0 */
> +static void inherit_fork2(void)
> +{
> +	tst_resm(TINFO, "Testcase #02: fork inherit(cont.)");
> +
> +	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
> +	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
> +	if (is_in_delta(ru.ru_maxrss - 102400) == 0)
> +		tst_resm(TPASS, "initial.children ~= 100MB");
> +	else
> +		tst_resm(TFAIL, "initial.children !~= 100MB");
> +
> +	switch (pid = fork()) {
> +	case -1:
> +		tst_brkm(TBROK|TERRNO, cleanup, "fork #2");
> +	case 0:
> +		SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
> +		tst_resm(TINFO, "child.children = %ld", ru.ru_maxrss);
> +		exit((ru.ru_maxrss == 0) ? 0 : 1);
> +	default:
> +		break;
> +	}
> +
> +	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
> +		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
> +	check_return(WEXITSTATUS(status), "child.children == 0",
> +		    "child.children != 0");
> +}
> +
> +/* Testcase #03: fork + malloc
> + * expect: initial.self + 50MB ~= child.self */
> +static void fork_malloc(void)
> +{
> +	tst_resm(TINFO, "Testcase #03: fork + malloc");
> +
> +	SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
> +	tst_resm(TINFO, "initial.self = %ld", ru.ru_maxrss);
> +
> +	switch (pid = fork()) {
> +	case -1:
> +		tst_brkm(TBROK|TERRNO, cleanup, "fork #3");
> +	case 0:
> +		maxrss_init = ru.ru_maxrss;
> +		tst_resm(TINFO, "child allocate +50MB");
> +		consume(50);
> +		SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
> +		tst_resm(TINFO, "child.self = %ld", ru.ru_maxrss);
> +		exit(is_in_delta(maxrss_init + 51200 - ru.ru_maxrss));
> +	default:
> +		break;
> +	}
> +
> +	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
> +		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
> +	check_return(WEXITSTATUS(status), "initial.self + 50MB ~= child.self",
> +		    "initial.self + 50MB !~= child.self");
> +}
> +
> +/* Testcase #04: grandchild maxrss
> + * expect: post_wait.children ~= 300MB */
> +static void grandchild_maxrss(void)
> +{
> +	tst_resm(TINFO, "Testcase #04: grandchild maxrss");
> +
> +	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
> +	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
> +
> +	switch (pid = fork()) {
> +	case -1:
> +		tst_brkm(TBROK|TERRNO, cleanup, "fork #4");
> +	case 0:
> +		retval = system("getrusage03_child -g 300");
> +		if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
> +			tst_brkm(TBROK|TERRNO, cleanup, "system");
> +		exit(0);
> +	default:
> +		break;
> +	}
> +
> +	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
> +		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
> +	if (WEXITSTATUS(status) != 0)
> +		tst_brkm(TBROK|TERRNO, cleanup, "child exit status is not 0");
> +
> +	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
> +	tst_resm(TINFO, "post_wait.children = %ld", ru.ru_maxrss);
> +	if (is_in_delta(ru.ru_maxrss - 307200) == 0)
> +		tst_resm(TPASS, "child.children ~= 300MB");
> +	else
> +		tst_resm(TFAIL, "child.children !~= 300MB");
> +}
> +
> +/* Testcase #05: zombie
> + * expect: initial ~= pre_wait, post_wait ~= 400MB */
> +static void zombie(void)
> +{
> +	tst_resm(TINFO, "Testcase #05: zombie");
> +
> +	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
> +	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
> +	maxrss_init = ru.ru_maxrss;
> +
> +	switch (pid = fork()) {
> +	case -1:
> +		tst_brkm(TBROK, cleanup, "fork #5");
> +	case 0:
> +		retval = system("getrusage03_child -n 400");
> +		if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
> +			tst_brkm(TBROK|TERRNO, cleanup, "system");
> +		exit(0);
> +	default:
> +		break;
> +	}
> +
> +	sleep(1); /* children become zombie */
> +	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
> +	tst_resm(TINFO, "pre_wait.children = %ld", ru.ru_maxrss);
> +	if (is_in_delta(ru.ru_maxrss - maxrss_init) == 0)
> +		tst_resm(TPASS, "initial.children ~= pre_wait.children");
> +	else
> +		tst_resm(TFAIL, "initial.children !~= pre_wait.children");
> +
> +	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
> +		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
> +	if (WEXITSTATUS(status) != 0)
> +		tst_brkm(TBROK|TERRNO, cleanup, "child exit status is not 0");
> +
> +	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
> +	tst_resm(TINFO, "post_wait.children = %ld", ru.ru_maxrss);
> +	if (is_in_delta(ru.ru_maxrss - 409600) == 0)
> +		tst_resm(TPASS, "post_wait.children ~= 400MB");
> +	else
> +		tst_resm(TFAIL, "post_wait.children !~= 400MB");
> +}
> +
> +/* Testcase #06: SIG_IGN
> + * expect: initial ~= after_zombie */
> +static void sig_ign(void)
> +{
> +	tst_resm(TINFO, "Testcase #06: SIG_IGN");
> +
> +	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
> +	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
> +	signal(SIGCHLD, SIG_IGN);
> +	maxrss_init = ru.ru_maxrss;
> +
> +	switch (pid = fork()) {
> +	case -1:
> +		tst_brkm(TBROK, cleanup, "fork #6");
> +	case 0:
> +		retval = system("getrusage03_child -n 500");
> +		if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
> +			tst_brkm(TBROK|TERRNO, cleanup, "system");
> +		exit(0);
> +	default:
> +		break;
> +	}
> +
> +	sleep(1); /* children become zombie */
> +	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
> +	tst_resm(TINFO, "after_zombie.children = %ld", ru.ru_maxrss);
> +	if (is_in_delta(ru.ru_maxrss - maxrss_init) == 0)
> +		tst_resm(TPASS, "initial.children ~= after_zombie.children");
> +	else
> +		tst_resm(TFAIL, "initial.children !~= after_zombie.children");
> +	signal(SIGCHLD, SIG_DFL);
> +}
> +
> +/* Testcase #07: exec without fork
> + * expect: initial ~= fork */
> +static void exec_without_fork(void)
> +{
> +	char str_maxrss_self[BUFSIZ], str_maxrss_child[BUFSIZ];
> +	long maxrss_self, maxrss_child;
> +
> +	tst_resm(TINFO, "Testcase #07: exec without fork");
> +
> +	SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
> +	maxrss_self = ru.ru_maxrss;
> +	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
> +	maxrss_child = ru.ru_maxrss;
> +	tst_resm(TINFO, "initial.self = %ld, initial.children = %ld",
> +		    maxrss_self, maxrss_child);
> +
> +	sprintf(str_maxrss_self, "%ld", maxrss_self);
> +	sprintf(str_maxrss_child, "%ld", maxrss_child);
> +	if (execlp("getrusage03_child", "getrusage03_child", "-v",
> +		    "-s", str_maxrss_self,
> +		    "-l", str_maxrss_child, NULL) == -1)
> +		tst_brkm(TBROK|TERRNO, cleanup, "execlp");
> +}
> +
> +static int is_in_delta(long value)
> +{
> +	return ((value >= -DELTA_MAX && value <= DELTA_MAX) ? 0 : 1);
> +}

Hmm, this is really confusing. The function name suggests that value is
"value is in delta range" but it actually returns 0 which is same as
false in C.

The 0 == success approach makes sence only for C functions that actually
returns error codes otherwise, but not for functions whose name suggests
boolean return value.

I would drop the ? 0:1 part and remove == 0 from the if() statements
abowe.

> +static void check_return(int status, char *pass_msg, char *fail_msg)
> +{
> +	switch (status) {
> +	case 0:
> +		tst_resm(TPASS, "%s", pass_msg);
> +		break;
> +	case 1:
> +		tst_resm(TFAIL, "%s", fail_msg);
> +		break;
> +	default:
> +		tst_resm(TFAIL, "child exit status is %d", status);
> +		break;
> +	}
> +}
> +
> +static void consume(int mega)
> +{
> +	size_t sz;
> +	void *ptr;
> +
> +	sz  = mega * 1024 * 1024;
> +	ptr = SAFE_MALLOC(cleanup, sz);
> +	if (memset(ptr, 0, sz) == NULL)
> +		tst_brkm(TBROK|TERRNO, cleanup, "memset");
> +}

The memset() can't fail, it just returns pointer to the passed buffer.

> +static void setup(void)
> +{
> +	tst_sig(FORK, DEF_HANDLER, cleanup);
> +
> +	TEST_PAUSE;
> +}
> +
> +static void cleanup(void)
> +{
> +	TEST_CLEANUP;
> +}
> diff --git a/testcases/kernel/syscalls/getrusage/getrusage03_child.c b/testcases/kernel/syscalls/getrusage/getrusage03_child.c
> new file mode 100644
> index 0000000..6127fd2
> --- /dev/null
> +++ b/testcases/kernel/syscalls/getrusage/getrusage03_child.c
> @@ -0,0 +1,183 @@
> +/*
> + * getrusage03_child.c - a child program executed by getrusage03
> + *
> + * Copyright (C) 2011  Red Hat, Inc.
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of version 2 of the GNU General Public
> + * License as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it would be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> + *
> + * Further, this software is distributed without any warranty that it
> + * is free of the rightful claim of any third person regarding
> + * infringement or the like.  Any license provided herein, whether
> + * implied or otherwise, applies only to this software file.  Patent
> + * licenses, if any, provided herein do not apply to combinations of
> + * this program with other software, or any other product whatsoever.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + */
> +#include <sys/types.h>
> +#include <sys/resource.h>
> +#include <sys/time.h>
> +#include <sys/wait.h>
> +#include <errno.h>
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include "test.h"
> +#include "usctest.h"
> +#include "safe_macros.h"
> +
> +char *TCID = "getrusage03_child";
> +int TST_TOTAL = 1;
> +
> +#define DELTA_MAX	10240
> +
> +static int opt_consume, opt_grand, opt_show, opt_self, opt_child;
> +static char *consume_str, *grand_consume_str, *self_str, *child_str;
> +
> +option_t child_options[] = {
> +	{ "n:", &opt_consume, &consume_str },
> +	{ "g:", &opt_grand,   &grand_consume_str },
> +	{ "v",  &opt_show,    NULL },
> +	{ "s:", &opt_self,    &self_str },
> +	{ "l:", &opt_child,   &child_str }
> +};
> +
> +static void usage(void);
> +static void consume(int mega);
> +static long get_long(const char *str);
> +static void setup(void);
> +static void cleanup(void);
> +
> +int main(int argc, char *argv[])
> +{
> +	int lc;
> +	pid_t pid;
> +	long maxrss_self, maxrss_children, delta;
> +	long consume_nr, grand_consume_nr, self_nr, child_nr;
> +	struct rusage ru;
> +	char *msg;
> +
> +	msg = parse_opts(argc, argv, child_options, usage);
> +	if (msg != NULL)
> +		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
> +
> +	setup();
> +
> +	for (lc = 0; TEST_LOOPING(lc); lc++) {
> +		Tst_count = 0;
> +
> +		if (opt_consume) {
> +			consume_nr = get_long(consume_str);
> +			tst_resm(TINFO, "child allocate %ldMB", consume_nr);
> +			consume(consume_nr);
> +		}
> +
> +		if (opt_grand) {
> +			grand_consume_nr = get_long(grand_consume_str);
> +			tst_resm(TINFO, "grandchild allocate %ldMB",
> +				    grand_consume_nr);
> +			switch (pid = fork()) {
> +			case -1:
> +				tst_brkm(TBROK, cleanup, "fork");
> +			case 0:
> +				consume(grand_consume_nr);
> +				exit(0);
> +			default:
> +				break;
> +			}
> +			while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
> +				if (WEXITSTATUS(pid) != 0)
> +					tst_brkm(TBROK|TERRNO, cleanup,
> +						"child exit status is not 0");
> +		}
> +
> +		if (opt_show) {
> +			SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
> +			maxrss_self = ru.ru_maxrss;
> +			SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
> +			maxrss_children = ru.ru_maxrss;
> +			tst_resm(TINFO, "exec.self = %ld, exec.children = %ld",
> +				    maxrss_self, maxrss_children);
> +			if (opt_self) {
> +				self_nr = get_long(self_str);
> +				delta = maxrss_self - self_nr;
> +				if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
> +					tst_resm(TPASS,
> +						"initial.self ~= exec.self");
> +				else
> +					tst_resm(TFAIL,
> +						"initial.self !~= exec.self");
> +			}
> +			if (opt_child) {
> +				child_nr = get_long(child_str);
> +				delta = maxrss_children - child_nr;
> +				if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
> +					tst_resm(TPASS,
> +						"initial.children ~= exec.children");
> +				else
> +					tst_resm(TFAIL,
> +						"initial.children !~= exec.children");
> +			}
> +		}
> +	}
> +
> +	cleanup();
> +	tst_exit();
> +}
> +
> +static void usage(void)
> +{
> +	printf("  -n NUM  consume NUM MB size\n");
> +	printf("  -g NUM  grandchild consume NUM MB size\n");
> +	printf("  -v      verbose mode, show rusage info\n");
> +	printf("  -s NUM  compare rusage_self.maxrss with given NUM\n");
> +	printf("  -l NUM  compare rusage_children.maxrss with given NUM\n");
> +}
> +
> +static void consume(int mega)
> +{
> +	size_t sz;
> +	void *ptr;
> +
> +	sz  = mega * 1024 * 1024;
> +	ptr = SAFE_MALLOC(cleanup, sz);
> +	if (memset(ptr, 0, sz) == NULL)
> +		tst_brkm(TBROK|TERRNO, cleanup, "memset");

Here too.

> +}
> +
> +static long get_long(const char *str)
> +{
> +	long val;
> +	char *endptr;
> +
> +	val = strtol(str, &endptr, 10);
> +	if (((val == LONG_MAX || val == LONG_MIN) && errno == ERANGE) ||
> +		    (errno != 0 && val == 0))
> +		tst_brkm(TBROK|TERRNO, cleanup, "strtol");
> +	if (endptr == str)
> +		tst_brkm(TBROK, cleanup, "No digits were found.");
> +
> +	return val;
> +}

This is not 100% correct. The strtol (for converting whole string into
number) is successfull if the endptr points to the end of string, eg.
*endptr = '\0' and if the value is not LONG_MAX or LONG_MIN both with
errno set to ERANGE. This will accept strings like "256foo".

> +static void setup()

Add void.

> +{
> +	tst_sig(FORK, DEF_HANDLER, cleanup);
> +
> +	TEST_PAUSE;
> +}
> +
> +static void cleanup()

And here.

> +{
> +	TEST_CLEANUP;
> +}

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* [LTP] [PATCH v3] [syscalls] getrusage03: test ru_maxrss
  2011-06-13 13:12 ` [LTP] [PATCH v2] " Caspar Zhang
  2011-06-29 14:14   ` Cyril Hrubis
@ 2011-06-29 15:36   ` Caspar Zhang
  2011-06-29 17:46     ` Cyril Hrubis
  2011-06-29 17:50     ` [LTP] [PATCH v4] " Caspar Zhang
  1 sibling, 2 replies; 10+ messages in thread
From: Caspar Zhang @ 2011-06-29 15:36 UTC (permalink / raw)
  To: LTP List

[-- Attachment #1: Type: text/plain, Size: 906 bytes --]


getrusage03 - test ru_maxrss behaviors in struct rusage

This test program is backported from upstream commit:
1f10206cf8e945220f7220a809d8bfc15c21f9a5, which fills ru_maxrss
value in struct rusage according to rss hiwater mark. To make sure
this feature works correctly, a series of tests are executed in
this program.

Signed-off-by: Caspar Zhang <czhang@redhat.com>
---
 include/safe_macros.h                              |    5 +
 lib/safe_macros.c                                  |   15 +
 runtest/syscalls                                   |    1 +
 testcases/kernel/syscalls/getrusage/getrusage03.c  |  358 ++++++++++++++++++++
 .../kernel/syscalls/getrusage/getrusage03_child.c  |  182 ++++++++++
 5 files changed, 561 insertions(+), 0 deletions(-)
 create mode 100644 testcases/kernel/syscalls/getrusage/getrusage03.c
 create mode 100644 testcases/kernel/syscalls/getrusage/getrusage03_child.c


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-syscalls-getrusage03-test-ru_maxrss.patch --]
[-- Type: text/x-patch; name="0001-syscalls-getrusage03-test-ru_maxrss.patch", Size: 17484 bytes --]

diff --git a/include/safe_macros.h b/include/safe_macros.h
index 7c99c66..3753b7f 100644
--- a/include/safe_macros.h
+++ b/include/safe_macros.h
@@ -58,6 +58,11 @@ struct passwd*	safe_getpwnam(const char *file, const int lineno,
 #define SAFE_GETPWNAM(cleanup_fn, name)	\
 	safe_getpwnam(__FILE__, __LINE__, cleanup_fn, (name))
 
+int     safe_getrusage(const char *file, const int lineno,
+	    void (*cleanup_fn)(void), int who, struct rusage *usage);
+#define SAFE_GETRUSAGE(cleanup_fn, who, usage) \
+	safe_getrusage(__FILE__, __LINE__, (cleanup_fn), (who), (usage))
+
 void*	safe_malloc(const char *file, const int lineno,
 	    void (*cleanup_fn)(void), size_t size);
 #define SAFE_MALLOC(cleanup_fn, size)	\
diff --git a/lib/safe_macros.c b/lib/safe_macros.c
index c98376d..11f5fe6 100644
--- a/lib/safe_macros.c
+++ b/lib/safe_macros.c
@@ -1,5 +1,6 @@
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <libgen.h>
@@ -108,6 +109,20 @@ safe_getpwnam(const char *file, const int lineno, void (*cleanup_fn)(void),
 	return (rval);
 }
 
+int
+safe_getrusage(const char *file, const int lineno, void (*cleanup_fn)(void),
+	    int who, struct rusage *usage)
+{
+	int rval;
+
+	rval = getrusage(who, usage);
+	if (rval == -1)
+		tst_brkm(TBROK|TERRNO, cleanup_fn, "getrusage failed at %s:%d",
+		    file, lineno);
+
+	return rval;
+}
+
 void*
 safe_malloc(const char *file, const int lineno, void (*cleanup_fn)(void),
     size_t size)
diff --git a/runtest/syscalls b/runtest/syscalls
index 4294d07..7989764 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -399,6 +399,7 @@ get_robust_list01 get_robust_list01
 
 getrusage01 getrusage01
 getrusage02 getrusage02
+getrusage03 getrusage03
 
 getsid01 getsid01
 getsid02 getsid02
diff --git a/testcases/kernel/syscalls/getrusage/getrusage03.c b/testcases/kernel/syscalls/getrusage/getrusage03.c
new file mode 100644
index 0000000..a50a852
--- /dev/null
+++ b/testcases/kernel/syscalls/getrusage/getrusage03.c
@@ -0,0 +1,358 @@
+/*
+ * getrusage03 - test ru_maxrss behaviors in struct rusage
+ *
+ * This test program is backported from upstream commit:
+ * 1f10206cf8e945220f7220a809d8bfc15c21f9a5, which fills ru_maxrss
+ * value in struct rusage according to rss hiwater mark. To make sure
+ * this feature works correctly, a series of tests are executed in
+ * this program.
+ *
+ * Copyright (C) 2011  Red Hat, Inc.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it
+ * is free of the rightful claim of any third person regarding
+ * infringement or the like.  Any license provided herein, whether
+ * implied or otherwise, applies only to this software file.  Patent
+ * licenses, if any, provided herein do not apply to combinations of
+ * this program with other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+#include "usctest.h"
+#include "safe_macros.h"
+
+char *TCID = "getrusage03";
+int TST_TOTAL = 1;
+
+#define DELTA_MAX	10240
+
+static struct rusage ru;
+static long maxrss_init;
+static int retval, status;
+static pid_t pid;
+
+static void inherit_fork(void);
+static void inherit_fork2(void);
+static void fork_malloc(void);
+static void grandchild_maxrss(void);
+static void zombie(void);
+static void sig_ign(void);
+static void exec_without_fork(void);
+static void check_return(int status, char *pass_msg, char *fail_msg);
+static int is_in_delta(long value);
+static void consume(int mega);
+static void setup(void);
+static void cleanup(void);
+
+int main(int argc, char *argv[])
+{
+	int lc;
+	char *msg;
+
+	msg = parse_opts(argc, argv, NULL, NULL);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		Tst_count = 0;
+
+		tst_resm(TINFO, "allocate 100MB");
+		consume(100);
+
+		inherit_fork();
+		inherit_fork2();
+		fork_malloc();
+		grandchild_maxrss();
+		zombie();
+		sig_ign();
+		exec_without_fork();
+	}
+	cleanup();
+	tst_exit();
+}
+
+/* Testcase #01: fork inherit
+ * expect: initial.self ~= child.self */
+static void inherit_fork(void)
+{
+	tst_resm(TINFO, "Testcase #01: fork inherit");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+	tst_resm(TINFO, "initial.self = %ld", ru.ru_maxrss);
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK|TERRNO, cleanup, "fork #1");
+	case 0:
+		maxrss_init = ru.ru_maxrss;
+		SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+		tst_resm(TINFO, "child.self = %ld", ru.ru_maxrss);
+		exit(is_in_delta(maxrss_init - ru.ru_maxrss));
+	default:
+		break;
+	}
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	check_return(WEXITSTATUS(status), "initial.self ~= child.self",
+		    "initial.self !~= child.self");
+}
+
+/* Testcase #02: fork inherit (cont.)
+ * expect: initial.children ~= 100MB, child.children = 0 */
+static void inherit_fork2(void)
+{
+	tst_resm(TINFO, "Testcase #02: fork inherit(cont.)");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - 102400))
+		tst_resm(TPASS, "initial.children ~= 100MB");
+	else
+		tst_resm(TFAIL, "initial.children !~= 100MB");
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK|TERRNO, cleanup, "fork #2");
+	case 0:
+		SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+		tst_resm(TINFO, "child.children = %ld", ru.ru_maxrss);
+		exit(ru.ru_maxrss == 0);
+	default:
+		break;
+	}
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	check_return(WEXITSTATUS(status), "child.children == 0",
+		    "child.children != 0");
+}
+
+/* Testcase #03: fork + malloc
+ * expect: initial.self + 50MB ~= child.self */
+static void fork_malloc(void)
+{
+	tst_resm(TINFO, "Testcase #03: fork + malloc");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+	tst_resm(TINFO, "initial.self = %ld", ru.ru_maxrss);
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK|TERRNO, cleanup, "fork #3");
+	case 0:
+		maxrss_init = ru.ru_maxrss;
+		tst_resm(TINFO, "child allocate +50MB");
+		consume(50);
+		SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+		tst_resm(TINFO, "child.self = %ld", ru.ru_maxrss);
+		exit(is_in_delta(maxrss_init + 51200 - ru.ru_maxrss));
+	default:
+		break;
+	}
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	check_return(WEXITSTATUS(status), "initial.self + 50MB ~= child.self",
+		    "initial.self + 50MB !~= child.self");
+}
+
+/* Testcase #04: grandchild maxrss
+ * expect: post_wait.children ~= 300MB */
+static void grandchild_maxrss(void)
+{
+	tst_resm(TINFO, "Testcase #04: grandchild maxrss");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK|TERRNO, cleanup, "fork #4");
+	case 0:
+		retval = system("getrusage03_child -g 300");
+		if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
+			tst_brkm(TBROK|TERRNO, cleanup, "system");
+		exit(0);
+	default:
+		break;
+	}
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	if (WEXITSTATUS(status) != 0)
+		tst_brkm(TBROK|TERRNO, cleanup, "child exit status is not 0");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "post_wait.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - 307200))
+		tst_resm(TPASS, "child.children ~= 300MB");
+	else
+		tst_resm(TFAIL, "child.children !~= 300MB");
+}
+
+/* Testcase #05: zombie
+ * expect: initial ~= pre_wait, post_wait ~= 400MB */
+static void zombie(void)
+{
+	tst_resm(TINFO, "Testcase #05: zombie");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+	maxrss_init = ru.ru_maxrss;
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK, cleanup, "fork #5");
+	case 0:
+		retval = system("getrusage03_child -n 400");
+		if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
+			tst_brkm(TBROK|TERRNO, cleanup, "system");
+		exit(0);
+	default:
+		break;
+	}
+
+	sleep(1); /* children become zombie */
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "pre_wait.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - maxrss_init))
+		tst_resm(TPASS, "initial.children ~= pre_wait.children");
+	else
+		tst_resm(TFAIL, "initial.children !~= pre_wait.children");
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	if (WEXITSTATUS(status) != 0)
+		tst_brkm(TBROK|TERRNO, cleanup, "child exit status is not 0");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "post_wait.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - 409600))
+		tst_resm(TPASS, "post_wait.children ~= 400MB");
+	else
+		tst_resm(TFAIL, "post_wait.children !~= 400MB");
+}
+
+/* Testcase #06: SIG_IGN
+ * expect: initial ~= after_zombie */
+static void sig_ign(void)
+{
+	tst_resm(TINFO, "Testcase #06: SIG_IGN");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+	signal(SIGCHLD, SIG_IGN);
+	maxrss_init = ru.ru_maxrss;
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK, cleanup, "fork #6");
+	case 0:
+		retval = system("getrusage03_child -n 500");
+		if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
+			tst_brkm(TBROK|TERRNO, cleanup, "system");
+		exit(0);
+	default:
+		break;
+	}
+
+	sleep(1); /* children become zombie */
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "after_zombie.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - maxrss_init))
+		tst_resm(TPASS, "initial.children ~= after_zombie.children");
+	else
+		tst_resm(TFAIL, "initial.children !~= after_zombie.children");
+	signal(SIGCHLD, SIG_DFL);
+}
+
+/* Testcase #07: exec without fork
+ * expect: initial ~= fork */
+static void exec_without_fork(void)
+{
+	char str_maxrss_self[BUFSIZ], str_maxrss_child[BUFSIZ];
+	long maxrss_self, maxrss_child;
+
+	tst_resm(TINFO, "Testcase #07: exec without fork");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+	maxrss_self = ru.ru_maxrss;
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	maxrss_child = ru.ru_maxrss;
+	tst_resm(TINFO, "initial.self = %ld, initial.children = %ld",
+		    maxrss_self, maxrss_child);
+
+	sprintf(str_maxrss_self, "%ld", maxrss_self);
+	sprintf(str_maxrss_child, "%ld", maxrss_child);
+	if (execlp("getrusage03_child", "getrusage03_child", "-v",
+		    "-s", str_maxrss_self,
+		    "-l", str_maxrss_child, NULL) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "execlp");
+}
+
+static int is_in_delta(long value)
+{
+	return (value >= -DELTA_MAX && value <= DELTA_MAX);
+}
+
+static void check_return(int status, char *pass_msg, char *fail_msg)
+{
+	switch (status) {
+	case 1:
+		tst_resm(TPASS, "%s", pass_msg);
+		break;
+	case 0:
+		tst_resm(TFAIL, "%s", fail_msg);
+		break;
+	default:
+		tst_resm(TFAIL, "child exit status is %d", status);
+		break;
+	}
+}
+
+static void consume(int mega)
+{
+	size_t sz;
+	void *ptr;
+
+	sz  = mega * 1024 * 1024;
+	ptr = SAFE_MALLOC(cleanup, sz);
+	memset(ptr, 0, sz);
+}
+
+static void setup(void)
+{
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	TEST_PAUSE;
+}
+
+static void cleanup(void)
+{
+	TEST_CLEANUP;
+}
diff --git a/testcases/kernel/syscalls/getrusage/getrusage03_child.c b/testcases/kernel/syscalls/getrusage/getrusage03_child.c
new file mode 100644
index 0000000..0008aea
--- /dev/null
+++ b/testcases/kernel/syscalls/getrusage/getrusage03_child.c
@@ -0,0 +1,182 @@
+/*
+ * getrusage03_child.c - a child program executed by getrusage03
+ *
+ * Copyright (C) 2011  Red Hat, Inc.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it
+ * is free of the rightful claim of any third person regarding
+ * infringement or the like.  Any license provided herein, whether
+ * implied or otherwise, applies only to this software file.  Patent
+ * licenses, if any, provided herein do not apply to combinations of
+ * this program with other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+#include "usctest.h"
+#include "safe_macros.h"
+
+char *TCID = "getrusage03_child";
+int TST_TOTAL = 1;
+
+#define DELTA_MAX	10240
+
+static int opt_consume, opt_grand, opt_show, opt_self, opt_child;
+static char *consume_str, *grand_consume_str, *self_str, *child_str;
+
+option_t child_options[] = {
+	{ "n:", &opt_consume, &consume_str },
+	{ "g:", &opt_grand,   &grand_consume_str },
+	{ "v",  &opt_show,    NULL },
+	{ "s:", &opt_self,    &self_str },
+	{ "l:", &opt_child,   &child_str }
+};
+
+static void usage(void);
+static void consume(int mega);
+static long get_long(const char *str);
+static void setup(void);
+static void cleanup(void);
+
+int main(int argc, char *argv[])
+{
+	int lc;
+	pid_t pid;
+	long maxrss_self, maxrss_children, delta;
+	long consume_nr, grand_consume_nr, self_nr, child_nr;
+	struct rusage ru;
+	char *msg;
+
+	msg = parse_opts(argc, argv, child_options, usage);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		Tst_count = 0;
+
+		if (opt_consume) {
+			consume_nr = get_long(consume_str);
+			tst_resm(TINFO, "child allocate %ldMB", consume_nr);
+			consume(consume_nr);
+		}
+
+		if (opt_grand) {
+			grand_consume_nr = get_long(grand_consume_str);
+			tst_resm(TINFO, "grandchild allocate %ldMB",
+				    grand_consume_nr);
+			switch (pid = fork()) {
+			case -1:
+				tst_brkm(TBROK, cleanup, "fork");
+			case 0:
+				consume(grand_consume_nr);
+				exit(0);
+			default:
+				break;
+			}
+			while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
+				if (WEXITSTATUS(pid) != 0)
+					tst_brkm(TBROK|TERRNO, cleanup,
+						"child exit status is not 0");
+		}
+
+		if (opt_show) {
+			SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+			maxrss_self = ru.ru_maxrss;
+			SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+			maxrss_children = ru.ru_maxrss;
+			tst_resm(TINFO, "exec.self = %ld, exec.children = %ld",
+				    maxrss_self, maxrss_children);
+			if (opt_self) {
+				self_nr = get_long(self_str);
+				delta = maxrss_self - self_nr;
+				if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+					tst_resm(TPASS,
+						"initial.self ~= exec.self");
+				else
+					tst_resm(TFAIL,
+						"initial.self !~= exec.self");
+			}
+			if (opt_child) {
+				child_nr = get_long(child_str);
+				delta = maxrss_children - child_nr;
+				if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+					tst_resm(TPASS,
+						"initial.children ~= exec.children");
+				else
+					tst_resm(TFAIL,
+						"initial.children !~= exec.children");
+			}
+		}
+	}
+
+	cleanup();
+	tst_exit();
+}
+
+static void usage(void)
+{
+	printf("  -n NUM  consume NUM MB size\n");
+	printf("  -g NUM  grandchild consume NUM MB size\n");
+	printf("  -v      verbose mode, show rusage info\n");
+	printf("  -s NUM  compare rusage_self.maxrss with given NUM\n");
+	printf("  -l NUM  compare rusage_children.maxrss with given NUM\n");
+}
+
+static void consume(int mega)
+{
+	size_t sz;
+	void *ptr;
+
+	sz  = mega * 1024 * 1024;
+	ptr = SAFE_MALLOC(cleanup, sz);
+	memset(ptr, 0, sz);
+}
+
+static long get_long(const char *str)
+{
+	long val;
+	char *endptr;
+
+	val = strtol(str, &endptr, 10);
+	if (((val == LONG_MAX || val == LONG_MIN) && errno == ERANGE) ||
+		    (errno != 0 && val == 0))
+		tst_brkm(TBROK|TERRNO, cleanup, "strtol");
+	if (endptr == str || *endptr != '\0')
+		tst_brkm(TBROK, cleanup, "Non-digits were found.");
+
+	return val;
+}
+
+static void setup(void)
+{
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	TEST_PAUSE;
+}
+
+static void cleanup(void)
+{
+	TEST_CLEANUP;
+}

[-- Attachment #3: Type: text/plain, Size: 377 bytes --]

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2

[-- Attachment #4: Type: text/plain, Size: 155 bytes --]

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH v3] [syscalls] getrusage03: test ru_maxrss
  2011-06-29 15:36   ` [LTP] [PATCH v3] " Caspar Zhang
@ 2011-06-29 17:46     ` Cyril Hrubis
  2011-06-29 17:50     ` [LTP] [PATCH v4] " Caspar Zhang
  1 sibling, 0 replies; 10+ messages in thread
From: Cyril Hrubis @ 2011-06-29 17:46 UTC (permalink / raw)
  To: Caspar Zhang; +Cc: LTP List

Hi!
> +static void consume(int mega)
> +{
> +	size_t sz;
> +	void *ptr;
> +
> +	sz  = mega * 1024 * 1024;
> +	ptr = SAFE_MALLOC(cleanup, sz);
> +	memset(ptr, 0, sz);
> +}
> +
> +static long get_long(const char *str)
> +{
> +	long val;
> +	char *endptr;
> +
> +	val = strtol(str, &endptr, 10);
> +	if (((val == LONG_MAX || val == LONG_MIN) && errno == ERANGE) ||
> +		    (errno != 0 && val == 0))
> +		tst_brkm(TBROK|TERRNO, cleanup, "strtol");
> +	if (endptr == str || *endptr != '\0')
> +		tst_brkm(TBROK, cleanup, "Non-digits were found.");
> +
> +	return val;
> +}

One more thing, please keep the error meesages sweet and to the point.

Just imagine you get "Non-digits were found." error from some utility.
Which doesn't say much, for example where was these non digits found.

I would do something like:

tst_brkm(TBROK, "Invalid number parameter '%s'", str);

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* [LTP] [PATCH v4] [syscalls] getrusage03: test ru_maxrss
  2011-06-29 15:36   ` [LTP] [PATCH v3] " Caspar Zhang
  2011-06-29 17:46     ` Cyril Hrubis
@ 2011-06-29 17:50     ` Caspar Zhang
  2011-07-11 13:16       ` Cyril Hrubis
  1 sibling, 1 reply; 10+ messages in thread
From: Caspar Zhang @ 2011-06-29 17:50 UTC (permalink / raw)
  To: LTP List

[-- Attachment #1: Type: text/plain, Size: 906 bytes --]


getrusage03 - test ru_maxrss behaviors in struct rusage

This test program is backported from upstream commit:
1f10206cf8e945220f7220a809d8bfc15c21f9a5, which fills ru_maxrss
value in struct rusage according to rss hiwater mark. To make sure
this feature works correctly, a series of tests are executed in
this program.

Signed-off-by: Caspar Zhang <czhang@redhat.com>
---
 include/safe_macros.h                              |    5 +
 lib/safe_macros.c                                  |   15 +
 runtest/syscalls                                   |    1 +
 testcases/kernel/syscalls/getrusage/getrusage03.c  |  358 ++++++++++++++++++++
 .../kernel/syscalls/getrusage/getrusage03_child.c  |  182 ++++++++++
 5 files changed, 561 insertions(+), 0 deletions(-)
 create mode 100644 testcases/kernel/syscalls/getrusage/getrusage03.c
 create mode 100644 testcases/kernel/syscalls/getrusage/getrusage03_child.c


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-syscalls-getrusage03-test-ru_maxrss.patch --]
[-- Type: text/x-patch; name="0001-syscalls-getrusage03-test-ru_maxrss.patch", Size: 17495 bytes --]

diff --git a/include/safe_macros.h b/include/safe_macros.h
index 7c99c66..3753b7f 100644
--- a/include/safe_macros.h
+++ b/include/safe_macros.h
@@ -58,6 +58,11 @@ struct passwd*	safe_getpwnam(const char *file, const int lineno,
 #define SAFE_GETPWNAM(cleanup_fn, name)	\
 	safe_getpwnam(__FILE__, __LINE__, cleanup_fn, (name))
 
+int     safe_getrusage(const char *file, const int lineno,
+	    void (*cleanup_fn)(void), int who, struct rusage *usage);
+#define SAFE_GETRUSAGE(cleanup_fn, who, usage) \
+	safe_getrusage(__FILE__, __LINE__, (cleanup_fn), (who), (usage))
+
 void*	safe_malloc(const char *file, const int lineno,
 	    void (*cleanup_fn)(void), size_t size);
 #define SAFE_MALLOC(cleanup_fn, size)	\
diff --git a/lib/safe_macros.c b/lib/safe_macros.c
index c98376d..11f5fe6 100644
--- a/lib/safe_macros.c
+++ b/lib/safe_macros.c
@@ -1,5 +1,6 @@
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <libgen.h>
@@ -108,6 +109,20 @@ safe_getpwnam(const char *file, const int lineno, void (*cleanup_fn)(void),
 	return (rval);
 }
 
+int
+safe_getrusage(const char *file, const int lineno, void (*cleanup_fn)(void),
+	    int who, struct rusage *usage)
+{
+	int rval;
+
+	rval = getrusage(who, usage);
+	if (rval == -1)
+		tst_brkm(TBROK|TERRNO, cleanup_fn, "getrusage failed at %s:%d",
+		    file, lineno);
+
+	return rval;
+}
+
 void*
 safe_malloc(const char *file, const int lineno, void (*cleanup_fn)(void),
     size_t size)
diff --git a/runtest/syscalls b/runtest/syscalls
index 4294d07..7989764 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -399,6 +399,7 @@ get_robust_list01 get_robust_list01
 
 getrusage01 getrusage01
 getrusage02 getrusage02
+getrusage03 getrusage03
 
 getsid01 getsid01
 getsid02 getsid02
diff --git a/testcases/kernel/syscalls/getrusage/getrusage03.c b/testcases/kernel/syscalls/getrusage/getrusage03.c
new file mode 100644
index 0000000..a50a852
--- /dev/null
+++ b/testcases/kernel/syscalls/getrusage/getrusage03.c
@@ -0,0 +1,358 @@
+/*
+ * getrusage03 - test ru_maxrss behaviors in struct rusage
+ *
+ * This test program is backported from upstream commit:
+ * 1f10206cf8e945220f7220a809d8bfc15c21f9a5, which fills ru_maxrss
+ * value in struct rusage according to rss hiwater mark. To make sure
+ * this feature works correctly, a series of tests are executed in
+ * this program.
+ *
+ * Copyright (C) 2011  Red Hat, Inc.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it
+ * is free of the rightful claim of any third person regarding
+ * infringement or the like.  Any license provided herein, whether
+ * implied or otherwise, applies only to this software file.  Patent
+ * licenses, if any, provided herein do not apply to combinations of
+ * this program with other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+#include "usctest.h"
+#include "safe_macros.h"
+
+char *TCID = "getrusage03";
+int TST_TOTAL = 1;
+
+#define DELTA_MAX	10240
+
+static struct rusage ru;
+static long maxrss_init;
+static int retval, status;
+static pid_t pid;
+
+static void inherit_fork(void);
+static void inherit_fork2(void);
+static void fork_malloc(void);
+static void grandchild_maxrss(void);
+static void zombie(void);
+static void sig_ign(void);
+static void exec_without_fork(void);
+static void check_return(int status, char *pass_msg, char *fail_msg);
+static int is_in_delta(long value);
+static void consume(int mega);
+static void setup(void);
+static void cleanup(void);
+
+int main(int argc, char *argv[])
+{
+	int lc;
+	char *msg;
+
+	msg = parse_opts(argc, argv, NULL, NULL);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		Tst_count = 0;
+
+		tst_resm(TINFO, "allocate 100MB");
+		consume(100);
+
+		inherit_fork();
+		inherit_fork2();
+		fork_malloc();
+		grandchild_maxrss();
+		zombie();
+		sig_ign();
+		exec_without_fork();
+	}
+	cleanup();
+	tst_exit();
+}
+
+/* Testcase #01: fork inherit
+ * expect: initial.self ~= child.self */
+static void inherit_fork(void)
+{
+	tst_resm(TINFO, "Testcase #01: fork inherit");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+	tst_resm(TINFO, "initial.self = %ld", ru.ru_maxrss);
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK|TERRNO, cleanup, "fork #1");
+	case 0:
+		maxrss_init = ru.ru_maxrss;
+		SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+		tst_resm(TINFO, "child.self = %ld", ru.ru_maxrss);
+		exit(is_in_delta(maxrss_init - ru.ru_maxrss));
+	default:
+		break;
+	}
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	check_return(WEXITSTATUS(status), "initial.self ~= child.self",
+		    "initial.self !~= child.self");
+}
+
+/* Testcase #02: fork inherit (cont.)
+ * expect: initial.children ~= 100MB, child.children = 0 */
+static void inherit_fork2(void)
+{
+	tst_resm(TINFO, "Testcase #02: fork inherit(cont.)");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - 102400))
+		tst_resm(TPASS, "initial.children ~= 100MB");
+	else
+		tst_resm(TFAIL, "initial.children !~= 100MB");
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK|TERRNO, cleanup, "fork #2");
+	case 0:
+		SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+		tst_resm(TINFO, "child.children = %ld", ru.ru_maxrss);
+		exit(ru.ru_maxrss == 0);
+	default:
+		break;
+	}
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	check_return(WEXITSTATUS(status), "child.children == 0",
+		    "child.children != 0");
+}
+
+/* Testcase #03: fork + malloc
+ * expect: initial.self + 50MB ~= child.self */
+static void fork_malloc(void)
+{
+	tst_resm(TINFO, "Testcase #03: fork + malloc");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+	tst_resm(TINFO, "initial.self = %ld", ru.ru_maxrss);
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK|TERRNO, cleanup, "fork #3");
+	case 0:
+		maxrss_init = ru.ru_maxrss;
+		tst_resm(TINFO, "child allocate +50MB");
+		consume(50);
+		SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+		tst_resm(TINFO, "child.self = %ld", ru.ru_maxrss);
+		exit(is_in_delta(maxrss_init + 51200 - ru.ru_maxrss));
+	default:
+		break;
+	}
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	check_return(WEXITSTATUS(status), "initial.self + 50MB ~= child.self",
+		    "initial.self + 50MB !~= child.self");
+}
+
+/* Testcase #04: grandchild maxrss
+ * expect: post_wait.children ~= 300MB */
+static void grandchild_maxrss(void)
+{
+	tst_resm(TINFO, "Testcase #04: grandchild maxrss");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK|TERRNO, cleanup, "fork #4");
+	case 0:
+		retval = system("getrusage03_child -g 300");
+		if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
+			tst_brkm(TBROK|TERRNO, cleanup, "system");
+		exit(0);
+	default:
+		break;
+	}
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	if (WEXITSTATUS(status) != 0)
+		tst_brkm(TBROK|TERRNO, cleanup, "child exit status is not 0");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "post_wait.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - 307200))
+		tst_resm(TPASS, "child.children ~= 300MB");
+	else
+		tst_resm(TFAIL, "child.children !~= 300MB");
+}
+
+/* Testcase #05: zombie
+ * expect: initial ~= pre_wait, post_wait ~= 400MB */
+static void zombie(void)
+{
+	tst_resm(TINFO, "Testcase #05: zombie");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+	maxrss_init = ru.ru_maxrss;
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK, cleanup, "fork #5");
+	case 0:
+		retval = system("getrusage03_child -n 400");
+		if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
+			tst_brkm(TBROK|TERRNO, cleanup, "system");
+		exit(0);
+	default:
+		break;
+	}
+
+	sleep(1); /* children become zombie */
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "pre_wait.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - maxrss_init))
+		tst_resm(TPASS, "initial.children ~= pre_wait.children");
+	else
+		tst_resm(TFAIL, "initial.children !~= pre_wait.children");
+
+	if (waitpid(pid, &status, WUNTRACED|WCONTINUED) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
+	if (WEXITSTATUS(status) != 0)
+		tst_brkm(TBROK|TERRNO, cleanup, "child exit status is not 0");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "post_wait.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - 409600))
+		tst_resm(TPASS, "post_wait.children ~= 400MB");
+	else
+		tst_resm(TFAIL, "post_wait.children !~= 400MB");
+}
+
+/* Testcase #06: SIG_IGN
+ * expect: initial ~= after_zombie */
+static void sig_ign(void)
+{
+	tst_resm(TINFO, "Testcase #06: SIG_IGN");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "initial.children = %ld", ru.ru_maxrss);
+	signal(SIGCHLD, SIG_IGN);
+	maxrss_init = ru.ru_maxrss;
+
+	switch (pid = fork()) {
+	case -1:
+		tst_brkm(TBROK, cleanup, "fork #6");
+	case 0:
+		retval = system("getrusage03_child -n 500");
+		if ((WIFEXITED(retval) && WEXITSTATUS(retval) != 0))
+			tst_brkm(TBROK|TERRNO, cleanup, "system");
+		exit(0);
+	default:
+		break;
+	}
+
+	sleep(1); /* children become zombie */
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	tst_resm(TINFO, "after_zombie.children = %ld", ru.ru_maxrss);
+	if (is_in_delta(ru.ru_maxrss - maxrss_init))
+		tst_resm(TPASS, "initial.children ~= after_zombie.children");
+	else
+		tst_resm(TFAIL, "initial.children !~= after_zombie.children");
+	signal(SIGCHLD, SIG_DFL);
+}
+
+/* Testcase #07: exec without fork
+ * expect: initial ~= fork */
+static void exec_without_fork(void)
+{
+	char str_maxrss_self[BUFSIZ], str_maxrss_child[BUFSIZ];
+	long maxrss_self, maxrss_child;
+
+	tst_resm(TINFO, "Testcase #07: exec without fork");
+
+	SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+	maxrss_self = ru.ru_maxrss;
+	SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+	maxrss_child = ru.ru_maxrss;
+	tst_resm(TINFO, "initial.self = %ld, initial.children = %ld",
+		    maxrss_self, maxrss_child);
+
+	sprintf(str_maxrss_self, "%ld", maxrss_self);
+	sprintf(str_maxrss_child, "%ld", maxrss_child);
+	if (execlp("getrusage03_child", "getrusage03_child", "-v",
+		    "-s", str_maxrss_self,
+		    "-l", str_maxrss_child, NULL) == -1)
+		tst_brkm(TBROK|TERRNO, cleanup, "execlp");
+}
+
+static int is_in_delta(long value)
+{
+	return (value >= -DELTA_MAX && value <= DELTA_MAX);
+}
+
+static void check_return(int status, char *pass_msg, char *fail_msg)
+{
+	switch (status) {
+	case 1:
+		tst_resm(TPASS, "%s", pass_msg);
+		break;
+	case 0:
+		tst_resm(TFAIL, "%s", fail_msg);
+		break;
+	default:
+		tst_resm(TFAIL, "child exit status is %d", status);
+		break;
+	}
+}
+
+static void consume(int mega)
+{
+	size_t sz;
+	void *ptr;
+
+	sz  = mega * 1024 * 1024;
+	ptr = SAFE_MALLOC(cleanup, sz);
+	memset(ptr, 0, sz);
+}
+
+static void setup(void)
+{
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	TEST_PAUSE;
+}
+
+static void cleanup(void)
+{
+	TEST_CLEANUP;
+}
diff --git a/testcases/kernel/syscalls/getrusage/getrusage03_child.c b/testcases/kernel/syscalls/getrusage/getrusage03_child.c
new file mode 100644
index 0000000..0008aea
--- /dev/null
+++ b/testcases/kernel/syscalls/getrusage/getrusage03_child.c
@@ -0,0 +1,182 @@
+/*
+ * getrusage03_child.c - a child program executed by getrusage03
+ *
+ * Copyright (C) 2011  Red Hat, Inc.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it
+ * is free of the rightful claim of any third person regarding
+ * infringement or the like.  Any license provided herein, whether
+ * implied or otherwise, applies only to this software file.  Patent
+ * licenses, if any, provided herein do not apply to combinations of
+ * this program with other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+#include "usctest.h"
+#include "safe_macros.h"
+
+char *TCID = "getrusage03_child";
+int TST_TOTAL = 1;
+
+#define DELTA_MAX	10240
+
+static int opt_consume, opt_grand, opt_show, opt_self, opt_child;
+static char *consume_str, *grand_consume_str, *self_str, *child_str;
+
+option_t child_options[] = {
+	{ "n:", &opt_consume, &consume_str },
+	{ "g:", &opt_grand,   &grand_consume_str },
+	{ "v",  &opt_show,    NULL },
+	{ "s:", &opt_self,    &self_str },
+	{ "l:", &opt_child,   &child_str }
+};
+
+static void usage(void);
+static void consume(int mega);
+static long get_long(const char *str);
+static void setup(void);
+static void cleanup(void);
+
+int main(int argc, char *argv[])
+{
+	int lc;
+	pid_t pid;
+	long maxrss_self, maxrss_children, delta;
+	long consume_nr, grand_consume_nr, self_nr, child_nr;
+	struct rusage ru;
+	char *msg;
+
+	msg = parse_opts(argc, argv, child_options, usage);
+	if (msg != NULL)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		Tst_count = 0;
+
+		if (opt_consume) {
+			consume_nr = get_long(consume_str);
+			tst_resm(TINFO, "child allocate %ldMB", consume_nr);
+			consume(consume_nr);
+		}
+
+		if (opt_grand) {
+			grand_consume_nr = get_long(grand_consume_str);
+			tst_resm(TINFO, "grandchild allocate %ldMB",
+				    grand_consume_nr);
+			switch (pid = fork()) {
+			case -1:
+				tst_brkm(TBROK, cleanup, "fork");
+			case 0:
+				consume(grand_consume_nr);
+				exit(0);
+			default:
+				break;
+			}
+			while (waitpid(-1, &pid, WUNTRACED|WCONTINUED) > 0)
+				if (WEXITSTATUS(pid) != 0)
+					tst_brkm(TBROK|TERRNO, cleanup,
+						"child exit status is not 0");
+		}
+
+		if (opt_show) {
+			SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru);
+			maxrss_self = ru.ru_maxrss;
+			SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru);
+			maxrss_children = ru.ru_maxrss;
+			tst_resm(TINFO, "exec.self = %ld, exec.children = %ld",
+				    maxrss_self, maxrss_children);
+			if (opt_self) {
+				self_nr = get_long(self_str);
+				delta = maxrss_self - self_nr;
+				if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+					tst_resm(TPASS,
+						"initial.self ~= exec.self");
+				else
+					tst_resm(TFAIL,
+						"initial.self !~= exec.self");
+			}
+			if (opt_child) {
+				child_nr = get_long(child_str);
+				delta = maxrss_children - child_nr;
+				if (delta >= -DELTA_MAX && delta <= DELTA_MAX)
+					tst_resm(TPASS,
+						"initial.children ~= exec.children");
+				else
+					tst_resm(TFAIL,
+						"initial.children !~= exec.children");
+			}
+		}
+	}
+
+	cleanup();
+	tst_exit();
+}
+
+static void usage(void)
+{
+	printf("  -n NUM  consume NUM MB size\n");
+	printf("  -g NUM  grandchild consume NUM MB size\n");
+	printf("  -v      verbose mode, show rusage info\n");
+	printf("  -s NUM  compare rusage_self.maxrss with given NUM\n");
+	printf("  -l NUM  compare rusage_children.maxrss with given NUM\n");
+}
+
+static void consume(int mega)
+{
+	size_t sz;
+	void *ptr;
+
+	sz  = mega * 1024 * 1024;
+	ptr = SAFE_MALLOC(cleanup, sz);
+	memset(ptr, 0, sz);
+}
+
+static long get_long(const char *str)
+{
+	long val;
+	char *endptr;
+
+	val = strtol(str, &endptr, 10);
+	if (((val == LONG_MAX || val == LONG_MIN) && errno == ERANGE) ||
+		    (errno != 0 && val == 0))
+		tst_brkm(TBROK|TERRNO, cleanup, "strtol");
+	if (endptr == str || *endptr != '\0')
+		tst_brkm(TBROK, cleanup, "Invalid number parameter: %s", str);
+
+	return val;
+}
+
+static void setup(void)
+{
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	TEST_PAUSE;
+}
+
+static void cleanup(void)
+{
+	TEST_CLEANUP;
+}

[-- Attachment #3: Type: text/plain, Size: 377 bytes --]

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2

[-- Attachment #4: Type: text/plain, Size: 155 bytes --]

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

* Re: [LTP] [PATCH v4] [syscalls] getrusage03: test ru_maxrss
  2011-06-29 17:50     ` [LTP] [PATCH v4] " Caspar Zhang
@ 2011-07-11 13:16       ` Cyril Hrubis
  0 siblings, 0 replies; 10+ messages in thread
From: Cyril Hrubis @ 2011-07-11 13:16 UTC (permalink / raw)
  To: Caspar Zhang; +Cc: LTP List

Hi!
> getrusage03 - test ru_maxrss behaviors in struct rusage
> 
> This test program is backported from upstream commit:
> 1f10206cf8e945220f7220a809d8bfc15c21f9a5, which fills ru_maxrss
> value in struct rusage according to rss hiwater mark. To make sure
> this feature works correctly, a series of tests are executed in
> this program.
> 
> Signed-off-by: Caspar Zhang <czhang@redhat.com>

Commited, thanks.

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

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

end of thread, other threads:[~2011-07-11 13:14 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-16 15:05 [LTP] [PATCH] [syscalls] getrusage03: test ru_maxrss Caspar Zhang
2011-05-16 15:08 ` Caspar Zhang
2011-05-19 17:40 ` Cyril Hrubis
     [not found]   ` <BANLkTi=m96RBZeFuRaOA5Sb_QANhgo4yCA@mail.gmail.com>
2011-05-20 13:29     ` Cyril Hrubis
2011-06-13 13:12 ` [LTP] [PATCH v2] " Caspar Zhang
2011-06-29 14:14   ` Cyril Hrubis
2011-06-29 15:36   ` [LTP] [PATCH v3] " Caspar Zhang
2011-06-29 17:46     ` Cyril Hrubis
2011-06-29 17:50     ` [LTP] [PATCH v4] " Caspar Zhang
2011-07-11 13:16       ` Cyril Hrubis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox