hugeshmget05.c revision 8fb1cdb0538640f295691929650408688537fb7f
1/* 2 * 3 * Copyright (c) International Business Machines Corp., 2004 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20/* 21 * NAME 22 * hugeshmget05.c 23 * 24 * DESCRIPTION 25 * hugeshmget05 - test for EACCES error 26 * 27 * ALGORITHM 28 * create a large shared memory segment with root only read & write permissions 29 * fork a child process 30 * if child 31 * set the ID of the child process to that of "nobody" 32 * loop if that option was specified 33 * call shmget() using the TEST() macro 34 * check the errno value 35 * issue a PASS message if we get EACCES 36 * otherwise, the tests fails 37 * issue a FAIL message 38 * call cleanup 39 * if parent 40 * wait for child to exit 41 * remove the shared memory segment 42 * 43 * USAGE: <for command-line> 44 * hugeshmget05 [-c n] [-e] [-i n] [-I x] [-P x] [-t] 45 * where, -c n : Run n copies concurrently. 46 * -e : Turn on errno logging. 47 * -i n : Execute test n times. 48 * -I x : Execute test for x seconds. 49 * -P x : Pause for x seconds between iterations. 50 * -t : Turn on syscall timing. 51 * 52 * HISTORY 53 * 03/2001 - Written by Wayne Boyer 54 * 04/2004 - Updated by Robbie Williamson 55 * 56 * RESTRICTIONS 57 * test must be run at root 58 */ 59 60#include "ipcshm.h" 61#include <sys/types.h> 62#include <sys/wait.h> 63#include "system_specific_hugepages_info.h" 64 65char *TCID = "hugeshmget05"; 66int TST_TOTAL = 1; 67extern int Tst_count; 68unsigned long huge_pages_shm_to_be_allocated; 69 70int exp_enos[] = {EACCES, 0}; /* 0 terminated list of expected errnos */ 71 72int shm_id_1 = -1; 73 74uid_t ltp_uid; 75char *ltp_user = "nobody"; 76 77int main(int ac, char **av) 78{ 79 char *msg; /* message returned from parse_opts */ 80 pid_t pid; 81 int status; 82 void do_child(void); 83 84 /* parse standard options */ 85 if ((msg = parse_opts(ac, av, NULL) { 86 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg); 87 } 88 89 if (get_no_of_hugepages() <= 0 || hugepages_size() <= 0) 90 tst_brkm(TCONF, cleanup, "Not enough available Hugepages"); 91 else 92 huge_pages_shm_to_be_allocated = ( get_no_of_hugepages() * hugepages_size() * 1024) / 2 ; 93 94 setup(); /* global setup */ 95 96 if ((pid = fork()) == -1) { 97 tst_brkm(TBROK, cleanup, "could not fork"); 98 } 99 100 if (pid == 0) { /* child */ 101 /* set the user ID of the child to the non root user */ 102 if (setuid(ltp_uid) == -1) { 103 tst_resm(TBROK, "setuid() failed"); 104 exit(1); 105 } 106 107 do_child(); 108 109 tst_exit(); 110 /*NOTREACHED*/ 111 } else { /* parent */ 112 /* wait for the child to return */ 113 if (waitpid(pid, &status, 0) == -1) { 114 tst_resm(TBROK, "waitpid failed"); 115 } 116 else if (status != 0) { 117 tst_resm(TFAIL, "child process failed to exit cleanly " 118 "(exit status = %d)", status); 119 } 120 } 121 122 cleanup(); 123 124 /* NOTREACHED */ 125 return 0; 126} 127 128/* 129 * do_child - make the TEST call as the child process 130 */ 131void 132do_child() 133{ 134 int lc; 135 136 /* The following loop checks looping state if -i option given */ 137 138 for (lc = 0; TEST_LOOPING(lc); lc++) { 139 /* reset Tst_count in case we are looping */ 140 Tst_count = 0; 141 142 /* 143 * Look for a failure ... 144 */ 145 146 TEST(shmget(shmkey, huge_pages_shm_to_be_allocated, SHM_HUGETLB | SHM_RW)); 147 148 if (TEST_RETURN != -1) { 149 tst_resm(TFAIL, "call succeeded when error expected"); 150 continue; 151 } 152 153 TEST_ERROR_LOG(TEST_ERRNO); 154 155 switch(TEST_ERRNO) { 156 case EACCES: 157 tst_resm(TPASS|TTERRNO, "expected failure"); 158 break; 159 default: 160 tst_resm(TFAIL|TTERRNO, "call failed with an " 161 "unexpected error"); 162 break; 163 } 164 } 165} 166 167/* 168 * setup() - performs all the ONE TIME setup for this test. 169 */ 170void 171setup(void) 172{ 173 /* check for root as process owner */ 174 check_root(); 175 176 /* capture signals */ 177 tst_sig(FORK, DEF_HANDLER, cleanup); 178 179 /* Set up the expected error numbers for -e option */ 180 TEST_EXP_ENOS(exp_enos); 181 182 /* Pause if that option was specified */ 183 TEST_PAUSE; 184 185 /* 186 * Create a temporary directory and cd into it. 187 * This helps to ensure that a unique msgkey is created. 188 * See ../lib/libipc.c for more information. 189 */ 190 tst_tmpdir(); 191 192 /* get an IPC resource key */ 193 shmkey = getipckey(); 194 195 /* create a shared memory segment with read and write permissions */ 196 if ((shm_id_1 = shmget(shmkey, huge_pages_shm_to_be_allocated, SHM_HUGETLB | SHM_RW | IPC_CREAT | IPC_EXCL)) == -1) { 197 tst_brkm(TBROK, cleanup, "Failed to create shared memory " 198 "segment in setup"); 199 } 200 201 /* get the userid for a non root user */ 202 ltp_uid = getuserid(ltp_user); 203} 204 205/* 206 * cleanup() - performs all the ONE TIME cleanup for this test at completion 207 * or premature exit. 208 */ 209void 210cleanup(void) 211{ 212 /* if it exists, remove the shared memory resource */ 213 rm_shm(shm_id_1); 214 215 /* 216 * print timing stats if that option was specified. 217 * print errno log if that option was specified. 218 */ 219 TEST_CLEANUP; 220 221 /* exit with return code appropriate for results */ 222 tst_exit(); 223} 224 225