]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
swapon: add control struct
authorSami Kerola <kerolasa@iki.fi>
Tue, 2 Feb 2016 13:40:08 +0000 (13:40 +0000)
committerKarel Zak <kzak@redhat.com>
Thu, 11 Feb 2016 09:52:18 +0000 (10:52 +0100)
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
sys-utils/swapon.c

index c4d15442059f63d62d93d9586367ba4df3ffb625..b677f505c1fa165b2034c27b3ee20108e2949bc9 100644 (file)
@@ -65,7 +65,6 @@
 # define swapon(path, flags) syscall(SYS_swapon, path, flags)
 #endif
 
-#define QUIET  1
 #define CANONIC        1
 
 #define MAX_PAGESIZE   (64 * 1024)
@@ -75,15 +74,6 @@ enum {
        SIG_SWSUSPEND
 };
 
-static int all;
-static int priority = -1;      /* non-prioritized swap by default */
-static int discard;            /* don't send swap discards by default */
-
-/* If true, don't complain if the device/file doesn't exist */
-static int ifexists;
-static int fixpgsz;
-static int verbose;
-
 /* column names */
 struct colinfo {
         const char *name; /* header */
@@ -92,10 +82,6 @@ struct colinfo {
         const char *help;
 };
 
-/* basic output flags */
-static int no_headings;
-static int raw;
-
 enum {
        COL_PATH,
        COL_TYPE,
@@ -115,8 +101,25 @@ struct colinfo infos[] = {
        [COL_LABEL]    = { "LABEL",     0.20, 0, N_("swap label")},
 };
 
-static int columns[ARRAY_SIZE(infos) * 2];
-static int ncolumns;
+/* control struct */
+struct swapon_ctl {
+       char *options;                  /* fstab-compatible option string */
+       const char *label;              /* swap label */
+       const char *uuid;               /* unique identifier */
+       int discard;                    /* discard policy */
+       int columns[ARRAY_SIZE(infos) * 2];     /* --show columns */
+       int ncolumns;                   /* number of columns */
+       int priority;                   /* non-prioritized swap by default */
+       unsigned int
+               all:1,                  /* turn on all swap devices */
+               bytes:1,                /* display --show in bytes */
+               fix_page_size:1,        /* reinitialize page size */
+               no_fail:1,              /* skip devices that do not exist */
+               no_heading:1,           /* toggle --show headers */
+               raw:1,                  /* toggle --show alignment */
+               show:1,                 /* display --show information */
+               verbose:1;              /* be chatty */
+};
 
 static int column_name_to_id(const char *name, size_t namesz)
 {
@@ -134,20 +137,20 @@ static int column_name_to_id(const char *name, size_t namesz)
        return -1;
 }
 
-static inline int get_column_id(int num)
+static inline int get_column_id(const struct swapon_ctl *ctl, int num)
 {
-       assert(num < ncolumns);
-       assert(columns[num] < (int) ARRAY_SIZE(infos));
+       assert(num < ctl->ncolumns);
+       assert(ctl->columns[num] < (int) ARRAY_SIZE(infos));
 
-       return columns[num];
+       return ctl->columns[num];
 }
 
-static inline struct colinfo *get_column_info(unsigned num)
+static inline struct colinfo *get_column_info(const struct swapon_ctl *ctl, unsigned num)
 {
-       return &infos[get_column_id(num)];
+       return &infos[get_column_id(ctl, num)];
 }
 
-static void add_scols_line(struct libscols_table *table, struct libmnt_fs *fs, int bytes)
+static void add_scols_line(const struct swapon_ctl *ctl, struct libscols_table *table, struct libmnt_fs *fs)
 {
        int i;
        struct libscols_line *line;
@@ -163,11 +166,11 @@ static void add_scols_line(struct libscols_table *table, struct libmnt_fs *fs, i
        data = mnt_fs_get_source(fs);
        if (access(data, R_OK) == 0)
                pr = get_swap_prober(data);
-       for (i = 0; i < ncolumns; i++) {
+       for (i = 0; i < ctl->ncolumns; i++) {
                char *str = NULL;
                off_t size;
 
-               switch (get_column_id(i)) {
+               switch (get_column_id(ctl, i)) {
                case COL_PATH:
                        xasprintf(&str, "%s", mnt_fs_get_source(fs));
                        break;
@@ -177,7 +180,7 @@ static void add_scols_line(struct libscols_table *table, struct libmnt_fs *fs, i
                case COL_SIZE:
                        size = mnt_fs_get_size(fs);
                        size *= 1024;   /* convert to bytes */
-                       if (bytes)
+                       if (ctl->bytes)
                                xasprintf(&str, "%jd", size);
                        else
                                str = size_to_human_string(SIZE_SUFFIX_1LETTER, size);
@@ -185,7 +188,7 @@ static void add_scols_line(struct libscols_table *table, struct libmnt_fs *fs, i
                case COL_USED:
                        size = mnt_fs_get_usedsize(fs);
                        size *= 1024;   /* convert to bytes */
-                       if (bytes)
+                       if (ctl->bytes)
                                xasprintf(&str, "%jd", size);
                        else
                                str = size_to_human_string(SIZE_SUFFIX_1LETTER, size);
@@ -244,7 +247,7 @@ static int display_summary(void)
        return 0;
 }
 
-static int show_table(int bytes)
+static int show_table(struct swapon_ctl *ctl)
 {
        struct libmnt_table *st = get_swaps();
        struct libmnt_iter *itr = NULL;
@@ -265,18 +268,18 @@ static int show_table(int bytes)
        if (!table)
                err(EXIT_FAILURE, _("failed to initialize output table"));
 
-       scols_table_enable_raw(table, raw);
-       scols_table_enable_noheadings(table, no_headings);
+       scols_table_enable_raw(table, ctl->raw);
+       scols_table_enable_noheadings(table, ctl->no_heading);
 
-       for (i = 0; i < ncolumns; i++) {
-               struct colinfo *col = get_column_info(i);
+       for (i = 0; i < ctl->ncolumns; i++) {
+               struct colinfo *col = get_column_info(ctl, i);
 
                if (!scols_table_new_column(table, col->name, col->whint, col->flags))
                        err(EXIT_FAILURE, _("failed to initialize output column"));
        }
 
        while (mnt_table_next_fs(st, itr, &fs) == 0)
-               add_scols_line(table, fs, bytes);
+               add_scols_line(ctl, table, fs);
 
        scols_print_table(table);
        scols_unref_table(table);
@@ -418,7 +421,8 @@ err:
 }
 
 /* returns real size of swap space */
-static unsigned long long swap_get_size(const char *hdr, const char *devname,
+static unsigned long long swap_get_size(const struct swapon_ctl *ctl,
+                                       const char *hdr, const char *devname,
                                        unsigned int pagesize)
 {
        unsigned int last_page = 0;
@@ -433,7 +437,7 @@ static unsigned long long swap_get_size(const char *hdr, const char *devname,
                flip = 1;
                last_page = swab32(s->last_page);
        }
-       if (verbose)
+       if (ctl->verbose)
                warnx(_("%s: found swap signature: version %ud, "
                        "page-size %d, %s byte order"),
                        devname,
@@ -444,14 +448,14 @@ static unsigned long long swap_get_size(const char *hdr, const char *devname,
        return ((unsigned long long) last_page + 1) * pagesize;
 }
 
-static void swap_get_info(const char *hdr, char **label, char **uuid)
+static void swap_get_info(struct swapon_ctl *ctl, const char *hdr)
 {
        struct swap_header_v1_2 *s = (struct swap_header_v1_2 *) hdr;
 
-       if (s && *s->volume_name && label)
-               *label = xstrdup(s->volume_name);
+       if (s && *s->volume_name && ctl->label)
+               ctl->label = xstrdup(s->volume_name);
 
-       if (s && *s->uuid && uuid) {
+       if (s && *s->uuid && ctl->uuid) {
                const unsigned char *u = s->uuid;
                char str[37];
 
@@ -462,11 +466,11 @@ static void swap_get_info(const char *hdr, char **label, char **uuid)
                        u[0], u[1], u[2], u[3],
                        u[4], u[5], u[6], u[7],
                        u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15]);
-               *uuid = xstrdup(str);
+               ctl->uuid = xstrdup(str);
        }
 }
 
-static int swapon_checks(const char *special)
+static int swapon_checks(struct swapon_ctl *ctl, const char *special)
 {
        struct stat st;
        int fd = -1, sig;
@@ -519,24 +523,24 @@ static int swapon_checks(const char *special)
 
        if (sig == SIG_SWAPSPACE && pagesize) {
                unsigned long long swapsize =
-                               swap_get_size(hdr, special, pagesize);
+                               swap_get_size(ctl, hdr, special, pagesize);
                int syspg = getpagesize();
 
-               if (verbose)
+               if (ctl->verbose)
                        warnx(_("%s: pagesize=%d, swapsize=%llu, devsize=%llu"),
                                special, pagesize, swapsize, devsize);
 
                if (swapsize > devsize) {
-                       if (verbose)
+                       if (ctl->verbose)
                                warnx(_("%s: last_page 0x%08llx is larger"
                                        " than actual size of swapspace"),
                                        special, swapsize);
                } else if (syspg < 0 || (unsigned) syspg != pagesize) {
-                       if (fixpgsz) {
+                       if (ctl->fix_page_size) {
                                char *label = NULL, *uuid = NULL;
                                int rc;
 
-                               swap_get_info(hdr, &label, &uuid);
+                               swap_get_info(ctl, hdr);
 
                                warnx(_("%s: swap format pagesize does not match."),
                                        special);
@@ -572,14 +576,14 @@ err:
        return -1;
 }
 
-static int do_swapon(const char *orig_special, int prio,
-                    int fl_discard, int canonic)
+static int do_swapon(struct swapon_ctl *ctl, const char *orig_special,
+                    int canonic)
 {
        int status;
        const char *special = orig_special;
        int flags = 0;
 
-       if (verbose)
+       if (ctl->verbose)
                printf(_("swapon %s\n"), orig_special);
 
        if (!canonic) {
@@ -588,15 +592,15 @@ static int do_swapon(const char *orig_special, int prio,
                        return cannot_find(orig_special);
        }
 
-       if (swapon_checks(special))
+       if (swapon_checks(ctl, special))
                return -1;
 
 #ifdef SWAP_FLAG_PREFER
-       if (prio >= 0) {
-               if (prio > SWAP_FLAG_PRIO_MASK)
-                       prio = SWAP_FLAG_PRIO_MASK;
+       if (ctl->priority >= 0) {
+               if (ctl->priority > SWAP_FLAG_PRIO_MASK)
+                       ctl->priority = SWAP_FLAG_PRIO_MASK;
                flags = SWAP_FLAG_PREFER
-                       | ((prio & SWAP_FLAG_PRIO_MASK)
+                       | ((ctl->priority & SWAP_FLAG_PRIO_MASK)
                           << SWAP_FLAG_PRIO_SHIFT);
        }
 #endif
@@ -604,17 +608,17 @@ static int do_swapon(const char *orig_special, int prio,
         * Validate the discard flags passed and set them
         * accordingly before calling sys_swapon.
         */
-       if (fl_discard && !(fl_discard & ~SWAP_FLAGS_DISCARD_VALID)) {
+       if (ctl->discard && !(ctl->discard & ~SWAP_FLAGS_DISCARD_VALID)) {
                /*
                 * If we get here with both discard policy flags set,
                 * we just need to tell the kernel to enable discards
                 * and it will do correctly, just as we expect.
                 */
-               if ((fl_discard & SWAP_FLAG_DISCARD_ONCE) &&
-                   (fl_discard & SWAP_FLAG_DISCARD_PAGES))
+               if ((ctl->discard & SWAP_FLAG_DISCARD_ONCE) &&
+                   (ctl->discard & SWAP_FLAG_DISCARD_PAGES))
                        flags |= SWAP_FLAG_DISCARD;
                else
-                       flags |= fl_discard;
+                       flags |= ctl->discard;
        }
 
        status = swapon(special, flags);
@@ -624,57 +628,56 @@ static int do_swapon(const char *orig_special, int prio,
        return status;
 }
 
-static int swapon_by_label(const char *label, int prio, int dsc)
+static int swapon_by_label(struct swapon_ctl *ctl)
 {
-       const char *special = mnt_resolve_tag("LABEL", label, mntcache);
-       return special ? do_swapon(special, prio, dsc, CANONIC) :
-                        cannot_find(label);
+       const char *special = mnt_resolve_tag("LABEL", ctl->label, mntcache);
+       return special ? do_swapon(ctl, special, CANONIC) :
+                        cannot_find(ctl->label);
 }
 
-static int swapon_by_uuid(const char *uuid, int prio, int dsc)
+static int swapon_by_uuid(struct swapon_ctl *ctl)
 {
-       const char *special = mnt_resolve_tag("UUID", uuid, mntcache);
-       return special ? do_swapon(special, prio, dsc, CANONIC) :
-                        cannot_find(uuid);
+       const char *special = mnt_resolve_tag("UUID", ctl->uuid, mntcache);
+       return special ? do_swapon(ctl, special, CANONIC) :
+                        cannot_find(ctl->uuid);
 }
 
 /* -o <options> or fstab */
-static int parse_options(const char *optstr,
-                        int *prio, int *disc, int *nofail)
+static int parse_options(struct swapon_ctl *ctl)
 {
        char *arg = NULL;
 
-       assert(optstr);
-       assert(prio);
-       assert(disc);
-       assert(nofail);
+       assert(ctl->options);
+       assert(ctl->priority);
+       assert(ctl->discard);
+       assert(ctl->no_fail);
 
-       if (mnt_optstr_get_option(optstr, "nofail", NULL, 0) == 0)
-               *nofail = 1;
+       if (mnt_optstr_get_option(ctl->options, "nofail", NULL, 0) == 0)
+               ctl->no_fail = 1;
 
-       if (mnt_optstr_get_option(optstr, "discard", &arg, NULL) == 0) {
-               *disc |= SWAP_FLAG_DISCARD;
+       if (mnt_optstr_get_option(ctl->options, "discard", &arg, NULL) == 0) {
+               ctl->discard |= SWAP_FLAG_DISCARD;
 
                if (arg) {
                        /* only single-time discards are wanted */
                        if (strcmp(arg, "once") == 0)
-                               *disc |= SWAP_FLAG_DISCARD_ONCE;
+                               ctl->discard |= SWAP_FLAG_DISCARD_ONCE;
 
                        /* do discard for every released swap page */
                        if (strcmp(arg, "pages") == 0)
-                               *disc |= SWAP_FLAG_DISCARD_PAGES;
+                               ctl->discard |= SWAP_FLAG_DISCARD_PAGES;
                        }
        }
 
        arg = NULL;
-       if (mnt_optstr_get_option(optstr, "pri", &arg, NULL) == 0 && arg)
-               *prio = atoi(arg);
+       if (mnt_optstr_get_option(ctl->options, "pri", &arg, NULL) == 0 && arg)
+               ctl->priority = atoi(arg);
 
        return 0;
 }
 
 
-static int swapon_all(void)
+static int swapon_all(struct swapon_ctl *ctl)
 {
        struct libmnt_table *tb = get_fstab();
        struct libmnt_iter *itr;
@@ -690,7 +693,6 @@ static int swapon_all(void)
 
        while (mnt_table_find_next_fs(tb, itr, match_swap, NULL, &fs) == 0) {
                /* defaults */
-               int pri = priority, dsc = discard, nofail = ifexists;
                const char *opts, *src;
 
                if (mnt_fs_get_option(fs, "noauto", NULL, NULL) == 0)
@@ -698,18 +700,18 @@ static int swapon_all(void)
 
                opts = mnt_fs_get_options(fs);
                if (opts)
-                       parse_options(opts, &pri, &dsc, &nofail);
+                       parse_options(ctl);
 
                src = mnt_resolve_spec(mnt_fs_get_source(fs), mntcache);
                if (!src) {
-                       if (!nofail)
+                       if (!ctl->no_fail)
                                status |= cannot_find(mnt_fs_get_source(fs));
                        continue;
                }
 
                if (!is_active_swap(src) &&
-                   (!nofail || !access(src, R_OK)))
-                       status |= do_swapon(src, pri, dsc, CANONIC);
+                   (!ctl->no_fail || !access(src, R_OK)))
+                       status |= do_swapon(ctl, src, CANONIC);
        }
 
        mnt_free_iter(itr);
@@ -769,10 +771,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
 
 int main(int argc, char *argv[])
 {
-       char *options = NULL;
        int status = 0, c;
-       int show = 0;
-       int bytes = 0;
        size_t i;
 
        enum {
@@ -809,6 +808,8 @@ int main(int argc, char *argv[])
        };
        int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
 
+       struct swapon_ctl ctl = { .priority = -1, 0 };
+
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
@@ -824,16 +825,16 @@ int main(int argc, char *argv[])
 
                switch (c) {
                case 'a':               /* all */
-                       ++all;
+                       ctl.all = 1;
                        break;
                case 'h':               /* help */
                        usage(stdout);
                        break;
                case 'o':
-                       options = optarg;
+                       ctl.options = optarg;
                        break;
                case 'p':               /* priority */
-                       priority = strtos16_or_err(optarg,
+                       ctl.priority = strtos16_or_err(optarg,
                                           _("failed to parse priority"));
                        break;
                case 'L':
@@ -843,50 +844,50 @@ int main(int argc, char *argv[])
                        add_uuid(optarg);
                        break;
                case 'd':
-                       discard |= SWAP_FLAG_DISCARD;
+                       ctl.discard |= SWAP_FLAG_DISCARD;
                        if (optarg) {
                                if (*optarg == '=')
                                        optarg++;
 
                                if (strcmp(optarg, "once") == 0)
-                                       discard |= SWAP_FLAG_DISCARD_ONCE;
+                                       ctl.discard |= SWAP_FLAG_DISCARD_ONCE;
                                else if (strcmp(optarg, "pages") == 0)
-                                       discard |= SWAP_FLAG_DISCARD_PAGES;
+                                       ctl.discard |= SWAP_FLAG_DISCARD_PAGES;
                                else
                                        errx(EXIT_FAILURE, _("unsupported discard policy: %s"), optarg);
                        }
                        break;
                case 'e':               /* ifexists */
-                       ifexists = 1;
+                       ctl.no_fail = 1;
                        break;
                case 'f':
-                       fixpgsz = 1;
+                       ctl.fix_page_size = 1;
                        break;
                case 's':               /* status report */
                        status = display_summary();
                        return status;
                case 'v':               /* be chatty */
-                       ++verbose;
+                       ctl.verbose = 1;
                        break;
                case SHOW_OPTION:
                        if (optarg) {
-                               ncolumns = string_to_idarray(optarg,
-                                                            columns,
-                                                            ARRAY_SIZE(columns),
+                               ctl.ncolumns = string_to_idarray(optarg,
+                                                            ctl.columns,
+                                                            ARRAY_SIZE(ctl.columns),
                                                             column_name_to_id);
-                               if (ncolumns < 0)
+                               if (ctl.ncolumns < 0)
                                        return EXIT_FAILURE;
                        }
-                       show = 1;
+                       ctl.show = 1;
                        break;
                case NOHEADINGS_OPTION:
-                       no_headings = 1;
+                       ctl.no_heading = 1;
                        break;
                case RAW_OPTION:
-                       raw = 1;
+                       ctl.raw = 1;
                        break;
                case BYTES_OPTION:
-                       bytes = 1;
+                       ctl.bytes = 1;
                        break;
                case 'V':               /* version */
                        printf(UTIL_LINUX_VERSION);
@@ -900,36 +901,40 @@ int main(int argc, char *argv[])
        }
        argv += optind;
 
-       if (show || (!all && !numof_labels() && !numof_uuids() && *argv == NULL)) {
-               if (!ncolumns) {
+       if (ctl.show || (!ctl.all && !numof_labels() && !numof_uuids() && *argv == NULL)) {
+               if (!ctl.ncolumns) {
                        /* default columns */
-                       columns[ncolumns++] = COL_PATH;
-                       columns[ncolumns++] = COL_TYPE;
-                       columns[ncolumns++] = COL_SIZE;
-                       columns[ncolumns++] = COL_USED;
-                       columns[ncolumns++] = COL_PRIO;
+                       ctl.columns[ctl.ncolumns++] = COL_PATH;
+                       ctl.columns[ctl.ncolumns++] = COL_TYPE;
+                       ctl.columns[ctl.ncolumns++] = COL_SIZE;
+                       ctl.columns[ctl.ncolumns++] = COL_USED;
+                       ctl.columns[ctl.ncolumns++] = COL_PRIO;
                }
-               status = show_table(bytes);
+               status = show_table(&ctl);
                return status;
        }
 
-       if (ifexists && !all)
+       if (ctl.no_fail && !ctl.all)
                usage(stderr);
 
-       if (all)
-               status |= swapon_all();
+       if (ctl.all)
+               status |= swapon_all(&ctl);
 
-       if (options)
-               parse_options(options, &priority, &discard, &ifexists);
+       if (ctl.options)
+               parse_options(&ctl);
 
-       for (i = 0; i < numof_labels(); i++)
-               status |= swapon_by_label(get_label(i), priority, discard);
+       for (i = 0; i < numof_labels(); i++) {
+               ctl.label = get_label(i);
+               status |= swapon_by_label(&ctl);
+       }
 
-       for (i = 0; i < numof_uuids(); i++)
-               status |= swapon_by_uuid(get_uuid(i), priority, discard);
+       for (i = 0; i < numof_uuids(); i++) {
+               ctl.uuid = get_uuid(i);
+               status |= swapon_by_uuid(&ctl);
+       }
 
        while (*argv != NULL)
-               status |= do_swapon(*argv++, priority, discard, !CANONIC);
+               status |= do_swapon(&ctl, *argv++, !CANONIC);
 
        free_tables();
        mnt_unref_cache(mntcache);