xfs: quotas on idmapped mounts
[xfstests-dev.git] / src / swapon.c
1 /* swapon(8) without any sanity checks; simply calls swapon(2) directly. */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <string.h>
7 #include <sys/swap.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <sys/mman.h>
11 #include <fcntl.h>
12 #include <signal.h>
13
14 static void usage(const char *prog)
15 {
16         fprintf(stderr, "usage: %s [-v verb] PATH\n", prog);
17         exit(EXIT_FAILURE);
18 }
19
20 enum verbs {
21         TEST_SWAPON = 0,
22         TEST_WRITE,
23         TEST_MWRITE_AFTER,
24         TEST_MWRITE_BEFORE_AND_MWRITE_AFTER,
25         TEST_MWRITE_BEFORE,
26         MAX_TEST_VERBS,
27 };
28
29 #define BUF_SIZE 262144
30 static char buf[BUF_SIZE];
31
32 static void handle_signal(int signal)
33 {
34         fprintf(stderr, "Caught signal %d, terminating...\n", signal);
35         exit(EXIT_FAILURE);
36 }
37
38 int main(int argc, char **argv)
39 {
40         struct sigaction act = {
41                 .sa_handler     = handle_signal,
42         };
43         enum verbs verb = TEST_SWAPON;
44         void *p = NULL;
45         ssize_t sz;
46         int fd = -1;
47         int ret, c;
48
49         memset(buf, 0x58, BUF_SIZE);
50
51         while ((c = getopt(argc, argv, "v:")) != -1) {
52                 switch (c) {
53                 case 'v':
54                         verb = atoi(optarg);
55                         if (verb < TEST_SWAPON || verb >= MAX_TEST_VERBS) {
56                                 fprintf(stderr, "Verbs must be 0-%d.\n",
57                                                 MAX_TEST_VERBS - 1);
58                                 usage(argv[0]);
59                         }
60                         break;
61                 default:
62                         usage(argv[0]);
63                         break;
64                 }
65         }
66
67         ret = sigaction(SIGSEGV, &act, NULL);
68         if (ret) {
69                 perror("sigsegv action");
70                 return EXIT_FAILURE;
71         }
72
73         ret = sigaction(SIGBUS, &act, NULL);
74         if (ret) {
75                 perror("sigbus action");
76                 return EXIT_FAILURE;
77         }
78
79         switch (verb) {
80         case TEST_WRITE:
81         case TEST_MWRITE_AFTER:
82         case TEST_MWRITE_BEFORE_AND_MWRITE_AFTER:
83         case TEST_MWRITE_BEFORE:
84                 fd = open(argv[optind], O_RDWR);
85                 if (fd < 0) {
86                         perror(argv[optind]);
87                         return EXIT_FAILURE;
88                 }
89                 break;
90         default:
91                 break;
92         }
93
94         switch (verb) {
95         case TEST_MWRITE_BEFORE_AND_MWRITE_AFTER:
96         case TEST_MWRITE_BEFORE:
97                 p = mmap(NULL, BUF_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED,
98                                 fd, 65536);
99                 if (p == MAP_FAILED) {
100                         perror("mmap");
101                         return EXIT_FAILURE;
102                 }
103                 memcpy(p, buf, BUF_SIZE);
104                 break;
105         default:
106                 break;
107         }
108
109         if (optind != argc - 1)
110                 usage(argv[0]);
111
112         ret = swapon(argv[optind], 0);
113         if (ret) {
114                 perror("swapon");
115                 return EXIT_FAILURE;
116         }
117
118         switch (verb) {
119         case TEST_WRITE:
120                 sz = pwrite(fd, buf, BUF_SIZE, 65536);
121                 if (sz < 0) {
122                         perror("pwrite");
123                         return EXIT_FAILURE;
124                 }
125                 break;
126         case TEST_MWRITE_AFTER:
127                 p = mmap(NULL, BUF_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED,
128                                 fd, 65536);
129                 if (p == MAP_FAILED) {
130                         perror("mmap");
131                         return EXIT_FAILURE;
132                 }
133                 /* fall through */
134         case TEST_MWRITE_BEFORE_AND_MWRITE_AFTER:
135                 memcpy(p, buf, BUF_SIZE);
136                 break;
137         default:
138                 break;
139         }
140
141         if (fd >= 0) {
142                 ret = fsync(fd);
143                 if (ret)
144                         perror("fsync");
145                 ret = close(fd);
146                 if (ret)
147                         perror("close");
148         }
149
150         return EXIT_SUCCESS;
151 }