1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
4*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) Linux Test Project, 2014-2024
5*49cdfc7eSAndroid Build Coastguard Worker * Author: Stanislav Kholmanskikh <[email protected]>
6*49cdfc7eSAndroid Build Coastguard Worker */
7*49cdfc7eSAndroid Build Coastguard Worker
8*49cdfc7eSAndroid Build Coastguard Worker #include <sys/statvfs.h>
9*49cdfc7eSAndroid Build Coastguard Worker #include <linux/fs.h>
10*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
11*49cdfc7eSAndroid Build Coastguard Worker #include <linux/fiemap.h>
12*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
13*49cdfc7eSAndroid Build Coastguard Worker #include <stdbool.h>
14*49cdfc7eSAndroid Build Coastguard Worker
15*49cdfc7eSAndroid Build Coastguard Worker #define TST_NO_DEFAULT_MAIN
16*49cdfc7eSAndroid Build Coastguard Worker #define DEFAULT_MAX_SWAPFILE 32
17*49cdfc7eSAndroid Build Coastguard Worker #define BUFSIZE 200
18*49cdfc7eSAndroid Build Coastguard Worker
19*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
20*49cdfc7eSAndroid Build Coastguard Worker #include "libswap.h"
21*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/syscalls.h"
22*49cdfc7eSAndroid Build Coastguard Worker #include "tst_kconfig.h"
23*49cdfc7eSAndroid Build Coastguard Worker #include "tst_kvercmp.h"
24*49cdfc7eSAndroid Build Coastguard Worker #include "tst_safe_stdio.h"
25*49cdfc7eSAndroid Build Coastguard Worker
26*49cdfc7eSAndroid Build Coastguard Worker static const char *const swap_supported_fs[] = {
27*49cdfc7eSAndroid Build Coastguard Worker "btrfs",
28*49cdfc7eSAndroid Build Coastguard Worker "ext2",
29*49cdfc7eSAndroid Build Coastguard Worker "ext3",
30*49cdfc7eSAndroid Build Coastguard Worker "ext4",
31*49cdfc7eSAndroid Build Coastguard Worker "xfs",
32*49cdfc7eSAndroid Build Coastguard Worker "vfat",
33*49cdfc7eSAndroid Build Coastguard Worker "exfat",
34*49cdfc7eSAndroid Build Coastguard Worker "ntfs",
35*49cdfc7eSAndroid Build Coastguard Worker NULL
36*49cdfc7eSAndroid Build Coastguard Worker };
37*49cdfc7eSAndroid Build Coastguard Worker
set_nocow_attr(const char * filename)38*49cdfc7eSAndroid Build Coastguard Worker static void set_nocow_attr(const char *filename)
39*49cdfc7eSAndroid Build Coastguard Worker {
40*49cdfc7eSAndroid Build Coastguard Worker int fd;
41*49cdfc7eSAndroid Build Coastguard Worker int attrs;
42*49cdfc7eSAndroid Build Coastguard Worker
43*49cdfc7eSAndroid Build Coastguard Worker tst_res(TINFO, "FS_NOCOW_FL attribute set on %s", filename);
44*49cdfc7eSAndroid Build Coastguard Worker
45*49cdfc7eSAndroid Build Coastguard Worker fd = SAFE_OPEN(filename, O_RDONLY);
46*49cdfc7eSAndroid Build Coastguard Worker
47*49cdfc7eSAndroid Build Coastguard Worker SAFE_IOCTL(fd, FS_IOC_GETFLAGS, &attrs);
48*49cdfc7eSAndroid Build Coastguard Worker
49*49cdfc7eSAndroid Build Coastguard Worker attrs |= FS_NOCOW_FL;
50*49cdfc7eSAndroid Build Coastguard Worker
51*49cdfc7eSAndroid Build Coastguard Worker SAFE_IOCTL(fd, FS_IOC_SETFLAGS, &attrs);
52*49cdfc7eSAndroid Build Coastguard Worker
53*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(fd);
54*49cdfc7eSAndroid Build Coastguard Worker }
55*49cdfc7eSAndroid Build Coastguard Worker
prealloc_contiguous_file(const char * path,size_t bs,size_t bcount)56*49cdfc7eSAndroid Build Coastguard Worker static int prealloc_contiguous_file(const char *path, size_t bs, size_t bcount)
57*49cdfc7eSAndroid Build Coastguard Worker {
58*49cdfc7eSAndroid Build Coastguard Worker int fd;
59*49cdfc7eSAndroid Build Coastguard Worker
60*49cdfc7eSAndroid Build Coastguard Worker fd = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0600);
61*49cdfc7eSAndroid Build Coastguard Worker if (fd < 0)
62*49cdfc7eSAndroid Build Coastguard Worker return -1;
63*49cdfc7eSAndroid Build Coastguard Worker
64*49cdfc7eSAndroid Build Coastguard Worker /* Btrfs file need set 'nocow' attribute */
65*49cdfc7eSAndroid Build Coastguard Worker if (tst_fs_type(path) == TST_BTRFS_MAGIC)
66*49cdfc7eSAndroid Build Coastguard Worker set_nocow_attr(path);
67*49cdfc7eSAndroid Build Coastguard Worker
68*49cdfc7eSAndroid Build Coastguard Worker if (tst_prealloc_size_fd(fd, bs, bcount)) {
69*49cdfc7eSAndroid Build Coastguard Worker close(fd);
70*49cdfc7eSAndroid Build Coastguard Worker unlink(path);
71*49cdfc7eSAndroid Build Coastguard Worker return -1;
72*49cdfc7eSAndroid Build Coastguard Worker }
73*49cdfc7eSAndroid Build Coastguard Worker
74*49cdfc7eSAndroid Build Coastguard Worker if (close(fd) < 0) {
75*49cdfc7eSAndroid Build Coastguard Worker unlink(path);
76*49cdfc7eSAndroid Build Coastguard Worker return -1;
77*49cdfc7eSAndroid Build Coastguard Worker }
78*49cdfc7eSAndroid Build Coastguard Worker
79*49cdfc7eSAndroid Build Coastguard Worker return 0;
80*49cdfc7eSAndroid Build Coastguard Worker }
81*49cdfc7eSAndroid Build Coastguard Worker
file_is_contiguous(const char * filename)82*49cdfc7eSAndroid Build Coastguard Worker static int file_is_contiguous(const char *filename)
83*49cdfc7eSAndroid Build Coastguard Worker {
84*49cdfc7eSAndroid Build Coastguard Worker int fd, contiguous = 0;
85*49cdfc7eSAndroid Build Coastguard Worker struct fiemap *fiemap;
86*49cdfc7eSAndroid Build Coastguard Worker
87*49cdfc7eSAndroid Build Coastguard Worker if (tst_fibmap(filename) == 0) {
88*49cdfc7eSAndroid Build Coastguard Worker contiguous = 1;
89*49cdfc7eSAndroid Build Coastguard Worker goto out;
90*49cdfc7eSAndroid Build Coastguard Worker }
91*49cdfc7eSAndroid Build Coastguard Worker
92*49cdfc7eSAndroid Build Coastguard Worker if (tst_fs_type(filename) == TST_TMPFS_MAGIC)
93*49cdfc7eSAndroid Build Coastguard Worker goto out;
94*49cdfc7eSAndroid Build Coastguard Worker
95*49cdfc7eSAndroid Build Coastguard Worker fd = SAFE_OPEN(filename, O_RDONLY);
96*49cdfc7eSAndroid Build Coastguard Worker
97*49cdfc7eSAndroid Build Coastguard Worker fiemap = (struct fiemap *)SAFE_MALLOC(sizeof(struct fiemap)
98*49cdfc7eSAndroid Build Coastguard Worker + sizeof(struct fiemap_extent));
99*49cdfc7eSAndroid Build Coastguard Worker
100*49cdfc7eSAndroid Build Coastguard Worker memset(fiemap, 0, sizeof(struct fiemap) + sizeof(struct fiemap_extent));
101*49cdfc7eSAndroid Build Coastguard Worker
102*49cdfc7eSAndroid Build Coastguard Worker fiemap->fm_start = 0;
103*49cdfc7eSAndroid Build Coastguard Worker fiemap->fm_length = ~0;
104*49cdfc7eSAndroid Build Coastguard Worker fiemap->fm_flags = 0;
105*49cdfc7eSAndroid Build Coastguard Worker fiemap->fm_extent_count = 1;
106*49cdfc7eSAndroid Build Coastguard Worker
107*49cdfc7eSAndroid Build Coastguard Worker SAFE_IOCTL(fd, FS_IOC_FIEMAP, fiemap);
108*49cdfc7eSAndroid Build Coastguard Worker
109*49cdfc7eSAndroid Build Coastguard Worker /*
110*49cdfc7eSAndroid Build Coastguard Worker * fiemap->fm_mapped_extents != 1:
111*49cdfc7eSAndroid Build Coastguard Worker * This checks if the file does not have exactly one extent. If there are more
112*49cdfc7eSAndroid Build Coastguard Worker * or zero extents, the file is not stored in a single contiguous block.
113*49cdfc7eSAndroid Build Coastguard Worker *
114*49cdfc7eSAndroid Build Coastguard Worker * fiemap->fm_extents[0].fe_logical != 0:
115*49cdfc7eSAndroid Build Coastguard Worker * This checks if the first extent does not start at the logical offset 0 of
116*49cdfc7eSAndroid Build Coastguard Worker * the file. If it doesn't, it indicates that the file's first block of data
117*49cdfc7eSAndroid Build Coastguard Worker * is not at the beginning of the file, which implies non-contiguity.
118*49cdfc7eSAndroid Build Coastguard Worker *
119*49cdfc7eSAndroid Build Coastguard Worker * (fiemap->fm_extents[0].fe_flags & FIEMAP_EXTENT_LAST) != FIEMAP_EXTENT_LAST:
120*49cdfc7eSAndroid Build Coastguard Worker * This checks if the first extent does not have the FIEMAP_EXTENT_LAST flag set.
121*49cdfc7eSAndroid Build Coastguard Worker * If the flag isn't set, it means that this extent is not the last one, suggesting
122*49cdfc7eSAndroid Build Coastguard Worker * that there are more extents and the file is not contiguous.
123*49cdfc7eSAndroid Build Coastguard Worker */
124*49cdfc7eSAndroid Build Coastguard Worker if (fiemap->fm_mapped_extents != 1 ||
125*49cdfc7eSAndroid Build Coastguard Worker fiemap->fm_extents[0].fe_logical != 0 ||
126*49cdfc7eSAndroid Build Coastguard Worker (fiemap->fm_extents[0].fe_flags & FIEMAP_EXTENT_LAST) != FIEMAP_EXTENT_LAST) {
127*49cdfc7eSAndroid Build Coastguard Worker
128*49cdfc7eSAndroid Build Coastguard Worker tst_res(TINFO, "File '%s' is not contiguous", filename);
129*49cdfc7eSAndroid Build Coastguard Worker contiguous = 0;
130*49cdfc7eSAndroid Build Coastguard Worker }
131*49cdfc7eSAndroid Build Coastguard Worker
132*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(fd);
133*49cdfc7eSAndroid Build Coastguard Worker free(fiemap);
134*49cdfc7eSAndroid Build Coastguard Worker
135*49cdfc7eSAndroid Build Coastguard Worker out:
136*49cdfc7eSAndroid Build Coastguard Worker return contiguous;
137*49cdfc7eSAndroid Build Coastguard Worker }
138*49cdfc7eSAndroid Build Coastguard Worker
make_swapfile(const char * file,const int lineno,const char * swapfile,unsigned int num,int safe,enum swapfile_method method)139*49cdfc7eSAndroid Build Coastguard Worker int make_swapfile(const char *file, const int lineno,
140*49cdfc7eSAndroid Build Coastguard Worker const char *swapfile, unsigned int num,
141*49cdfc7eSAndroid Build Coastguard Worker int safe, enum swapfile_method method)
142*49cdfc7eSAndroid Build Coastguard Worker {
143*49cdfc7eSAndroid Build Coastguard Worker struct statvfs fs_info;
144*49cdfc7eSAndroid Build Coastguard Worker unsigned long blk_size;
145*49cdfc7eSAndroid Build Coastguard Worker unsigned int blocks = 0;
146*49cdfc7eSAndroid Build Coastguard Worker size_t pg_size = sysconf(_SC_PAGESIZE);
147*49cdfc7eSAndroid Build Coastguard Worker char mnt_path[PATH_MAX];
148*49cdfc7eSAndroid Build Coastguard Worker
149*49cdfc7eSAndroid Build Coastguard Worker if (statvfs(".", &fs_info) == -1)
150*49cdfc7eSAndroid Build Coastguard Worker tst_brk_(file, lineno, TBROK, "statvfs failed");
151*49cdfc7eSAndroid Build Coastguard Worker
152*49cdfc7eSAndroid Build Coastguard Worker blk_size = fs_info.f_bsize;
153*49cdfc7eSAndroid Build Coastguard Worker
154*49cdfc7eSAndroid Build Coastguard Worker if (method == SWAPFILE_BY_SIZE) {
155*49cdfc7eSAndroid Build Coastguard Worker tst_res_(file, lineno, TINFO, "create a swapfile size of %u megabytes (MB)", num);
156*49cdfc7eSAndroid Build Coastguard Worker blocks = num * 1024 * 1024 / blk_size;
157*49cdfc7eSAndroid Build Coastguard Worker } else if (method == SWAPFILE_BY_BLKS) {
158*49cdfc7eSAndroid Build Coastguard Worker blocks = num;
159*49cdfc7eSAndroid Build Coastguard Worker tst_res_(file, lineno, TINFO, "create a swapfile with %u block numbers", blocks);
160*49cdfc7eSAndroid Build Coastguard Worker } else {
161*49cdfc7eSAndroid Build Coastguard Worker tst_brk_(file, lineno, TBROK, "Invalid method, please see include/libswap.h");
162*49cdfc7eSAndroid Build Coastguard Worker }
163*49cdfc7eSAndroid Build Coastguard Worker
164*49cdfc7eSAndroid Build Coastguard Worker /* To guarantee at least one page can be swapped out */
165*49cdfc7eSAndroid Build Coastguard Worker if (blk_size * blocks < pg_size) {
166*49cdfc7eSAndroid Build Coastguard Worker tst_res_(file, lineno, TWARN, "Swapfile size is less than the system page size. "
167*49cdfc7eSAndroid Build Coastguard Worker "Using page size (%lu bytes) instead of block size (%lu bytes).",
168*49cdfc7eSAndroid Build Coastguard Worker (unsigned long)pg_size, blk_size);
169*49cdfc7eSAndroid Build Coastguard Worker blk_size = pg_size;
170*49cdfc7eSAndroid Build Coastguard Worker }
171*49cdfc7eSAndroid Build Coastguard Worker
172*49cdfc7eSAndroid Build Coastguard Worker if (sscanf(swapfile, "%[^/]", mnt_path) != 1)
173*49cdfc7eSAndroid Build Coastguard Worker tst_brk_(file, lineno, TBROK, "sscanf failed");
174*49cdfc7eSAndroid Build Coastguard Worker
175*49cdfc7eSAndroid Build Coastguard Worker if (!tst_fs_has_free(mnt_path, blk_size * blocks, TST_BYTES))
176*49cdfc7eSAndroid Build Coastguard Worker tst_brk_(file, lineno, TCONF, "Insufficient disk space to create swap file");
177*49cdfc7eSAndroid Build Coastguard Worker
178*49cdfc7eSAndroid Build Coastguard Worker /* create file */
179*49cdfc7eSAndroid Build Coastguard Worker if (prealloc_contiguous_file(swapfile, blk_size, blocks) != 0)
180*49cdfc7eSAndroid Build Coastguard Worker tst_brk_(file, lineno, TBROK, "Failed to create swapfile");
181*49cdfc7eSAndroid Build Coastguard Worker
182*49cdfc7eSAndroid Build Coastguard Worker /* Fill the file if needed (specific to old xfs filesystems) */
183*49cdfc7eSAndroid Build Coastguard Worker if (tst_fs_type(swapfile) == TST_XFS_MAGIC) {
184*49cdfc7eSAndroid Build Coastguard Worker if (tst_fill_file(swapfile, 0, blk_size, blocks) != 0)
185*49cdfc7eSAndroid Build Coastguard Worker tst_brk_(file, lineno, TBROK, "Failed to fill swapfile");
186*49cdfc7eSAndroid Build Coastguard Worker }
187*49cdfc7eSAndroid Build Coastguard Worker
188*49cdfc7eSAndroid Build Coastguard Worker /* make the file swapfile */
189*49cdfc7eSAndroid Build Coastguard Worker const char *const argv[] = {"mkswap", swapfile, NULL};
190*49cdfc7eSAndroid Build Coastguard Worker
191*49cdfc7eSAndroid Build Coastguard Worker return tst_cmd(argv, "/dev/null", "/dev/null", safe ?
192*49cdfc7eSAndroid Build Coastguard Worker TST_CMD_PASS_RETVAL | TST_CMD_TCONF_ON_MISSING : 0);
193*49cdfc7eSAndroid Build Coastguard Worker }
194*49cdfc7eSAndroid Build Coastguard Worker
is_swap_supported(const char * filename)195*49cdfc7eSAndroid Build Coastguard Worker bool is_swap_supported(const char *filename)
196*49cdfc7eSAndroid Build Coastguard Worker {
197*49cdfc7eSAndroid Build Coastguard Worker int i, sw_support = 0;
198*49cdfc7eSAndroid Build Coastguard Worker int ret = SAFE_MAKE_SMALL_SWAPFILE(filename);
199*49cdfc7eSAndroid Build Coastguard Worker int fi_contiguous = file_is_contiguous(filename);
200*49cdfc7eSAndroid Build Coastguard Worker long fs_type = tst_fs_type(filename);
201*49cdfc7eSAndroid Build Coastguard Worker const char *fstype = tst_fs_type_name(fs_type);
202*49cdfc7eSAndroid Build Coastguard Worker
203*49cdfc7eSAndroid Build Coastguard Worker if (fs_type == TST_BTRFS_MAGIC &&
204*49cdfc7eSAndroid Build Coastguard Worker tst_kvercmp(5, 0, 0) < 0)
205*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TCONF, "Swapfile on Btrfs (kernel < 5.0) not implemented");
206*49cdfc7eSAndroid Build Coastguard Worker
207*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; swap_supported_fs[i]; i++) {
208*49cdfc7eSAndroid Build Coastguard Worker if (strstr(fstype, swap_supported_fs[i])) {
209*49cdfc7eSAndroid Build Coastguard Worker sw_support = 1;
210*49cdfc7eSAndroid Build Coastguard Worker break;
211*49cdfc7eSAndroid Build Coastguard Worker }
212*49cdfc7eSAndroid Build Coastguard Worker }
213*49cdfc7eSAndroid Build Coastguard Worker
214*49cdfc7eSAndroid Build Coastguard Worker if (ret != 0) {
215*49cdfc7eSAndroid Build Coastguard Worker if (fi_contiguous == 0 && sw_support == 0) {
216*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TCONF, "mkswap on %s not supported", fstype);
217*49cdfc7eSAndroid Build Coastguard Worker } else {
218*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "mkswap on %s failed", fstype);
219*49cdfc7eSAndroid Build Coastguard Worker return false;
220*49cdfc7eSAndroid Build Coastguard Worker }
221*49cdfc7eSAndroid Build Coastguard Worker }
222*49cdfc7eSAndroid Build Coastguard Worker
223*49cdfc7eSAndroid Build Coastguard Worker TEST(tst_syscall(__NR_swapon, filename, 0));
224*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1) {
225*49cdfc7eSAndroid Build Coastguard Worker if (errno == EPERM) {
226*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TCONF, "Permission denied for swapon()");
227*49cdfc7eSAndroid Build Coastguard Worker } else if (errno == EINVAL && fi_contiguous == 0 && sw_support == 0) {
228*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TCONF, "Swapfile on %s not implemented", fstype);
229*49cdfc7eSAndroid Build Coastguard Worker } else {
230*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "swapon() on %s failed", fstype);
231*49cdfc7eSAndroid Build Coastguard Worker return false;
232*49cdfc7eSAndroid Build Coastguard Worker }
233*49cdfc7eSAndroid Build Coastguard Worker }
234*49cdfc7eSAndroid Build Coastguard Worker
235*49cdfc7eSAndroid Build Coastguard Worker TEST(tst_syscall(__NR_swapoff, filename, 0));
236*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1) {
237*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "swapoff on %s failed", fstype);
238*49cdfc7eSAndroid Build Coastguard Worker return false;
239*49cdfc7eSAndroid Build Coastguard Worker }
240*49cdfc7eSAndroid Build Coastguard Worker
241*49cdfc7eSAndroid Build Coastguard Worker return true;
242*49cdfc7eSAndroid Build Coastguard Worker }
243*49cdfc7eSAndroid Build Coastguard Worker
tst_max_swapfiles(void)244*49cdfc7eSAndroid Build Coastguard Worker int tst_max_swapfiles(void)
245*49cdfc7eSAndroid Build Coastguard Worker {
246*49cdfc7eSAndroid Build Coastguard Worker unsigned int swp_migration_num = 0, swp_hwpoison_num = 0,
247*49cdfc7eSAndroid Build Coastguard Worker swp_device_num = 0, swp_pte_marker_num = 0,
248*49cdfc7eSAndroid Build Coastguard Worker swp_swapin_error_num = 0;
249*49cdfc7eSAndroid Build Coastguard Worker struct tst_kconfig_var migration = TST_KCONFIG_INIT("CONFIG_MIGRATION");
250*49cdfc7eSAndroid Build Coastguard Worker struct tst_kconfig_var memory = TST_KCONFIG_INIT("CONFIG_MEMORY_FAILURE");
251*49cdfc7eSAndroid Build Coastguard Worker struct tst_kconfig_var device = TST_KCONFIG_INIT("CONFIG_DEVICE_PRIVATE");
252*49cdfc7eSAndroid Build Coastguard Worker struct tst_kconfig_var marker = TST_KCONFIG_INIT("CONFIG_PTE_MARKER");
253*49cdfc7eSAndroid Build Coastguard Worker struct tst_kern_exv kvers_marker_migration[] = {
254*49cdfc7eSAndroid Build Coastguard Worker /* RHEL9 kernel has patch 6c287605f and 679d10331 since 5.14.0-179 */
255*49cdfc7eSAndroid Build Coastguard Worker { "RHEL9", "5.14.0-179" },
256*49cdfc7eSAndroid Build Coastguard Worker { NULL, NULL},
257*49cdfc7eSAndroid Build Coastguard Worker };
258*49cdfc7eSAndroid Build Coastguard Worker
259*49cdfc7eSAndroid Build Coastguard Worker struct tst_kern_exv kvers_device[] = {
260*49cdfc7eSAndroid Build Coastguard Worker /* SLES12-SP4 has patch 5042db43cc26 since 4.12.14-5.5 */
261*49cdfc7eSAndroid Build Coastguard Worker { "SLES", "4.12.14-5.5" },
262*49cdfc7eSAndroid Build Coastguard Worker { NULL, NULL},
263*49cdfc7eSAndroid Build Coastguard Worker };
264*49cdfc7eSAndroid Build Coastguard Worker
265*49cdfc7eSAndroid Build Coastguard Worker tst_kconfig_read(&migration, 1);
266*49cdfc7eSAndroid Build Coastguard Worker tst_kconfig_read(&memory, 1);
267*49cdfc7eSAndroid Build Coastguard Worker tst_kconfig_read(&device, 1);
268*49cdfc7eSAndroid Build Coastguard Worker tst_kconfig_read(&marker, 1);
269*49cdfc7eSAndroid Build Coastguard Worker
270*49cdfc7eSAndroid Build Coastguard Worker if (migration.choice == 'y') {
271*49cdfc7eSAndroid Build Coastguard Worker if (tst_kvercmp2(5, 19, 0, kvers_marker_migration) < 0)
272*49cdfc7eSAndroid Build Coastguard Worker swp_migration_num = 2;
273*49cdfc7eSAndroid Build Coastguard Worker else
274*49cdfc7eSAndroid Build Coastguard Worker swp_migration_num = 3;
275*49cdfc7eSAndroid Build Coastguard Worker }
276*49cdfc7eSAndroid Build Coastguard Worker
277*49cdfc7eSAndroid Build Coastguard Worker if (memory.choice == 'y')
278*49cdfc7eSAndroid Build Coastguard Worker swp_hwpoison_num = 1;
279*49cdfc7eSAndroid Build Coastguard Worker
280*49cdfc7eSAndroid Build Coastguard Worker if (device.choice == 'y') {
281*49cdfc7eSAndroid Build Coastguard Worker if (tst_kvercmp2(4, 14, 0, kvers_device) >= 0)
282*49cdfc7eSAndroid Build Coastguard Worker swp_device_num = 2;
283*49cdfc7eSAndroid Build Coastguard Worker if (tst_kvercmp(5, 14, 0) >= 0)
284*49cdfc7eSAndroid Build Coastguard Worker swp_device_num = 4;
285*49cdfc7eSAndroid Build Coastguard Worker }
286*49cdfc7eSAndroid Build Coastguard Worker
287*49cdfc7eSAndroid Build Coastguard Worker if ((marker.choice == 'y' &&
288*49cdfc7eSAndroid Build Coastguard Worker tst_kvercmp2(5, 19, 0, kvers_marker_migration) >= 0)
289*49cdfc7eSAndroid Build Coastguard Worker || tst_kvercmp(6, 2, 0) >= 0) {
290*49cdfc7eSAndroid Build Coastguard Worker swp_pte_marker_num = 1;
291*49cdfc7eSAndroid Build Coastguard Worker }
292*49cdfc7eSAndroid Build Coastguard Worker
293*49cdfc7eSAndroid Build Coastguard Worker if ((tst_kvercmp(5, 19, 0) >= 0) && (tst_kvercmp(6, 2, 0) < 0))
294*49cdfc7eSAndroid Build Coastguard Worker swp_swapin_error_num = 1;
295*49cdfc7eSAndroid Build Coastguard Worker
296*49cdfc7eSAndroid Build Coastguard Worker return DEFAULT_MAX_SWAPFILE - swp_migration_num - swp_hwpoison_num
297*49cdfc7eSAndroid Build Coastguard Worker - swp_device_num - swp_pte_marker_num - swp_swapin_error_num;
298*49cdfc7eSAndroid Build Coastguard Worker }
299*49cdfc7eSAndroid Build Coastguard Worker
tst_count_swaps(void)300*49cdfc7eSAndroid Build Coastguard Worker int tst_count_swaps(void)
301*49cdfc7eSAndroid Build Coastguard Worker {
302*49cdfc7eSAndroid Build Coastguard Worker FILE *fp;
303*49cdfc7eSAndroid Build Coastguard Worker int used = -1;
304*49cdfc7eSAndroid Build Coastguard Worker char buf[BUFSIZE];
305*49cdfc7eSAndroid Build Coastguard Worker
306*49cdfc7eSAndroid Build Coastguard Worker fp = SAFE_FOPEN("/proc/swaps", "r");
307*49cdfc7eSAndroid Build Coastguard Worker if (fp == NULL)
308*49cdfc7eSAndroid Build Coastguard Worker return -1;
309*49cdfc7eSAndroid Build Coastguard Worker
310*49cdfc7eSAndroid Build Coastguard Worker while (fgets(buf, BUFSIZE, fp) != NULL)
311*49cdfc7eSAndroid Build Coastguard Worker used++;
312*49cdfc7eSAndroid Build Coastguard Worker
313*49cdfc7eSAndroid Build Coastguard Worker SAFE_FCLOSE(fp);
314*49cdfc7eSAndroid Build Coastguard Worker if (used < 0)
315*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK, "can't read /proc/swaps to get used swapfiles resource total");
316*49cdfc7eSAndroid Build Coastguard Worker
317*49cdfc7eSAndroid Build Coastguard Worker return used;
318*49cdfc7eSAndroid Build Coastguard Worker }
319