blob: 5d1e85dada860fcacd41cdbbb609a9a4e1851ab5 [file] [log] [blame]
robbiewa3cc71f2003-02-18 20:53:50 +00001/* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
robbiewdcc848e2003-01-02 21:03:35 +00002 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of version 2 of the GNU General Public License as
5 * published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it would be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 *
11 * You should have received a copy of the GNU General Public License along
Wanlong Gaofed96412012-10-24 10:10:29 +080012 * with this program; if not, write the Free Software Foundation, Inc.,
13 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
robbiewdcc848e2003-01-02 21:03:35 +000014 *
15 */
16/**************************************************************************
subrata_modak4bb656a2009-02-26 12:02:09 +000017 *
robbiewef957512003-03-13 15:33:06 +000018 * TEST IDENTIFIER : swapon02
subrata_modak4bb656a2009-02-26 12:02:09 +000019 *
robbiewef957512003-03-13 15:33:06 +000020 * EXECUTED BY : root / superuser
subrata_modak4bb656a2009-02-26 12:02:09 +000021 *
robbiewef957512003-03-13 15:33:06 +000022 * TEST TITLE : Test checking for basic error conditions
subrata_modakdaeac7a2007-05-17 14:31:45 +000023 * for swapon(2)
subrata_modak4bb656a2009-02-26 12:02:09 +000024 *
25 * TEST CASE TOTAL : 5
26 *
subrata_modakdaeac7a2007-05-17 14:31:45 +000027 * AUTHOR : Aniruddha Marathe <aniruddha.marathe@wipro.com> and
28 * Ricardo Salveti de Araujo <rsalveti@linux.vnet.ibm.com> for
29 * the EBUSY test case
subrata_modak4bb656a2009-02-26 12:02:09 +000030 *
robbiewdcc848e2003-01-02 21:03:35 +000031 * SIGNALS
robbiew6b01d682003-04-28 20:27:26 +000032 * Uses SIGUSR1 to pause before test if option set.
33 * (See the parse_opts(3) man page).
robbiewdcc848e2003-01-02 21:03:35 +000034 *
35 * DESCRIPTION
subrata_modak4bb656a2009-02-26 12:02:09 +000036 * This test case checks whether swapon(2) system call returns
subrata_modakdaeac7a2007-05-17 14:31:45 +000037 * 1. ENOENT when the path does not exist
38 * 2. EINVAL when the path exists but is invalid
subrata_modak413ec142007-08-28 07:17:29 +000039 * 3. EPERM when user is not a superuser
40 * 4. EBUSY when the specified path is already being used as a swap area
subrata_modak56207ce2009-03-23 13:35:39 +000041 * $
robbiew6b01d682003-04-28 20:27:26 +000042 * Setup:
43 * Setup signal handling.
44 * Pause for SIGUSR1 if option specified.
subrata_modak413ec142007-08-28 07:17:29 +000045 * 1. For testing error on invalid user, change the effective uid
Garrett Cooper2c282152010-12-16 00:55:50 -080046 *
robbiew6b01d682003-04-28 20:27:26 +000047 * Test:
48 * Loop if the proper options are given.
49 * Execute system call.
50 * Check return code, if system call fails with errno == expected errno
51 * Issue syscall passed with expected errno
subrata_modak4bb656a2009-02-26 12:02:09 +000052 * Otherwise,
robbiew6b01d682003-04-28 20:27:26 +000053 * Issue syscall failed to produce expected errno
subrata_modak4bb656a2009-02-26 12:02:09 +000054 *
robbiew6b01d682003-04-28 20:27:26 +000055 * Cleanup:
56 * Do cleanup for the test.
subrata_modak56207ce2009-03-23 13:35:39 +000057 * $
robbiewdcc848e2003-01-02 21:03:35 +000058 * USAGE: <for command-line>
59 * swapon02 [-e] [-i n] [-I x] [-p x] [-t] [-h] [-f] [-p]
subrata_modak4bb656a2009-02-26 12:02:09 +000060 * where
robbiew6b01d682003-04-28 20:27:26 +000061 * -e : Turn on errno logging.
62 * -i n : Execute test n times.
63 * -I x : Execute test for x seconds.
64 * -p : Pause for SIGUSR1 before starting
65 * -P x : Pause for x seconds between iterations.
66 * -t : Turn on syscall timing.
Garrett Cooper2c282152010-12-16 00:55:50 -080067 *
robbiewdcc848e2003-01-02 21:03:35 +000068 *RESTRICTIONS:
69 *Incompatible with kernel versions below 2.1.35.
70 *Incompatible if MAX_SWAPFILES definition in later kernels is changed
71 * -c option can't be used.
72 *
73 *CHANGES:
robbiew143090a2005-01-17 22:10:09 +000074 * 2005/01/01 Add extra check to stop test if swap file is on tmpfs
75 * -Ricky Ng-Adam (rngadam@yahoo.com)
robbiewab941562003-01-09 15:30:18 +000076 * 01/02/03 Added fork to handle SIGSEGV generated when the intentional EPERM
subrata_modak4bb656a2009-02-26 12:02:09 +000077 * error for hitting MAX_SWAPFILES is hit.
robbiewab941562003-01-09 15:30:18 +000078 * -Robbie Williamson <robbiew@us.ibm.com>
subrata_modakdaeac7a2007-05-17 14:31:45 +000079 * 05/17/07 Fixing the test description and added the EBUSY test case
80 * - Ricardo Salveti de Araujo (rsalveti@linux.vnet.ibm.com)
subrata_modak413ec142007-08-28 07:17:29 +000081 * 08/16/07 Removed the the 'more than MAX_SWAPFILES swapfiles in use' test
82 * case as now we have a separated file only for this test.
83 * - Ricardo Salveti de Araujo (rsalveti@linux.vnet.ibm.com)
robbiewdcc848e2003-01-02 21:03:35 +000084 *****************************************************************************/
85
86#include <unistd.h>
87#include <errno.h>
88#include <stdlib.h>
89#include <sys/types.h>
90#include <sys/wait.h>
91#include <sys/stat.h>
robbiewdcc848e2003-01-02 21:03:35 +000092#include <fcntl.h>
93#include <pwd.h>
94#include <string.h>
robbiewef957512003-03-13 15:33:06 +000095#include <sys/utsname.h>
robbiewdcc848e2003-01-02 21:03:35 +000096#include <signal.h>
97#include "test.h"
98#include "usctest.h"
yaberauneya77772ef2009-10-17 06:53:58 +000099#include "config.h"
yaberauneyaa2a05e32009-11-26 14:19:32 +0000100#include "linux_syscall_numbers.h"
yaberauneya89911a12009-11-26 14:11:35 +0000101#include "swaponoff.h"
robbiewdcc848e2003-01-02 21:03:35 +0000102
103static void setup();
104static void cleanup();
105static int setup01();
106static int cleanup01();
107static int setup02();
robbiewdcc848e2003-01-02 21:03:35 +0000108static int setup03();
109static int cleanup03();
robbiewdcc848e2003-01-02 21:03:35 +0000110void handler(int);
111
subrata_modak56207ce2009-03-23 13:35:39 +0000112char *TCID = "swapon02"; /* Test program identifier. */
113int TST_TOTAL = 4; /* Total number of test cases. */
robbiewdcc848e2003-01-02 21:03:35 +0000114char nobody_uid[] = "nobody";
115struct passwd *ltpuser;
robbiewef957512003-03-13 15:33:06 +0000116
117struct utsname uval;
118char *kmachine;
119
subrata_modak56207ce2009-03-23 13:35:39 +0000120static int exp_enos[] = { EPERM, EINVAL, ENOENT, EBUSY, 0 };
robbiewdcc848e2003-01-02 21:03:35 +0000121
122static struct test_case_t {
subrata_modak56207ce2009-03-23 13:35:39 +0000123 char *err_desc; /* error description */
124 int exp_errno; /* expected error number */
125 char *exp_errval; /* Expected errorvalue string */
126 char *path; /* path to swapon */
127 int (*setupfunc) (); /* Test setup function */
128 int (*cleanfunc) (); /* Test cleanup function */
robbiewdcc848e2003-01-02 21:03:35 +0000129} testcase[] = {
subrata_modak56207ce2009-03-23 13:35:39 +0000130 {
131 "Path does not exist", ENOENT, "ENOENT", "./abcd", NULL, NULL}, {
132 "Invalid path", EINVAL, "EINVAL", "./nofile", setup02, NULL}, {
133 "Permission denied", EPERM, "EPERM", "./swapfile01",
134 setup01, cleanup01}, {
135 "The specified path is already being used as a swap area",
136 EBUSY, "EBUSY", "./alreadyused", setup03, cleanup03}
robbiewdcc848e2003-01-02 21:03:35 +0000137};
138
subrata_modak56207ce2009-03-23 13:35:39 +0000139int main(int ac, char **av)
robbiewdcc848e2003-01-02 21:03:35 +0000140{
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200141 int lc, i;
142 char *msg;
robbiewdcc848e2003-01-02 21:03:35 +0000143
Garrett Cooper53740502010-12-16 00:04:01 -0800144 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper62383b82010-11-22 12:02:14 -0800145 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
robbiewdcc848e2003-01-02 21:03:35 +0000146
subrata_modak56207ce2009-03-23 13:35:39 +0000147 uname(&uval);
148 kmachine = uval.machine;
149 setup();
subrata_modakdaeac7a2007-05-17 14:31:45 +0000150
subrata_modak56207ce2009-03-23 13:35:39 +0000151 for (lc = 0; TEST_LOOPING(lc); lc++) {
152 Tst_count = 0;
153 for (i = 0; i < TST_TOTAL; i++) {
Garrett Cooper2c282152010-12-16 00:55:50 -0800154
subrata_modak56207ce2009-03-23 13:35:39 +0000155 /* do the setup if the test have one */
156 if (testcase[i].setupfunc
157 && testcase[i].setupfunc() == -1) {
158 tst_resm(TWARN,
159 "Failed to setup test %d."
160 " Skipping test", i);
161 continue;
162 } else {
163 /* run the test */
Jan Stancek359980f2013-02-15 10:16:05 +0100164 TEST(ltp_syscall(__NR_swapon,
165 testcase[i].path, 0));
subrata_modak56207ce2009-03-23 13:35:39 +0000166 }
167 /* do the clean if the test have one */
168 if (testcase[i].cleanfunc
169 && testcase[i].cleanfunc() == -1) {
170 tst_brkm(TBROK, cleanup,
Garrett Cooper62383b82010-11-22 12:02:14 -0800171 "Cleanup failed, quitting the test");
subrata_modak56207ce2009-03-23 13:35:39 +0000172 }
173 /* check return code */
174 if ((TEST_RETURN == -1)
175 && (TEST_ERRNO == testcase[i].exp_errno)) {
176 tst_resm(TPASS,
177 "swapon(2) expected failure;"
178 " Got errno - %s : %s",
179 testcase[i].exp_errval,
180 testcase[i].err_desc);
181 } else {
182 tst_resm(TFAIL, "swapon(2) failed to produce"
183 " expected error: %d, errno"
184 ": %s and got %d. "
185 " System reboot after"
186 " execution of LTP"
187 " test suite is"
188 " recommended.",
189 testcase[i].exp_errno,
190 testcase[i].exp_errval, TEST_ERRNO);
191 /*If swapfile is turned on, turn it off */
192 if (TEST_RETURN == 0) {
Jan Stancek359980f2013-02-15 10:16:05 +0100193 if (ltp_syscall
Wanlong Gao354ebb42012-12-07 10:10:04 +0800194 (__NR_swapoff,
195 testcase[i].path) != 0) {
196 tst_resm(TWARN,
197 "Failed to"
subrata_modak56207ce2009-03-23 13:35:39 +0000198 " turn off swapfile"
199 " swapfile. System"
200 " reboot after"
201 " execution of LTP"
202 " test suite is"
203 " recommended.");
204 }
205 }
206 }
207 TEST_ERROR_LOG(TEST_ERRNO);
208 } /*End of TEST LOOPS */
209 } /*End of TEST LOOPING */
subrata_modakdaeac7a2007-05-17 14:31:45 +0000210
Garrett Cooper62383b82010-11-22 12:02:14 -0800211 cleanup();
212 tst_exit();
subrata_modak56207ce2009-03-23 13:35:39 +0000213} /*End of main */
robbiewdcc848e2003-01-02 21:03:35 +0000214
215/*
subrata_modakdaeac7a2007-05-17 14:31:45 +0000216 * setup01() - This function creates the file and sets the user as nobody
robbiewdcc848e2003-01-02 21:03:35 +0000217 */
subrata_modak56207ce2009-03-23 13:35:39 +0000218int setup01()
robbiewdcc848e2003-01-02 21:03:35 +0000219{
subrata_modak56207ce2009-03-23 13:35:39 +0000220 int pagesize = getpagesize();
robbiewdcc848e2003-01-02 21:03:35 +0000221
subrata_modak56207ce2009-03-23 13:35:39 +0000222 /*create file */
223 if ((strncmp(kmachine, "ia64", 4)) == 0) {
224 if (system
225 ("dd if=/dev/zero of=swapfile01 bs=1024 count=65536 > tmpfile"
226 " 2>&1") != 0) {
227 tst_brkm(TBROK, cleanup,
228 "Failed to create file for swap");
229 }
230 } else if (pagesize == 65536) {
231 if (system
232 ("dd if=/dev/zero of=swapfile01 bs=1048 count=655 > tmpfile"
233 " 2>&1") != 0) {
234 tst_brkm(TBROK, cleanup,
235 "Failed to create file for swap");
236 }
237 } else {
238 if (system
239 ("dd if=/dev/zero of=swapfile01 bs=1048 count=40 > tmpfile"
240 " 2>&1") != 0) {
241 tst_brkm(TBROK, cleanup,
242 "Failed to create file for swap");
243 }
244 }
subrata_modakdaeac7a2007-05-17 14:31:45 +0000245
subrata_modak56207ce2009-03-23 13:35:39 +0000246 /* make above file a swap file */
247 if (system("mkswap swapfile01 > tmpfile 2>&1") != 0) {
248 tst_brkm(TBROK, cleanup, "Failed to make swapfile");
249 }
subrata_modakdaeac7a2007-05-17 14:31:45 +0000250
subrata_modak56207ce2009-03-23 13:35:39 +0000251 if ((ltpuser = getpwnam(nobody_uid)) == NULL) {
252 tst_resm(TWARN, "\"nobody\" user not present. skipping test");
253 return -1;
254 }
subrata_modakdaeac7a2007-05-17 14:31:45 +0000255
subrata_modak56207ce2009-03-23 13:35:39 +0000256 if (seteuid(ltpuser->pw_uid) == -1) {
257 tst_resm(TWARN, "seteuid failed to "
258 "to set the effective uid to %d", ltpuser->pw_uid);
259 perror("seteuid");
260 return -1;
261 }
262 return 0; /* user switched to nobody */
robbiewdcc848e2003-01-02 21:03:35 +0000263}
264
265/*
subrata_modakdaeac7a2007-05-17 14:31:45 +0000266 * cleanup01() - switch back to user root and gives swapoff to the swap file
robbiewdcc848e2003-01-02 21:03:35 +0000267 */
subrata_modak56207ce2009-03-23 13:35:39 +0000268int cleanup01()
robbiewdcc848e2003-01-02 21:03:35 +0000269{
subrata_modak56207ce2009-03-23 13:35:39 +0000270 if (seteuid(0) == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800271 tst_brkm(TBROK | TERRNO, cleanup,
272 "seteuid failed to set uid to root");
subrata_modak56207ce2009-03-23 13:35:39 +0000273 }
subrata_modakdaeac7a2007-05-17 14:31:45 +0000274
subrata_modak56207ce2009-03-23 13:35:39 +0000275 return 0;
robbiewdcc848e2003-01-02 21:03:35 +0000276}
277
subrata_modakdaeac7a2007-05-17 14:31:45 +0000278/*
subrata_modak4bb656a2009-02-26 12:02:09 +0000279 * setup02() - create a normal file, to be used with swapon
subrata_modakdaeac7a2007-05-17 14:31:45 +0000280 */
subrata_modak56207ce2009-03-23 13:35:39 +0000281int setup02()
robbiewdcc848e2003-01-02 21:03:35 +0000282{
subrata_modak56207ce2009-03-23 13:35:39 +0000283 int fd;
284 fd = creat("nofile", S_IRWXU);
285 if (fd == -1)
286 tst_resm(TWARN, "Failed to create temporary file");
287 close(fd);
288 return 0;
robbiewdcc848e2003-01-02 21:03:35 +0000289}
290
291/*
subrata_modak413ec142007-08-28 07:17:29 +0000292 * setup03() - This function creates the swap file and turn it on
robbiewdcc848e2003-01-02 21:03:35 +0000293 */
subrata_modak56207ce2009-03-23 13:35:39 +0000294int setup03()
robbiewdcc848e2003-01-02 21:03:35 +0000295{
subrata_modak56207ce2009-03-23 13:35:39 +0000296 int pagesize = getpagesize();
297 int res = 0;
subrata_modakdaeac7a2007-05-17 14:31:45 +0000298
subrata_modak56207ce2009-03-23 13:35:39 +0000299 /*create file */
300 if ((strncmp(kmachine, "ia64", 4)) == 0) {
301 if (system
302 ("dd if=/dev/zero of=alreadyused bs=1024 count=65536 > tmpfile"
303 " 2>&1") != 0) {
304 tst_brkm(TBROK, cleanup,
305 "Failed to create file for swap");
306 }
307 } else if (pagesize == 65536) {
308 if (system
309 ("dd if=/dev/zero of=alreadyused bs=1048 count=655 > tmpfile"
310 " 2>&1") != 0) {
311 tst_brkm(TBROK, cleanup,
312 "Failed to create file for swap");
313 }
314 } else {
315 if (system
316 ("dd if=/dev/zero of=alreadyused bs=1048 count=40 > tmpfile"
317 " 2>&1") != 0) {
318 tst_brkm(TBROK, cleanup,
319 "Failed to create file for swap");
320 }
321 }
subrata_modakdaeac7a2007-05-17 14:31:45 +0000322
subrata_modak56207ce2009-03-23 13:35:39 +0000323 /* make above file a swap file */
324 if (system("mkswap alreadyused > tmpfile 2>&1") != 0) {
325 tst_brkm(TBROK, cleanup, "Failed to make swapfile");
326 }
subrata_modakdaeac7a2007-05-17 14:31:45 +0000327
subrata_modak56207ce2009-03-23 13:35:39 +0000328 /* turn on the swap file */
Jan Stancek359980f2013-02-15 10:16:05 +0100329 res = ltp_syscall(__NR_swapon, "alreadyused", 0);
330 if (res != 0) {
subrata_modak56207ce2009-03-23 13:35:39 +0000331 tst_resm(TWARN, "Failed swapon for file alreadyused"
332 " returned %d", res);
333 return -1;
334 }
subrata_modakdaeac7a2007-05-17 14:31:45 +0000335
subrata_modak56207ce2009-03-23 13:35:39 +0000336 return 0;
subrata_modakdaeac7a2007-05-17 14:31:45 +0000337}
338
339/*
subrata_modak413ec142007-08-28 07:17:29 +0000340 * cleanup03() - clearing the turned on swap file
subrata_modakdaeac7a2007-05-17 14:31:45 +0000341 */
subrata_modak56207ce2009-03-23 13:35:39 +0000342int cleanup03()
subrata_modakdaeac7a2007-05-17 14:31:45 +0000343{
subrata_modak56207ce2009-03-23 13:35:39 +0000344 /* give swapoff to the test swap file */
Jan Stancek359980f2013-02-15 10:16:05 +0100345 if (ltp_syscall(__NR_swapoff, "alreadyused") != 0) {
subrata_modak56207ce2009-03-23 13:35:39 +0000346 tst_resm(TWARN, "Failed to turn off swap files. system"
347 " reboot after execution of LTP test"
348 " suite is recommended");
349 return -1;
350 }
subrata_modakdaeac7a2007-05-17 14:31:45 +0000351
subrata_modak56207ce2009-03-23 13:35:39 +0000352 return 0;
robbiewdcc848e2003-01-02 21:03:35 +0000353}
354
355/* setup() - performs all ONE TIME setup for this test */
subrata_modak56207ce2009-03-23 13:35:39 +0000356void setup()
robbiewdcc848e2003-01-02 21:03:35 +0000357{
mreed10ed3af432006-09-15 20:17:23 +0000358
subrata_modak56207ce2009-03-23 13:35:39 +0000359 tst_sig(FORK, DEF_HANDLER, cleanup);
robbiewdcc848e2003-01-02 21:03:35 +0000360
subrata_modak56207ce2009-03-23 13:35:39 +0000361 /* set the expected errnos... */
362 TEST_EXP_ENOS(exp_enos);
robbiewdcc848e2003-01-02 21:03:35 +0000363
subrata_modak56207ce2009-03-23 13:35:39 +0000364 /* Check whether we are root */
365 if (geteuid() != 0) {
Garrett Cooper53740502010-12-16 00:04:01 -0800366 tst_brkm(TBROK, NULL, "Test must be run as root");
subrata_modak04c009e2007-11-28 09:38:08 +0000367 }
368
subrata_modak56207ce2009-03-23 13:35:39 +0000369 tst_tmpdir();
robbiewa3cc71f2003-02-18 20:53:50 +0000370
subrata_modak56207ce2009-03-23 13:35:39 +0000371 if (tst_is_cwd_tmpfs()) {
372 tst_brkm(TCONF, cleanup,
373 "Cannot do swapon on a file located on a tmpfs filesystem");
374 }
375
376 if (tst_is_cwd_nfs()) {
377 tst_brkm(TCONF, cleanup,
378 "Cannot do swapon on a file located on a nfs filesystem");
379 }
380
subrata_modak56207ce2009-03-23 13:35:39 +0000381 TEST_PAUSE;
382
Garrett Cooper2c282152010-12-16 00:55:50 -0800383}
robbiewdcc848e2003-01-02 21:03:35 +0000384
385/*
386* cleanup() - Performs one time cleanup for this test at
387* completion or premature exit
388*/
subrata_modak56207ce2009-03-23 13:35:39 +0000389void cleanup()
robbiewdcc848e2003-01-02 21:03:35 +0000390{
subrata_modak56207ce2009-03-23 13:35:39 +0000391 /*
392 * print timing stats if that option was specified.
393 * print errno log if that option was specified.
394 */
395 TEST_CLEANUP;
robbiewdcc848e2003-01-02 21:03:35 +0000396
subrata_modak56207ce2009-03-23 13:35:39 +0000397 tst_rmdir();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700398}