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 static 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 allocate output line"));
178 data
= mnt_fs_get_source(fs
);
179 if (access(data
, R_OK
) == 0)
180 pr
= get_swap_prober(data
);
181 for (i
= 0; i
< ctl
->ncolumns
; i
++) {
185 switch (get_column_id(ctl
, i
)) {
187 xasprintf(&str
, "%s", mnt_fs_get_source(fs
));
190 xasprintf(&str
, "%s", mnt_fs_get_swaptype(fs
));
193 size
= mnt_fs_get_size(fs
);
194 size
*= 1024; /* convert to bytes */
196 xasprintf(&str
, "%jd", size
);
198 str
= size_to_human_string(SIZE_SUFFIX_1LETTER
, size
);
201 size
= mnt_fs_get_usedsize(fs
);
202 size
*= 1024; /* convert to bytes */
204 xasprintf(&str
, "%jd", size
);
206 str
= size_to_human_string(SIZE_SUFFIX_1LETTER
, size
);
209 xasprintf(&str
, "%d", mnt_fs_get_priority(fs
));
212 if (pr
&& !blkid_probe_lookup_value(pr
, "UUID", &data
, NULL
))
213 xasprintf(&str
, "%s", data
);
216 if (pr
&& !blkid_probe_lookup_value(pr
, "LABEL", &data
, NULL
))
217 xasprintf(&str
, "%s", data
);
223 if (str
&& scols_line_refer_data(line
, i
, str
))
224 err(EXIT_FAILURE
, _("failed to add output data"));
227 blkid_free_probe(pr
);
231 static int display_summary(void)
233 struct libmnt_table
*st
= get_swaps();
234 struct libmnt_iter
*itr
;
235 struct libmnt_fs
*fs
;
240 if (mnt_table_is_empty(st
))
243 itr
= mnt_new_iter(MNT_ITER_FORWARD
);
245 err(EXIT_FAILURE
, _("failed to initialize libmount iterator"));
247 printf(_("%s\t\t\t\tType\t\tSize\tUsed\tPriority\n"), _("Filename"));
249 while (mnt_table_next_fs(st
, itr
, &fs
) == 0) {
250 printf("%-39s\t%-8s\t%jd\t%jd\t%d\n",
251 mnt_fs_get_source(fs
),
252 mnt_fs_get_swaptype(fs
),
254 mnt_fs_get_usedsize(fs
),
255 mnt_fs_get_priority(fs
));
262 static int show_table(struct swapon_ctl
*ctl
)
264 struct libmnt_table
*st
= get_swaps();
265 struct libmnt_iter
*itr
= NULL
;
266 struct libmnt_fs
*fs
;
268 struct libscols_table
*table
= NULL
;
273 itr
= mnt_new_iter(MNT_ITER_FORWARD
);
275 err(EXIT_FAILURE
, _("failed to initialize libmount iterator"));
279 table
= scols_new_table();
281 err(EXIT_FAILURE
, _("failed to allocate output table"));
283 scols_table_enable_raw(table
, ctl
->raw
);
284 scols_table_enable_noheadings(table
, ctl
->no_heading
);
286 for (i
= 0; i
< ctl
->ncolumns
; i
++) {
287 struct colinfo
*col
= get_column_info(ctl
, i
);
289 if (!scols_table_new_column(table
, col
->name
, col
->whint
, col
->flags
))
290 err(EXIT_FAILURE
, _("failed to allocate output column"));
293 while (mnt_table_next_fs(st
, itr
, &fs
) == 0)
294 add_scols_line(ctl
, table
, fs
);
296 scols_print_table(table
);
297 scols_unref_table(table
);
303 static int swap_reinitialize(struct swap_device
*dev
)
313 warnx(_("%s: reinitializing the swap."), dev
->path
);
315 switch ((pid
=fork())) {
316 case -1: /* fork error */
317 warn(_("fork failed"));
321 if (geteuid() != getuid()) {
322 /* in case someone uses swapon as setuid binary */
323 if (setgid(getgid()) < 0)
325 if (setuid(getuid()) < 0)
329 cmd
[idx
++] = "mkswap";
332 cmd
[idx
++] = dev
->label
;
336 cmd
[idx
++] = dev
->uuid
;
338 cmd
[idx
++] = dev
->path
;
340 execvp(cmd
[0], (char * const *) cmd
);
341 err(EXIT_FAILURE
, _("failed to execute %s"), cmd
[0]);
343 default: /* parent */
345 ret
= waitpid(pid
, &status
, 0);
346 } while (ret
== -1 && errno
== EINTR
);
349 warn(_("waitpid failed"));
353 /* mkswap returns: 0=suss, 1=error */
354 if (WIFEXITED(status
) && WEXITSTATUS(status
)==0)
358 return -1; /* error */
361 /* Replaces unwanted SWSUSPEND signature with swap signature */
362 static int swap_rewrite_signature(const struct swap_device
*dev
)
368 assert(dev
->pagesize
);
370 fd
= open(dev
->path
, O_WRONLY
);
372 warn(_("cannot open %s"), dev
->path
);
376 if (lseek(fd
, dev
->pagesize
- SWAP_SIGNATURE_SZ
, SEEK_SET
) < 0) {
377 warn(_("%s: lseek failed"), dev
->path
);
381 if (write(fd
, (void *) SWAP_SIGNATURE
,
382 SWAP_SIGNATURE_SZ
) != SWAP_SIGNATURE_SZ
) {
383 warn(_("%s: write signature failed"), dev
->path
);
389 if (close_fd(fd
) != 0) {
390 warn(_("write failed: %s"), dev
->path
);
396 static int swap_detect_signature(const char *buf
, int *sig
)
401 if (memcmp(buf
, SWAP_SIGNATURE
, SWAP_SIGNATURE_SZ
) == 0)
402 *sig
= SIG_SWAPSPACE
;
404 else if (memcmp(buf
, "S1SUSPEND", 9) == 0 ||
405 memcmp(buf
, "S2SUSPEND", 9) == 0 ||
406 memcmp(buf
, "ULSUSPEND", 9) == 0 ||
407 memcmp(buf
, "\xed\xc3\x02\xe9\x98\x56\xe5\x0c", 8) == 0 ||
408 memcmp(buf
, "LINHIB0001", 10) == 0)
409 *sig
= SIG_SWSUSPEND
;
416 static char *swap_get_header(int fd
, int *sig
, unsigned int *pagesize
)
428 buf
= xmalloc(MAX_PAGESIZE
);
430 datasz
= read(fd
, buf
, MAX_PAGESIZE
);
431 if (datasz
== (ssize_t
) -1)
434 for (page
= 0x1000; page
<= MAX_PAGESIZE
; page
<<= 1) {
435 /* skip 32k pagesize since this does not seem to
439 /* the smallest swap area is PAGE_SIZE*10, it means
440 * 40k, that's less than MAX_PAGESIZE */
441 if (datasz
< 0 || (size_t) datasz
< (page
- SWAP_SIGNATURE_SZ
))
443 if (swap_detect_signature(buf
+ page
- SWAP_SIGNATURE_SZ
, sig
)) {
456 /* returns real size of swap space */
457 static unsigned long long swap_get_size(const struct swap_device
*dev
,
460 unsigned int last_page
= 0;
461 const unsigned int swap_version
= SWAP_VERSION
;
462 struct swap_header_v1_2
*s
;
465 assert(dev
->pagesize
> 0);
467 s
= (struct swap_header_v1_2
*) hdr
;
469 if (s
->version
== swap_version
)
470 last_page
= s
->last_page
;
471 else if (swab32(s
->version
) == swap_version
)
472 last_page
= swab32(s
->last_page
);
474 return ((unsigned long long) last_page
+ 1) * dev
->pagesize
;
477 static void swap_get_info(struct swap_device
*dev
, const char *hdr
)
479 struct swap_header_v1_2
*s
= (struct swap_header_v1_2
*) hdr
;
483 if (s
&& *s
->volume_name
)
484 dev
->label
= xstrdup(s
->volume_name
);
487 const unsigned char *u
= s
->uuid
;
490 snprintf(str
, sizeof(str
),
493 "%02x%02x-%02x%02x%02x%02x%02x%02x",
494 u
[0], u
[1], u
[2], u
[3],
495 u
[4], u
[5], u
[6], u
[7],
496 u
[8], u
[9], u
[10], u
[11], u
[12], u
[13], u
[14], u
[15]);
497 dev
->uuid
= xstrdup(str
);
501 static int swapon_checks(const struct swapon_ctl
*ctl
, struct swap_device
*dev
)
506 unsigned long long devsize
= 0;
513 fd
= open(dev
->path
, O_RDONLY
);
515 warn(_("cannot open %s"), dev
->path
);
519 if (fstat(fd
, &st
) < 0) {
520 warn(_("stat of %s failed"), dev
->path
);
524 permMask
= S_ISBLK(st
.st_mode
) ? 07007 : 07077;
525 if ((st
.st_mode
& permMask
) != 0)
526 warnx(_("%s: insecure permissions %04o, %04o suggested."),
527 dev
->path
, st
.st_mode
& 07777,
530 if (S_ISREG(st
.st_mode
) && st
.st_uid
!= 0)
531 warnx(_("%s: insecure file owner %d, 0 (root) suggested."),
532 dev
->path
, st
.st_uid
);
534 /* test for holes by LBT */
535 if (S_ISREG(st
.st_mode
)) {
536 if (st
.st_blocks
* 512 < st
.st_size
) {
537 warnx(_("%s: skipping - it appears to have holes."),
541 devsize
= st
.st_size
;
544 if (S_ISBLK(st
.st_mode
) && blkdev_get_size(fd
, &devsize
)) {
545 warnx(_("%s: get size failed"), dev
->path
);
549 hdr
= swap_get_header(fd
, &sig
, &dev
->pagesize
);
551 warnx(_("%s: read swap header failed"), dev
->path
);
556 warnx(_("%s: found signature [pagesize=%d, signature=%s]"),
559 sig
== SIG_SWAPSPACE
? "swap" :
560 sig
== SIG_SWSUSPEND
? "suspend" : "unknown");
562 if (sig
== SIG_SWAPSPACE
&& dev
->pagesize
) {
563 unsigned long long swapsize
= swap_get_size(dev
, hdr
);
564 int syspg
= getpagesize();
567 warnx(_("%s: pagesize=%d, swapsize=%llu, devsize=%llu"),
568 dev
->path
, dev
->pagesize
, swapsize
, devsize
);
570 if (swapsize
> devsize
) {
572 warnx(_("%s: last_page 0x%08llx is larger"
573 " than actual size of swapspace"),
574 dev
->path
, swapsize
);
576 } else if (syspg
< 0 || (unsigned int) syspg
!= dev
->pagesize
) {
577 if (ctl
->fix_page_size
) {
580 swap_get_info(dev
, hdr
);
582 warnx(_("%s: swap format pagesize does not match."),
584 rc
= swap_reinitialize(dev
);
588 warnx(_("%s: swap format pagesize does not match. "
589 "(Use --fixpgsz to reinitialize it.)"),
592 } else if (sig
== SIG_SWSUSPEND
) {
593 /* We have to reinitialize swap with old (=useless) software suspend
594 * data. The problem is that if we don't do it, then we get data
595 * corruption the next time an attempt at unsuspending is made.
597 warnx(_("%s: software suspend data detected. "
598 "Rewriting the swap signature."),
600 if (swap_rewrite_signature(dev
) < 0)
614 static int do_swapon(const struct swapon_ctl
*ctl
,
615 const struct swap_prop
*prop
,
619 struct swap_device dev
= { .path
= NULL
};
628 dev
.path
= mnt_resolve_spec(spec
, mntcache
);
630 return cannot_find(spec
);
634 priority
= prop
->priority
;
636 if (swapon_checks(ctl
, &dev
))
639 #ifdef SWAP_FLAG_PREFER
641 if (priority
> SWAP_FLAG_PRIO_MASK
)
642 priority
= SWAP_FLAG_PRIO_MASK
;
644 flags
= SWAP_FLAG_PREFER
645 | ((priority
& SWAP_FLAG_PRIO_MASK
)
646 << SWAP_FLAG_PRIO_SHIFT
);
650 * Validate the discard flags passed and set them
651 * accordingly before calling sys_swapon.
653 if (prop
->discard
&& !(prop
->discard
& ~SWAP_FLAGS_DISCARD_VALID
)) {
655 * If we get here with both discard policy flags set,
656 * we just need to tell the kernel to enable discards
657 * and it will do correctly, just as we expect.
659 if ((prop
->discard
& SWAP_FLAG_DISCARD_ONCE
) &&
660 (prop
->discard
& SWAP_FLAG_DISCARD_PAGES
))
661 flags
|= SWAP_FLAG_DISCARD
;
663 flags
|= prop
->discard
;
667 printf(_("swapon %s\n"), dev
.path
);
669 status
= swapon(dev
.path
, flags
);
671 warn(_("%s: swapon failed"), dev
.path
);
676 static int swapon_by_label(struct swapon_ctl
*ctl
, const char *label
)
678 char *device
= mnt_resolve_tag("LABEL", label
, mntcache
);
679 return device
? do_swapon(ctl
, &ctl
->props
, device
, TRUE
) : cannot_find(label
);
682 static int swapon_by_uuid(struct swapon_ctl
*ctl
, const char *uuid
)
684 char *device
= mnt_resolve_tag("UUID", uuid
, mntcache
);
685 return device
? do_swapon(ctl
, &ctl
->props
, device
, TRUE
) : cannot_find(uuid
);
688 /* -o <options> or fstab */
689 static int parse_options(struct swap_prop
*props
, const char *options
)
697 if (mnt_optstr_get_option(options
, "nofail", NULL
, NULL
) == 0)
700 if (mnt_optstr_get_option(options
, "discard", &arg
, &argsz
) == 0) {
701 props
->discard
|= SWAP_FLAG_DISCARD
;
704 /* only single-time discards are wanted */
705 if (strncmp(arg
, "once", argsz
) == 0)
706 props
->discard
|= SWAP_FLAG_DISCARD_ONCE
;
708 /* do discard for every released swap page */
709 if (strncmp(arg
, "pages", argsz
) == 0)
710 props
->discard
|= SWAP_FLAG_DISCARD_PAGES
;
715 if (mnt_optstr_get_option(options
, "pri", &arg
, NULL
) == 0 && arg
)
716 props
->priority
= atoi(arg
);
722 static int swapon_all(struct swapon_ctl
*ctl
)
724 struct libmnt_table
*tb
= get_fstab();
725 struct libmnt_iter
*itr
;
726 struct libmnt_fs
*fs
;
730 err(EXIT_FAILURE
, _("failed to parse %s"), mnt_get_fstab_path());
732 itr
= mnt_new_iter(MNT_ITER_FORWARD
);
734 err(EXIT_FAILURE
, _("failed to initialize libmount iterator"));
736 while (mnt_table_find_next_fs(tb
, itr
, match_swap
, NULL
, &fs
) == 0) {
740 struct swap_prop prop
; /* per device setting */
742 if (mnt_fs_get_option(fs
, "noauto", NULL
, NULL
) == 0) {
744 warnx(_("%s: noauto option -- ignored"), mnt_fs_get_source(fs
));
748 /* default setting */
751 /* overwrite default by setting from fstab */
752 opts
= mnt_fs_get_options(fs
);
754 parse_options(&prop
, opts
);
756 /* convert LABEL=, UUID= etc. from fstab to device name */
757 device
= mnt_resolve_spec(mnt_fs_get_source(fs
), mntcache
);
760 status
|= cannot_find(mnt_fs_get_source(fs
));
764 if (is_active_swap(device
)) {
766 warnx(_("%s: already active -- ignored"), device
);
770 if (prop
.no_fail
&& access(device
, R_OK
) != 0) {
772 warnx(_("%s: inaccessible -- ignored"), device
);
777 status
|= do_swapon(ctl
, &prop
, device
, TRUE
);
785 static void __attribute__ ((__noreturn__
)) usage(FILE * out
)
788 fputs(USAGE_HEADER
, out
);
789 fprintf(out
, _(" %s [options] [<spec>]\n"), program_invocation_short_name
);
791 fputs(USAGE_SEPARATOR
, out
);
792 fputs(_("Enable devices and files for paging and swapping.\n"), out
);
794 fputs(USAGE_OPTIONS
, out
);
795 fputs(_(" -a, --all enable all swaps from /etc/fstab\n"), out
);
796 fputs(_(" -d, --discard[=<policy>] enable swap discards, if supported by device\n"), out
);
797 fputs(_(" -e, --ifexists silently skip devices that do not exist\n"), out
);
798 fputs(_(" -f, --fixpgsz reinitialize the swap space if necessary\n"), out
);
799 fputs(_(" -o, --options <list> comma-separated list of swap options\n"), out
);
800 fputs(_(" -p, --priority <prio> specify the priority of the swap device\n"), out
);
801 fputs(_(" -s, --summary display summary about used swap devices (DEPRECATED)\n"), out
);
802 fputs(_(" --show[=<columns>] display summary in definable table\n"), out
);
803 fputs(_(" --noheadings don't print table heading (with --show)\n"), out
);
804 fputs(_(" --raw use the raw output format (with --show)\n"), out
);
805 fputs(_(" --bytes display swap size in bytes in --show output\n"), out
);
806 fputs(_(" -v, --verbose verbose mode\n"), out
);
808 fputs(USAGE_SEPARATOR
, out
);
809 fputs(USAGE_HELP
, out
);
810 fputs(USAGE_VERSION
, out
);
812 fputs(_("\nThe <spec> parameter:\n" \
813 " -L <label> synonym for LABEL=<label>\n"
814 " -U <uuid> synonym for UUID=<uuid>\n"
815 " LABEL=<label> specifies device by swap area label\n"
816 " UUID=<uuid> specifies device by swap area UUID\n"
817 " PARTLABEL=<label> specifies device by partition label\n"
818 " PARTUUID=<uuid> specifies device by partition UUID\n"
819 " <device> name of device to be used\n"
820 " <file> name of file to be used\n"), out
);
822 fputs(_("\nAvailable discard policy types (for --discard):\n"
823 " once : only single-time area discards are issued\n"
824 " pages : freed pages are discarded before they are reused\n"
825 "If no policy is selected, both discard types are enabled (default).\n"), out
);
827 fputs(_("\nAvailable columns (for --show):\n"), out
);
828 for (i
= 0; i
< ARRAY_SIZE(infos
); i
++)
829 fprintf(out
, " %-5s %s\n", infos
[i
].name
, _(infos
[i
].help
));
831 fprintf(out
, USAGE_MAN_TAIL("swapon(8)"));
832 exit(out
== stderr
? EXIT_FAILURE
: EXIT_SUCCESS
);
835 int main(int argc
, char *argv
[])
839 char *options
= NULL
;
842 BYTES_OPTION
= CHAR_MAX
+ 1,
848 static const struct option long_opts
[] = {
849 { "priority", required_argument
, NULL
, 'p' },
850 { "discard", optional_argument
, NULL
, 'd' },
851 { "ifexists", no_argument
, NULL
, 'e' },
852 { "options", optional_argument
, NULL
, 'o' },
853 { "summary", no_argument
, NULL
, 's' },
854 { "fixpgsz", no_argument
, NULL
, 'f' },
855 { "all", no_argument
, NULL
, 'a' },
856 { "help", no_argument
, NULL
, 'h' },
857 { "verbose", no_argument
, NULL
, 'v' },
858 { "version", no_argument
, NULL
, 'V' },
859 { "show", optional_argument
, NULL
, SHOW_OPTION
},
860 { "noheadings", no_argument
, NULL
, NOHEADINGS_OPTION
},
861 { "raw", no_argument
, NULL
, RAW_OPTION
},
862 { "bytes", no_argument
, NULL
, BYTES_OPTION
},
866 static const ul_excl_t excl
[] = { /* rows and cols in ASCII order */
867 { 'a','o','s', SHOW_OPTION
},
868 { 'a','o', BYTES_OPTION
},
869 { 'a','o', NOHEADINGS_OPTION
},
870 { 'a','o', RAW_OPTION
},
873 int excl_st
[ARRAY_SIZE(excl
)] = UL_EXCL_STATUS_INIT
;
875 struct swapon_ctl ctl
;
877 setlocale(LC_ALL
, "");
878 bindtextdomain(PACKAGE
, LOCALEDIR
);
880 atexit(close_stdout
);
882 memset(&ctl
, 0, sizeof(struct swapon_ctl
));
883 ctl
.props
.priority
= -1;
886 mntcache
= mnt_new_cache();
888 while ((c
= getopt_long(argc
, argv
, "ahd::efo:p:svVL:U:",
889 long_opts
, NULL
)) != -1) {
891 err_exclusive_options(c
, long_opts
, excl
, excl_st
);
903 case 'p': /* priority */
904 ctl
.props
.priority
= strtos16_or_err(optarg
,
905 _("failed to parse priority"));
914 ctl
.props
.discard
|= SWAP_FLAG_DISCARD
;
919 if (strcmp(optarg
, "once") == 0)
920 ctl
.props
.discard
|= SWAP_FLAG_DISCARD_ONCE
;
921 else if (strcmp(optarg
, "pages") == 0)
922 ctl
.props
.discard
|= SWAP_FLAG_DISCARD_PAGES
;
924 errx(EXIT_FAILURE
, _("unsupported discard policy: %s"), optarg
);
927 case 'e': /* ifexists */
928 ctl
.props
.no_fail
= 1;
931 ctl
.fix_page_size
= 1;
933 case 's': /* status report */
934 status
= display_summary();
936 case 'v': /* be chatty */
941 ctl
.ncolumns
= string_to_idarray(optarg
,
943 ARRAY_SIZE(ctl
.columns
),
945 if (ctl
.ncolumns
< 0)
950 case NOHEADINGS_OPTION
:
959 case 'V': /* version */
960 printf(UTIL_LINUX_VERSION
);
965 errtryhelp(EXIT_FAILURE
);
970 if (ctl
.show
|| (!ctl
.all
&& !numof_labels() && !numof_uuids() && *argv
== NULL
)) {
972 /* default columns */
973 ctl
.columns
[ctl
.ncolumns
++] = COL_PATH
;
974 ctl
.columns
[ctl
.ncolumns
++] = COL_TYPE
;
975 ctl
.columns
[ctl
.ncolumns
++] = COL_SIZE
;
976 ctl
.columns
[ctl
.ncolumns
++] = COL_USED
;
977 ctl
.columns
[ctl
.ncolumns
++] = COL_PRIO
;
979 status
= show_table(&ctl
);
983 if (ctl
.props
.no_fail
&& !ctl
.all
)
987 status
|= swapon_all(&ctl
);
990 parse_options(&ctl
.props
, options
);
992 for (i
= 0; i
< numof_labels(); i
++)
993 status
|= swapon_by_label(&ctl
, get_label(i
));
995 for (i
= 0; i
< numof_uuids(); i
++)
996 status
|= swapon_by_uuid(&ctl
, get_uuid(i
));
998 while (*argv
!= NULL
)
999 status
|= do_swapon(&ctl
, &ctl
.props
, *argv
++, FALSE
);
1002 mnt_unref_cache(mntcache
);