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 * hugeshmget01.c
23 *
24 * DESCRIPTION
25 * hugeshmget01 - test that shmget() correctly creates a large
26 * shared memory segment
27 *
28 * ALGORITHM
29 * loop if that option was specified
30 * use the TEST() macro to call shmget()
31 * check the return code
32 * if failure, issue a FAIL message.
33 * otherwise,
34 * if doing functionality testing
35 * stat the shared memory resource
36 * check the size, creator pid and mode
37 * if correct,
38 * issue a PASS message
39 * otherwise
40 * issue a FAIL message
41 * else issue a PASS message
42 * call cleanup
43 *
44 * USAGE: <for command-line>
45 * shmget01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
46 * where, -c n : Run n copies concurrently.
47 * -f : Turn off functionality Testing.
48 * -i n : Execute test n times.
49 * -I x : Execute test for x seconds.
50 * -P x : Pause for x seconds between iterations.
51 * -t : Turn on syscall timing.
52 *
53 * HISTORY
54 * 03/2001 - Written by Wayne Boyer
55 * 04/2004 - Updated by Robbie Williamson
56 *
57 * RESTRICTIONS
58 * none
59 */
60
61 #include "hugetlb.h"
62 #include "safe_macros.h"
63 #include "mem.h"
64
65 char *TCID = "hugeshmget01";
66 int TST_TOTAL = 1;
67
68 static size_t shm_size;
69 static int shm_id_1 = -1;
70
71 static long hugepages = 128;
72 static option_t options[] = {
73 {"s:", &sflag, &nr_opt},
74 {NULL, NULL, NULL}
75 };
76
main(int ac,char ** av)77 int main(int ac, char **av)
78 {
79 int lc;
80 struct shmid_ds buf;
81
82 tst_parse_opts(ac, av, options, NULL);
83
84 if (sflag)
85 hugepages = SAFE_STRTOL(NULL, nr_opt, 0, LONG_MAX);
86
87 setup();
88
89 for (lc = 0; TEST_LOOPING(lc); lc++) {
90 tst_count = 0;
91
92 shm_id_1 = shmget(shmkey, shm_size,
93 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW);
94 if (shm_id_1 == -1) {
95 tst_resm(TFAIL | TERRNO, "shmget");
96 } else {
97 /* do a STAT and check some info */
98 if (shmctl(shm_id_1, IPC_STAT, &buf) == -1) {
99 tst_resm(TBROK | TERRNO,
100 "shmctl(IPC_STAT)");
101 continue;
102 }
103 /* check the seqment size */
104 if (buf.shm_segsz != shm_size) {
105 tst_resm(TFAIL, "seqment size is not "
106 "correct");
107 continue;
108 }
109 /* check the pid of the creator */
110 if (buf.shm_cpid != getpid()) {
111 tst_resm(TFAIL, "creator pid is not "
112 "correct");
113 continue;
114 }
115 /*
116 * check the mode of the seqment
117 * mask out all but the lower 9 bits
118 */
119 if ((buf.shm_perm.mode & MODE_MASK) !=
120 ((SHM_RW) & MODE_MASK)) {
121 tst_resm(TFAIL, "segment mode is not "
122 "correct");
123 continue;
124 }
125 /* if we get here, everything looks good */
126 tst_resm(TPASS, "size, pid & mode are correct");
127 }
128
129 /*
130 * clean up things in case we are looping
131 */
132 if (shmctl(shm_id_1, IPC_RMID, NULL) == -1)
133 tst_resm(TBROK | TERRNO, "shmctl(IPC_RMID)");
134 else
135 shm_id_1 = -1;
136 }
137 cleanup();
138 tst_exit();
139 }
140
setup(void)141 void setup(void)
142 {
143 long hpage_size;
144
145 tst_require_root();
146 check_hugepage();
147 tst_sig(NOFORK, DEF_HANDLER, cleanup);
148 tst_tmpdir();
149
150 orig_hugepages = get_sys_tune("nr_hugepages");
151 set_sys_tune("nr_hugepages", hugepages, 1);
152 hpage_size = read_meminfo("Hugepagesize:") * 1024;
153
154 shm_size = hpage_size * hugepages / 2;
155 update_shm_size(&shm_size);
156 shmkey = getipckey(cleanup);
157
158 TEST_PAUSE;
159 }
160
cleanup(void)161 void cleanup(void)
162 {
163 rm_shm(shm_id_1);
164
165 set_sys_tune("nr_hugepages", orig_hugepages, 0);
166
167 tst_rmdir();
168 }
169