15 #include <libsmartcols.h>
21 #include "pathnames.h"
25 #include "closestream.h"
27 #include "swapheader.h"
28 #include "swapprober.h"
29 #include "swapon-common.h"
31 #ifdef HAVE_SYS_SWAP_H
32 # include <sys/swap.h>
35 #ifndef SWAP_FLAG_DISCARD
36 # define SWAP_FLAG_DISCARD 0x10000 /* enable discard for swap */
39 #ifndef SWAP_FLAG_DISCARD_ONCE
40 # define SWAP_FLAG_DISCARD_ONCE 0x20000 /* discard swap area at swapon-time */
43 #ifndef SWAP_FLAG_DISCARD_PAGES
44 # define SWAP_FLAG_DISCARD_PAGES 0x40000 /* discard page-clusters after use */
47 #define SWAP_FLAGS_DISCARD_VALID (SWAP_FLAG_DISCARD | SWAP_FLAG_DISCARD_ONCE | \
48 SWAP_FLAG_DISCARD_PAGES)
50 #ifndef SWAP_FLAG_PREFER
51 # define SWAP_FLAG_PREFER 0x8000 /* set if swap priority specified */
54 #ifndef SWAP_FLAG_PRIO_MASK
55 # define SWAP_FLAG_PRIO_MASK 0x7fff
58 #ifndef SWAP_FLAG_PRIO_SHIFT
59 # define SWAP_FLAG_PRIO_SHIFT 0
62 #ifndef SWAPON_HAS_TWO_ARGS
63 /* libc is insane, let's call the kernel */
64 # include <sys/syscall.h>
65 # define swapon(path, flags) syscall(SYS_swapon, path, flags)
68 #define MAX_PAGESIZE (64 * 1024)
77 const char *name
; /* header */
78 double whint
; /* width hint (N < 1 is in percent of termwidth) */
79 int flags
; /* SCOLS_FL_* */
92 struct colinfo infos
[] = {
93 [COL_PATH
] = { "NAME", 0.20, 0, N_("device file or partition path") },
94 [COL_TYPE
] = { "TYPE", 0.20, SCOLS_FL_TRUNC
, N_("type of the device")},
95 [COL_SIZE
] = { "SIZE", 0.20, SCOLS_FL_RIGHT
, N_("size of the swap area")},
96 [COL_USED
] = { "USED", 0.20, SCOLS_FL_RIGHT
, N_("bytes in use")},
97 [COL_PRIO
] = { "PRIO", 0.20, SCOLS_FL_RIGHT
, N_("swap priority")},
98 [COL_UUID
] = { "UUID", 0.20, 0, N_("swap uuid")},
99 [COL_LABEL
] = { "LABEL", 0.20, 0, N_("swap label")},
103 /* swap area properties */
105 int discard
; /* discard policy */
106 int priority
; /* non-prioritized swap by default */
107 int no_fail
; /* skip device if not exist */
110 /* device description */
112 const char *path
; /* device or file to be turned on */
113 const char *label
; /* swap label */
114 const char *uuid
; /* unique identifier */
115 unsigned int pagesize
;
120 int columns
[ARRAY_SIZE(infos
) * 2]; /* --show columns */
121 int ncolumns
; /* number of columns */
123 struct swap_prop props
; /* global settings for all devices */
126 all
:1, /* turn on all swap devices */
127 bytes
:1, /* display --show in bytes */
128 fix_page_size
:1, /* reinitialize page size */
129 no_heading
:1, /* toggle --show headers */
130 raw
:1, /* toggle --show alignment */
131 show
:1, /* display --show information */
132 verbose
:1; /* be chatty */
135 static int column_name_to_id(const char *name
, size_t namesz
)
141 for (i
= 0; i
< ARRAY_SIZE(infos
); i
++) {
142 const char *cn
= infos
[i
].name
;
144 if (!strncasecmp(name
, cn
, namesz
) && !*(cn
+ namesz
))
147 warnx(_("unknown column: %s"), name
);
151 static inline int get_column_id(const struct swapon_ctl
*ctl
, int num
)
153 assert(num
< ctl
->ncolumns
);
154 assert(ctl
->columns
[num
] < (int) ARRAY_SIZE(infos
));
156 return ctl
->columns
[num
];
159 static inline struct colinfo
*get_column_info(const struct swapon_ctl
*ctl
, unsigned num
)
161 return &infos
[get_column_id(ctl
, num
)];
164 static void add_scols_line(const struct swapon_ctl
*ctl
, struct libscols_table
*table
, struct libmnt_fs
*fs
)
167 struct libscols_line
*line
;
168 blkid_probe pr
= NULL
;
174 line
= scols_table_new_line(table
, NULL
);
176 err(EXIT_FAILURE
, _("failed to initialize output line"));
177 data
= mnt_fs_get_source(fs
);
178 if (access(data
, R_OK
) == 0)
179 pr
= get_swap_prober(data
);
180 for (i
= 0; i
< ctl
->ncolumns
; i
++) {
184 switch (get_column_id(ctl
, i
)) {
186 xasprintf(&str
, "%s", mnt_fs_get_source(fs
));
189 xasprintf(&str
, "%s", mnt_fs_get_swaptype(fs
));
192 size
= mnt_fs_get_size(fs
);
193 size
*= 1024; /* convert to bytes */
195 xasprintf(&str
, "%jd", size
);
197 str
= size_to_human_string(SIZE_SUFFIX_1LETTER
, size
);
200 size
= mnt_fs_get_usedsize(fs
);
201 size
*= 1024; /* convert to bytes */
203 xasprintf(&str
, "%jd", size
);
205 str
= size_to_human_string(SIZE_SUFFIX_1LETTER
, size
);
208 xasprintf(&str
, "%d", mnt_fs_get_priority(fs
));
211 if (pr
&& !blkid_probe_lookup_value(pr
, "UUID", &data
, NULL
))
212 xasprintf(&str
, "%s", data
);
215 if (pr
&& !blkid_probe_lookup_value(pr
, "LABEL", &data
, NULL
))
216 xasprintf(&str
, "%s", data
);
223 scols_line_refer_data(line
, i
, str
);
226 blkid_free_probe(pr
);
230 static int display_summary(void)
232 struct libmnt_table
*st
= get_swaps();
233 struct libmnt_iter
*itr
;
234 struct libmnt_fs
*fs
;
239 if (mnt_table_is_empty(st
))
242 itr
= mnt_new_iter(MNT_ITER_FORWARD
);
244 err(EXIT_FAILURE
, _("failed to initialize libmount iterator"));
246 printf(_("%s\t\t\t\tType\t\tSize\tUsed\tPriority\n"), _("Filename"));
248 while (mnt_table_next_fs(st
, itr
, &fs
) == 0) {
249 printf("%-39s\t%-8s\t%jd\t%jd\t%d\n",
250 mnt_fs_get_source(fs
),
251 mnt_fs_get_swaptype(fs
),
253 mnt_fs_get_usedsize(fs
),
254 mnt_fs_get_priority(fs
));
261 static int show_table(struct swapon_ctl
*ctl
)
263 struct libmnt_table
*st
= get_swaps();
264 struct libmnt_iter
*itr
= NULL
;
265 struct libmnt_fs
*fs
;
267 struct libscols_table
*table
= NULL
;
272 itr
= mnt_new_iter(MNT_ITER_FORWARD
);
274 err(EXIT_FAILURE
, _("failed to initialize libmount iterator"));
278 table
= scols_new_table();
280 err(EXIT_FAILURE
, _("failed to initialize output table"));
282 scols_table_enable_raw(table
, ctl
->raw
);
283 scols_table_enable_noheadings(table
, ctl
->no_heading
);
285 for (i
= 0; i
< ctl
->ncolumns
; i
++) {
286 struct colinfo
*col
= get_column_info(ctl
, i
);
288 if (!scols_table_new_column(table
, col
->name
, col
->whint
, col
->flags
))
289 err(EXIT_FAILURE
, _("failed to initialize output column"));
292 while (mnt_table_next_fs(st
, itr
, &fs
) == 0)
293 add_scols_line(ctl
, table
, fs
);
295 scols_print_table(table
);
296 scols_unref_table(table
);
302 static int swap_reinitialize(struct swap_device
*dev
)
312 warnx(_("%s: reinitializing the swap."), dev
->path
);
314 switch ((pid
=fork())) {
315 case -1: /* fork error */
316 warn(_("fork failed"));
320 if (geteuid() != getuid()) {
321 /* in case someone uses swapon as setuid binary */
322 if (setgid(getgid()) < 0)
324 if (setuid(getuid()) < 0)
328 cmd
[idx
++] = "mkswap";
331 cmd
[idx
++] = dev
->label
;
335 cmd
[idx
++] = dev
->uuid
;
337 cmd
[idx
++] = dev
->path
;
339 execvp(cmd
[0], (char * const *) cmd
);
340 err(EXIT_FAILURE
, _("failed to execute %s"), cmd
[0]);
342 default: /* parent */
344 ret
= waitpid(pid
, &status
, 0);
345 } while (ret
== -1 && errno
== EINTR
);
348 warn(_("waitpid failed"));
352 /* mkswap returns: 0=suss, 1=error */
353 if (WIFEXITED(status
) && WEXITSTATUS(status
)==0)
357 return -1; /* error */
360 /* Replaces unwanted SWSUSPEND signature with swap signature */
361 static int swap_rewrite_signature(const struct swap_device
*dev
)
367 assert(dev
->pagesize
);
369 fd
= open(dev
->path
, O_WRONLY
);
371 warn(_("cannot open %s"), dev
->path
);
375 if (lseek(fd
, dev
->pagesize
- SWAP_SIGNATURE_SZ
, SEEK_SET
) < 0) {
376 warn(_("%s: lseek failed"), dev
->path
);
380 if (write(fd
, (void *) SWAP_SIGNATURE
,
381 SWAP_SIGNATURE_SZ
) != SWAP_SIGNATURE_SZ
) {
382 warn(_("%s: write signature failed"), dev
->path
);
388 if (close_fd(fd
) != 0) {
389 warn(_("write failed: %s"), dev
->path
);
395 static int swap_detect_signature(const char *buf
, int *sig
)
400 if (memcmp(buf
, SWAP_SIGNATURE
, SWAP_SIGNATURE_SZ
) == 0)
401 *sig
= SIG_SWAPSPACE
;
403 else if (memcmp(buf
, "S1SUSPEND", 9) == 0 ||
404 memcmp(buf
, "S2SUSPEND", 9) == 0 ||
405 memcmp(buf
, "ULSUSPEND", 9) == 0 ||
406 memcmp(buf
, "\xed\xc3\x02\xe9\x98\x56\xe5\x0c", 8) == 0 ||
407 memcmp(buf
, "LINHIB0001", 10) == 0)
408 *sig
= SIG_SWSUSPEND
;
415 static char *swap_get_header(int fd
, int *sig
, unsigned int *pagesize
)
427 buf
= xmalloc(MAX_PAGESIZE
);
429 datasz
= read(fd
, buf
, MAX_PAGESIZE
);
430 if (datasz
== (ssize_t
) -1)
433 for (page
= 0x1000; page
<= MAX_PAGESIZE
; page
<<= 1) {
434 /* skip 32k pagesize since this does not seem to
438 /* the smallest swap area is PAGE_SIZE*10, it means
439 * 40k, that's less than MAX_PAGESIZE */
440 if (datasz
< 0 || (size_t) datasz
< (page
- SWAP_SIGNATURE_SZ
))
442 if (swap_detect_signature(buf
+ page
- SWAP_SIGNATURE_SZ
, sig
)) {
455 /* returns real size of swap space */
456 static unsigned long long swap_get_size(const struct swap_device
*dev
,
459 unsigned int last_page
= 0;
460 const unsigned int swap_version
= SWAP_VERSION
;
461 struct swap_header_v1_2
*s
;
464 assert(dev
->pagesize
> 0);
466 s
= (struct swap_header_v1_2
*) hdr
;
468 if (s
->version
== swap_version
)
469 last_page
= s
->last_page
;
470 else if (swab32(s
->version
) == swap_version
)
471 last_page
= swab32(s
->last_page
);
473 return ((unsigned long long) last_page
+ 1) * dev
->pagesize
;
476 static void swap_get_info(struct swap_device
*dev
, const char *hdr
)
478 struct swap_header_v1_2
*s
= (struct swap_header_v1_2
*) hdr
;
482 if (s
&& *s
->volume_name
)
483 dev
->label
= xstrdup(s
->volume_name
);
486 const unsigned char *u
= s
->uuid
;
489 snprintf(str
, sizeof(str
),
492 "%02x%02x-%02x%02x%02x%02x%02x%02x",
493 u
[0], u
[1], u
[2], u
[3],
494 u
[4], u
[5], u
[6], u
[7],
495 u
[8], u
[9], u
[10], u
[11], u
[12], u
[13], u
[14], u
[15]);
496 dev
->uuid
= xstrdup(str
);
500 static int swapon_checks(const struct swapon_ctl
*ctl
, struct swap_device
*dev
)
505 unsigned long long devsize
= 0;
512 fd
= open(dev
->path
, O_RDONLY
);
514 warn(_("cannot open %s"), dev
->path
);
518 if (fstat(fd
, &st
) < 0) {
519 warn(_("stat of %s failed"), dev
->path
);
523 permMask
= S_ISBLK(st
.st_mode
) ? 07007 : 07077;
524 if ((st
.st_mode
& permMask
) != 0)
525 warnx(_("%s: insecure permissions %04o, %04o suggested."),
526 dev
->path
, st
.st_mode
& 07777,
529 if (S_ISREG(st
.st_mode
) && st
.st_uid
!= 0)
530 warnx(_("%s: insecure file owner %d, 0 (root) suggested."),
531 dev
->path
, st
.st_uid
);
533 /* test for holes by LBT */
534 if (S_ISREG(st
.st_mode
)) {
535 if (st
.st_blocks
* 512 < st
.st_size
) {
536 warnx(_("%s: skipping - it appears to have holes."),
540 devsize
= st
.st_size
;
543 if (S_ISBLK(st
.st_mode
) && blkdev_get_size(fd
, &devsize
)) {
544 warnx(_("%s: get size failed"), dev
->path
);
548 hdr
= swap_get_header(fd
, &sig
, &dev
->pagesize
);
550 warnx(_("%s: read swap header failed"), dev
->path
);
555 warnx(_("%s: found signature [pagesize=%d, signature=%s]"),
558 sig
== SIG_SWAPSPACE
? "swap" :
559 sig
== SIG_SWSUSPEND
? "suspend" : "unknown");
561 if (sig
== SIG_SWAPSPACE
&& dev
->pagesize
) {
562 unsigned long long swapsize
= swap_get_size(dev
, hdr
);
563 int syspg
= getpagesize();
566 warnx(_("%s: pagesize=%d, swapsize=%llu, devsize=%llu"),
567 dev
->path
, dev
->pagesize
, swapsize
, devsize
);
569 if (swapsize
> devsize
) {
571 warnx(_("%s: last_page 0x%08llx is larger"
572 " than actual size of swapspace"),
573 dev
->path
, swapsize
);
575 } else if (syspg
< 0 || (unsigned int) syspg
!= dev
->pagesize
) {
576 if (ctl
->fix_page_size
) {
579 swap_get_info(dev
, hdr
);
581 warnx(_("%s: swap format pagesize does not match."),
583 rc
= swap_reinitialize(dev
);
587 warnx(_("%s: swap format pagesize does not match. "
588 "(Use --fixpgsz to reinitialize it.)"),
591 } else if (sig
== SIG_SWSUSPEND
) {
592 /* We have to reinitialize swap with old (=useless) software suspend
593 * data. The problem is that if we don't do it, then we get data
594 * corruption the next time an attempt at unsuspending is made.
596 warnx(_("%s: software suspend data detected. "
597 "Rewriting the swap signature."),
599 if (swap_rewrite_signature(dev
) < 0)
613 static int do_swapon(const struct swapon_ctl
*ctl
,
614 const struct swap_prop
*prop
,
618 struct swap_device dev
= { .path
= NULL
};
627 dev
.path
= mnt_resolve_spec(spec
, mntcache
);
629 return cannot_find(spec
);
633 priority
= prop
->priority
;
635 if (swapon_checks(ctl
, &dev
))
638 #ifdef SWAP_FLAG_PREFER
640 if (priority
> SWAP_FLAG_PRIO_MASK
)
641 priority
= SWAP_FLAG_PRIO_MASK
;
643 flags
= SWAP_FLAG_PREFER
644 | ((priority
& SWAP_FLAG_PRIO_MASK
)
645 << SWAP_FLAG_PRIO_SHIFT
);
649 * Validate the discard flags passed and set them
650 * accordingly before calling sys_swapon.
652 if (prop
->discard
&& !(prop
->discard
& ~SWAP_FLAGS_DISCARD_VALID
)) {
654 * If we get here with both discard policy flags set,
655 * we just need to tell the kernel to enable discards
656 * and it will do correctly, just as we expect.
658 if ((prop
->discard
& SWAP_FLAG_DISCARD_ONCE
) &&
659 (prop
->discard
& SWAP_FLAG_DISCARD_PAGES
))
660 flags
|= SWAP_FLAG_DISCARD
;
662 flags
|= prop
->discard
;
666 printf(_("swapon %s\n"), dev
.path
);
668 status
= swapon(dev
.path
, flags
);
670 warn(_("%s: swapon failed"), dev
.path
);
675 static int swapon_by_label(struct swapon_ctl
*ctl
, const char *label
)
677 char *device
= mnt_resolve_tag("LABEL", label
, mntcache
);
678 return device
? do_swapon(ctl
, &ctl
->props
, device
, TRUE
) : cannot_find(label
);
681 static int swapon_by_uuid(struct swapon_ctl
*ctl
, const char *uuid
)
683 char *device
= mnt_resolve_tag("UUID", uuid
, mntcache
);
684 return device
? do_swapon(ctl
, &ctl
->props
, device
, TRUE
) : cannot_find(uuid
);
687 /* -o <options> or fstab */
688 static int parse_options(struct swap_prop
*props
, const char *options
)
695 if (mnt_optstr_get_option(options
, "nofail", NULL
, 0) == 0)
698 if (mnt_optstr_get_option(options
, "discard", &arg
, NULL
) == 0) {
699 props
->discard
|= SWAP_FLAG_DISCARD
;
702 /* only single-time discards are wanted */
703 if (strcmp(arg
, "once") == 0)
704 props
->discard
|= SWAP_FLAG_DISCARD_ONCE
;
706 /* do discard for every released swap page */
707 if (strcmp(arg
, "pages") == 0)
708 props
->discard
|= SWAP_FLAG_DISCARD_PAGES
;
713 if (mnt_optstr_get_option(options
, "pri", &arg
, NULL
) == 0 && arg
)
714 props
->priority
= atoi(arg
);
720 static int swapon_all(struct swapon_ctl
*ctl
)
722 struct libmnt_table
*tb
= get_fstab();
723 struct libmnt_iter
*itr
;
724 struct libmnt_fs
*fs
;
728 err(EXIT_FAILURE
, _("failed to parse %s"), mnt_get_fstab_path());
730 itr
= mnt_new_iter(MNT_ITER_FORWARD
);
732 err(EXIT_FAILURE
, _("failed to initialize libmount iterator"));
734 while (mnt_table_find_next_fs(tb
, itr
, match_swap
, NULL
, &fs
) == 0) {
738 struct swap_prop prop
; /* per device setting */
740 if (mnt_fs_get_option(fs
, "noauto", NULL
, NULL
) == 0) {
742 warnx(_("%s: noauto option -- ignored"), mnt_fs_get_source(fs
));
746 /* default setting */
749 /* overwrite default by setting from fstab */
750 opts
= mnt_fs_get_options(fs
);
752 parse_options(&prop
, opts
);
754 /* convert LABEL=, UUID= etc. from fstab to device name */
755 device
= mnt_resolve_spec(mnt_fs_get_source(fs
), mntcache
);
758 status
|= cannot_find(mnt_fs_get_source(fs
));
762 if (is_active_swap(device
)) {
764 warnx(_("%s: already active -- ignored"), device
);
768 if (prop
.no_fail
&& access(device
, R_OK
) != 0) {
770 warnx(_("%s: unaccessible -- ignored"), device
);
775 status
|= do_swapon(ctl
, &prop
, device
, TRUE
);
783 static void __attribute__ ((__noreturn__
)) usage(FILE * out
)
786 fputs(USAGE_HEADER
, out
);
787 fprintf(out
, _(" %s [options] [<spec>]\n"), program_invocation_short_name
);
789 fputs(USAGE_SEPARATOR
, out
);
790 fputs(_("Enable devices and files for paging and swapping.\n"), out
);
792 fputs(USAGE_OPTIONS
, out
);
793 fputs(_(" -a, --all enable all swaps from /etc/fstab\n"), out
);
794 fputs(_(" -d, --discard[=<policy>] enable swap discards, if supported by device\n"), out
);
795 fputs(_(" -e, --ifexists silently skip devices that do not exist\n"), out
);
796 fputs(_(" -f, --fixpgsz reinitialize the swap space if necessary\n"), out
);
797 fputs(_(" -o, --options <list> comma-separated list of swap options\n"), out
);
798 fputs(_(" -p, --priority <prio> specify the priority of the swap device\n"), out
);
799 fputs(_(" -s, --summary display summary about used swap devices (DEPRECATED)\n"), out
);
800 fputs(_(" --show[=<columns>] display summary in definable table\n"), out
);
801 fputs(_(" --noheadings don't print table heading (with --show)\n"), out
);
802 fputs(_(" --raw use the raw output format (with --show)\n"), out
);
803 fputs(_(" --bytes display swap size in bytes in --show output\n"), out
);
804 fputs(_(" -v, --verbose verbose mode\n"), out
);
806 fputs(USAGE_SEPARATOR
, out
);
807 fputs(USAGE_HELP
, out
);
808 fputs(USAGE_VERSION
, out
);
810 fputs(_("\nThe <spec> parameter:\n" \
811 " -L <label> synonym for LABEL=<label>\n"
812 " -U <uuid> synonym for UUID=<uuid>\n"
813 " LABEL=<label> specifies device by swap area label\n"
814 " UUID=<uuid> specifies device by swap area UUID\n"
815 " PARTLABEL=<label> specifies device by partition label\n"
816 " PARTUUID=<uuid> specifies device by partition UUID\n"
817 " <device> name of device to be used\n"
818 " <file> name of file to be used\n"), out
);
820 fputs(_("\nAvailable discard policy types (for --discard):\n"
821 " once : only single-time area discards are issued\n"
822 " pages : freed pages are discarded before they are reused\n"
823 "If no policy is selected, both discard types are enabled (default).\n"), out
);
825 fputs(_("\nAvailable columns (for --show):\n"), out
);
826 for (i
= 0; i
< ARRAY_SIZE(infos
); i
++)
827 fprintf(out
, " %-5s %s\n", infos
[i
].name
, _(infos
[i
].help
));
829 fprintf(out
, USAGE_MAN_TAIL("swapon(8)"));
830 exit(out
== stderr
? EXIT_FAILURE
: EXIT_SUCCESS
);
833 int main(int argc
, char *argv
[])
837 char *options
= NULL
;
840 BYTES_OPTION
= CHAR_MAX
+ 1,
846 static const struct option long_opts
[] = {
847 { "priority", 1, 0, 'p' },
848 { "discard", 2, 0, 'd' },
849 { "ifexists", 0, 0, 'e' },
850 { "options", 2, 0, 'o' },
851 { "summary", 0, 0, 's' },
852 { "fixpgsz", 0, 0, 'f' },
853 { "all", 0, 0, 'a' },
854 { "help", 0, 0, 'h' },
855 { "verbose", 0, 0, 'v' },
856 { "version", 0, 0, 'V' },
857 { "show", 2, 0, SHOW_OPTION
},
858 { "noheadings", 0, 0, NOHEADINGS_OPTION
},
859 { "raw", 0, 0, RAW_OPTION
},
860 { "bytes", 0, 0, BYTES_OPTION
},
864 static const ul_excl_t excl
[] = { /* rows and cols in in ASCII order */
865 { 'a','o','s', SHOW_OPTION
},
866 { 'a','o', BYTES_OPTION
},
867 { 'a','o', NOHEADINGS_OPTION
},
868 { 'a','o', RAW_OPTION
},
871 int excl_st
[ARRAY_SIZE(excl
)] = UL_EXCL_STATUS_INIT
;
873 struct swapon_ctl ctl
;
875 setlocale(LC_ALL
, "");
876 bindtextdomain(PACKAGE
, LOCALEDIR
);
878 atexit(close_stdout
);
880 memset(&ctl
, 0, sizeof(struct swapon_ctl
));
881 ctl
.props
.priority
= -1;
884 mntcache
= mnt_new_cache();
886 while ((c
= getopt_long(argc
, argv
, "ahd::efo:p:svVL:U:",
887 long_opts
, NULL
)) != -1) {
889 err_exclusive_options(c
, long_opts
, excl
, excl_st
);
901 case 'p': /* priority */
902 ctl
.props
.priority
= strtos16_or_err(optarg
,
903 _("failed to parse priority"));
912 ctl
.props
.discard
|= SWAP_FLAG_DISCARD
;
917 if (strcmp(optarg
, "once") == 0)
918 ctl
.props
.discard
|= SWAP_FLAG_DISCARD_ONCE
;
919 else if (strcmp(optarg
, "pages") == 0)
920 ctl
.props
.discard
|= SWAP_FLAG_DISCARD_PAGES
;
922 errx(EXIT_FAILURE
, _("unsupported discard policy: %s"), optarg
);
925 case 'e': /* ifexists */
926 ctl
.props
.no_fail
= 1;
929 ctl
.fix_page_size
= 1;
931 case 's': /* status report */
932 status
= display_summary();
934 case 'v': /* be chatty */
939 ctl
.ncolumns
= string_to_idarray(optarg
,
941 ARRAY_SIZE(ctl
.columns
),
943 if (ctl
.ncolumns
< 0)
948 case NOHEADINGS_OPTION
:
957 case 'V': /* version */
958 printf(UTIL_LINUX_VERSION
);
969 if (ctl
.show
|| (!ctl
.all
&& !numof_labels() && !numof_uuids() && *argv
== NULL
)) {
971 /* default columns */
972 ctl
.columns
[ctl
.ncolumns
++] = COL_PATH
;
973 ctl
.columns
[ctl
.ncolumns
++] = COL_TYPE
;
974 ctl
.columns
[ctl
.ncolumns
++] = COL_SIZE
;
975 ctl
.columns
[ctl
.ncolumns
++] = COL_USED
;
976 ctl
.columns
[ctl
.ncolumns
++] = COL_PRIO
;
978 status
= show_table(&ctl
);
982 if (ctl
.props
.no_fail
&& !ctl
.all
)
986 status
|= swapon_all(&ctl
);
989 parse_options(&ctl
.props
, options
);
991 for (i
= 0; i
< numof_labels(); i
++)
992 status
|= swapon_by_label(&ctl
, get_label(i
));
994 for (i
= 0; i
< numof_uuids(); i
++)
995 status
|= swapon_by_uuid(&ctl
, get_uuid(i
));
997 while (*argv
!= NULL
)
998 status
|= do_swapon(&ctl
, &ctl
.props
, *argv
++, FALSE
);
1001 mnt_unref_cache(mntcache
);