hugeshmget03.c revision 0b9589f3f9c0345b29cfcf7da5a1253c708303eb
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20/* 21 * NAME 22 * hugeshmget03.c 23 * 24 * DESCRIPTION 25 * hugeshmget03 - test for ENOSPC error 26 * 27 * ALGORITHM 28 * create large shared memory segments in a loop until reaching 29 * the system limit 30 * loop if that option was specified 31 * attempt to create yet another shared memory segment 32 * check the errno value 33 * issue a PASS message if we get ENOSPC 34 * otherwise, the tests fails 35 * issue a FAIL message 36 * call cleanup 37 * 38 * USAGE: <for command-line> 39 * hugeshmget03 [-c n] [-e] [-i n] [-I x] [-P x] [-t] 40 * where, -c n : Run n copies concurrently. 41 * -e : Turn on errno logging. 42 * -i n : Execute test n times. 43 * -I x : Execute test for x seconds. 44 * -P x : Pause for x seconds between iterations. 45 * -t : Turn on syscall timing. 46 * 47 * HISTORY 48 * 03/2001 - Written by Wayne Boyer 49 * 04/2004 - Updated by Robbie Williamson 50 * 51 * RESTRICTIONS 52 * none 53 */ 54 55#include "ipcshm.h" 56#include "safe_macros.h" 57#include "mem.h" 58 59char *TCID = "hugeshmget03"; 60int TST_TOTAL = 1; 61 62/* 63 * The MAXIDS value is somewhat arbitrary and may need to be increased 64 * depending on the system being tested. 65 */ 66#define MAXIDS 8192 67#define PATH_SHMMNI "/proc/sys/kernel/shmmni" 68 69static size_t shm_size; 70static int shm_id_1 = -1; 71static int num_shms; 72static int shm_id_arr[MAXIDS]; 73 74static long hugepages = 128; 75static long orig_shmmni; 76static option_t options[] = { 77 {"s:", &sflag, &nr_opt}, 78 {NULL, NULL, NULL} 79}; 80 81int main(int ac, char **av) 82{ 83 int lc; 84 const char *msg; 85 86 msg = parse_opts(ac, av, options, &help); 87 if (msg != NULL) 88 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); 89 if (sflag) 90 hugepages = SAFE_STRTOL(NULL, nr_opt, 0, LONG_MAX); 91 92 setup(); 93 94 for (lc = 0; TEST_LOOPING(lc); lc++) { 95 tst_count = 0; 96 97 TEST(shmget(IPC_PRIVATE, shm_size, 98 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW)); 99 if (TEST_RETURN != -1) { 100 tst_resm(TFAIL, "shmget succeeded unexpectedly"); 101 continue; 102 } 103 if (TEST_ERRNO == ENOSPC) 104 tst_resm(TPASS | TTERRNO, "shmget failed as expected"); 105 else 106 tst_resm(TFAIL | TTERRNO, "shmget failed unexpectedly " 107 "- expect errno=ENOSPC, got"); 108 } 109 cleanup(); 110 tst_exit(); 111} 112 113void setup(void) 114{ 115 long hpage_size; 116 117 tst_require_root(NULL); 118 tst_sig(NOFORK, DEF_HANDLER, cleanup); 119 tst_tmpdir(); 120 121 orig_hugepages = get_sys_tune("nr_hugepages"); 122 set_sys_tune("nr_hugepages", hugepages, 1); 123 hpage_size = read_meminfo("Hugepagesize:") * 1024; 124 125 shm_size = hpage_size; 126 127 SAFE_FILE_SCANF(NULL, PATH_SHMMNI, "%ld", &orig_shmmni); 128 SAFE_FILE_PRINTF(NULL, PATH_SHMMNI, "%ld", hugepages / 2); 129 130 /* 131 * Use a while loop to create the maximum number of memory segments. 132 * If the loop exceeds MAXIDS, then break the test and cleanup. 133 */ 134 num_shms = 0; 135 shm_id_1 = shmget(IPC_PRIVATE, shm_size, 136 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW); 137 while (shm_id_1 != -1) { 138 shm_id_arr[num_shms++] = shm_id_1; 139 if (num_shms == MAXIDS) 140 tst_brkm(TBROK, cleanup, "The maximum number of " 141 "shared memory ID's has been reached. " 142 "Please increase the MAXIDS value in " 143 "the test."); 144 shm_id_1 = shmget(IPC_PRIVATE, shm_size, 145 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW); 146 } 147 if (errno != ENOSPC) 148 tst_brkm(TBROK | TERRNO, cleanup, "shmget #setup"); 149 150 TEST_PAUSE; 151} 152 153void cleanup(void) 154{ 155 int i; 156 157 TEST_CLEANUP; 158 159 for (i = 0; i < num_shms; i++) 160 rm_shm(shm_id_arr[i]); 161 162 SAFE_FILE_PRINTF(NULL, PATH_SHMMNI, "%ld", orig_shmmni); 163 set_sys_tune("nr_hugepages", orig_hugepages, 0); 164 165 tst_rmdir(); 166} 167