From owner-freebsd-rc@FreeBSD.ORG Sun Jun 23 16:58:50 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 C1497F1D; Sun, 23 Jun 2013 16:58:50 +0000 (UTC) (envelope-from swhetzel@gmail.com) Received: from mail-bk0-x236.google.com (mail-bk0-x236.google.com [IPv6:2a00:1450:4008:c01::236]) by mx1.freebsd.org (Postfix) with ESMTP id 0570215D6; Sun, 23 Jun 2013 16:58:49 +0000 (UTC) Received: by mail-bk0-f54.google.com with SMTP id it16so3930009bkc.13 for ; Sun, 23 Jun 2013 09:58:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=62kCkak0882mBu5cjQj/4IN+/B8N9X+gKlOlIeljnDM=; b=NC4nVvRg8zuFjdxSZnpppdSFo+vDmamMk6D8pIYv24QMrmfT1DMS0IsQXZS8u8m8wP OZd6nNlSuWIbkIw0gSOEKtBBr6AguzTM7E7CyENXiJ6bk0yAMi1vAe9wzgPZS4e0yO1D V9vguhU8OjKzqv6SOOPhDIwVuB66QDtNxIm+95bkOxY351vv9Rl4FoBYEdo8p/j8paix E9AwQRVm+WAbtp21N8QZFSZ12xRRTNNqfys5+JlGBHhaRZn9c8+r+Tmyf1C9tfvVldb7 DdkmTWATB1UB2dNqxRLqifZATs4C7726pl3URDGb2uTGjW05aok1jmdZRK/2ZXnkUz3r TyVw== MIME-Version: 1.0 X-Received: by 10.204.228.207 with SMTP id jf15mr3162257bkb.16.1372006729124; Sun, 23 Jun 2013 09:58:49 -0700 (PDT) Received: by 10.205.129.204 with HTTP; Sun, 23 Jun 2013 09:58:48 -0700 (PDT) In-Reply-To: <20130623.035356.644417021040610458.hrs@allbsd.org> References: <20130623.035356.644417021040610458.hrs@allbsd.org> Date: Sun, 23 Jun 2013 11:58:48 -0500 Message-ID: Subject: Re: RFC: swapon(8) vnode-backed md and gbde/geli encryption support From: Scot Hetzel To: Hiroki Sato Content-Type: text/plain; charset=ISO-8859-1 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 16:58:50 -0000 On Sat, Jun 22, 2013 at 1:53 PM, Hiroki Sato wrote: > Hi, > > I created a patchset to add support of automatic generation of > vnode-backed md(4) devices and gbde/geli geom providers to swapon(8) > via /etc/fstab. We already have equivalent functionality by using > rc.d scripts. This simplifies rc.d scripts and fixes a race between > mdconfig/gbde/geli and swapon/swapoff by using /etc/fstab. > > More specifically, the following specification will be supported: > > /dev/ada1p1.bde none swap sw 0 0 > /dev/ada1p2.eli none swap sw 0 0 > md none swap sw,file=/swap.bin 0 0 > md10 none swap sw,file=/swap10.bin 0 0 > md12 none swap sw,file=/usr/swap12.bin,late 0 0 > > Currently, rc.d/swap1, rc.d/encswap handles entries with FSTAB_SW and > then rc.d/addswap for additional swap space specified in rc.conf. > The rc.d/addswap script runs before NETWORKING, so it is difficult to > add a swap space by using a file via NFS on a diskless client. The > "late" keyword in /etc/fstab will give more flexibility in such a > case. > > So, the changes to rc.d scripts are the following: > > rc.d/encswap -> (removed) > rc.d/swap1 -> rc.d/swap > rc.d/swaplate -> (added) > > rc.d/addswap is not removed in the patchset, but is it still > necessary? I do not think using combination of rc.d scripts to > support md(4) device generation for swap spaces is robust, and I > believe /etc/fstab is sufficient for the same functionality. > > Any comments are welcome. Thank you. > The only thing I see is that you are hard coding the geli_swap_flags (i.e. -e aes -l 256 -s 4096 -d) into swapon. It would be better to have swapon read the /etc/fstab file to get these values: /dev/ada1p2.eli none swap sw,ealgo=aes,keylen=256,sectorsize=4096 0 0 /dev/ada2p2.eli none swap sw 0 0 What you could do is that if no options are specified in the swap file, swapon would then use default values for ealgo=aes, keylen=256 and sectorsize=4096. geli onetime [-d] [-a aalgo] [-e ealgo] [-l keylen] [-s sectorsize] prov The options for the geli encrypted swap file in /etc/fstab would then become: aalgo ealgo keylen sectorsize Note: the '-d' option would still be hard coded. -- DISCLAIMER: No electrons were maimed while sending this message. Only slightly bruised. 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)---- From owner-freebsd-rc@FreeBSD.ORG Mon Jun 24 11:06:52 2013 Return-Path: Delivered-To: freebsd-rc@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 75C87156 for ; Mon, 24 Jun 2013 11:06:52 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) by mx1.freebsd.org (Postfix) with ESMTP id 66DDD1DD8 for ; Mon, 24 Jun 2013 11:06:52 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.7/8.14.7) with ESMTP id r5OB6qP5001108 for ; Mon, 24 Jun 2013 11:06:52 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.7/8.14.7/Submit) id r5OB6p2l001106 for freebsd-rc@FreeBSD.org; Mon, 24 Jun 2013 11:06:51 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 24 Jun 2013 11:06:51 GMT Message-Id: <201306241106.r5OB6p2l001106@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: gnats set sender to owner-bugmaster@FreeBSD.org using -f From: FreeBSD bugmaster To: freebsd-rc@FreeBSD.org Subject: Current problem reports assigned to 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: Mon, 24 Jun 2013 11:06:52 -0000 Note: to view an individual PR, use: http://www.freebsd.org/cgi/query-pr.cgi?pr=(number). The following is a listing of current problems submitted by FreeBSD users. These represent problem reports covering all versions including experimental development code and obsolete releases. S Tracker Resp. Description -------------------------------------------------------------------------------- o conf/179828 rc [rc.d] [PATCH] rc.d/syslogd link socket to /dev/log fa o conf/177217 rc [patch] rc.d/ddb -- squelch warning when ddb_enable=ye o conf/177089 rc ntpd startup script does not work well o conf/176347 rc [rc.conf] [patch] Add support for firewall deny lists o conf/176181 rc [rc.subr] rc.subr emitting warnings for non-defined xx o conf/175311 rc [patch] add "dump" fs type support to rc.d/dumpon o conf/175105 rc /etc/rc.d/* and more: syntax 'return_boolean_cmd && do o conf/175079 rc [rc.subr] [patch] rc.subr poorly handles recursive run o bin/173153 rc [rc.d] [patch] $netwait_ip should be more parallel o conf/172787 rc [rc.conf] FreeBSD 9.x broken alias syntax on vlan inte o conf/172532 rc [rc] [patch] service routing restart always fails o conf/169047 rc [rc.subr] [patch] /etc/rc.subr not checking some scrip p bin/168544 rc [patch] [rc]: addswap-mounted swapfiles cause panic on o conf/167566 rc [rc.d] [patch] ipdivert module loading vs. ipfw rc.d o o conf/166484 rc [rc] [patch] rc.initdiskless patch for different major o conf/165769 rc [rc][jai][ipv6] IPv6 Initialization on external iface o conf/164393 rc [rc.d] restarting netif with static addresses doesn't o conf/163508 rc [rc.subr] [patch] Add "enable" and "disable" commands o conf/163488 rc Confusing explanation in defaults/rc.conf o conf/163321 rc [rc.conf] [patch] allow _fib syntax in rc.conf o conf/162642 rc .sh scripts in /usr/local/etc/rc.d get executed, not s o conf/161107 rc [rc] stop_boot in mountcritlocal usage is incorrect. o conf/160403 rc [rc] [patch] concurrently running rc-scripts during bo o conf/160240 rc rc.d/mdconfig and mdconfig2 should autoset $_type to v o conf/159846 rc [rc.conf] routing_stop_inet6() logic doesn't handle ip o conf/158557 rc [patch] /etc/rc.d/pf broken messages o conf/158127 rc [patch] remount_optional option in rc.initdiskless doe o conf/153666 rc [rc.d][patch] mount filesystems from fstab over zfs da o conf/153200 rc post-boot /etc/rc.d/network_ipv6 start can miss neighb o conf/153123 rc [rc] [patch] add gsched rc file to automatically inser o conf/150474 rc [patch] rc.d/accounting: Add ability to set location o o conf/149867 rc [PATCH] rc.d script to manage multiple FIBS (kern opti o conf/149831 rc [PATCH] add support to /etc/rc.d/jail for delegating Z o conf/148656 rc rc.firewall(8): {oip} and {iip} variables in rc.firewa o conf/147685 rc [rc.d] [patch] new feature for /etc/rc.d/fsck o conf/147444 rc [rc.d] [patch] /etc/rc.d/zfs stop not called on reboot o conf/146053 rc [patch] [request] shutdown of jails breaks inter-jail o conf/145399 rc [patch] rc.d scripts are unable to start/stop programs o conf/145009 rc [patch] rc.subr(8): rc.conf should allow mac label con o conf/143637 rc [patch] ntpdate(8) support for ntp-servers supplied by o conf/143085 rc [patch] ftp-proxy(8) rc(8) with multiple instances a conf/142973 rc [jail] [patch] Strange counter init value in jail rc o conf/142434 rc [patch] Add cpuset(1) support to rc.subr(8) o conf/142304 rc rc.conf(5): mdconfig and mdconfig2 rc.d scripts lack e o conf/141909 rc rc.subr(8): [patch] add rc.conf.d support to /usr/loca o conf/141678 rc [patch] A minor enhancement to how /etc/rc.d/jail dete o conf/140440 rc [patch] allow local command files in rc.{suspend,resum o conf/140261 rc [patch] Improve flexibility of mdconfig2 startup scrip p conf/138208 rc [rc.d] [patch] Making rc.firewall (workstation) IPv6 a o conf/137271 rc [rc.d] Cannot update /etc/host.conf when root filesyst o conf/136624 rc [rc.d] sysctl variables for ipnat are not applied on b o conf/134918 rc [patch] rc.subr fails to detect perl daemons o conf/134660 rc [patch] rc-script for initializing ng_netflow+ng_ipfw o conf/134333 rc PPP configuration problem in the rc.d scripts in combi o conf/133890 rc [patch] sshd(8): add multiple profiles to the rc.d scr o conf/128299 rc [patch] /etc/rc.d/geli does not mount partitions using o conf/126392 rc [patch] rc.conf ifconfig_xx keywords cannot be escaped o conf/124747 rc [patch] savecore can't create dump from encrypted swap o conf/124248 rc [jail] [patch] add support for nice value for rc.d/jai o conf/123734 rc [patch] Chipset VIA CX700 requires extra initializatio o conf/123222 rc [patch] Add rtprio(1)/idprio(1) support to rc.subr(8). o conf/122968 rc [rc.d] /etc/rc.d/addswap: md swapfile multiplication a o conf/122477 rc [patch] /etc/rc.d/mdconfig and mdconfig2 are ignoring o conf/122170 rc [patch] [request] New feature: notify admin via page o o kern/121566 rc [nfs] [request] [patch] ethernet iface should be broug a conf/119874 rc [patch] "/etc/rc.d/pf reload" fails if there are macro o conf/119076 rc [patch] [rc.d] /etc/rc.d/netif tries to remove alias a o bin/118325 rc [patch] [request] new periodic script to test statuses f conf/118255 rc savecore never finding kernel core dumps (rcorder prob f conf/117935 rc [patch] ppp fails to start at boot because of missing f conf/113915 rc [ndis] [patch] ndis wireless driver fails to associate o conf/108589 rc rtsol(8) fails due to default ipfw rules o conf/106009 rc [ppp] [patch] [request] Fix pppoed startup script to p f conf/105689 rc [ppp] [request] syslogd starts too late at boot f conf/105145 rc [ppp] [patch] [request] add redial function to rc.d/pp f conf/104549 rc [patch] rc.d/nfsd needs special _find_processes functi o conf/102700 rc [geli] [patch] Add encrypted /tmp support to GELI/GBDE o conf/93815 rc [patch] Adds in the ability to save ipfw rules to rc.d f conf/92523 rc [patch] allow rc scripts to kill process after a timeo o conf/89870 rc [patch] [request] make netif verbose rc.conf toggle a conf/88913 rc [patch] wrapper support for rc.subr o conf/85819 rc [patch] script allowing multiuser mode in spite of fsc o kern/81006 rc ipnat not working with tunnel interfaces on startup o conf/77663 rc Suggestion: add /etc/rc.d/addnetswap after addcritremo o conf/73677 rc [patch] add support for powernow states to power_profi a conf/58939 rc [patch] dumb little hack for /etc/rc.firewall{,6} f conf/56934 rc [patch] rc.firewall rules for natd expect an interface f conf/13775 rc multi-user boot may hang in NIS environment 88 problems total. From owner-freebsd-rc@FreeBSD.ORG Thu Jun 27 08:07:16 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 22D91567; Thu, 27 Jun 2013 08:07:16 +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 C61C0110C; Thu, 27 Jun 2013 08:07:14 +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 r5R86uUO034136 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 27 Jun 2013 17:07:06 +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 r5R86s1a002546; Thu, 27 Jun 2013 17:06:56 +0900 (JST) (envelope-from hrs@FreeBSD.org) Date: Thu, 27 Jun 2013 17:06:42 +0900 (JST) Message-Id: <20130627.170642.243849725172853011.hrs@allbsd.org> To: freebsd-current@FreeBSD.org, freebsd-rc@FreeBSD.org Subject: Re: RFC: swapon(8) vnode-backed md and gbde/geli encryption support From: Hiroki Sato In-Reply-To: <20130624.032458.2116947740119973135.hrs@allbsd.org> <20130623.035356.644417021040610458.hrs@allbsd.org> References: <20130623.035356.644417021040610458.hrs@allbsd.org> <20130624.032458.2116947740119973135.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(Thu_Jun_27_17_06_42_2013_463)--" 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]); Thu, 27 Jun 2013 17:07:07 +0900 (JST) X-Spam-Status: No, score=-89.3 required=13.0 tests=CONTENT_TYPE_PRESENT, DIRECTOCNDYN,DYN_PBL,ONLY1HOPDIRECT,QENCPTR2,RCVD_IN_PBL,SAMEHELOBY2HOP, USER_IN_WHITELIST autolearn=no version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on gatekeeper.allbsd.org Cc: swhetzel@gmail.com, wblock@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: Thu, 27 Jun 2013 08:07:16 -0000 ----Security_Multipart0(Thu_Jun_27_17_06_42_2013_463)-- Content-Type: Multipart/Mixed; boundary="--Next_Part(Thu_Jun_27_17_06_42_2013_845)--" Content-Transfer-Encoding: 7bit ----Next_Part(Thu_Jun_27_17_06_42_2013_845)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hiroki Sato wrote in <20130623.035356.644417021040610458.hrs@allbsd.org>: hr> Hi, hr> hr> I created a patchset to add support of automatic generation of hr> vnode-backed md(4) devices and gbde/geli geom providers to swapon(8) hr> via /etc/fstab. We already have equivalent functionality by using hr> rc.d scripts. This simplifies rc.d scripts and fixes a race between hr> mdconfig/gbde/geli and swapon/swapoff by using /etc/fstab. A slightly revised patch is attached. I will commit this today. -- Hiroki ----Next_Part(Thu_Jun_27_17_06_42_2013_845)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="swap_20130627-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 accepts 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/addswap -> just display a warning message if is defined. 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: 1 week ==== 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/addswap =================================================================== --- etc/rc.d/addswap (revision 252094) +++ etc/rc.d/addswap (working copy) @@ -13,57 +13,11 @@ . /etc/rc.subr name="addswap" -start_cmd="addswap_start" -stop_cmd="addswap_stop" +start_cmd=":" +stop_cmd=":" +rcvar= -addswap_start() -{ - case ${swapfile} in - [Nn][Oo] | '') - ;; - *) - if [ -w "${swapfile}" ]; then - check_startmsgs && echo "Adding ${swapfile} as additional swap" +set_rcvar_obsolete swapfile - if [ -n "${swapfile_mdunit}" ]; then - mdev="/dev/md${swapfile_mdunit#md}" - mdconfig -a -t vnode -f "${swapfile}" -u ${swapfile_mdunit} - else - mdev="/dev/`mdconfig -a -t vnode -f "${swapfile}"`" - fi - - if [ $? -eq 0 ]; then - swapon ${mdev} - else - echo "error creating swapfile device" - fi - fi - ;; - esac -} - -addswap_stop() -{ - case ${swapfile} in - [Nn][Oo] | '') - ;; - *) - if [ -n "${swapfile_mdunit}" ]; then - mdev="/dev/md${swapfile_mdunit#md}" - else - mdev="/dev/`mdconfig -lv | grep "${swapfile}" | cut -f1`" - swapfile_mdunit=${mdev#md} - fi - if [ -n "${swapfile_mdunit}" ]; then - swapctl -l | grep -q ${mdev} - if [ $? -eq 0 ]; then - echo "Dismounting swapfile ${swapfile}" - swapoff ${mdev} && mdconfig -d -u ${swapfile_mdunit} - fi - fi - ;; - esac -} - 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:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: etc/defaults/rc.conf =================================================================== --- etc/defaults/rc.conf (revision 252094) +++ etc/defaults/rc.conf (working copy) @@ -32,8 +32,6 @@ early_late_divider="FILESYSTEMS" # Script that sep always_force_depends="NO" # Set to check that indicated dependencies are # running during boot (can increase boot time). -swapfile="NO" # Set to name of swapfile if aux swapfile desired. -swapfile_mdunit="99" # Swapfile md(4) unit number created by mdconfig(8). apm_enable="NO" # Set to YES to enable APM BIOS functions (or NO). apmd_enable="NO" # Run apmd to handle APM event from userland. apmd_flags="" # Flags to apmd (if enabled). @@ -85,9 +83,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(Thu_Jun_27_17_06_42_2013_845)---- ----Security_Multipart0(Thu_Jun_27_17_06_42_2013_463)-- Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.13 (FreeBSD) iEYEABECAAYFAlHL8pIACgkQTyzT2CeTzy2xOQCgt3A70bClskSprxiorPkKTIdj CXYAnRHTujWShABAAHTtSopc9yo7V+LO =7lnX -----END PGP SIGNATURE----- ----Security_Multipart0(Thu_Jun_27_17_06_42_2013_463)---- From owner-freebsd-rc@FreeBSD.ORG Thu Jun 27 16:59:35 2013 Return-Path: Delivered-To: freebsd-rc@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id AA1E4BDD; Thu, 27 Jun 2013 16:59:35 +0000 (UTC) (envelope-from crees@bayofrum.net) Received: from mk-outboundfilter-1.mail.uk.tiscali.com (mk-outboundfilter-1.mail.uk.tiscali.com [212.74.114.37]) by mx1.freebsd.org (Postfix) with ESMTP id 6A6FF125D; Thu, 27 Jun 2013 16:59:34 +0000 (UTC) X-Trace: 734424731/mk-outboundfilter-1.mail.uk.tiscali.com/PIPEX/$ON_NET_AUTH_ACCEPTED/Talk_Talk_Customer/2.102.6.254/None/crees@bayofrum.net X-SBRS: None X-RemoteIP: 2.102.6.254 X-IP-MAIL-FROM: crees@bayofrum.net X-SMTP-AUTH: bayofrum@uwclub.net X-MUA: Apple Mail (2.1085) X-IP-BHB: Once X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AnIGAC5uzFECZgb+/2dsb2JhbABbgwnABX8XdIIjAQEEAScTHCMFCwsOODkeBhOICAq7II9VB4MCYwOdU4s3gxI7 X-IronPort-AV: E=Sophos;i="4.87,953,1363132800"; d="scan'208";a="734424731" X-IP-Direction: OUT Received: from host-2-102-6-254.as13285.net (HELO pegasus.bayofrum.net) ([2.102.6.254]) by smtp.pipex.tiscali.co.uk with ESMTP; 27 Jun 2013 17:59:32 +0100 Received: from zeus.bayofrum.net (zeus.bayofrum.net [192.168.1.151]) by pegasus.bayofrum.net (Postfix) with ESMTPA id EB0CD2B406; Thu, 27 Jun 2013 17:57:42 +0100 (BST) References: <20130623.035356.644417021040610458.hrs@allbsd.org> <20130624.032458.2116947740119973135.hrs@allbsd.org> <20130627.170642.243849725172853011.hrs@allbsd.org> In-Reply-To: <20130627.170642.243849725172853011.hrs@allbsd.org> Mime-Version: 1.0 (Apple Message framework v1085) Content-Type: text/plain; charset=us-ascii Message-Id: <3F225AB1-8111-4841-97D7-0B525F9CC96C@bayofrum.net> Content-Transfer-Encoding: 7bit From: Chris Rees Subject: Re: RFC: swapon(8) vnode-backed md and gbde/geli encryption support Date: Thu, 27 Jun 2013 17:57:43 +0100 To: Hiroki Sato X-Mailer: Apple Mail (2.1085) X-bayofrum-MailScanner-Information: Please contact the ISP for more information X-bayofrum-MailScanner-ID: EB0CD2B406.ACE3B X-bayofrum-MailScanner: Found to be clean X-bayofrum-MailScanner-From: crees@bayofrum.net X-Spam-Status: No Cc: swhetzel@gmail.com, freebsd-current@FreeBSD.org, freebsd-rc@FreeBSD.org, wblock@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: Thu, 27 Jun 2013 16:59:35 -0000 On 27 Jun 2013, at 09:06, Hiroki Sato wrote: > Hiroki Sato wrote > in <20130623.035356.644417021040610458.hrs@allbsd.org>: > > hr> Hi, > hr> > hr> I created a patchset to add support of automatic generation of > hr> vnode-backed md(4) devices and gbde/geli geom providers to swapon(8) > hr> via /etc/fstab. We already have equivalent functionality by using > hr> rc.d scripts. This simplifies rc.d scripts and fixes a race between > hr> mdconfig/gbde/geli and swapon/swapoff by using /etc/fstab. > > A slightly revised patch is attached. I will commit this today. > > -- Hiroki > - 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 accepts 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/addswap -> just display a warning message if is defined. > 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: 1 week Looks fantastic-- better than hacking around in shell scripts I suppose :) Chris -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.