From owner-freebsd-rc@FreeBSD.ORG Sun Jun 23 18:26:11 2013 Return-Path: Delivered-To: freebsd-rc@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 5C7997F2; Sun, 23 Jun 2013 18:26:11 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from mail.allbsd.org (gatekeeper.allbsd.org [IPv6:2001:2f0:104:e001::32]) by mx1.freebsd.org (Postfix) with ESMTP id 02BDA1852; Sun, 23 Jun 2013 18:26:09 +0000 (UTC) Received: from alph.d.allbsd.org (p3086-ipbf906funabasi.chiba.ocn.ne.jp [122.26.46.86]) (authenticated bits=128) by mail.allbsd.org (8.14.5/8.14.5) with ESMTP id r5NIPpGg009714 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 24 Jun 2013 03:26:02 +0900 (JST) (envelope-from hrs@FreeBSD.org) Received: from localhost (localhost [127.0.0.1]) (authenticated bits=0) by alph.d.allbsd.org (8.14.5/8.14.5) with ESMTP id r5NIPoo3041283; Mon, 24 Jun 2013 03:25:51 +0900 (JST) (envelope-from hrs@FreeBSD.org) Date: Mon, 24 Jun 2013 03:24:58 +0900 (JST) Message-Id: <20130624.032458.2116947740119973135.hrs@allbsd.org> To: swhetzel@gmail.com Subject: Re: RFC: swapon(8) vnode-backed md and gbde/geli encryption support From: Hiroki Sato In-Reply-To: References: <20130623.035356.644417021040610458.hrs@allbsd.org> X-PGPkey-fingerprint: BDB3 443F A5DD B3D0 A530 FFD7 4F2C D3D8 2793 CF2D X-Mailer: Mew version 6.5 on Emacs 24.3 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Multipart/Signed; protocol="application/pgp-signature"; micalg=pgp-sha1; boundary="--Security_Multipart0(Mon_Jun_24_03_24_58_2013_483)--" Content-Transfer-Encoding: 7bit X-Virus-Scanned: clamav-milter 0.97.4 at gatekeeper.allbsd.org X-Virus-Status: Clean X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.7 (mail.allbsd.org [133.31.130.32]); Mon, 24 Jun 2013 03:26:02 +0900 (JST) X-Spam-Status: No, score=-89.2 required=13.0 tests=CONTENT_TYPE_PRESENT, DIRECTOCNDYN,DYN_PBL,ONLY1HOPDIRECT,QENCPTR1,RCVD_IN_PBL,SAMEHELOBY2HOP, USER_IN_WHITELIST,X_CHINESE_RELAY autolearn=no version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on gatekeeper.allbsd.org Cc: freebsd-current@FreeBSD.org, freebsd-rc@FreeBSD.org X-BeenThere: freebsd-rc@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Discussion related to /etc/rc.d design and implementation." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 23 Jun 2013 18:26:11 -0000 ----Security_Multipart0(Mon_Jun_24_03_24_58_2013_483)-- Content-Type: Multipart/Mixed; boundary="--Next_Part(Mon_Jun_24_03_24_58_2013_798)--" Content-Transfer-Encoding: 7bit ----Next_Part(Mon_Jun_24_03_24_58_2013_798)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Scot Hetzel wrote in : sw> The only thing I see is that you are hard coding the geli_swap_flags sw> (i.e. -e aes -l 256 -s 4096 -d) into swapon. It would be better to sw> have swapon read the /etc/fstab file to get these values: sw> sw> /dev/ada1p2.eli none swap sw> sw,ealgo=aes,keylen=256,sectorsize=4096 0 0 sw> /dev/ada2p2.eli none swap sw 0 0 sw> sw> What you could do is that if no options are specified in the swap sw> file, swapon would then use default values for ealgo=aes, keylen=256 sw> and sectorsize=4096. Thank you for your feedback. These options are implemented in the attached patch. -- Hiroki ----Next_Part(Mon_Jun_24_03_24_58_2013_798)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="swap_20130624-1.diff" - Add vnode-backed swap space specification support. This is enabled when device names "md" or "md[0-9]*" and a "file" option are specified in /etc/fstab like this: md none swap sw,file=/swap.bin 0 0 - Add GBDE/GELI encrypted swap space specification support, which rc.d/encswap supported. The /etc/fstab lines are like the following: /dev/ada1p1.bde none swap sw 0 0 /dev/ada1p2.eli none swap sw 0 0 .eli devices supports aalgo, ealgo, keylen, and sectorsize as options. swapctl(8) can understand an encrypted device in the command line like this: # swapctl -a /dev/ada2p1.bde - "-L" flag is added to support "late" option to defer swapon until rc.d/mountlate runs. - rc.d script change: rc.d/encswap -> removed rc.d/swap1 -> renamed to rc.d/swap rc.d/swaplate -> newly added to support "late" option These changes alleviate a race condition between device creation/removal and swapon/swapoff. MFC after: 2 weeks ==== Index: sbin/swapon/swapon.c =================================================================== --- sbin/swapon/swapon.c (revision 252094) +++ sbin/swapon/swapon.c (working copy) @@ -41,35 +41,51 @@ static char sccsid[] = "@(#)swapon.c 8.1 (Berkeley #include __FBSDID("$FreeBSD$"); +#include +#include +#include #include -#include #include +#include #include #include #include +#include +#include #include +#include +#include +#include +#include +#include #include #include #include #include -#include -#include static void usage(void); -static int swap_on_off(char *name, int ignoreebusy); +static const char *swap_on_off(char *, int, char *); +static const char *swap_on_off_gbde(char *, int); +static const char *swap_on_off_geli(char *, char *, int); +static const char *swap_on_off_md(char *, char *, int); +static const char *swap_on_off_sfile(char *, int); static void swaplist(int, int, int); +static int run_cmd(int *, const char *, ...) __printflike(2, 3); static enum { SWAPON, SWAPOFF, SWAPCTL } orig_prog, which_prog = SWAPCTL; +static int qflag; + int main(int argc, char **argv) { struct fstab *fsp; + const char *swfile; char *ptr; int ret; int ch, doall; - int sflag = 0, lflag = 0, hflag = 0, qflag = 0; + int sflag = 0, lflag = 0, late = 0, hflag = 0; const char *etc_fstab; if ((ptr = strrchr(argv[0], '/')) == NULL) @@ -82,7 +98,7 @@ main(int argc, char **argv) doall = 0; etc_fstab = NULL; - while ((ch = getopt(argc, argv, "AadghklmqsUF:")) != -1) { + while ((ch = getopt(argc, argv, "AadghklLmqsUF:")) != -1) { switch(ch) { case 'A': if (which_prog == SWAPCTL) { @@ -116,6 +132,9 @@ main(int argc, char **argv) case 'l': lflag = 1; break; + case 'L': + late = 1; + break; case 'm': hflag = 'M'; break; @@ -145,6 +164,7 @@ main(int argc, char **argv) argv += optind; ret = 0; + swfile = NULL; if (etc_fstab != NULL) setfstab(etc_fstab); if (which_prog == SWAPON || which_prog == SWAPOFF) { @@ -154,27 +174,37 @@ main(int argc, char **argv) continue; if (strstr(fsp->fs_mntops, "noauto")) continue; - if (swap_on_off(fsp->fs_spec, 1)) { + if (which_prog != SWAPOFF && + strstr(fsp->fs_mntops, "late") && + !late) + continue; + swfile = swap_on_off(fsp->fs_spec, 1, + fsp->fs_mntops); + if (swfile == NULL) { ret = 1; - } else { - if (!qflag) { - printf("%s: %sing %s as swap device\n", - getprogname(), - which_prog == SWAPOFF ? "remov" : "add", - fsp->fs_spec); - } + continue; } + if (!qflag) { + printf("%s: %sing %s as swap device\n", + getprogname(), + (which_prog == SWAPOFF) ? + "remov" : "add", swfile); + } } } else if (!*argv) usage(); for (; *argv; ++argv) { - if (swap_on_off(*argv, 0)) { + swfile = swap_on_off(*argv, 0, NULL); + if (swfile == NULL) { ret = 1; - } else if (orig_prog == SWAPCTL) { + continue; + } + if (orig_prog == SWAPCTL) { printf("%s: %sing %s as swap device\n", - getprogname(), which_prog == SWAPOFF ? "remov" : "add", - *argv); + getprogname(), + (which_prog == SWAPOFF) ? "remov" : "add", + swfile); } } } else { @@ -186,14 +216,503 @@ main(int argc, char **argv) exit(ret); } +static const char * +swap_on_off(char *name, int doingall, char *mntops) +{ + char base[PATH_MAX]; + + /* Swap on vnode-backed md(4) device. */ + if (mntops != NULL && + (fnmatch(_PATH_DEV MD_NAME "[0-9]*", name, 0) != FNM_NOMATCH || + fnmatch(MD_NAME "[0-9]*", name, 0) != FNM_NOMATCH || + strncmp(_PATH_DEV MD_NAME, name, + sizeof(_PATH_DEV) + sizeof(MD_NAME)) == 0 || + strncmp(MD_NAME, name, sizeof(MD_NAME)) == 0)) + return (swap_on_off_md(name, mntops, doingall)); + + /* Swap on encrypted device by GEOM_BDE. */ + basename_r(name, base); + if (fnmatch("*.bde", base, 0) != FNM_NOMATCH) + return (swap_on_off_gbde(name, doingall)); + + /* Swap on encrypted device by GEOM_ELI. */ + if (fnmatch("*.eli", base, 0) != FNM_NOMATCH) + return (swap_on_off_geli(name, mntops, doingall)); + + /* Swap on special file. */ + return (swap_on_off_sfile(name, doingall)); +} + +static const char * +swap_on_off_gbde(char *name, int doingall) +{ + const char *ret; + char pass[64 * 2 + 1], bpass[64]; + char *devname, *p; + int i, fd, error; + + devname = strdup(name); + p = strrchr(devname, '.'); + if (p == NULL) { + warnx("%s: Malformed device name", name); + return (NULL); + } + *p = '\0'; + + fd = -1; + switch (which_prog) { + case SWAPON: + arc4random_buf(bpass, sizeof(bpass)); + for (i = 0; i < (int)sizeof(bpass); i++) + sprintf(&pass[2 * i], "%02x", bpass[i]); + pass[sizeof(pass) - 1] = '\0'; + + error = run_cmd(&fd, "%s init %s -P %s", _PATH_GBDE, + devname, pass); + if (error) { + /* bde device found. Ignore it. */ + close(fd); + if (!qflag) + warnx("%s: Device already in use", name); + return (NULL); + } + close(fd); + error = run_cmd(&fd, "%s attach %s -p %s", _PATH_GBDE, + devname, pass); + if (error) { + close(fd); + warnx("gbde (attach) error: %s", name); + return (NULL); + } + break; + case SWAPOFF: + break; + default: + return (NULL); + break; + } + if (fd != -1) + close(fd); + ret = swap_on_off_sfile(name, doingall); + + fd = -1; + switch (which_prog) { + case SWAPOFF: + error = run_cmd(&fd, "%s detach %s", _PATH_GBDE, devname); + if (error) { + /* bde device not found. Ignore it. */ + if (!qflag) + warnx("%s: Device not found", devname); + return (NULL); + } + break; + default: + return (NULL); + break; + } + + if (fd != -1) + close(fd); + return (ret); +} + +static const char * +swap_on_off_geli(char *name, char *mntops, int doingall) +{ + const char *ops, *aalgo, *ealgo, *keylen_str, *sectorsize_str; + char *devname, *p; + char args[4096]; + struct stat sb; + int fd, error, keylen, sectorsize; + u_long ul; + + devname = strdup(name); + p = strrchr(devname, '.'); + if (p == NULL) { + warnx("%s: Malformed device name", name); + return (NULL); + } + *p = '\0'; + + ops = strdup(mntops); + + /* Default parameters for geli(8). */ + aalgo = "hmac/sha256"; + ealgo = "aes"; + keylen = 256; + sectorsize = 4096; + + if ((p = strstr(ops, "aalgo=")) != NULL) { + aalgo = p + sizeof("aalgo=") - 1; + p = strchr(aalgo, ','); + if (p != NULL) + *p = '\0'; + } + if ((p = strstr(ops, "ealgo=")) != NULL) { + ealgo = p + sizeof("ealgo=") - 1; + p = strchr(ealgo, ','); + if (p != NULL) + *p = '\0'; + } + if ((p = strstr(ops, "keylen=")) != NULL) { + keylen_str = p + sizeof("keylen=") - 1; + p = strchr(keylen_str, ','); + if (p != NULL) + *p = '\0'; + errno = 0; + ul = strtoul(keylen_str, &p, 10); + if (errno == 0) { + if (*p != '\0' || ul > INT_MAX) + errno = EINVAL; + } + if (errno) { + warn("Invalid keylen: %s", keylen_str); + return (NULL); + } + keylen = (int)ul; + } + if ((p = strstr(ops, "sectorsize=")) != NULL) { + sectorsize_str = p + sizeof("sectorsize=") - 1; + p = strchr(sectorsize_str, ','); + if (p != NULL) + *p = '\0'; + errno = 0; + ul = strtoul(sectorsize_str, &p, 10); + if (errno == 0) { + if (*p != '\0' || ul > INT_MAX) + errno = EINVAL; + } + if (errno) { + warn("Invalid sectorsize: %s", sectorsize_str); + return (NULL); + } + sectorsize = (int)ul; + } + snprintf(args, sizeof(args), "-a %s -e %s -l %d -s %d -d", + aalgo, ealgo, keylen, sectorsize); + args[sizeof(args) - 1] = '\0'; + free((void *)ops); + + fd = -1; + switch (which_prog) { + case SWAPON: + error = run_cmd(&fd, "%s onetime %s %s", _PATH_GELI, args, + devname); + if (error) { + /* eli device found. Ignore it. */ + close(fd); + if (!qflag) + warnx("%s: Device already in use " + "or invalid parameters", name); + return (NULL); + } + break; + case SWAPOFF: + if (stat(name, &sb) == -1 && errno == ENOENT) { + if (!qflag) + warnx("%s: Device not found", name); + return (NULL); + } + break; + default: + return (NULL); + break; + } + if (fd != -1) + close(fd); + + return (swap_on_off_sfile(name, doingall)); +} + +static const char * +swap_on_off_md(char *name, char *mntops, int doingall) +{ + FILE *sfd; + int fd, mdunit, error; + const char *ret; + char mdpath[PATH_MAX], linebuf[PATH_MAX]; + char *p, *vnodefile; + size_t linelen; + u_long ul; + + fd = -1; + sfd = NULL; + if (strlen(name) == (sizeof(MD_NAME) - 1)) + mdunit = -1; + else { + errno = 0; + ul = strtoul(name + 2, &p, 10); + if (errno == 0) { + if (*p != '\0' || ul > INT_MAX) + errno = EINVAL; + } + if (errno) { + warn("Bad device unit: %s", name); + return (NULL); + } + mdunit = (int)ul; + } + + vnodefile = NULL; + if ((p = strstr(mntops, "file=")) != NULL) { + vnodefile = strdup(p + sizeof("file=") - 1); + p = strchr(vnodefile, ','); + if (p != NULL) + *p = '\0'; + } + if (vnodefile == NULL) { + warnx("file option not found for %s", name); + return (NULL); + } + + switch (which_prog) { + case SWAPON: + if (mdunit == -1) { + error = run_cmd(&fd, "%s -l -n -f %s", + _PATH_MDCONFIG, vnodefile); + if (error == 0) { + /* md device found. Ignore it. */ + close(fd); + if (!qflag) + warnx("%s: Device already in use", + vnodefile); + return (NULL); + } + error = run_cmd(&fd, "%s -a -t vnode -n -f %s", + _PATH_MDCONFIG, vnodefile); + if (error) { + warnx("mdconfig (attach) error: file=%s", + vnodefile); + return (NULL); + } + sfd = fdopen(fd, "r"); + if (sfd == NULL) { + warn("mdconfig (attach) fdopen error"); + ret = NULL; + goto err; + } + p = fgetln(sfd, &linelen); + if (p == NULL && + (linelen < 2 || linelen > sizeof(linebuf))) { + warn("mdconfig (attach) unexpected output"); + ret = NULL; + goto err; + } + strncpy(linebuf, p, linelen); + linebuf[linelen - 1] = '\0'; + errno = 0; + ul = strtoul(linebuf, &p, 10); + if (errno == 0) { + if (*p != '\0' || ul > INT_MAX) + errno = EINVAL; + } + if (errno) { + warn("mdconfig (attach) unexpected output: %s", + linebuf); + ret = NULL; + goto err; + } + mdunit = (int)ul; + } else { + error = run_cmd(&fd, "%s -l -n -f %s -u %d", + _PATH_MDCONFIG, vnodefile, mdunit); + if (error == 0) { + /* md device found. Ignore it. */ + close(fd); + if (!qflag) + warnx("md%d on %s: Device already " + "in use", mdunit, vnodefile); + return (NULL); + } + error = run_cmd(NULL, "%s -a -t vnode -u %d -f %s", + _PATH_MDCONFIG, mdunit, vnodefile); + if (error) { + warnx("mdconfig (attach) error: " + "md%d on file=%s", mdunit, vnodefile); + return (NULL); + } + } + break; + case SWAPOFF: + if (mdunit == -1) { + error = run_cmd(&fd, "%s -l -n -f %s", + _PATH_MDCONFIG, vnodefile); + if (error) { + /* md device not found. Ignore it. */ + close(fd); + if (!qflag) + warnx("md on %s: Device not found", + vnodefile); + return (NULL); + } + sfd = fdopen(fd, "r"); + if (sfd == NULL) { + warn("mdconfig (list) fdopen error"); + ret = NULL; + goto err; + } + p = fgetln(sfd, &linelen); + if (p == NULL && + (linelen < 2 || linelen > sizeof(linebuf) - 1)) { + warn("mdconfig (list) unexpected output"); + ret = NULL; + goto err; + } + strncpy(linebuf, p, linelen); + linebuf[linelen - 1] = '\0'; + p = strchr(linebuf, ' '); + if (p != NULL) + *p = '\0'; + errno = 0; + ul = strtoul(linebuf, &p, 10); + if (errno == 0) { + if (*p != '\0' || ul > INT_MAX) + errno = EINVAL; + } + if (errno) { + warn("mdconfig (list) unexpected output: %s", + linebuf); + ret = NULL; + goto err; + } + mdunit = (int)ul; + } else { + error = run_cmd(&fd, "%s -l -n -f %s -u %d", + _PATH_MDCONFIG, vnodefile, mdunit); + if (error) { + /* md device not found. Ignore it. */ + close(fd); + if (!qflag) + warnx("md%d on %s: Device not found", + mdunit, vnodefile); + return (NULL); + } + } + break; + default: + return (NULL); + } + snprintf(mdpath, sizeof(mdpath), "%s%s%d", _PATH_DEV, + MD_NAME, mdunit); + mdpath[sizeof(mdpath) - 1] = '\0'; + ret = swap_on_off_sfile(mdpath, doingall); + + switch (which_prog) { + case SWAPOFF: + if (ret != NULL) { + error = run_cmd(NULL, "%s -d -u %d", + _PATH_MDCONFIG, mdunit); + if (error) + warn("mdconfig (detach) detach failed: %s%s%d", + _PATH_DEV, MD_NAME, mdunit); + } + break; + default: + break; + } +err: + if (sfd != NULL) + fclose(sfd); + if (fd != -1) + close(fd); + return (ret); +} + static int -swap_on_off(char *name, int doingall) +run_cmd(int *ofd, const char *cmdline, ...) { - if ((which_prog == SWAPOFF ? swapoff(name) : swapon(name)) == -1) { + va_list ap; + char **argv, **argvp, *cmd, *p; + int argc, pid, status, rv; + int pfd[2], nfd, dup2dn; + + va_start(ap, cmdline); + rv = vasprintf(&cmd, cmdline, ap); + if (rv == -1) { + warn("%s", __func__); + return (rv); + } + va_end(ap); + + for (argc = 1, p = cmd; (p = strchr(p, ' ')) != NULL; p++) + argc++; + argv = (char **)malloc(sizeof(*argv) * (argc + 1)); + for (p = cmd, argvp = argv; (*argvp = strsep(&p, " ")) != NULL;) + if (**argvp != '\0' && (++argvp > &argv[argc])) { + *argvp = NULL; + break; + } + /* The argv array ends up NULL-terminated here. */ +#if 0 + { + int i; + + fprintf(stderr, "DEBUG: running:"); + /* Should be equivalent to 'cmd' (before strsep, of course). */ + for (i = 0; argv[i] != NULL; i++) + fprintf(stderr, " %s", argv[i]); + fprintf(stderr, "\n"); + } +#endif + dup2dn = 1; + if (ofd != NULL) { + if (pipe(&pfd[0]) == -1) { + warn("%s: pipe", __func__); + return (-1); + } + *ofd = pfd[0]; + dup2dn = 0; + } + pid = fork(); + switch (pid) { + case 0: + /* Child process. */ + if (ofd != NULL) + if (dup2(pfd[1], STDOUT_FILENO) < 0) + err(1, "dup2 in %s", __func__); + nfd = open(_PATH_DEVNULL, O_RDWR); + if (nfd == -1) + err(1, "%s: open %s", __func__, _PATH_DEVNULL); + if (dup2(nfd, STDIN_FILENO) < 0) + err(1, "%s: dup2", __func__); + if (dup2dn && dup2(nfd, STDOUT_FILENO) < 0) + err(1, "%s: dup2", __func__); + if (dup2(nfd, STDERR_FILENO) < 0) + err(1, "%s: dup2", __func__); + execv(argv[0], argv); + warn("exec: %s", argv[0]); + _exit(-1); + case -1: + err(1, "%s: fork", __func__); + } + free(cmd); + free(argv); + while (waitpid(pid, &status, 0) != pid) + ; + return (WEXITSTATUS(status)); +} + +static const char * +swap_on_off_sfile(char *name, int doingall) +{ + int error; + + switch (which_prog) { + case SWAPON: + error = swapon(name); + break; + case SWAPOFF: + error = swapoff(name); + break; + default: + error = 0; + break; + } + if (error == -1) { switch (errno) { case EBUSY: if (!doingall) - warnx("%s: device already in use", name); + warnx("%s: Device already in use", name); break; case EINVAL: if (which_prog == SWAPON) @@ -205,9 +724,9 @@ static int warn("%s", name); break; } - return(1); + return (NULL); } - return(0); + return (name); } static void @@ -217,7 +736,7 @@ usage(void) switch(orig_prog) { case SWAPON: case SWAPOFF: - fprintf(stderr, "[-F fstab] -aq | file ...\n"); + fprintf(stderr, "[-F fstab] -aLq | file ...\n"); break; case SWAPCTL: fprintf(stderr, "[-AghklmsU] [-a file ... | -d file ...]\n"); Index: sbin/swapon/swapon.8 =================================================================== --- sbin/swapon/swapon.8 (revision 252094) +++ sbin/swapon/swapon.8 (working copy) @@ -28,7 +28,7 @@ .\" @(#)swapon.8 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd June 23, 2008 +.Dd June 21, 2013 .Dt SWAPON 8 .Os .Sh NAME @@ -38,11 +38,11 @@ .Nm swapon .Oo Fl F Ar fstab .Oc -.Fl aq | Ar +.Fl aLq | Ar .Nm swapoff .Oo Fl F Ar fstab .Oc -.Fl aq | Ar +.Fl aLq | Ar .Nm swapctl .Op Fl AghklmsU .Oo @@ -74,8 +74,16 @@ option is used, all swap devices in .Pa /etc/fstab will be added, unless their .Dq noauto +or +.Dq late option is also set. If the +.Fl L +option is specified, +the swap devices with +.Dq late +option will be added as well as ones with no option. +If the .Fl q option is used informational messages will not be written to standard output when a swap device is added. @@ -89,8 +97,16 @@ option is used, all swap devices in .Pa /etc/fstab will be removed, unless their .Dq noauto +or +.Dq late option is also set. If the +.Fl L +option is specified, +the swap devices with +.Dq late +option will be removed as well as ones with no option. +If the .Fl q option is used informational messages will not be written to standard output when a swap device is removed. Index: share/man/man5/fstab.5 =================================================================== --- share/man/man5/fstab.5 (revision 252094) +++ share/man/man5/fstab.5 (working copy) @@ -32,7 +32,7 @@ .\" @(#)fstab.5 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd October 11, 2012 +.Dd June 21, 2013 .Dt FSTAB 5 .Os .Sh NAME @@ -185,6 +185,15 @@ variable must be used to extend the .Xr rc 8 startup script's list of network file system types. .Pp +If the option +.Dq late +is specified, the file system will be automatically mounted +at a stage of system startup after remote mount points are mounted. +For more detail about this option, +see +.Xr mount 8 +manual page. +.Pp The type of the mount is extracted from the .Fa fs_mntops field and stored separately in the @@ -202,6 +211,7 @@ then the file system whose name is given in the .Fa fs_file field is normally mounted read-write or read-only on the specified special file. +.Pp If .Fa fs_type is @@ -210,6 +220,25 @@ then the special file is made available as a piece space by the .Xr swapon 8 command at the end of the system reboot procedure. +For vnode-backed swap spaces, +.Dq file +is supported in the +.Fa fs_mntops +field. +When +.Fa fs_spec +is a +.Xr md 4 +device file +.Pq Do md Dc or Do md[0-9]* Dc +and +.Dq file +is specified in +.Fa fs_mntopts , +a +.Xr md 4 +device is created and the specified file is used as backing store of it, +and then it is used as a swap space. The fields other than .Fa fs_spec and Index: include/paths.h =================================================================== --- include/paths.h (revision 252094) +++ include/paths.h (working copy) @@ -57,6 +57,8 @@ #define _PATH_ETC "/etc" #define _PATH_FTPUSERS "/etc/ftpusers" #define _PATH_FWMEM "/dev/fwmem" +#define _PATH_GBDE "/sbin/gbde" +#define _PATH_GELI "/sbin/geli" #define _PATH_HALT "/sbin/halt" #ifdef COMPAT_32BIT #define _PATH_I18NMODULE "/usr/lib32/i18n" Index: etc/rc.d/swap1 =================================================================== --- etc/rc.d/swap1 (revision 252094) +++ etc/rc.d/swap1 (working copy) @@ -1,17 +0,0 @@ -#!/bin/sh -# -# $FreeBSD$ -# - -# PROVIDE: localswap -# REQUIRE: disks -# KEYWORD: nojail shutdown - -. /etc/rc.subr - -name="swap1" -start_cmd='swapon -aq' -stop_cmd=':' - -load_rc_config swap -run_rc_command "$1" Index: etc/rc.d/swap =================================================================== --- etc/rc.d/swap (revision 251659) +++ etc/rc.d/swap (working copy) @@ -3,15 +3,15 @@ # $FreeBSD$ # -# PROVIDE: localswap +# PROVIDE: swap # REQUIRE: disks # KEYWORD: nojail shutdown . /etc/rc.subr -name="swap1" +name="swap" start_cmd='swapon -aq' stop_cmd=':' -load_rc_config swap +load_rc_config $name run_rc_command "$1" Index: etc/rc.d/fsck =================================================================== --- etc/rc.d/fsck (revision 252094) +++ etc/rc.d/fsck (working copy) @@ -4,7 +4,7 @@ # # PROVIDE: fsck -# REQUIRE: localswap +# REQUIRE: swap # KEYWORD: nojail . /etc/rc.subr Index: etc/rc.d/mdconfig =================================================================== --- etc/rc.d/mdconfig (revision 252094) +++ etc/rc.d/mdconfig (working copy) @@ -28,7 +28,7 @@ # # PROVIDE: mdconfig -# REQUIRE: localswap root +# REQUIRE: swap root . /etc/rc.subr Index: etc/rc.d/swaplate =================================================================== --- etc/rc.d/swaplate (revision 0) +++ etc/rc.d/swaplate (working copy) @@ -0,0 +1,17 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +# PROVIDE: swaplate +# REQUIRE: mountlate +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="swaplate" +start_cmd='swapon -aLq' +stop_cmd='swapoff -aq' + +load_rc_config swap +run_rc_command "$1" Property changes on: etc/rc.d/swaplate ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: etc/defaults/rc.conf =================================================================== --- etc/defaults/rc.conf (revision 252094) +++ etc/defaults/rc.conf (working copy) @@ -85,9 +85,6 @@ geli_autodetach="YES" # Automatically detach on la #geli_da1_autodetach="NO" #geli_mirror_home_flags="-k /etc/geli/home.keys" -geli_swap_flags="-e aes -l 256 -s 4096 -d" # Options for GELI-encrypted - # swap partitions. - root_rw_mount="YES" # Set to NO to inhibit remounting root read-write. fsck_y_enable="NO" # Set to YES to do fsck -y if the initial preen fails. fsck_y_flags="" # Additional flags for fsck -y ----Next_Part(Mon_Jun_24_03_24_58_2013_798)---- ----Security_Multipart0(Mon_Jun_24_03_24_58_2013_483)-- Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.13 (FreeBSD) iEYEABECAAYFAlHHPXoACgkQTyzT2CeTzy225ACdEmcdiJuWWb8rGTAJzEW+QCTo TKsAn1RQGwlo6AhK9mwtdOTHpEuUj+p5 =kezt -----END PGP SIGNATURE----- ----Security_Multipart0(Mon_Jun_24_03_24_58_2013_483)----