# define swapon(path, flags) syscall(SYS_swapon, path, flags)
#endif
-#define CANONIC 1
-
#define MAX_PAGESIZE (64 * 1024)
enum {
/* control struct */
struct swapon_ctl {
+ char *device; /* device or file to be turned on */
+ char *dev_canonical; /* canonical path to device */
char *options; /* fstab-compatible option string */
const char *label; /* swap label */
const char *uuid; /* unique identifier */
int columns[ARRAY_SIZE(infos) * 2]; /* --show columns */
int ncolumns; /* number of columns */
int priority; /* non-prioritized swap by default */
+ unsigned int pagesize; /* swap page size */
unsigned int
all:1, /* turn on all swap devices */
bytes:1, /* display --show in bytes */
+ canonic:1, /* is device path canonical */
fix_page_size:1, /* reinitialize page size */
no_fail:1, /* skip devices that do not exist */
no_heading:1, /* toggle --show headers */
}
/* calls mkswap */
-static int swap_reinitialize(const char *device,
- const char *label, const char *uuid)
+static int swap_reinitialize(struct swapon_ctl *ctl)
{
pid_t pid;
int status, ret;
- char *cmd[7];
+ char const *cmd[7];
int idx=0;
- warnx(_("%s: reinitializing the swap."), device);
+ warnx(_("%s: reinitializing the swap."), ctl->device);
switch((pid=fork())) {
case -1: /* fork error */
case 0: /* child */
cmd[idx++] = "mkswap";
- if (label && *label) {
+ if (ctl->label) {
cmd[idx++] = "-L";
- cmd[idx++] = (char *) label;
+ cmd[idx++] = ctl->label;
}
- if (uuid && *uuid) {
+ if (ctl->uuid) {
cmd[idx++] = "-U";
- cmd[idx++] = (char *) uuid;
+ cmd[idx++] = ctl->uuid;
}
- cmd[idx++] = (char *) device;
+ cmd[idx++] = ctl->device;
cmd[idx++] = NULL;
- execvp(cmd[0], cmd);
+ execvp(cmd[0], (char * const *) cmd);
err(EXIT_FAILURE, _("failed to execute %s"), cmd[0]);
default: /* parent */
return -1; /* error */
}
-static int swap_rewrite_signature(const char *devname, unsigned int pagesize)
+static int swap_rewrite_signature(const struct swapon_ctl *ctl)
{
int fd, rc = -1;
- fd = open(devname, O_WRONLY);
+ fd = open(ctl->dev_canonical, O_WRONLY);
if (fd == -1) {
- warn(_("cannot open %s"), devname);
+ warn(_("cannot open %s"), ctl->device);
return -1;
}
- if (lseek(fd, pagesize - SWAP_SIGNATURE_SZ, SEEK_SET) < 0) {
- warn(_("%s: lseek failed"), devname);
+ if (lseek(fd, ctl->pagesize - SWAP_SIGNATURE_SZ, SEEK_SET) < 0) {
+ warn(_("%s: lseek failed"), ctl->device);
goto err;
}
if (write(fd, (void *) SWAP_SIGNATURE,
SWAP_SIGNATURE_SZ) != SWAP_SIGNATURE_SZ) {
- warn(_("%s: write signature failed"), devname);
+ warn(_("%s: write signature failed"), ctl->device);
goto err;
}
rc = 0;
err:
if (close_fd(fd) != 0) {
- warn(_("write failed: %s"), devname);
+ warn(_("write failed: %s"), ctl->device);
rc = -1;
}
return rc;
return 1;
}
-static char *swap_get_header(int fd, int *sig, unsigned int *pagesize)
+static char *swap_get_header(struct swapon_ctl *ctl, int fd, int *sig)
{
char *buf;
ssize_t datasz;
unsigned int page;
- *pagesize = 0;
+ ctl->pagesize = 0;
*sig = 0;
buf = xmalloc(MAX_PAGESIZE);
if (datasz < 0 || (size_t) datasz < (page - SWAP_SIGNATURE_SZ))
break;
if (swap_detect_signature(buf + page - SWAP_SIGNATURE_SZ, sig)) {
- *pagesize = page;
+ ctl->pagesize = page;
break;
}
}
- if (*pagesize)
+ if (ctl->pagesize)
return buf;
err:
free(buf);
}
/* returns real size of swap space */
-static unsigned long long swap_get_size(const struct swapon_ctl *ctl,
- const char *hdr, const char *devname,
- unsigned int pagesize)
+static unsigned long long swap_get_size(const struct swapon_ctl *ctl, const char *hdr)
{
unsigned int last_page = 0;
const unsigned int swap_version = SWAP_VERSION;
if (ctl->verbose)
warnx(_("%s: found swap signature: version %ud, "
"page-size %d, %s byte order"),
- devname,
+ ctl->device,
swap_version,
- pagesize / 1024,
+ ctl->pagesize / 1024,
flip ? _("different") : _("same"));
- return ((unsigned long long) last_page + 1) * pagesize;
+ return ((unsigned long long) last_page + 1) * ctl->pagesize;
}
static void swap_get_info(struct swapon_ctl *ctl, const char *hdr)
}
}
-static int swapon_checks(struct swapon_ctl *ctl, const char *special)
+static int swapon_checks(struct swapon_ctl *ctl)
{
struct stat st;
int fd = -1, sig;
char *hdr = NULL;
- unsigned int pagesize;
unsigned long long devsize = 0;
int permMask;
- fd = open(special, O_RDONLY);
+ fd = open(ctl->dev_canonical, O_RDONLY);
if (fd == -1) {
- warn(_("cannot open %s"), special);
+ warn(_("cannot open %s"), ctl->device);
goto err;
}
if (fstat(fd, &st) < 0) {
- warn(_("stat of %s failed"), special);
+ warn(_("stat of %s failed"), ctl->device);
goto err;
}
permMask = S_ISBLK(st.st_mode) ? 07007 : 07077;
if ((st.st_mode & permMask) != 0)
warnx(_("%s: insecure permissions %04o, %04o suggested."),
- special, st.st_mode & 07777,
+ ctl->device, st.st_mode & 07777,
~permMask & 0666);
if (S_ISREG(st.st_mode) && st.st_uid != 0)
warnx(_("%s: insecure file owner %d, 0 (root) suggested."),
- special, st.st_uid);
+ ctl->device, st.st_uid);
/* test for holes by LBT */
if (S_ISREG(st.st_mode)) {
if (st.st_blocks * 512 < st.st_size) {
warnx(_("%s: skipping - it appears to have holes."),
- special);
+ ctl->device);
goto err;
}
devsize = st.st_size;
}
if (S_ISBLK(st.st_mode) && blkdev_get_size(fd, &devsize)) {
- warnx(_("%s: get size failed"), special);
+ warnx(_("%s: get size failed"), ctl->device);
goto err;
}
- hdr = swap_get_header(fd, &sig, &pagesize);
+ hdr = swap_get_header(ctl, fd, &sig);
if (!hdr) {
- warnx(_("%s: read swap header failed"), special);
+ warnx(_("%s: read swap header failed"), ctl->device);
goto err;
}
- if (sig == SIG_SWAPSPACE && pagesize) {
+ if (sig == SIG_SWAPSPACE && ctl->pagesize) {
unsigned long long swapsize =
- swap_get_size(ctl, hdr, special, pagesize);
+ swap_get_size(ctl, hdr);
int syspg = getpagesize();
if (ctl->verbose)
warnx(_("%s: pagesize=%d, swapsize=%llu, devsize=%llu"),
- special, pagesize, swapsize, devsize);
+ ctl->device, ctl->pagesize, swapsize, devsize);
if (swapsize > devsize) {
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) {
+ ctl->device, swapsize);
+ } else if (syspg < 0 || (unsigned int) syspg != ctl->pagesize) {
if (ctl->fix_page_size) {
- char *label = NULL, *uuid = NULL;
int rc;
swap_get_info(ctl, hdr);
warnx(_("%s: swap format pagesize does not match."),
- special);
- rc = swap_reinitialize(special, label, uuid);
- free(label);
- free(uuid);
+ ctl->device);
+ rc = swap_reinitialize(ctl);
if (rc < 0)
goto err;
} else
warnx(_("%s: swap format pagesize does not match. "
"(Use --fixpgsz to reinitialize it.)"),
- special);
+ ctl->device);
}
} else if (sig == SIG_SWSUSPEND) {
/* We have to reinitialize swap with old (=useless) software suspend
*/
warnx(_("%s: software suspend data detected. "
"Rewriting the swap signature."),
- special);
- if (swap_rewrite_signature(special, pagesize) < 0)
+ ctl->device);
+ if (swap_rewrite_signature(ctl) < 0)
goto err;
}
return -1;
}
-static int do_swapon(struct swapon_ctl *ctl, const char *orig_special,
- int canonic)
+static int do_swapon(struct swapon_ctl *ctl)
{
int status;
- const char *special = orig_special;
int flags = 0;
if (ctl->verbose)
- printf(_("swapon %s\n"), orig_special);
+ printf(_("swapon %s\n"), ctl->device);
- if (!canonic) {
- special = mnt_resolve_spec(orig_special, mntcache);
- if (!special)
- return cannot_find(orig_special);
- }
+ if (!ctl->canonic) {
+ ctl->dev_canonical = mnt_resolve_spec(ctl->device, mntcache);
+ if (!ctl->dev_canonical)
+ return cannot_find(ctl->device);
+ } else
+ ctl->dev_canonical = ctl->device;
- if (swapon_checks(ctl, special))
+ if (swapon_checks(ctl))
return -1;
#ifdef SWAP_FLAG_PREFER
flags |= ctl->discard;
}
- status = swapon(special, flags);
+ status = swapon(ctl->dev_canonical, flags);
if (status < 0)
- warn(_("%s: swapon failed"), orig_special);
+ warn(_("%s: swapon failed"), ctl->device);
return status;
}
static int swapon_by_label(struct swapon_ctl *ctl)
{
- const char *special = mnt_resolve_tag("LABEL", ctl->label, mntcache);
- return special ? do_swapon(ctl, special, CANONIC) :
- cannot_find(ctl->label);
+ ctl->device = mnt_resolve_tag("LABEL", ctl->label, mntcache);
+ return ctl->device ? do_swapon(ctl) : cannot_find(ctl->label);
}
static int swapon_by_uuid(struct swapon_ctl *ctl)
{
- const char *special = mnt_resolve_tag("UUID", ctl->uuid, mntcache);
- return special ? do_swapon(ctl, special, CANONIC) :
- cannot_find(ctl->uuid);
+ ctl->device = mnt_resolve_tag("UUID", ctl->uuid, mntcache);
+ return ctl->device ? do_swapon(ctl) : cannot_find(ctl->uuid);
}
/* -o <options> or fstab */
while (mnt_table_find_next_fs(tb, itr, match_swap, NULL, &fs) == 0) {
/* defaults */
- const char *opts, *src;
+ const char *opts;
if (mnt_fs_get_option(fs, "noauto", NULL, NULL) == 0)
continue;
if (opts)
parse_options(ctl);
- src = mnt_resolve_spec(mnt_fs_get_source(fs), mntcache);
- if (!src) {
+ ctl->device = mnt_resolve_spec(mnt_fs_get_source(fs), mntcache);
+ if (!ctl->device) {
if (!ctl->no_fail)
status |= cannot_find(mnt_fs_get_source(fs));
continue;
}
- if (!is_active_swap(src) &&
- (!ctl->no_fail || !access(src, R_OK)))
- status |= do_swapon(ctl, src, CANONIC);
+ if (!is_active_swap(ctl->device) &&
+ (!ctl->no_fail || !access(ctl->device, R_OK)))
+ status |= do_swapon(ctl);
}
mnt_free_iter(itr);
};
int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
- struct swapon_ctl ctl = { .priority = -1, 0 };
+ struct swapon_ctl ctl = { .priority = -1, .canonic = 1, 0 };
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
ctl.uuid = get_uuid(i);
status |= swapon_by_uuid(&ctl);
}
-
- while (*argv != NULL)
- status |= do_swapon(&ctl, *argv++, !CANONIC);
+ if (*argv != NULL) {
+ ctl.canonic = 0;
+ while (*argv != NULL) {
+ ctl.device = *argv++;
+ status |= do_swapon(&ctl);
+ }
+ }
free_tables();
mnt_unref_cache(mntcache);