Skip site navigation (1)Skip section navigation (2)


| raw e-mail | index | archive | help
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 <src.opts.mk>
+
+HAS_TESTS=
+SUBDIR.${MK_TESTS}+= tests
+
 .include <bsd.prog.mk>
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 <string.h>
 #include <unistd.h>
 
+#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 <bsd.test.mk>
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 <ronald@FreeBSD.org>
+#
+# 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
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?>