--- swapon.c.orig 2017-05-04 17:22:29.396661000 +0200 +++ swapon.c 2017-08-30 00:25:41.542625000 +0200 @@ -68,7 +68,8 @@ static const char *swap_on_off(const char *, int, char *); static const char *swap_on_off_gbde(const char *, int); static const char *swap_on_off_geli(const char *, char *, int); -static const char *swap_on_off_md(const char *, char *, int); +static const char *swap_on_off_md(const char *, char *, int, int, + const char *); static const char *swap_on_off_sfile(const char *, int); static void swaplist(int, int, int); static int run_cmd(int *, const char *, ...) __printflike(2, 3); @@ -217,48 +218,79 @@ exit(ret); } +/* Strip off .bde or .eli suffix from swap device name */ +static char * +swap_basename(const char *name) +{ + char *dname, *p; + + dname = strdup(name); + p = strrchr(dname, '.'); + /* assert(p != NULL); */ + *p = '\0'; + + return (dname); +} + static const char * swap_on_off(const char *name, int doingall, char *mntops) { char base[PATH_MAX]; + const char *ret; + char *dname, *eliname; + int is_eli = 0; + + basename_r(name, base); + + if (fnmatch("*.eli", base, 0) == 0) { + is_eli = 1; + dname = swap_basename(name); + } else + dname = strdup(name); /* Swap on vnode-backed md(4) device. */ if (mntops != NULL && - (fnmatch(_PATH_DEV MD_NAME "[0-9]*", name, 0) == 0 || - fnmatch(MD_NAME "[0-9]*", name, 0) == 0 || - strncmp(_PATH_DEV MD_NAME, name, + (fnmatch(_PATH_DEV MD_NAME "[0-9]*", dname, 0) == 0 || + fnmatch(MD_NAME "[0-9]*", dname, 0) == 0 || + strncmp(_PATH_DEV MD_NAME, dname, sizeof(_PATH_DEV) + sizeof(MD_NAME)) == 0 || - strncmp(MD_NAME, name, sizeof(MD_NAME)) == 0)) - return (swap_on_off_md(name, mntops, doingall)); + strncmp(MD_NAME, dname, sizeof(MD_NAME)) == 0)) { + if (is_eli && which_prog == SWAPON) { + ret = swap_on_off_md(dname, mntops, doingall, + 0, ""); + free(dname); + if (ret == NULL) + return (NULL); + asprintf(&eliname, "%s.eli", ret); + ret = swap_on_off_geli(eliname, mntops, doingall); + free(eliname); + return (ret); + } else if (is_eli /* SWAPOFF */) { + ret = swap_on_off_md(dname, mntops, doingall, + 1, ".eli"); + free(dname); + return (ret); + } else { + free(dname); + return (swap_on_off_md(name, mntops, doingall, + 1, "")); + } + } - basename_r(name, base); + free(dname); /* Swap on encrypted device by GEOM_BDE. */ if (fnmatch("*.bde", base, 0) == 0) return (swap_on_off_gbde(name, doingall)); /* Swap on encrypted device by GEOM_ELI. */ - if (fnmatch("*.eli", base, 0) == 0) + if (is_eli) return (swap_on_off_geli(name, mntops, doingall)); /* Swap on special file. */ return (swap_on_off_sfile(name, doingall)); } -/* Strip off .bde or .eli suffix from swap device name */ -static char * -swap_basename(const char *name) -{ - char *dname, *p; - - dname = strdup(name); - p = strrchr(dname, '.'); - /* assert(p != NULL); */ - *p = '\0'; - - return (dname); -} - static const char * swap_on_off_gbde(const char *name, int doingall) { @@ -373,6 +405,8 @@ /* ignore known option */ } else if (strcmp(token, "noauto") == 0) { /* ignore known option */ + } else if ((p = strstr(token, "file=")) == token) { + /* ignore known option */ } else if (strcmp(token, "sw") != 0) { warnx("Invalid option: %s", token); free(ops); @@ -445,7 +479,8 @@ } static const char * -swap_on_off_md(const char *name, char *mntops, int doingall) +swap_on_off_md(const char *name, char *mntops, int doingall, + int do_sfile, const char *suffix) { FILE *sfd; int fd, mdunit, error; @@ -613,10 +648,13 @@ } } } - snprintf(mdpath, sizeof(mdpath), "%s%s%d", _PATH_DEV, - MD_NAME, mdunit); + snprintf(mdpath, sizeof(mdpath), "%s%s%d%s", _PATH_DEV, + MD_NAME, mdunit, suffix); mdpath[sizeof(mdpath) - 1] = '\0'; - ret = swap_on_off_sfile(mdpath, doingall); + if (do_sfile) + ret = swap_on_off_sfile(mdpath, doingall); + else + ret = mdpath; if (which_prog == SWAPOFF) { if (ret != NULL) {