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 * hugeshmctl02.c 23 * 24 * DESCRIPTION 25 * hugeshmctl02 - check for EACCES, EFAULT and EINVAL errors 26 * 27 * ALGORITHM 28 * create a large shared memory segment without read or write permissions 29 * create a large shared memory segment with read & write permissions 30 * loop if that option was specified 31 * call shmctl() using five different invalid cases 32 * check the errno value 33 * issue a PASS message if we get EACCES, EFAULT or EINVAL 34 * otherwise, the tests fails 35 * issue a FAIL message 36 * call cleanup 37 * 38 * USAGE: <for command-line> 39 * hugeshmctl02 [-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 <pwd.h> 56 #include "test.h" 57 #include "safe_macros.h" 58 #include "mem.h" 59 #include "hugetlb.h" 60 61 char *TCID = "hugeshmctl02"; 62 int TST_TOTAL = 4; 63 64 static size_t shm_size; 65 static int shm_id_1 = -1; 66 static int shm_id_2 = -1; 67 static int shm_id_3 = -1; 68 static struct shmid_ds buf; 69 70 static long hugepages = 128; 71 static option_t options[] = { 72 {"s:", &sflag, &nr_opt}, 73 {NULL, NULL, NULL} 74 }; 75 76 struct test_case_t { 77 int *shmid; 78 int cmd; 79 struct shmid_ds *sbuf; 80 int error; 81 } TC[] = { 82 /* EFAULT - IPC_SET & buf isn't valid */ 83 { 84 &shm_id_2, IPC_SET, (struct shmid_ds *)-1, EFAULT}, 85 /* EFAULT - IPC_STAT & buf isn't valid */ 86 { 87 &shm_id_2, IPC_STAT, (struct shmid_ds *)-1, EFAULT}, 88 /* EINVAL - the shmid is not valid */ 89 { 90 &shm_id_3, IPC_STAT, &buf, EINVAL}, 91 /* EINVAL - the command is not valid */ 92 { 93 &shm_id_2, -1, &buf, EINVAL},}; 94 95 int main(int ac, char **av) 96 { 97 int lc, i; 98 99 tst_parse_opts(ac, av, options, NULL); 100 101 if (sflag) 102 hugepages = SAFE_STRTOL(NULL, nr_opt, 0, LONG_MAX); 103 104 setup(); 105 106 for (lc = 0; TEST_LOOPING(lc); lc++) { 107 tst_count = 0; 108 109 for (i = 0; i < TST_TOTAL; i++) { 110 TEST(shmctl(*(TC[i].shmid), TC[i].cmd, TC[i].sbuf)); 111 if (TEST_RETURN != -1) { 112 tst_resm(TFAIL, "shmctl succeeded " 113 "unexpectedly"); 114 continue; 115 } 116 if (TEST_ERRNO == TC[i].error) 117 tst_resm(TPASS | TTERRNO, "shmctl failed " 118 "as expected"); 119 else 120 tst_resm(TFAIL | TTERRNO, "shmctl failed " 121 "unexpectedly - expect errno = " 122 "%d, got", TC[i].error); 123 } 124 } 125 cleanup(); 126 tst_exit(); 127 } 128 129 void setup(void) 130 { 131 long hpage_size; 132 133 tst_require_root(); 134 check_hugepage(); 135 tst_sig(NOFORK, DEF_HANDLER, cleanup); 136 tst_tmpdir(); 137 138 orig_hugepages = get_sys_tune("nr_hugepages"); 139 set_sys_tune("nr_hugepages", hugepages, 1); 140 hpage_size = read_meminfo("Hugepagesize:") * 1024; 141 142 shm_size = hpage_size * hugepages / 2; 143 update_shm_size(&shm_size); 144 shmkey = getipckey(cleanup); 145 146 /* create a shared memory segment without read or write permissions */ 147 shm_id_1 = shmget(shmkey, shm_size, SHM_HUGETLB | IPC_CREAT | IPC_EXCL); 148 if (shm_id_1 == -1) 149 tst_brkm(TBROK | TERRNO, cleanup, "shmget #1"); 150 151 /* create a shared memory segment with read and write permissions */ 152 shm_id_2 = shmget(shmkey + 1, shm_size, 153 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW); 154 if (shm_id_2 == -1) 155 tst_brkm(TBROK | TERRNO, cleanup, "shmget #2"); 156 157 TEST_PAUSE; 158 } 159 160 void cleanup(void) 161 { 162 rm_shm(shm_id_1); 163 rm_shm(shm_id_2); 164 165 set_sys_tune("nr_hugepages", orig_hugepages, 0); 166 167 tst_rmdir(); 168 } 169