From 9eeba70eeda0585d224bd27ec9df8c1d7fa96dae Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Tue, 2 Feb 2016 13:40:08 +0000 Subject: swapon: add control struct Signed-off-by: Sami Kerola --- sys-utils/swapon.c | 253 +++++++++++++++++++++++++++-------------------------- 1 file changed, 129 insertions(+), 124 deletions(-) (limited to 'sys-utils/swapon.c') diff --git a/sys-utils/swapon.c b/sys-utils/swapon.c index c4d154420..b677f505c 100644 --- a/sys-utils/swapon.c +++ b/sys-utils/swapon.c @@ -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 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); -- cgit v1.2.3-55-g7522