hugeshmget03.c revision bdbaec51a423e715c2b03ed9e497e9a1fba6103e
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 *	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 the system limit
29 *	loop if that option was specified
30 *	  attempt to create yet another shared memory segment
31 *	  check the errno value
32 *	    issue a PASS message if we get ENOSPC
33 *	  otherwise, the tests fails
34 *	    issue a FAIL message
35 *	call cleanup
36 *
37 * USAGE:  <for command-line>
38 *  hugeshmget03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
39 *     where,  -c n : Run n copies concurrently.
40 *             -e   : Turn on errno logging.
41 *	       -i n : Execute test n times.
42 *	       -I x : Execute test for x seconds.
43 *	       -P x : Pause for x seconds between iterations.
44 *	       -t   : Turn on syscall timing.
45 *
46 * HISTORY
47 *	03/2001 - Written by Wayne Boyer
48 *	04/2004 - Updated by Robbie Williamson
49 *
50 * RESTRICTIONS
51 *	none
52 */
53
54#include "ipcshm.h"
55#include "system_specific_hugepages_info.h"
56
57char *TCID = "hugeshmget03";
58int TST_TOTAL = 1;
59extern int Tst_count;
60
61int exp_enos[] = {ENOSPC, 0};	/* 0 terminated list of expected errnos */
62void setup2(unsigned long huge_pages_shm_to_be_allocated);
63/*
64 * The MAXIDS value is somewhat arbitrary and may need to be increased
65 * depending on the system being tested.
66 */
67#define MAXIDS	8192
68
69int shm_id_1 = -1;
70int num_shms = 0;
71
72int shm_id_arr[MAXIDS];
73
74
75int main(int ac, char **av)
76{
77	int lc;				/* loop counter */
78	char *msg;			/* message returned from parse_opts */
79        unsigned long huge_pages_shm_to_be_allocated;
80
81	/* parse standard options */
82	if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
83		tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
84	}
85
86	/* The following loop checks looping state if -i option given */
87        if ( get_no_of_hugepages() <= 0 || hugepages_size() <= 0 )
88             tst_brkm(TBROK, cleanup, "Test cannot be continued owning to sufficient availability of Hugepages on the system");
89        else
90             huge_pages_shm_to_be_allocated = ( get_no_of_hugepages() * hugepages_size() * 1024) / 2 ;
91
92	setup2(huge_pages_shm_to_be_allocated);			/* local  setup */
93
94
95	for (lc = 0; TEST_LOOPING(lc); lc++) {
96		/* reset Tst_count in case we are looping */
97		Tst_count = 0;
98
99		/*
100		 * use the TEST() macro to make the call
101		 */
102
103		TEST(shmget(IPC_PRIVATE, huge_pages_shm_to_be_allocated, SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW));
104
105		if (TEST_RETURN != -1) {
106			tst_resm(TFAIL, "call succeeded when error expected");
107			continue;
108		}
109
110		TEST_ERROR_LOG(TEST_ERRNO);
111
112		switch(TEST_ERRNO) {
113		case ENOSPC:
114			tst_resm(TPASS, "expected failure - errno = "
115				 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO));
116			break;
117		default:
118			tst_resm(TFAIL, "call failed with an "
119				 "unexpected error - %d : %s",
120				 TEST_ERRNO, strerror(TEST_ERRNO));
121			break;
122		}
123	}
124
125	cleanup();
126
127	/*NOTREACHED*/
128	return 0;
129}
130
131/*
132 * setup2() - performs all the ONE TIME setup for this test.
133 */
134void setup2(unsigned long huge_pages_shm_to_be_allocated) {
135	/* capture signals */
136	tst_sig(NOFORK, DEF_HANDLER, cleanup);
137
138	/* Set up the expected error numbers for -e option */
139	TEST_EXP_ENOS(exp_enos);
140
141	/* Pause if that option was specified */
142	TEST_PAUSE;
143
144	/*
145	 * Create a temporary directory and cd into it.
146	 * This helps to ensure that a unique msgkey is created.
147	 * See ../lib/libipc.c for more information.
148	 */
149	tst_tmpdir();
150
151	/* get an IPC resource key */
152	shmkey = getipckey();
153
154	/*
155	 * Use a while loop to create the maximum number of memory segments.
156	 * If the loop exceeds MAXIDS, then break the test and cleanup.
157	 */
158	while ((shm_id_1 = shmget(IPC_PRIVATE, huge_pages_shm_to_be_allocated, SHM_HUGETLB | IPC_CREAT |
159	     IPC_EXCL | SHM_RW)) != -1) {
160		shm_id_arr[num_shms++] = shm_id_1;
161		if (num_shms == MAXIDS) {
162			tst_brkm(TBROK, cleanup, "The maximum number of shared "
163				 "memory ID's has been\n\t reached.  Please "
164				 "increase the MAXIDS value in the test.");
165		}
166	}
167
168	/*
169	 * If the errno is other than ENOSPC, then something else is wrong.
170	 */
171	if (errno != ENOSPC) {
172		tst_resm(TINFO, "errno = %d : %s", errno, strerror(errno));
173		tst_brkm(TBROK, cleanup, "Didn't get ENOSPC in test setup");
174	}
175}
176
177/*
178 * cleanup() - performs all the ONE TIME cleanup for this test at completion
179 * 	       or premature exit.
180 */
181void
182cleanup(void)
183{
184	int i;
185
186	/* remove the shared memory resources that were created */
187	for(i=0; i<num_shms; i++) {
188		rm_shm(shm_id_arr[i]);
189	}
190
191	/* Remove the temporary directory */
192	tst_rmdir();
193
194	/*
195	 * print timing stats if that option was specified.
196	 * print errno log if that option was specified.
197	 */
198	TEST_CLEANUP;
199
200	/* exit with return code appropriate for results */
201	tst_exit();
202}
203
204