1 /* 2 * getrusage03_child.c - a child program executed by getrusage03 3 * 4 * Copyright (C) 2011 Red Hat, Inc. 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of version 2 of the GNU General Public 7 * License as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * 13 * Further, this software is distributed without any warranty that it 14 * is free of the rightful claim of any third person regarding 15 * infringement or the like. Any license provided herein, whether 16 * implied or otherwise, applies only to this software file. Patent 17 * licenses, if any, provided herein do not apply to combinations of 18 * this program with other software, or any other product whatsoever. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write the Free Software 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 23 * 02110-1301, USA. 24 */ 25 #include <sys/types.h> 26 #include <sys/resource.h> 27 #include <sys/time.h> 28 #include <sys/wait.h> 29 #include <errno.h> 30 #include <unistd.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 35 #include "test.h" 36 #include "safe_macros.h" 37 38 char *TCID = "getrusage03_child"; 39 int TST_TOTAL = 1; 40 41 #define DELTA_MAX 10240 42 43 static int opt_consume, opt_grand, opt_show, opt_self, opt_child; 44 static char *consume_str, *grand_consume_str, *self_str, *child_str; 45 46 option_t child_options[] = { 47 {"n:", &opt_consume, &consume_str}, 48 {"g:", &opt_grand, &grand_consume_str}, 49 {"v", &opt_show, NULL}, 50 {"s:", &opt_self, &self_str}, 51 {"l:", &opt_child, &child_str}, 52 {NULL, NULL, NULL} 53 }; 54 55 static void usage(void); 56 static void consume(int mega); 57 static void setup(void); 58 static void cleanup(void); 59 60 int main(int argc, char *argv[]) 61 { 62 int lc; 63 pid_t pid; 64 long maxrss_self, maxrss_children, delta; 65 long consume_nr, grand_consume_nr, self_nr, child_nr; 66 struct rusage ru; 67 68 tst_parse_opts(argc, argv, child_options, usage); 69 70 setup(); 71 72 for (lc = 0; TEST_LOOPING(lc); lc++) { 73 tst_count = 0; 74 75 if (opt_consume) { 76 consume_nr = SAFE_STRTOL(cleanup, 77 consume_str, 0, LONG_MAX); 78 tst_resm(TINFO, "child allocate %ldMB", consume_nr); 79 consume(consume_nr); 80 } 81 82 if (opt_grand) { 83 grand_consume_nr = SAFE_STRTOL(cleanup, 84 grand_consume_str, 0, 85 LONG_MAX); 86 tst_resm(TINFO, "grandchild allocate %ldMB", 87 grand_consume_nr); 88 switch (pid = fork()) { 89 case -1: 90 tst_brkm(TBROK, cleanup, "fork"); 91 case 0: 92 consume(grand_consume_nr); 93 exit(0); 94 default: 95 break; 96 } 97 while (waitpid(-1, &pid, WUNTRACED | WCONTINUED) > 0) 98 if (WEXITSTATUS(pid) != 0) 99 tst_brkm(TBROK | TERRNO, cleanup, 100 "child exit status is not 0"); 101 } 102 103 if (opt_show) { 104 SAFE_GETRUSAGE(cleanup, RUSAGE_SELF, &ru); 105 maxrss_self = ru.ru_maxrss; 106 SAFE_GETRUSAGE(cleanup, RUSAGE_CHILDREN, &ru); 107 maxrss_children = ru.ru_maxrss; 108 tst_resm(TINFO, "exec.self = %ld, exec.children = %ld", 109 maxrss_self, maxrss_children); 110 if (opt_self) { 111 self_nr = SAFE_STRTOL(cleanup, 112 self_str, 0, LONG_MAX); 113 delta = maxrss_self - self_nr; 114 if (delta >= -DELTA_MAX && delta <= DELTA_MAX) 115 tst_resm(TPASS, 116 "initial.self ~= exec.self"); 117 else 118 tst_resm(TFAIL, 119 "initial.self !~= exec.self"); 120 } 121 if (opt_child) { 122 child_nr = SAFE_STRTOL(cleanup, 123 child_str, 0, LONG_MAX); 124 delta = maxrss_children - child_nr; 125 if (delta >= -DELTA_MAX && delta <= DELTA_MAX) 126 tst_resm(TPASS, 127 "initial.children ~= exec.children"); 128 else 129 tst_resm(TFAIL, 130 "initial.children !~= exec.children"); 131 } 132 } 133 } 134 135 cleanup(); 136 tst_exit(); 137 } 138 139 static void usage(void) 140 { 141 printf(" -n NUM consume NUM MB size\n"); 142 printf(" -g NUM grandchild consume NUM MB size\n"); 143 printf(" -v verbose mode, show rusage info\n"); 144 printf(" -s NUM compare rusage_self.maxrss with given NUM\n"); 145 printf(" -l NUM compare rusage_children.maxrss with given NUM\n"); 146 } 147 148 static void consume(int mega) 149 { 150 size_t sz; 151 void *ptr; 152 153 sz = mega * 1024 * 1024; 154 ptr = SAFE_MALLOC(cleanup, sz); 155 memset(ptr, 0, sz); 156 } 157 158 static void setup(void) 159 { 160 tst_sig(FORK, DEF_HANDLER, cleanup); 161 162 TEST_PAUSE; 163 } 164 165 static void cleanup(void) 166 { 167 } 168