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 "hugetlb.h"
56 #include "safe_macros.h"
57 #include "mem.h"
58
59 char *TCID = "hugeshmget03";
60 int 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
69 static size_t shm_size;
70 static int shm_id_1 = -1;
71 static int num_shms;
72 static int shm_id_arr[MAXIDS];
73
74 static long hugepages = 128;
75 static long orig_shmmni;
76 static option_t options[] = {
77 {"s:", &sflag, &nr_opt},
78 {NULL, NULL, NULL}
79 };
80
main(int ac,char ** av)81 int main(int ac, char **av)
82 {
83 int lc;
84
85 tst_parse_opts(ac, av, options, NULL);
86
87 if (sflag)
88 hugepages = SAFE_STRTOL(NULL, nr_opt, 0, LONG_MAX);
89
90 setup();
91
92 for (lc = 0; TEST_LOOPING(lc); lc++) {
93 tst_count = 0;
94
95 TEST(shmget(IPC_PRIVATE, shm_size,
96 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW));
97 if (TEST_RETURN != -1) {
98 tst_resm(TFAIL, "shmget succeeded unexpectedly");
99 continue;
100 }
101 if (TEST_ERRNO == ENOSPC)
102 tst_resm(TPASS | TTERRNO, "shmget failed as expected");
103 else
104 tst_resm(TFAIL | TTERRNO, "shmget failed unexpectedly "
105 "- expect errno=ENOSPC, got");
106 }
107 cleanup();
108 tst_exit();
109 }
110
setup(void)111 void setup(void)
112 {
113 long hpage_size;
114
115 tst_require_root();
116 check_hugepage();
117 tst_sig(NOFORK, DEF_HANDLER, cleanup);
118 tst_tmpdir();
119
120 orig_hugepages = get_sys_tune("nr_hugepages");
121 set_sys_tune("nr_hugepages", hugepages, 1);
122 hpage_size = read_meminfo("Hugepagesize:") * 1024;
123
124 shm_size = hpage_size;
125
126 SAFE_FILE_SCANF(NULL, PATH_SHMMNI, "%ld", &orig_shmmni);
127 SAFE_FILE_PRINTF(NULL, PATH_SHMMNI, "%ld", hugepages / 2);
128
129 /*
130 * Use a while loop to create the maximum number of memory segments.
131 * If the loop exceeds MAXIDS, then break the test and cleanup.
132 */
133 num_shms = 0;
134 shm_id_1 = shmget(IPC_PRIVATE, shm_size,
135 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW);
136 while (shm_id_1 != -1) {
137 shm_id_arr[num_shms++] = shm_id_1;
138 if (num_shms == MAXIDS)
139 tst_brkm(TBROK, cleanup, "The maximum number of "
140 "shared memory ID's has been reached. "
141 "Please increase the MAXIDS value in "
142 "the test.");
143 shm_id_1 = shmget(IPC_PRIVATE, shm_size,
144 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW);
145 }
146 if (errno != ENOSPC)
147 tst_brkm(TBROK | TERRNO, cleanup, "shmget #setup");
148
149 TEST_PAUSE;
150 }
151
cleanup(void)152 void cleanup(void)
153 {
154 int i;
155
156 for (i = 0; i < num_shms; i++)
157 rm_shm(shm_id_arr[i]);
158
159 FILE_PRINTF(PATH_SHMMNI, "%ld", orig_shmmni);
160 set_sys_tune("nr_hugepages", orig_hugepages, 0);
161
162 tst_rmdir();
163 }
164