xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/swapon/swapon03.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) International Business Machines Corp., 2007
4  * Created by <[email protected]>
5  *
6  */
7 
8 /*\
9  * [Description]
10  *
11  * This test case checks whether swapon(2) system call returns:
12  *
13  *  - EPERM when there are more than MAX_SWAPFILES already in use.
14  */
15 
16 #include <stdio.h>
17 #include <errno.h>
18 #include <stdlib.h>
19 #include <sys/wait.h>
20 #include <sys/swap.h>
21 #include "tst_test.h"
22 #include "lapi/syscalls.h"
23 #include "libswap.h"
24 
25 #define MNTPOINT	"mntpoint"
26 #define TEST_FILE	MNTPOINT"/testswap"
27 
28 static int swapfiles;
29 
setup_swap(void)30 static int setup_swap(void)
31 {
32 	pid_t pid;
33 	int status;
34 	int j, max_swapfiles, used_swapfiles;
35 	char filename[FILENAME_MAX];
36 
37 	SAFE_SETEUID(0);
38 
39 	/* Determine how many more files are to be created */
40 	max_swapfiles = tst_max_swapfiles();
41 	used_swapfiles = tst_count_swaps();
42 	swapfiles = max_swapfiles - used_swapfiles;
43 	if (swapfiles > max_swapfiles)
44 		swapfiles = max_swapfiles;
45 
46 	pid = SAFE_FORK();
47 	if (pid == 0) {
48 		/*create and turn on remaining swapfiles */
49 		for (j = 0; j < swapfiles; j++) {
50 
51 			/* Create the swapfile */
52 			snprintf(filename, sizeof(filename), "%s%02d", TEST_FILE, j + 2);
53 			MAKE_SMALL_SWAPFILE(filename);
54 
55 			/* turn on the swap file */
56 			TST_EXP_PASS_SILENT(swapon(filename, 0));
57 		}
58 		exit(0);
59 	} else
60 		waitpid(pid, &status, 0);
61 
62 	if (WEXITSTATUS(status))
63 		tst_brk(TFAIL, "Failed to setup swap files");
64 
65 	tst_res(TINFO, "Successfully created %d swap files", swapfiles);
66 	MAKE_SMALL_SWAPFILE(TEST_FILE);
67 
68 	return 0;
69 }
70 
71 /*
72  * Check if the file is at /proc/swaps and remove it giving swapoff
73  */
check_and_swapoff(const char * filename)74 static int check_and_swapoff(const char *filename)
75 {
76 	char cmd_buffer[256];
77 	int rc = -1;
78 
79 	snprintf(cmd_buffer, sizeof(cmd_buffer), "grep -q '%s.*file' /proc/swaps", filename);
80 
81 	if (system(cmd_buffer) == 0 && swapoff(filename) != 0) {
82 		tst_res(TWARN, "Failed to swapoff %s", filename);
83 		rc = -1;
84 	}
85 
86 	return rc;
87 }
88 
89 /*
90  * Turn off all swapfiles previously turned on
91  */
clean_swap(void)92 static void clean_swap(void)
93 {
94 	int j;
95 	char filename[FILENAME_MAX];
96 
97 	for (j = 0; j < swapfiles; j++) {
98 		snprintf(filename, sizeof(filename), "%s%02d", TEST_FILE, j + 2);
99 		check_and_swapoff(filename);
100 	}
101 
102 	check_and_swapoff("testfile");
103 }
104 
verify_swapon(void)105 static void verify_swapon(void)
106 {
107 	TST_EXP_FAIL(swapon(TEST_FILE, 0), EPERM, "swapon(%s, 0)", TEST_FILE);
108 }
109 
setup(void)110 static void setup(void)
111 {
112 	if (access("/proc/swaps", F_OK))
113 		tst_brk(TCONF, "swap not supported by kernel");
114 
115 	is_swap_supported(TEST_FILE);
116 	if (setup_swap() < 0) {
117 		clean_swap();
118 		tst_brk(TBROK, "Setup failed, quitting the test");
119 	}
120 }
121 
cleanup(void)122 static void cleanup(void)
123 {
124 	clean_swap();
125 }
126 
127 static struct tst_test test = {
128 	.mntpoint = MNTPOINT,
129 	.mount_device = 1,
130 	.all_filesystems = 1,
131 	.needs_root = 1,
132 	.forks_child = 1,
133 	.test_all = verify_swapon,
134 	.setup = setup,
135 	.cleanup = cleanup
136 };
137