git: e0dfe185cbca - main - jail(8): add support for ZFS datasets

From: Alexander Leidinger <netchild_at_FreeBSD.org>
Date: Wed, 17 Jan 2024 07:41:00 UTC
The branch main has been updated by netchild:

URL: https://cgit.FreeBSD.org/src/commit/?id=e0dfe185cbcae48b4c4493ed4c2626c46181eb80

commit e0dfe185cbcae48b4c4493ed4c2626c46181eb80
Author:     Alexander Leidinger <netchild@FreeBSD.org>
AuthorDate: 2024-01-17 07:40:40 +0000
Commit:     Alexander Leidinger <netchild@FreeBSD.org>
CommitDate: 2024-01-17 07:40:40 +0000

    jail(8): add support for ZFS datasets
    
    Add zfs.dataset to jail(8) to add a list of ZFS datasets.
    Bump FreeBSD version for jail managers to switch to native
    dataset support.
    
    Datasets are attached to the jail after the jail creation and
    before the execution of any start command. Unlike current
    implementations in jail managers which attach datasets after
    the start command, this allows the zfs rc.d script to mount
    the datasets on start.
    
    Discussed with: jamie
---
 sys/sys/param.h         |  2 +-
 usr.sbin/jail/command.c | 29 +++++++++++++++++++++++++++--
 usr.sbin/jail/config.c  |  1 +
 usr.sbin/jail/jail.8    | 12 +++++++++++-
 usr.sbin/jail/jail.c    |  1 +
 usr.sbin/jail/jailp.h   |  1 +
 6 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/sys/sys/param.h b/sys/sys/param.h
index f912d193bc4a..b5a5398497e0 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -73,7 +73,7 @@
  * cannot include sys/param.h and should only be updated here.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1500010
+#define __FreeBSD_version 1500011
 
 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/usr.sbin/jail/command.c b/usr.sbin/jail/command.c
index 8ffcca8039ac..60893444e9de 100644
--- a/usr.sbin/jail/command.c
+++ b/usr.sbin/jail/command.c
@@ -291,9 +291,9 @@ run_command(struct cfjail *j)
 	login_cap_t *lcap;
 	const char **argv;
 	char *acs, *cs, *comcs, *devpath;
-	const char *jidstr, *conslog, *path, *ruleset, *term, *username;
+	const char *jidstr, *conslog, *fmt, *path, *ruleset, *term, *username;
 	enum intparam comparam;
-	size_t comlen;
+	size_t comlen, ret;
 	pid_t pid;
 	cpusetid_t setid;
 	int argc, bg, clean, consfd, down, fib, i, injail, sjuser, timeout;
@@ -590,6 +590,31 @@ run_command(struct cfjail *j)
 		}
 		break;
 
+	case IP_ZFS_DATASET:
+		argv = alloca(4 * sizeof(char *));
+		jidstr = string_param(j->intparams[KP_JID]) ?
+		    string_param(j->intparams[KP_JID]) :
+		    string_param(j->intparams[KP_NAME]);
+		fmt = "if [ $(/sbin/zfs get -H -o value jailed %s) = on ]; then /sbin/zfs jail %s %s || echo error, attaching %s to jail %s failed; else echo error, you need to set jailed=on for dataset %s; fi";
+		comlen = strlen(fmt)
+		    + 2 * strlen(jidstr)
+		    + 4 * comstring->len
+		    - 6 * 2	/* 6 * "%s" */
+		    + 1;
+		comcs = alloca(comlen);
+		ret = snprintf(comcs, comlen, fmt, comstring->s,
+		    jidstr, comstring->s, comstring->s, jidstr,
+		    comstring->s);
+		if (ret >= comlen) {
+			jail_warnx(j, "internal error in ZFS dataset handling");
+			exit(1);
+		}
+		argv[0] = _PATH_BSHELL;
+		argv[1] = "-c";
+		argv[2] = comcs;
+		argv[3] = NULL;
+		break;
+
 	case IP_COMMAND:
 		if (j->name != NULL)
 			goto default_command;
diff --git a/usr.sbin/jail/config.c b/usr.sbin/jail/config.c
index 63adc9652145..3af0088626c9 100644
--- a/usr.sbin/jail/config.c
+++ b/usr.sbin/jail/config.c
@@ -93,6 +93,7 @@ static const struct ipspec intparams[] = {
     [IP_MOUNT_FSTAB] =		{"mount.fstab",		PF_INTERNAL},
     [IP_STOP_TIMEOUT] =		{"stop.timeout",	PF_INTERNAL | PF_INT},
     [IP_VNET_INTERFACE] =	{"vnet.interface",	PF_INTERNAL},
+    [IP_ZFS_DATASET] =		{"zfs.dataset",		PF_INTERNAL},
 #ifdef INET
     [IP__IP4_IFADDR] =		{"ip4.addr",	PF_INTERNAL | PF_CONV | PF_REV},
 #endif
diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8
index 1f745caa5e7c..e49c3fe95e7f 100644
--- a/usr.sbin/jail/jail.8
+++ b/usr.sbin/jail/jail.8
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd November 29, 2023
+.Dd January 17, 2024
 .Dt JAIL 8
 .Os
 .Sh NAME
@@ -918,6 +918,15 @@ may also be specified, in the form
 .It Va vnet.interface
 A network interface to give to a vnet-enabled jail after is it created.
 The interface will automatically be released when the jail is removed.
+.It Va zfs.dataset
+A list of ZFS datasets to be attached to the jail.
+This requires
+.Va allow.mount.zfs
+to be set.
+See 
+.Xr zfs-jail 8
+for information on how to configure a ZFS dataset to be operated from
+within a jail.
 .It Va ip_hostname
 Resolve the
 .Va host.hostname
@@ -1431,6 +1440,7 @@ environment of the first jail.
 .Xr sysctl 8 ,
 .Xr syslogd 8 ,
 .Xr umount 8 ,
+.Xr zfs-jail 8 ,
 .Xr extattr 9
 .Sh HISTORY
 The
diff --git a/usr.sbin/jail/jail.c b/usr.sbin/jail/jail.c
index f65c51fc6de6..9f8267dc1bde 100644
--- a/usr.sbin/jail/jail.c
+++ b/usr.sbin/jail/jail.c
@@ -98,6 +98,7 @@ static const enum intparam startcommands[] = {
     IP_EXEC_PRESTART,
     IP__OP,
     IP_EXEC_CREATED,
+    IP_ZFS_DATASET,
     IP_VNET_INTERFACE,
     IP_EXEC_START,
     IP_COMMAND,
diff --git a/usr.sbin/jail/jailp.h b/usr.sbin/jail/jailp.h
index c064da09d7a5..74ef2a8acab8 100644
--- a/usr.sbin/jail/jailp.h
+++ b/usr.sbin/jail/jailp.h
@@ -107,6 +107,7 @@ enum intparam {
 	IP_MOUNT_FSTAB,		/* A standard fstab(5) file */
 	IP_STOP_TIMEOUT,	/* Time to wait after sending SIGTERM */
 	IP_VNET_INTERFACE,	/* Assign interface(s) to vnet jail */
+	IP_ZFS_DATASET,		/* Jail ZFS datasets */
 #ifdef INET
 	IP__IP4_IFADDR,		/* Copy of ip4.addr with interface/netmask */
 #endif