From nobody Thu Jun 26 09:22:26 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4bSY9v0XMSz60JTF; Thu, 26 Jun 2025 09:22:27 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4bSY9t2wSSz3Zrs; Thu, 26 Jun 2025 09:22:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1750929746; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=3WaEvNXdKYClqCs9B2Ffd+ovfUXrqnbMr76JMgBXhMI=; b=t5dKR65sPil7L62UXe/TlGUSvqu+LmlVcL6pMugpOTcY325roPiRi4/MfCcVgDht68jAAa v8LtPIgg1N92ZLu7rUEwTnfyAD5WgkilF96+/BUXcxsomJFGCGwg7Hhfxkz31UGVj4Cyiz UBJq96xpkwe5ggSrWPGyaVP6H9mDCIEmTsbOifX0aLkWiiuE2SzEDCPxfxJh3G4yzutLQQ fQOwqy1gDyYDUaN4YhOZFY8mjqV3c6nEvRzM4ps+fwrBnZa74URwuhi+4fmdNpK3WwjkrI iMJKg/HcsqOR/pRtWjQMfn2qtHyZotfxtGX9dCLSmgN/84H/LO7lzB1i/D9/WA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1750929746; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=3WaEvNXdKYClqCs9B2Ffd+ovfUXrqnbMr76JMgBXhMI=; b=UsLbOAdLSI6sW3aHRgVy+qZaiVROn7p+PJDrmAuVs8h8pAXYF1724gt9GBiCPcZfA838y4 LBw1kVjvc7mcFo5qiHiLzFfBKgPDMRVYE8EpznhhPV0U6Ul1Ka4Qv2vujph3n03x8X4rgb MUkGnuOUHoZ0kqUtSJsYGhkP1vXxCJhhjzjQW5Hg0oKpqln7UfGwGAQGhYAwtKpVx90BeW Zoz4sK6GisalDS8w4wJ5rhTjDzLuG0tmSMTdK8NSeSYmAVyKRy5HYilVl1R70kOH4q9SKt PQe3Rp+QN0zgiMz1pXGkdM/vihYWYogstxoUyV0KnrFGWp3SlnrN1l12XUH0Vw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1750929746; a=rsa-sha256; cv=none; b=JGzMbq74QXb53ocY0qwbVuuOGOSArwM/MIaEV7o1odbT70QQdMMuIp/g3hgUw0h6PklZ3X xwFd4J2o+9XAR9Onj3Vg7eweTWevYK8VLHAPV8XG/svXpNJu2GlHtC2zjCmEyQEs/nq9jP kBGp+CW27uhbOFCIOuWiJ3hGurisQrWx3WyCuQs7/sHCdHUn7Xlz6P0QUSWdKdiCiN6kVP lh2Z/rNufWevfwdMYuzOiObU48cofWaeGOPT7ReWUrgHrHmxSg9hq9x3+ac886+63wojNc mz6+m6CeFq7Z8+SVLyQ+nU38O4FdHYtO7/xZSN1os1UwB1f3T1k15Qq1vLedYQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4bSY9t1h4TzxWp; Thu, 26 Jun 2025 09:22:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 55Q9MQJS085047; Thu, 26 Jun 2025 09:22:26 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 55Q9MQW9085032; Thu, 26 Jun 2025 09:22:26 GMT (envelope-from git) Date: Thu, 26 Jun 2025 09:22:26 GMT Message-Id: <202506260922.55Q9MQW9085032@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Ronald Klop Subject: git: 1ee33e3a578c - main - swapon: parse md.eli device for encrypted swapfile from fstab List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: ronald X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 1ee33e3a578c35ff0e8ef5db87a8005f1f99546a Auto-Submitted: auto-generated The branch main has been updated by ronald: URL: https://cgit.FreeBSD.org/src/commit/?id=1ee33e3a578c35ff0e8ef5db87a8005f1f99546a commit 1ee33e3a578c35ff0e8ef5db87a8005f1f99546a Author: Ronald Klop AuthorDate: 2025-02-06 21:50:46 +0000 Commit: Ronald Klop CommitDate: 2025-06-26 09:22:01 +0000 swapon: parse md.eli device for encrypted swapfile from fstab Summary: Although fstab(5) suggests usage of md(4) and an .eli suffix in the same paragraph, the combination did not work. This patch adds a bit of parsing, creates the md device and then passes that device to the *_geli function. Add unit tests. PR: 186252 Approved by: delphij MFC after: 2 weeks Relnotes: yes Differential Revision: https://reviews.freebsd.org/D48874 --- etc/mtree/BSD.tests.dist | 2 + sbin/swapon/Makefile | 5 ++ sbin/swapon/swapon.c | 50 ++++++++--- sbin/swapon/tests/Makefile | 5 ++ sbin/swapon/tests/swapon_test.sh | 181 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 233 insertions(+), 10 deletions(-) diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist index 183c88038742..b3b2b61da143 100644 --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -513,6 +513,8 @@ .. savecore .. + swapon + .. sysctl .. .. diff --git a/sbin/swapon/Makefile b/sbin/swapon/Makefile index ef87c9668dd7..0c034338a533 100644 --- a/sbin/swapon/Makefile +++ b/sbin/swapon/Makefile @@ -8,4 +8,9 @@ MLINKS+=swapon.8 swapctl.8 LIBADD= util +.include + +HAS_TESTS= +SUBDIR.${MK_TESTS}+= tests + .include diff --git a/sbin/swapon/swapon.c b/sbin/swapon/swapon.c index a09f2598e2ac..3dff4df5e63f 100644 --- a/sbin/swapon/swapon.c +++ b/sbin/swapon/swapon.c @@ -54,6 +54,8 @@ #include #include +#define DOT_ELI ".eli" + static void usage(void) __dead2; static const char *swap_on_off(const char *, int, char *); static const char *swap_on_off_geli(const char *, char *, int); @@ -230,15 +232,18 @@ swap_on_off(const char *name, int doingall, char *mntops) (fnmatch(_PATH_DEV MD_NAME "[0-9]*", name, 0) == 0 || fnmatch(MD_NAME "[0-9]*", name, 0) == 0 || strncmp(_PATH_DEV MD_NAME, name, - sizeof(_PATH_DEV) + sizeof(MD_NAME)) == 0 || - strncmp(MD_NAME, name, sizeof(MD_NAME)) == 0)) + sizeof(_PATH_DEV MD_NAME)) == 0 || + strncmp(MD_NAME, name, sizeof(MD_NAME)) == 0 || + strncmp(_PATH_DEV MD_NAME DOT_ELI, name, + sizeof(_PATH_DEV MD_NAME DOT_ELI)) == 0 || + strncmp(MD_NAME DOT_ELI, name, sizeof(MD_NAME DOT_ELI)) == 0)) return (swap_on_off_md(name, mntops, doingall)); basebuf = strdup(name); base = basename(basebuf); /* Swap on encrypted device by GEOM_ELI. */ - if (fnmatch("*.eli", base, 0) == 0) { + if (fnmatch("*" DOT_ELI, base, 0) == 0) { free(basebuf); return (swap_on_off_geli(name, mntops, doingall)); } @@ -327,6 +332,8 @@ swap_on_geli_args(const char *mntops) return (NULL); } Tflag = " -T "; + } else if ((p = strstr(token, "file=")) == token) { + /* ignore known option */ } else if (strcmp(token, "late") == 0) { /* ignore known option */ } else if (strcmp(token, "noauto") == 0) { @@ -416,24 +423,38 @@ swap_on_off_md(const char *name, char *mntops, int doingall) char *p, *vnodefile; size_t linelen; u_long ul; + const char *suffix; + char *devbuf, *dname; + int name_len; fd = -1; sfd = NULL; - if (strlen(name) == (sizeof(MD_NAME) - 1)) + devbuf = strdup(name); + name_len = strlen(name) - strlen(DOT_ELI); + if (name_len > 0 && strcmp(suffix = &name[name_len], DOT_ELI) == 0) { + suffix++; + devbuf[name_len] = '\0'; + } else + suffix = NULL; + /* dname will be name without /dev/ prefix and .eli suffix */ + dname = basename(devbuf); + if (strlen(dname) == (sizeof(MD_NAME) - 1)) mdunit = -1; else { errno = 0; - ul = strtoul(name + 2, &p, 10); + ul = strtoul(dname + 2, &p, 10); if (errno == 0) { if (*p != '\0' || ul > INT_MAX) errno = EINVAL; } if (errno) { - warn("Bad device unit: %s", name); + warn("Bad device unit: %s", dname); + free(devbuf); return (NULL); } mdunit = (int)ul; } + free(devbuf); vnodefile = NULL; if ((p = strstr(mntops, "file=")) != NULL) { @@ -573,10 +594,19 @@ swap_on_off_md(const char *name, char *mntops, int doingall) } } } - snprintf(mdpath, sizeof(mdpath), "%s%s%d", _PATH_DEV, - MD_NAME, mdunit); - mdpath[sizeof(mdpath) - 1] = '\0'; - ret = swap_on_off_sfile(mdpath, doingall); + + if (suffix != NULL && strcmp("eli", suffix) == 0) { + /* Swap on encrypted device by GEOM_ELI. */ + snprintf(mdpath, sizeof(mdpath), "%s%s%d" DOT_ELI, _PATH_DEV, + MD_NAME, mdunit); + mdpath[sizeof(mdpath) - 1] = '\0'; + ret = swap_on_off_geli(mdpath, mntops, doingall); + } else { + snprintf(mdpath, sizeof(mdpath), "%s%s%d", _PATH_DEV, + MD_NAME, mdunit); + mdpath[sizeof(mdpath) - 1] = '\0'; + ret = swap_on_off_sfile(mdpath, doingall); + } if (which_prog == SWAPOFF) { if (ret != NULL) { diff --git a/sbin/swapon/tests/Makefile b/sbin/swapon/tests/Makefile new file mode 100644 index 000000000000..aa0c9cf202d6 --- /dev/null +++ b/sbin/swapon/tests/Makefile @@ -0,0 +1,5 @@ +ATF_TESTS_SH= swapon_test + +TEST_METADATA.swapon_test+= required_user="root" + +.include diff --git a/sbin/swapon/tests/swapon_test.sh b/sbin/swapon/tests/swapon_test.sh new file mode 100755 index 000000000000..3c4286cd6815 --- /dev/null +++ b/sbin/swapon/tests/swapon_test.sh @@ -0,0 +1,181 @@ +# Copyright (c) 2025 Ronald Klop +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +atf_test_case attach_mdX cleanup +attach_mdX_head() +{ + atf_set "descr" "mdX device should attach" +} +attach_mdX_body() +{ + # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md + atf_check -s exit:0 -x "truncate -s 10k swapfile" + atf_check -s exit:0 -o save:fstab.out -x "echo 'md3 none swap sw,file=swapfile 0 0'" + atf_check -s exit:0 -o match:"swapon: adding /dev/md3 as swap device" -x "swapon -F fstab.out -a" +} +attach_mdX_cleanup() +{ + swapoff -F fstab.out -a +} + +### +atf_test_case attach_dev_mdX cleanup +attach_dev_mdX_head() +{ + atf_set "descr" "/dev/mdX device should attach" +} +attach_dev_mdX_body() +{ + # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md + atf_check -s exit:0 -x "truncate -s 10k swapfile" + atf_check -s exit:0 -o save:fstab.out -x "echo '/dev/md3 none swap sw,file=swapfile 0 0'" + atf_check -s exit:0 -o match:"swapon: adding /dev/md3 as swap device" -x "swapon -F fstab.out -a" +} +attach_dev_mdX_cleanup() +{ + swapoff -F fstab.out -a +} + +### +atf_test_case attach_md cleanup +attach_md_head() +{ + atf_set "descr" "mdX device should attach" +} +attach_md_body() +{ + # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md + atf_check -s exit:0 -x "truncate -s 10k swapfile" + atf_check -s exit:0 -o save:fstab.out -x "echo 'md none swap sw,file=swapfile 0 0'" + atf_check -s exit:0 -o match:"swapon: adding /dev/md0 as swap device" -x "swapon -F fstab.out -a" +} +attach_md_cleanup() +{ + swapoff -F fstab.out -a +} + +### +atf_test_case attach_dev_md cleanup +attach_dev_md_head() +{ + atf_set "descr" "/dev/md device should attach" +} +attach_dev_md_body() +{ + # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md + atf_check -s exit:0 -x "truncate -s 10k swapfile" + atf_check -s exit:0 -o save:fstab.out -x "echo '/dev/md none swap sw,file=swapfile 0 0'" + atf_check -s exit:0 -o match:"swapon: adding /dev/md0 as swap device" -x "swapon -F fstab.out -a" +} +attach_dev_md_cleanup() +{ + swapoff -F fstab.out -a +} + +### +atf_test_case attach_mdX_eli cleanup +attach_mdX_eli_head() +{ + atf_set "descr" "mdX.eli device should attach" +} +attach_mdX_eli_body() +{ + # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md + atf_check -s exit:0 -x "truncate -s 10k swapfile" + atf_check -s exit:0 -o save:fstab.out -x "echo 'md3.eli none swap sw,file=swapfile 0 0'" + atf_check -s exit:0 -o match:"swapon: adding /dev/md3.eli as swap device" -x "swapon -F fstab.out -a" +} +attach_mdX_eli_cleanup() +{ + swapoff -F fstab.out -a +} + +### +atf_test_case attach_dev_mdX_eli cleanup +attach_dev_mdX_eli_head() +{ + atf_set "descr" "/dev/mdX.eli device should attach" +} +attach_dev_mdX_eli_body() +{ + # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md + atf_check -s exit:0 -x "truncate -s 10k swapfile" + atf_check -s exit:0 -o save:fstab.out -x "echo '/dev/md3.eli none swap sw,file=swapfile 0 0'" + atf_check -s exit:0 -o match:"swapon: adding /dev/md3.eli as swap device" -x "swapon -F fstab.out -a" +} +attach_dev_mdX_eli_cleanup() +{ + swapoff -F fstab.out -a +} + +### +atf_test_case attach_md_eli cleanup +attach_md_eli_head() +{ + atf_set "descr" "md.eli device should attach" +} +attach_md_eli_body() +{ + # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md + atf_check -s exit:0 -x "truncate -s 10k swapfile" + atf_check -s exit:0 -o save:fstab.out -x "echo 'md.eli none swap sw,file=swapfile 0 0'" + atf_check -s exit:0 -o match:"swapon: adding /dev/md0.eli as swap device" -x "swapon -F fstab.out -a" +} +attach_md_eli_cleanup() +{ + swapoff -F fstab.out -a +} + +### +atf_test_case attach_dev_md_eli cleanup +attach_dev_md_eli_head() +{ + atf_set "descr" "/dev/md.eli device should attach" +} +attach_dev_md_eli_body() +{ + # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md + atf_check -s exit:0 -x "truncate -s 10k swapfile" + atf_check -s exit:0 -o save:fstab.out -x "echo '/dev/md.eli none swap sw,file=swapfile 0 0'" + atf_check -s exit:0 -o match:"swapon: adding /dev/md0.eli as swap device" -x "swapon -F fstab.out -a" +} +attach_dev_md_eli_cleanup() +{ + swapoff -F fstab.out -a +} + +### +atf_init_test_cases() +{ + atf_add_test_case attach_mdX + atf_add_test_case attach_dev_mdX + atf_add_test_case attach_md + atf_add_test_case attach_dev_md + + atf_add_test_case attach_mdX_eli + atf_add_test_case attach_dev_mdX_eli + atf_add_test_case attach_md_eli + atf_add_test_case attach_dev_md_eli +}