blob: 93276eb1e484ae499b951b75c2330bbbebec7a08 [file] [log] [blame]
subrata_modak413ec142007-08-28 07:17:29 +00001/******************************************************************************
2 *
Cyril Hrubisa432c4d2014-03-06 14:28:30 +01003 * Copyright (c) International Business Machines Corp., 2007
4 * Created by <rsalveti@linux.vnet.ibm.com>
subrata_modak413ec142007-08-28 07:17:29 +00005 *
Cyril Hrubisa432c4d2014-03-06 14:28:30 +01006 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
subrata_modak413ec142007-08-28 07:17:29 +000010 *
Cyril Hrubisa432c4d2014-03-06 14:28:30 +010011 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 * the GNU General Public License for more details.
subrata_modak413ec142007-08-28 07:17:29 +000015 *
Cyril Hrubisa432c4d2014-03-06 14:28:30 +010016 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
subrata_modak413ec142007-08-28 07:17:29 +000019 *
Cyril Hrubisa432c4d2014-03-06 14:28:30 +010020 ******************************************************************************/
21
22/*
23 * This test case checks whether swapon(2) system call returns:
24 * - EPERM when there are more than MAX_SWAPFILES already in use.
subrata_modak413ec142007-08-28 07:17:29 +000025 *
Cyril Hrubisa432c4d2014-03-06 14:28:30 +010026 */
subrata_modak413ec142007-08-28 07:17:29 +000027
yaberauneya89911a12009-11-26 14:11:35 +000028#include <sys/types.h>
subrata_modak413ec142007-08-28 07:17:29 +000029#include <unistd.h>
30#include <errno.h>
31#include <stdlib.h>
subrata_modak413ec142007-08-28 07:17:29 +000032#include <sys/wait.h>
33#include <sys/stat.h>
Garrett Coopera83e7dc2010-02-24 17:05:14 -080034#include <sys/utsname.h>
subrata_modak413ec142007-08-28 07:17:29 +000035#include <fcntl.h>
36#include <pwd.h>
37#include <string.h>
subrata_modak413ec142007-08-28 07:17:29 +000038#include <signal.h>
39#include "test.h"
yaberauneya89911a12009-11-26 14:11:35 +000040#include "linux_syscall_numbers.h"
Cyril Hrubis0f0e3482014-02-27 16:08:04 +010041#include "tst_fs_type.h"
yaberauneya89911a12009-11-26 14:11:35 +000042#include "swaponoff.h"
Stanislav Kholmanskikh4bdda042013-08-14 10:01:47 +040043#include "libswapon.h"
subrata_modak413ec142007-08-28 07:17:29 +000044
Cyril Hrubisf6f4b7f2014-02-26 17:45:31 +010045static void setup(void);
46static void cleanup(void);
47static int setup_swap(void);
48static int clean_swap(void);
49static int check_and_swapoff(const char *filename);
subrata_modak413ec142007-08-28 07:17:29 +000050
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020051char *TCID = "swapon03";
52int TST_TOTAL = 1;
subrata_modak413ec142007-08-28 07:17:29 +000053
Cyril Hrubisa432c4d2014-03-06 14:28:30 +010054static int swapfiles;
subrata_modak413ec142007-08-28 07:17:29 +000055
Cyril Hrubisb16efb82014-03-06 14:49:17 +010056static long fs_type;
57
subrata_modak413ec142007-08-28 07:17:29 +000058int testfiles = 3;
59static struct swap_testfile_t {
60 char *filename;
61} swap_testfiles[] = {
Cyril Hrubisa432c4d2014-03-06 14:28:30 +010062 {"firstswapfile"},
63 {"secondswapfile"},
64 {"thirdswapfile"}
subrata_modak413ec142007-08-28 07:17:29 +000065};
subrata_modakbdbaec52009-02-26 12:14:51 +000066
Cyril Hrubisf6f4b7f2014-02-26 17:45:31 +010067int expected_errno = EPERM;
subrata_modak413ec142007-08-28 07:17:29 +000068
69int main(int ac, char **av)
70{
Cyril Hrubisd9235f82012-06-29 14:08:41 +020071 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020072 const char *msg;
subrata_modak413ec142007-08-28 07:17:29 +000073
Garrett Cooper45e285d2010-11-22 12:19:25 -080074 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080075 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modak413ec142007-08-28 07:17:29 +000076
subrata_modak56207ce2009-03-23 13:35:39 +000077 setup();
subrata_modak413ec142007-08-28 07:17:29 +000078
subrata_modak413ec142007-08-28 07:17:29 +000079 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +080080 tst_count = 0;
subrata_modak413ec142007-08-28 07:17:29 +000081
subrata_modak413ec142007-08-28 07:17:29 +000082 if (setup_swap() < 0) {
83 clean_swap();
subrata_modak56207ce2009-03-23 13:35:39 +000084 tst_brkm(TBROK, cleanup,
85 "Setup failed, quitting the test");
subrata_modak413ec142007-08-28 07:17:29 +000086 }
87
Jan Stancek359980f2013-02-15 10:16:05 +010088 TEST(ltp_syscall(__NR_swapon, swap_testfiles[0].filename, 0));
subrata_modak413ec142007-08-28 07:17:29 +000089
subrata_modak413ec142007-08-28 07:17:29 +000090 if ((TEST_RETURN == -1) && (TEST_ERRNO == expected_errno)) {
Garrett Cooper1e27c532010-11-22 14:33:28 -080091 tst_resm(TPASS, "swapon(2) got expected failure (%d),",
Wanlong Gao354ebb42012-12-07 10:10:04 +080092 expected_errno);
subrata_modak413ec142007-08-28 07:17:29 +000093 } else if (TEST_RETURN < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +080094 tst_resm(TFAIL | TTERRNO,
95 "swapon(2) failed to produce expected error "
96 "(%d). System reboot recommended.",
97 expected_errno);
subrata_modak413ec142007-08-28 07:17:29 +000098 } else {
99 /* Probably the system supports MAX_SWAPFILES > 30,
100 * let's try with MAX_SWAPFILES == 32 */
101
102 /* Call swapon sys call once again for 32
103 * now we can't receive an error */
Jan Stancek359980f2013-02-15 10:16:05 +0100104 TEST(ltp_syscall
Wanlong Gao354ebb42012-12-07 10:10:04 +0800105 (__NR_swapon, swap_testfiles[1].filename, 0));
subrata_modak413ec142007-08-28 07:17:29 +0000106
107 /* Check return code (now we're expecting success) */
108 if (TEST_RETURN < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800109 tst_resm(TFAIL | TTERRNO,
Garrett Cooper1e27c532010-11-22 14:33:28 -0800110 "swapon(2) got an unexpected failure");
subrata_modak56207ce2009-03-23 13:35:39 +0000111 } else {
subrata_modak413ec142007-08-28 07:17:29 +0000112 /* Call swapon sys call once again for 33
113 * now we have to receive an error */
Jan Stancek359980f2013-02-15 10:16:05 +0100114 TEST(ltp_syscall
Wanlong Gao354ebb42012-12-07 10:10:04 +0800115 (__NR_swapon, swap_testfiles[2].filename,
116 0));
subrata_modak413ec142007-08-28 07:17:29 +0000117
118 /* Check return code (should be an error) */
subrata_modak56207ce2009-03-23 13:35:39 +0000119 if ((TEST_RETURN == -1)
120 && (TEST_ERRNO == expected_errno)) {
121 tst_resm(TPASS,
122 "swapon(2) got expected failure;"
Garrett Cooperbe5c7882010-08-02 22:01:02 -0700123 " Got errno = %d, probably your"
subrata_modak56207ce2009-03-23 13:35:39 +0000124 " MAX_SWAPFILES is 32",
125 expected_errno);
126 } else {
127 tst_resm(TFAIL,
128 "swapon(2) failed to produce"
129 " expected error: %d, got %s."
130 " System reboot after execution of LTP"
131 " test suite is recommended.",
132 expected_errno,
133 strerror(TEST_ERRNO));
subrata_modak413ec142007-08-28 07:17:29 +0000134 }
135
136 }
137 }
138
subrata_modak413ec142007-08-28 07:17:29 +0000139 if (clean_swap() < 0)
subrata_modak56207ce2009-03-23 13:35:39 +0000140 tst_brkm(TBROK, cleanup,
141 "Cleanup failed, quitting the test");
subrata_modak413ec142007-08-28 07:17:29 +0000142
Garrett Cooper2c282152010-12-16 00:55:50 -0800143 }
subrata_modak413ec142007-08-28 07:17:29 +0000144
subrata_modak413ec142007-08-28 07:17:29 +0000145 cleanup();
Garrett Cooper1e27c532010-11-22 14:33:28 -0800146 tst_exit();
subrata_modak413ec142007-08-28 07:17:29 +0000147
Garrett Cooper2c282152010-12-16 00:55:50 -0800148}
subrata_modak413ec142007-08-28 07:17:29 +0000149
Cyril Hrubisf6f4b7f2014-02-26 17:45:31 +0100150/*
151 * Create 33 and activate 30 swapfiles.
152 */
153static int setup_swap(void)
subrata_modak413ec142007-08-28 07:17:29 +0000154{
Garrett Cooper62383b82010-11-22 12:02:14 -0800155 pid_t pid;
Cyril Hrubisf6f4b7f2014-02-26 17:45:31 +0100156 int j, fd;
157 int status;
Stanislav Kholmanskikh4bdda042013-08-14 10:01:47 +0400158 int res = 0;
Cyril Hrubisf6f4b7f2014-02-26 17:45:31 +0100159 char filename[15];
160 char buf[BUFSIZ + 1];
subrata_modak413ec142007-08-28 07:17:29 +0000161
subrata_modak56207ce2009-03-23 13:35:39 +0000162 /* Find out how many swapfiles (1 line per entry) already exist */
subrata_modak413ec142007-08-28 07:17:29 +0000163 swapfiles = 0;
164
yaberauneya89911a12009-11-26 14:11:35 +0000165 if (seteuid(0) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800166 tst_brkm(TFAIL | TERRNO, cleanup, "Failed to call seteuid");
yaberauneya89911a12009-11-26 14:11:35 +0000167 }
168
subrata_modak56207ce2009-03-23 13:35:39 +0000169 /* This includes the first (header) line */
170 if ((fd = open("/proc/swaps", O_RDONLY)) == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800171 tst_brkm(TFAIL | TERRNO, cleanup,
subrata_modak56207ce2009-03-23 13:35:39 +0000172 "Failed to find out existing number of swap files");
subrata_modak56207ce2009-03-23 13:35:39 +0000173 }
yaberauneya89911a12009-11-26 14:11:35 +0000174 do {
subrata_modak56207ce2009-03-23 13:35:39 +0000175 char *p = buf;
yaberauneya89911a12009-11-26 14:11:35 +0000176 res = read(fd, buf, BUFSIZ);
subrata_modak56207ce2009-03-23 13:35:39 +0000177 if (res < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800178 tst_brkm(TFAIL | TERRNO, cleanup,
Garrett Cooper62383b82010-11-22 12:02:14 -0800179 "Failed to find out existing number of swap "
180 "files");
subrata_modak56207ce2009-03-23 13:35:39 +0000181 }
182 buf[res] = '\0';
183 while ((p = strchr(p, '\n'))) {
184 p++;
185 swapfiles++;
186 }
yaberauneya89911a12009-11-26 14:11:35 +0000187 } while (BUFSIZ <= res);
subrata_modak56207ce2009-03-23 13:35:39 +0000188 close(fd);
189 if (swapfiles)
190 swapfiles--; /* don't count the /proc/swaps header */
subrata_modak413ec142007-08-28 07:17:29 +0000191
subrata_modak56207ce2009-03-23 13:35:39 +0000192 if (swapfiles < 0) {
Garrett Cooper62383b82010-11-22 12:02:14 -0800193 tst_brkm(TFAIL, cleanup,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800194 "Failed to find existing number of swapfiles");
subrata_modak56207ce2009-03-23 13:35:39 +0000195 }
subrata_modak413ec142007-08-28 07:17:29 +0000196
subrata_modak56207ce2009-03-23 13:35:39 +0000197 /* Determine how many more files are to be created */
yaberauneya96db7a42009-10-25 06:33:33 +0000198 swapfiles = MAX_SWAPFILES - swapfiles;
199 if (swapfiles > MAX_SWAPFILES) {
200 swapfiles = MAX_SWAPFILES;
subrata_modak56207ce2009-03-23 13:35:39 +0000201 }
subrata_modak413ec142007-08-28 07:17:29 +0000202
subrata_modak56207ce2009-03-23 13:35:39 +0000203 pid = FORK_OR_VFORK();
204 if (pid == 0) {
205 /*create and turn on remaining swapfiles */
206 for (j = 0; j < swapfiles; j++) {
subrata_modak413ec142007-08-28 07:17:29 +0000207
subrata_modak56207ce2009-03-23 13:35:39 +0000208 /* prepare filename for the iteration */
209 if (sprintf(filename, "swapfile%02d", j + 2) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800210 printf("sprintf() failed to create "
211 "filename");
Garrett Cooper1e27c532010-11-22 14:33:28 -0800212 exit(1);
subrata_modak413ec142007-08-28 07:17:29 +0000213 }
214
subrata_modak56207ce2009-03-23 13:35:39 +0000215 /* Create the swapfile */
Stanislav Kholmanskikh4bdda042013-08-14 10:01:47 +0400216 make_swapfile(cleanup, filename);
subrata_modak05fd0c72009-02-12 15:06:05 +0000217
subrata_modak56207ce2009-03-23 13:35:39 +0000218 /* turn on the swap file */
Jan Stancek359980f2013-02-15 10:16:05 +0100219 res = ltp_syscall(__NR_swapon, filename, 0);
220 if (res != 0) {
Cyril Hrubisb16efb82014-03-06 14:49:17 +0100221 if (fs_type == TST_BTRFS_MAGIC && errno == EINVAL)
222 exit(2);
223
Garrett Cooperbe5c7882010-08-02 22:01:02 -0700224 if (errno == EPERM) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800225 printf("Successfully created %d "
226 "swapfiles\n", j);
Garrett Cooperbe5c7882010-08-02 22:01:02 -0700227 break;
228 } else {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800229 printf("Failed to create "
230 "swapfile: %s\n", filename);
Garrett Cooperbe5c7882010-08-02 22:01:02 -0700231 exit(1);
232 }
subrata_modak56207ce2009-03-23 13:35:39 +0000233 }
234 }
Garrett Cooper62383b82010-11-22 12:02:14 -0800235 exit(0);
subrata_modak56207ce2009-03-23 13:35:39 +0000236 } else
237 waitpid(pid, &status, 0);
238
Cyril Hrubisb16efb82014-03-06 14:49:17 +0100239 switch (WEXITSTATUS(status)) {
240 case 0:
241 break;
242 case 2:
243 tst_brkm(TCONF, cleanup, "Swapfile on BTRFS not implemeted");
244 break;
245 default:
Garrett Cooper1e27c532010-11-22 14:33:28 -0800246 tst_brkm(TFAIL, cleanup, "Failed to setup swaps");
Cyril Hrubisb16efb82014-03-06 14:49:17 +0100247 break;
subrata_modak05fd0c72009-02-12 15:06:05 +0000248 }
subrata_modak413ec142007-08-28 07:17:29 +0000249
subrata_modak56207ce2009-03-23 13:35:39 +0000250 /* Create all needed extra swapfiles for testing */
Stanislav Kholmanskikh4bdda042013-08-14 10:01:47 +0400251 for (j = 0; j < testfiles; j++)
252 make_swapfile(cleanup, swap_testfiles[j].filename);
subrata_modak413ec142007-08-28 07:17:29 +0000253
254 return 0;
255
256}
257
Cyril Hrubisf6f4b7f2014-02-26 17:45:31 +0100258/*
259 * Turn off all swapfiles previously turned on
260 */
261static int clean_swap(void)
subrata_modak413ec142007-08-28 07:17:29 +0000262{
Cyril Hrubisd9235f82012-06-29 14:08:41 +0200263 int j;
Garrett Coopera83e7dc2010-02-24 17:05:14 -0800264 char filename[FILENAME_MAX];
subrata_modak413ec142007-08-28 07:17:29 +0000265
subrata_modak56207ce2009-03-23 13:35:39 +0000266 for (j = 0; j < swapfiles; j++) {
Garrett Coopera83e7dc2010-02-24 17:05:14 -0800267 if (snprintf(filename, sizeof(filename),
Wanlong Gao354ebb42012-12-07 10:10:04 +0800268 "swapfile%02d", j + 2) < 0) {
subrata_modak56207ce2009-03-23 13:35:39 +0000269 tst_resm(TWARN, "sprintf() failed to create filename");
270 tst_resm(TWARN, "Failed to turn off swap files. System"
271 " reboot after execution of LTP test"
272 " suite is recommended");
273 return -1;
274 }
275 if (check_and_swapoff(filename) != 0) {
276 tst_resm(TWARN, "Failed to turn off swap file %s.",
277 filename);
278 return -1;
279 }
280 }
subrata_modak413ec142007-08-28 07:17:29 +0000281
282 for (j = 0; j < testfiles; j++) {
283 if (check_and_swapoff(swap_testfiles[j].filename) != 0) {
subrata_modak56207ce2009-03-23 13:35:39 +0000284 tst_resm(TWARN, "Failed to turn off swap file %s.",
285 swap_testfiles[j].filename);
286 return -1;
287 }
subrata_modak413ec142007-08-28 07:17:29 +0000288 }
289
subrata_modak56207ce2009-03-23 13:35:39 +0000290 return 0;
subrata_modak413ec142007-08-28 07:17:29 +0000291}
292
Cyril Hrubisf6f4b7f2014-02-26 17:45:31 +0100293/*
294 * Check if the file is at /proc/swaps and remove it giving swapoff
295 */
296static int check_and_swapoff(const char *filename)
subrata_modak413ec142007-08-28 07:17:29 +0000297{
Cyril Hrubisd9235f82012-06-29 14:08:41 +0200298 char cmd_buffer[256];
Garrett Coopera83e7dc2010-02-24 17:05:14 -0800299 int rc = -1;
subrata_modak413ec142007-08-28 07:17:29 +0000300
Cyril Hrubisd9235f82012-06-29 14:08:41 +0200301 if (snprintf(cmd_buffer, sizeof(cmd_buffer),
Wanlong Gao354ebb42012-12-07 10:10:04 +0800302 "grep -q '%s.*file' /proc/swaps", filename) < 0) {
subrata_modak56207ce2009-03-23 13:35:39 +0000303 tst_resm(TWARN,
304 "sprintf() failed to create the command string");
Garrett Coopera83e7dc2010-02-24 17:05:14 -0800305 } else {
306
307 rc = 0;
308
309 if (system(cmd_buffer) == 0) {
310
311 /* now we need to swapoff the file */
Jan Stancek359980f2013-02-15 10:16:05 +0100312 if (ltp_syscall(__NR_swapoff, filename) != 0) {
Garrett Coopera83e7dc2010-02-24 17:05:14 -0800313
314 tst_resm(TWARN, "Failed to turn off swap "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800315 "file. system reboot after "
316 "execution of LTP test suite "
317 "is recommended");
Garrett Coopera83e7dc2010-02-24 17:05:14 -0800318 rc = -1;
319
Garrett Cooper2c282152010-12-16 00:55:50 -0800320 }
Garrett Coopera83e7dc2010-02-24 17:05:14 -0800321
Cyril Hrubisd9235f82012-06-29 14:08:41 +0200322 }
subrata_modak413ec142007-08-28 07:17:29 +0000323 }
subrata_modak413ec142007-08-28 07:17:29 +0000324
Garrett Coopera83e7dc2010-02-24 17:05:14 -0800325 return rc;
subrata_modak413ec142007-08-28 07:17:29 +0000326}
327
Cyril Hrubisf6f4b7f2014-02-26 17:45:31 +0100328static void setup(void)
subrata_modak413ec142007-08-28 07:17:29 +0000329{
subrata_modak56207ce2009-03-23 13:35:39 +0000330 tst_sig(FORK, DEF_HANDLER, cleanup);
subrata_modak413ec142007-08-28 07:17:29 +0000331
Cyril Hrubisf6f4b7f2014-02-26 17:45:31 +0100332 tst_require_root(NULL);
subrata_modak04c009e2007-11-28 09:38:08 +0000333
subrata_modak56207ce2009-03-23 13:35:39 +0000334 tst_tmpdir();
subrata_modak413ec142007-08-28 07:17:29 +0000335
Cyril Hrubisb16efb82014-03-06 14:49:17 +0100336 switch ((fs_type = tst_fs_type(cleanup, "."))) {
Cyril Hrubis0f0e3482014-02-27 16:08:04 +0100337 case TST_NFS_MAGIC:
338 case TST_TMPFS_MAGIC:
subrata_modak56207ce2009-03-23 13:35:39 +0000339 tst_brkm(TCONF, cleanup,
Cyril Hrubis0f0e3482014-02-27 16:08:04 +0100340 "Cannot do swapon on a file on %s filesystem",
Cyril Hrubisb16efb82014-03-06 14:49:17 +0100341 tst_fs_type_name(fs_type));
Cyril Hrubis0f0e3482014-02-27 16:08:04 +0100342 break;
subrata_modak56207ce2009-03-23 13:35:39 +0000343 }
344
subrata_modak56207ce2009-03-23 13:35:39 +0000345 TEST_PAUSE;
Garrett Cooper2c282152010-12-16 00:55:50 -0800346}
subrata_modak413ec142007-08-28 07:17:29 +0000347
Cyril Hrubisf6f4b7f2014-02-26 17:45:31 +0100348static void cleanup(void)
subrata_modak413ec142007-08-28 07:17:29 +0000349{
Garrett Coopera83e7dc2010-02-24 17:05:14 -0800350 clean_swap();
351
subrata_modak56207ce2009-03-23 13:35:39 +0000352 tst_rmdir();
Cyril Hrubisd9235f82012-06-29 14:08:41 +0200353}