]> git.ipfire.org Git - thirdparty/util-linux.git/blame - sys-utils/swapon.c
swapoff: cleanup usage() and includes
[thirdparty/util-linux.git] / sys-utils / swapon.c
CommitLineData
fd6b7a7f
KZ
1#include <stdlib.h>
2#include <stdio.h>
3#include <getopt.h>
4#include <string.h>
5#include <mntent.h>
6#include <errno.h>
5c36a0eb 7#include <sys/stat.h>
ffa63a3d 8#include <unistd.h>
6274b987
KC
9#include <sys/types.h>
10#include <sys/wait.h>
11#include <fcntl.h>
3399a218 12#include <stdint.h>
57a60bf0 13#include <ctype.h>
81772d3c 14
64b58881 15#include <libmount.h>
b5b2c388 16
3399a218
MK
17#include "bitops.h"
18#include "blkdev.h"
7eda085c 19#include "nls.h"
4e270e3f 20#include "pathnames.h"
3399a218 21#include "swapheader.h"
bfbb12d2 22#include "xalloc.h"
eb76ca98 23#include "c.h"
efb8854f 24#include "closestream.h"
167eaed7 25
0b0c231f
KZ
26#include "swapon-common.h"
27
6274b987
KC
28#define PATH_MKSWAP "/sbin/mkswap"
29
ffa63a3d
MF
30#ifdef HAVE_SYS_SWAP_H
31# include <sys/swap.h>
32#endif
33
c2301380
HD
34#ifndef SWAP_FLAG_DISCARD
35# define SWAP_FLAG_DISCARD 0x10000 /* discard swap cluster after use */
36#endif
37
9514a612
KZ
38#ifndef SWAP_FLAG_PREFER
39# define SWAP_FLAG_PREFER 0x8000 /* set if swap priority specified */
40#endif
41
42#ifndef SWAP_FLAG_PRIO_MASK
43# define SWAP_FLAG_PRIO_MASK 0x7fff
44#endif
45
46#ifndef SWAP_FLAG_PRIO_SHIFT
47# define SWAP_FLAG_PRIO_SHIFT 0
48#endif
49
ffa63a3d
MF
50#ifndef SWAPON_HAS_TWO_ARGS
51/* libc is insane, let's call the kernel */
52# include <sys/syscall.h>
53# define swapon(path, flags) syscall(SYS_swapon, path, flags)
ffa63a3d
MF
54#endif
55
fd6b7a7f
KZ
56#define streq(s, t) (strcmp ((s), (t)) == 0)
57
63cccae4 58#define QUIET 1
12ac2bbe 59#define CANONIC 1
63cccae4 60
3399a218
MK
61#define MAX_PAGESIZE (64 * 1024)
62
e8be80dd
KZ
63enum {
64 SIG_SWAPSPACE = 1,
65 SIG_SWSUSPEND
66};
67
617d8a3b
KZ
68#define SWAP_SIGNATURE "SWAPSPACE2"
69#define SWAP_SIGNATURE_SZ (sizeof(SWAP_SIGNATURE) - 1)
70
16ff9813
TK
71static int all;
72static int priority = -1; /* non-prioritized swap by default */
73static int discard;
6dbe3af9 74
95f1bdee 75/* If true, don't complain if the device/file doesn't exist */
16ff9813
TK
76static int ifexists;
77static int fixpgsz;
81772d3c 78
16ff9813
TK
79static int verbose;
80static char *progname;
95f1bdee 81
16ff9813 82static const struct option longswaponopts[] = {
63cccae4
KZ
83 /* swapon only */
84 { "priority", required_argument, 0, 'p' },
c2301380 85 { "discard", 0, 0, 'd' },
95f1bdee 86 { "ifexists", 0, 0, 'e' },
63cccae4 87 { "summary", 0, 0, 's' },
0d761944 88 { "fixpgsz", 0, 0, 'f' },
63cccae4
KZ
89 /* also for swapoff */
90 { "all", 0, 0, 'a' },
91 { "help", 0, 0, 'h' },
92 { "verbose", 0, 0, 'v' },
93 { "version", 0, 0, 'V' },
94 { NULL, 0, 0, 0 }
6dbe3af9
KZ
95};
96
240e20b5 97#define PRINT_USAGE_SPECIAL(_fp) \
53e20cec
KZ
98 fputs(_("\nThe <spec> parameter:\n" \
99 " -L <label> LABEL of device to be used\n" \
100 " -U <uuid> UUID of device to be used\n" \
101 " LABEL=<label> LABEL of device to be used\n" \
102 " UUID=<uuid> UUID of device to be used\n" \
103 " <device> name of device to be used\n" \
104 " <file> name of file to be used\n\n"), _fp)
240e20b5 105
6dbe3af9 106static void
53e20cec
KZ
107swapon_usage(FILE *out, int n) {
108 fputs(_("\nUsage:\n"), out);
109 fprintf(out, _(" %s [options] [<spec>]\n"), progname);
110
111 fputs(_("\nOptions:\n"), out);
112 fputs(_(" -a, --all enable all swaps from /etc/fstab\n"
113 " -d, --discard discard freed pages before they are reused\n"
114 " -e, --ifexists silently skip devices that do not exis\n"
115 " -f, --fixpgsz reinitialize the swap space if necessary\n"
116 " -h, --help display help and exit\n"
f9bd0858 117 " -p, --priority <prio> specify the priority of the swap device\n"
53e20cec
KZ
118 " -s, --summary display summary about used swap devices and exit\n"
119 " -v, --verbose verbose mode\n"
120 " -V, --version display version and exit\n"), out);
121
122 PRINT_USAGE_SPECIAL(out);
240e20b5 123
63cccae4
KZ
124 exit(n);
125}
126
fd6b7a7f
KZ
127static int
128display_summary(void)
129{
5072b90a 130 struct libmnt_table *st = get_swaps();
64b58881
KZ
131 struct libmnt_iter *itr;
132 struct libmnt_fs *fs;
fd6b7a7f 133
64b58881 134 if (!st)
57a60bf0 135 return -1;
e8f26419 136
64b58881
KZ
137 itr = mnt_new_iter(MNT_ITER_FORWARD);
138 if (!itr)
139 err(EXIT_FAILURE, _("failed to initialize libmount iterator"));
57a60bf0 140
64b58881
KZ
141 if (mnt_table_get_nents(st) > 0)
142 printf(_("%-39s\tType\tSize\tUsed\tPriority\n"), _("Filename"));
143
144 while (mnt_table_next_fs(st, itr, &fs) == 0) {
145 printf("%-39s\t%s\t%jd\t%jd\t%d\n",
146 mnt_fs_get_source(fs),
147 mnt_fs_get_swaptype(fs),
148 mnt_fs_get_size(fs),
149 mnt_fs_get_usedsize(fs),
150 mnt_fs_get_priority(fs));
57a60bf0 151 }
fd6b7a7f 152
64b58881
KZ
153 mnt_free_iter(itr);
154 return 0;
fd6b7a7f
KZ
155}
156
6274b987
KC
157/* calls mkswap */
158static int
b5b2c388
KZ
159swap_reinitialize(const char *device, const char *label, const char *uuid)
160{
6274b987
KC
161 pid_t pid;
162 int status, ret;
163 char *cmd[7];
164 int idx=0;
165
0d761944
KZ
166 warnx(_("%s: reinitializing the swap."), device);
167
6274b987
KC
168 switch((pid=fork())) {
169 case -1: /* fork error */
d51d05d3 170 warn(_("fork failed"));
6274b987
KC
171 return -1;
172
173 case 0: /* child */
174 cmd[idx++] = PATH_MKSWAP;
175 if (label && *label) {
176 cmd[idx++] = "-L";
177 cmd[idx++] = (char *) label;
178 }
179 if (uuid && *uuid) {
180 cmd[idx++] = "-U";
181 cmd[idx++] = (char *) uuid;
182 }
183 cmd[idx++] = (char *) device;
184 cmd[idx++] = NULL;
185 execv(cmd[0], cmd);
d51d05d3 186 err(EXIT_FAILURE, _("execv failed"));
6274b987
KC
187
188 default: /* parent */
189 do {
190 if ((ret = waitpid(pid, &status, 0)) < 0
191 && errno == EINTR)
192 continue;
193 else if (ret < 0) {
d51d05d3 194 warn(_("waitpid failed"));
6274b987
KC
195 return -1;
196 }
197 } while (0);
198
199 /* mkswap returns: 0=suss, 1=error */
200 if (WIFEXITED(status) && WEXITSTATUS(status)==0)
201 return 0; /* ok */
f8ff4ebb 202 break;
6274b987
KC
203 }
204 return -1; /* error */
205}
206
617d8a3b
KZ
207static int
208swap_rewrite_signature(const char *devname, unsigned int pagesize)
209{
210 int fd, rc = -1;
211
212 fd = open(devname, O_WRONLY);
213 if (fd == -1) {
214 warn(_("%s: open failed"), devname);
215 return -1;
216 }
217
5dd53f43
KZ
218 if (lseek(fd, pagesize - SWAP_SIGNATURE_SZ, SEEK_SET) < 0) {
219 warn(_("%s: lseek failed"), devname);
617d8a3b 220 goto err;
5dd53f43 221 }
617d8a3b
KZ
222
223 if (write(fd, (void *) SWAP_SIGNATURE,
5dd53f43
KZ
224 SWAP_SIGNATURE_SZ) != SWAP_SIGNATURE_SZ) {
225 warn(_("%s: write signature failed"), devname);
617d8a3b 226 goto err;
5dd53f43 227 }
617d8a3b
KZ
228
229 rc = 0;
230err:
231 close(fd);
232 return rc;
233}
234
e8be80dd
KZ
235static int
236swap_detect_signature(const char *buf, int *sig)
3399a218 237{
e8be80dd
KZ
238 if (memcmp(buf, "SWAP-SPACE", 10) == 0 ||
239 memcmp(buf, "SWAPSPACE2", 10) == 0)
240 *sig = SIG_SWAPSPACE;
241
242 else if (memcmp(buf, "S1SUSPEND", 9) == 0 ||
243 memcmp(buf, "S2SUSPEND", 9) == 0 ||
244 memcmp(buf, "ULSUSPEND", 9) == 0 ||
5a16af58
KZ
245 memcmp(buf, "\xed\xc3\x02\xe9\x98\x56\xe5\x0c", 8) == 0 ||
246 memcmp(buf, "LINHIB0001", 10) == 0)
e8be80dd
KZ
247 *sig = SIG_SWSUSPEND;
248 else
249 return 0;
3399a218 250
e8be80dd 251 return 1;
3399a218
MK
252}
253
e8be80dd
KZ
254static char *
255swap_get_header(int fd, int *sig, unsigned int *pagesize)
3399a218 256{
3399a218 257 char *buf;
e8be80dd
KZ
258 ssize_t datasz;
259 unsigned int page;
3399a218 260
e8be80dd
KZ
261 *pagesize = 0;
262 *sig = 0;
3399a218 263
bfbb12d2 264 buf = xmalloc(MAX_PAGESIZE);
3399a218
MK
265
266 datasz = read(fd, buf, MAX_PAGESIZE);
e8be80dd
KZ
267 if (datasz == (ssize_t) -1)
268 goto err;
3399a218
MK
269
270 for (page = 0x1000; page <= MAX_PAGESIZE; page <<= 1) {
271 /* skip 32k pagesize since this does not seem to
272 * be supported */
273 if (page == 0x8000)
274 continue;
275 /* the smallest swap area is PAGE_SIZE*10, it means
276 * 40k, that's less than MAX_PAGESIZE */
24f010e8 277 if (datasz < 0 || (size_t) datasz < (page - SWAP_SIGNATURE_SZ))
3399a218 278 break;
617d8a3b 279 if (swap_detect_signature(buf + page - SWAP_SIGNATURE_SZ, sig)) {
e8be80dd 280 *pagesize = page;
3399a218
MK
281 break;
282 }
283 }
284
e8be80dd
KZ
285 if (*pagesize)
286 return buf;
3399a218 287err:
e8be80dd
KZ
288 free(buf);
289 return NULL;
290}
291
292/* returns real size of swap space */
293unsigned long long
294swap_get_size(const char *hdr, const char *devname, unsigned int pagesize)
295{
296 unsigned int last_page = 0;
297 int swap_version = 0;
298 int flip = 0;
299 struct swap_header_v1_2 *s;
300
301 s = (struct swap_header_v1_2 *) hdr;
302 if (s->version == 1) {
303 swap_version = 1;
304 last_page = s->last_page;
305 } else if (swab32(s->version) == 1) {
306 flip = 1;
307 swap_version = 1;
308 last_page = swab32(s->last_page);
309 }
310 if (verbose)
04c94441
KZ
311 warnx(_("%s: found swap signature: version %d, "
312 "page-size %d, %s byte order"),
e8be80dd 313 devname,
e8be80dd 314 swap_version,
04c94441
KZ
315 pagesize / 1024,
316 flip ? _("different") : _("same"));
e8be80dd 317
98e9ff61 318 return ((unsigned long long) last_page + 1) * pagesize;
3399a218
MK
319}
320
b5b2c388
KZ
321void
322swap_get_info(const char *hdr, char **label, char **uuid)
323{
324 struct swap_header_v1_2 *s = (struct swap_header_v1_2 *) hdr;
325
326 if (s && *s->volume_name && label)
327 *label = xstrdup(s->volume_name);
328
329 if (s && *s->uuid && uuid) {
330 const unsigned char *u = s->uuid;
331 char str[37];
332
333 snprintf(str, sizeof(str),
334 "%02x%02x%02x%02x-"
335 "%02x%02x-%02x%02x-"
336 "%02x%02x-%02x%02x%02x%02x%02x%02x",
337 u[0], u[1], u[2], u[3],
338 u[4], u[5], u[6], u[7],
339 u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15]);
340 *uuid = xstrdup(str);
341 }
342}
343
63cccae4 344static int
05c79b78
KZ
345swapon_checks(const char *special)
346{
63cccae4 347 struct stat st;
05c79b78
KZ
348 int fd = -1, sig;
349 char *hdr = NULL;
e8be80dd
KZ
350 unsigned int pagesize;
351 unsigned long long devsize = 0;
63cccae4 352
63cccae4 353 if (stat(special, &st) < 0) {
d51d05d3 354 warn(_("%s: stat failed"), special);
05c79b78 355 goto err;
63cccae4
KZ
356 }
357
88530f9f
KZ
358 /* people generally dislike this warning - now it is printed
359 only when `verbose' is set */
360 if (verbose) {
361 int permMask = (S_ISBLK(st.st_mode) ? 07007 : 07077);
362
d51d05d3
KZ
363 if ((st.st_mode & permMask) != 0)
364 warnx(_("%s: insecure permissions %04o, %04o suggested."),
365 special, st.st_mode & 07777,
88530f9f 366 ~permMask & 0666);
306c1df2
KZ
367
368 if (S_ISREG(st.st_mode) && st.st_uid != 0)
369 warnx(_("%s: insecure file owner %d, 0 (root) suggested."),
370 special, st.st_uid);
88530f9f
KZ
371 }
372
373 /* test for holes by LBT */
374 if (S_ISREG(st.st_mode)) {
375 if (st.st_blocks * 512 < st.st_size) {
d51d05d3
KZ
376 warnx(_("%s: skipping - it appears to have holes."),
377 special);
05c79b78 378 goto err;
88530f9f 379 }
e8be80dd
KZ
380 devsize = st.st_size;
381 }
382
383 fd = open(special, O_RDONLY);
384 if (fd == -1) {
d51d05d3 385 warn(_("%s: open failed"), special);
05c79b78 386 goto err;
e8be80dd
KZ
387 }
388
05c79b78
KZ
389 if (S_ISBLK(st.st_mode) && blkdev_get_size(fd, &devsize)) {
390 warn(_("%s: get size failed"), special);
391 goto err;
e8be80dd
KZ
392 }
393
394 hdr = swap_get_header(fd, &sig, &pagesize);
395 if (!hdr) {
d51d05d3 396 warn(_("%s: read swap header failed"), special);
05c79b78 397 goto err;
88530f9f
KZ
398 }
399
e8be80dd
KZ
400 if (sig == SIG_SWAPSPACE && pagesize) {
401 unsigned long long swapsize =
402 swap_get_size(hdr, special, pagesize);
24f010e8
KZ
403 int syspg = getpagesize();
404
3399a218 405 if (verbose)
e6b0611b 406 warnx(_("%s: pagesize=%d, swapsize=%llu, devsize=%llu"),
e8be80dd
KZ
407 special, pagesize, swapsize, devsize);
408
409 if (swapsize > devsize) {
410 if (verbose)
d51d05d3
KZ
411 warnx(_("%s: last_page 0x%08llx is larger"
412 " than actual size of swapspace"),
e8be80dd 413 special, swapsize);
24f010e8 414 } else if (syspg < 0 || (unsigned) syspg != pagesize) {
0d761944 415 if (fixpgsz) {
b5b2c388
KZ
416 char *label = NULL, *uuid = NULL;
417 int rc;
418
419 swap_get_info(hdr, &label, &uuid);
420
93bfcc94 421 warnx(_("%s: swap format pagesize does not match."),
0d761944 422 special);
b5b2c388
KZ
423 rc = swap_reinitialize(special, label, uuid);
424 free(label);
425 free(uuid);
426 if (rc < 0)
0d761944
KZ
427 goto err;
428 } else
93bfcc94
KZ
429 warnx(_("%s: swap format pagesize does not match. "
430 "(Use --fixpgsz to reinitialize it.)"),
0d761944 431 special);
e8be80dd
KZ
432 }
433 } else if (sig == SIG_SWSUSPEND) {
434 /* We have to reinitialize swap with old (=useless) software suspend
435 * data. The problem is that if we don't do it, then we get data
436 * corruption the next time an attempt at unsuspending is made.
437 */
d51d05d3 438 warnx(_("%s: software suspend data detected. "
617d8a3b 439 "Rewriting the swap signature."),
d51d05d3 440 special);
617d8a3b 441 if (swap_rewrite_signature(special, pagesize) < 0)
05c79b78 442 goto err;
6274b987
KC
443 }
444
05c79b78
KZ
445 free(hdr);
446 close(fd);
447 return 0;
05c79b78
KZ
448err:
449 if (fd != -1)
450 close(fd);
451 free(hdr);
452 return -1;
453}
63cccae4 454
05c79b78 455static int
c2301380 456do_swapon(const char *orig_special, int prio, int fl_discard, int canonic) {
05c79b78
KZ
457 int status;
458 const char *special = orig_special;
459 int flags = 0;
63cccae4 460
05c79b78
KZ
461 if (verbose)
462 printf(_("%s on %s\n"), progname, orig_special);
463
464 if (!canonic) {
e5157fc9 465 special = mnt_resolve_spec(orig_special, mntcache);
05c79b78
KZ
466 if (!special)
467 return cannot_find(orig_special);
63cccae4 468 }
ffa63a3d 469
05c79b78
KZ
470 if (swapon_checks(special))
471 return -1;
472
473#ifdef SWAP_FLAG_PREFER
474 if (prio >= 0) {
475 if (prio > SWAP_FLAG_PRIO_MASK)
476 prio = SWAP_FLAG_PRIO_MASK;
477 flags = SWAP_FLAG_PREFER
478 | ((prio & SWAP_FLAG_PRIO_MASK)
479 << SWAP_FLAG_PRIO_SHIFT);
480 }
481#endif
c2301380
HD
482 if (fl_discard)
483 flags |= SWAP_FLAG_DISCARD;
484
05c79b78 485 status = swapon(special, flags);
d51d05d3
KZ
486 if (status < 0)
487 warn(_("%s: swapon failed"), orig_special);
63cccae4
KZ
488
489 return status;
490}
491
756bfd01 492static int
c2301380 493swapon_by_label(const char *label, int prio, int dsc) {
e5157fc9 494 const char *special = mnt_resolve_tag("LABEL", label, mntcache);
c2301380
HD
495 return special ? do_swapon(special, prio, dsc, CANONIC) :
496 cannot_find(label);
756bfd01
KZ
497}
498
499static int
c2301380 500swapon_by_uuid(const char *uuid, int prio, int dsc) {
e5157fc9 501 const char *special = mnt_resolve_tag("UUID", uuid, mntcache);
c2301380
HD
502 return special ? do_swapon(special, prio, dsc, CANONIC) :
503 cannot_find(uuid);
756bfd01
KZ
504}
505
756bfd01
KZ
506static int
507swapon_all(void) {
5072b90a
KZ
508 struct libmnt_table *tb = get_fstab();
509 struct libmnt_iter *itr;
510 struct libmnt_fs *fs;
63cccae4 511 int status = 0;
63cccae4 512
5072b90a
KZ
513 if (!tb)
514 err(2, _("failed to parse %s"), mnt_get_fstab_path());
756bfd01 515
5072b90a
KZ
516 itr = mnt_new_iter(MNT_ITER_FORWARD);
517 if (!itr)
518 err(EXIT_FAILURE, _("failed to initialize libmount iterator"));
756bfd01 519
5072b90a
KZ
520 while (mnt_table_find_next_fs(tb, itr, match_swap, NULL, &fs) == 0) {
521 /* defaults */
522 int pri = priority, dsc = discard, nofail = ifexists;
523 char *p, *src;
1b414d89 524
5072b90a 525 if (mnt_fs_get_option(fs, "noauto", NULL, NULL) == 0)
1b414d89 526 continue;
5072b90a
KZ
527 if (mnt_fs_get_option(fs, "discard", NULL, NULL) == 0)
528 dsc = 1;
529 if (mnt_fs_get_option(fs, "nofail", NULL, NULL) == 0)
530 nofail = 1;
531 if (mnt_fs_get_option(fs, "pri", &p, NULL) == 0 && p)
532 pri = atoi(p);
533
534 src = mnt_resolve_spec(mnt_fs_get_source(fs), mntcache);
535 if (!src) {
a5fd3d68 536 if (!nofail)
5072b90a 537 status |= cannot_find(mnt_fs_get_source(fs));
756bfd01 538 continue;
1b414d89 539 }
756bfd01 540
5072b90a
KZ
541 if (!is_active_swap(src) &&
542 (!nofail || !access(src, R_OK)))
543 status |= do_swapon(src, pri, dsc, CANONIC);
756bfd01 544 }
756bfd01 545
5072b90a 546 mnt_free_iter(itr);
756bfd01
KZ
547 return status;
548}
549
756bfd01
KZ
550static int
551main_swapon(int argc, char *argv[]) {
552 int status = 0;
0b0c231f
KZ
553 int c;
554 size_t i;
756bfd01 555
c2301380 556 while ((c = getopt_long(argc, argv, "ahdefp:svVL:U:",
756bfd01 557 longswaponopts, NULL)) != -1) {
63cccae4
KZ
558 switch (c) {
559 case 'a': /* all */
560 ++all;
561 break;
562 case 'h': /* help */
563 swapon_usage(stdout, 0);
564 break;
565 case 'p': /* priority */
566 priority = atoi(optarg);
567 break;
756bfd01 568 case 'L':
0b0c231f 569 add_label(optarg);
756bfd01
KZ
570 break;
571 case 'U':
0b0c231f 572 add_uuid(optarg);
756bfd01 573 break;
c2301380
HD
574 case 'd':
575 discard = 1;
576 break;
95f1bdee
KZ
577 case 'e': /* ifexists */
578 ifexists = 1;
579 break;
0d761944
KZ
580 case 'f':
581 fixpgsz = 1;
582 break;
63cccae4
KZ
583 case 's': /* status report */
584 status = display_summary();
585 exit(status);
586 case 'v': /* be chatty */
587 ++verbose;
588 break;
589 case 'V': /* version */
e6b0611b 590 printf(_("%s (%s)\n"), progname, PACKAGE_STRING);
8fdf2bf7 591 exit(EXIT_SUCCESS);
63cccae4
KZ
592 case 0:
593 break;
594 case '?':
595 default:
596 swapon_usage(stderr, 1);
597 }
598 }
599 argv += optind;
600
0b0c231f 601 if (!all && !numof_labels() && numof_uuids() && *argv == NULL)
63cccae4
KZ
602 swapon_usage(stderr, 2);
603
756bfd01
KZ
604 if (ifexists && (!all || strcmp(progname, "swapon")))
605 swapon_usage(stderr, 1);
95f1bdee 606
756bfd01
KZ
607 if (all)
608 status |= swapon_all();
63cccae4 609
0b0c231f
KZ
610 for (i = 0; i < numof_labels(); i++)
611 status |= swapon_by_label(get_label(i), priority, discard);
63cccae4 612
0b0c231f
KZ
613 for (i = 0; i < numof_uuids(); i++)
614 status |= swapon_by_uuid(get_uuid(i), priority, discard);
63cccae4
KZ
615
616 while (*argv != NULL)
c2301380 617 status |= do_swapon(*argv++, priority, discard, !CANONIC);
63cccae4
KZ
618
619 return status;
620}
621
63cccae4
KZ
622int
623main(int argc, char *argv[]) {
63cccae4 624
64b58881
KZ
625 int status;
626
63cccae4
KZ
627 setlocale(LC_ALL, "");
628 bindtextdomain(PACKAGE, LOCALEDIR);
629 textdomain(PACKAGE);
efb8854f 630 atexit(close_stdout);
63cccae4 631
d51d05d3
KZ
632 progname = program_invocation_short_name;
633 if (!progname) {
634 char *p = strrchr(argv[0], '/');
635 progname = p ? p+1 : argv[0];
636 }
63cccae4 637
64b58881 638 mnt_init_debug(0);
e5157fc9 639 mntcache = mnt_new_cache();
64b58881 640
6cf8d46c 641 status = main_swapon(argc, argv);
64b58881 642
0b0c231f 643 free_tables();
64b58881
KZ
644 mnt_free_cache(mntcache);
645 return status;
6dbe3af9 646}