Add FreeBSD jail support hooks
Add the 'zfs jail/unjail' subcommands along with the relevant documentation from FreeBSD. This feature is not supported on Linux and still requires the match kernel ioctls which will be included when the FreeBSD platform code is integrated. Reviewed-by: Jorgen Lundman <lundman@lundman.net> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Matt Macy <mmacy@FreeBSD.org> Signed-off-by: Ryan Moeller <ryan@ixsystems.com> Closes #9686
This commit is contained in:
parent
657ce25357
commit
4bc721965f
|
@ -15,3 +15,7 @@ zfs_LDADD = \
|
|||
$(top_builddir)/lib/libuutil/libuutil.la \
|
||||
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||
$(top_builddir)/lib/libzfs_core/libzfs_core.la
|
||||
|
||||
if BUILD_FREEBSD
|
||||
zfs_LDADD += -L/usr/local/lib -lintl -lgeom -ljail
|
||||
endif
|
||||
|
|
|
@ -122,6 +122,11 @@ static int zfs_do_project(int argc, char **argv);
|
|||
static int zfs_do_version(int argc, char **argv);
|
||||
static int zfs_do_redact(int argc, char **argv);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
static int zfs_do_jail(int argc, char **argv);
|
||||
static int zfs_do_unjail(int argc, char **argv);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
|
||||
*/
|
||||
|
@ -176,6 +181,8 @@ typedef enum {
|
|||
HELP_CHANGE_KEY,
|
||||
HELP_VERSION,
|
||||
HELP_REDACT,
|
||||
HELP_JAIL,
|
||||
HELP_UNJAIL
|
||||
} zfs_help_t;
|
||||
|
||||
typedef struct zfs_command {
|
||||
|
@ -240,6 +247,11 @@ static zfs_command_t command_table[] = {
|
|||
{ "unload-key", zfs_do_unload_key, HELP_UNLOAD_KEY },
|
||||
{ "change-key", zfs_do_change_key, HELP_CHANGE_KEY },
|
||||
{ "redact", zfs_do_redact, HELP_REDACT },
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
{ "jail", zfs_do_jail, HELP_JAIL },
|
||||
{ "unjail", zfs_do_unjail, HELP_UNJAIL },
|
||||
#endif
|
||||
};
|
||||
|
||||
#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
|
||||
|
@ -391,6 +403,10 @@ get_usage(zfs_help_t idx)
|
|||
case HELP_REDACT:
|
||||
return (gettext("\tredact <snapshot> <bookmark> "
|
||||
"<redaction_snapshot> ..."));
|
||||
case HELP_JAIL:
|
||||
return (gettext("\tjail <jailid|jailname> <filesystem>\n"));
|
||||
case HELP_UNJAIL:
|
||||
return (gettext("\tunjail <jailid|jailname> <filesystem>\n"));
|
||||
}
|
||||
|
||||
abort();
|
||||
|
@ -734,7 +750,7 @@ zfs_mount_and_share(libzfs_handle_t *hdl, const char *dataset, zfs_type_t type)
|
|||
*/
|
||||
if (zfs_prop_valid_for_type(ZFS_PROP_CANMOUNT, type, B_FALSE) &&
|
||||
zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_ON) {
|
||||
if (geteuid() != 0) {
|
||||
if (zfs_mount_delegation_check()) {
|
||||
(void) fprintf(stderr, gettext("filesystem "
|
||||
"successfully created, but it may only be "
|
||||
"mounted by root\n"));
|
||||
|
@ -6970,7 +6986,6 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
|
|||
const char *cmdname = (op == OP_SHARE) ? "unshare" : "unmount";
|
||||
ino_t path_inode;
|
||||
|
||||
|
||||
/*
|
||||
* Search for the given (major,minor) pair in the mount table.
|
||||
*/
|
||||
|
@ -7233,8 +7248,12 @@ unshare_unmount(int op, int argc, char **argv)
|
|||
nomem();
|
||||
|
||||
while ((node = uu_avl_walk_next(walk)) != NULL) {
|
||||
uu_avl_remove(tree, node);
|
||||
const char *mntarg = NULL;
|
||||
|
||||
uu_avl_remove(tree, node);
|
||||
#ifndef __FreeBSD__
|
||||
mntarg = node->un_zhp->zfs_name;
|
||||
#endif
|
||||
switch (op) {
|
||||
case OP_SHARE:
|
||||
if (zfs_unshareall_bytype(node->un_zhp,
|
||||
|
@ -7244,7 +7263,7 @@ unshare_unmount(int op, int argc, char **argv)
|
|||
|
||||
case OP_MOUNT:
|
||||
if (zfs_unmount(node->un_zhp,
|
||||
node->un_zhp->zfs_name, flags) != 0)
|
||||
mntarg, flags) != 0)
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -8350,3 +8369,67 @@ main(int argc, char **argv)
|
|||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/jail.h>
|
||||
#include <jail.h>
|
||||
/*
|
||||
* Attach/detach the given dataset to/from the given jail
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
zfs_do_jail_impl(int argc, char **argv, boolean_t attach)
|
||||
{
|
||||
zfs_handle_t *zhp;
|
||||
int jailid, ret;
|
||||
|
||||
/* check number of arguments */
|
||||
if (argc < 3) {
|
||||
(void) fprintf(stderr, gettext("missing argument(s)\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
if (argc > 3) {
|
||||
(void) fprintf(stderr, gettext("too many arguments\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
jailid = jail_getid(argv[1]);
|
||||
if (jailid < 0) {
|
||||
(void) fprintf(stderr, gettext("invalid jail id or name\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
zhp = zfs_open(g_zfs, argv[2], ZFS_TYPE_FILESYSTEM);
|
||||
if (zhp == NULL)
|
||||
return (1);
|
||||
|
||||
ret = (zfs_jail(zhp, jailid, attach) != 0);
|
||||
|
||||
zfs_close(zhp);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* zfs jail jailid filesystem
|
||||
*
|
||||
* Attach the given dataset to the given jail
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
zfs_do_jail(int argc, char **argv)
|
||||
{
|
||||
return (zfs_do_jail_impl(argc, argv, B_TRUE));
|
||||
}
|
||||
|
||||
/*
|
||||
* zfs unjail jailid filesystem
|
||||
*
|
||||
* Detach the given dataset from the given jail
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
zfs_do_unjail(int argc, char **argv)
|
||||
{
|
||||
return (zfs_do_jail_impl(argc, argv, B_FALSE));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -237,7 +237,7 @@ extern proto_table_t proto_table[PROTO_END];
|
|||
|
||||
extern int do_mount(const char *src, const char *mntpt, char *opts, int flags);
|
||||
extern int do_unmount(const char *mntpt, int flags);
|
||||
extern int zfs_can_user_mount(void);
|
||||
extern int zfs_mount_delegation_check(void);
|
||||
extern int zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto);
|
||||
extern int unshare_one(libzfs_handle_t *hdl, const char *name,
|
||||
const char *mountpoint, zfs_share_proto_t proto);
|
||||
|
|
|
@ -361,7 +361,7 @@ do_unmount(const char *mntpt, int flags)
|
|||
}
|
||||
|
||||
int
|
||||
zfs_can_user_mount(void)
|
||||
zfs_mount_delegation_check(void)
|
||||
{
|
||||
return (geteuid() == 0);
|
||||
return ((geteuid() != 0) ? EACCES : 0);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ dist_man_MANS = \
|
|||
zfs-groupspace.8 \
|
||||
zfs-hold.8 \
|
||||
zfs-inherit.8 \
|
||||
zfs-jail.8 \
|
||||
zfs-list.8 \
|
||||
zfs-load-key.8 \
|
||||
zfs-mount.8 \
|
||||
|
@ -35,6 +36,7 @@ dist_man_MANS = \
|
|||
zfs-share.8 \
|
||||
zfs-snapshot.8 \
|
||||
zfs-unallow.8 \
|
||||
zfs-unjail.8 \
|
||||
zfs-unload-key.8 \
|
||||
zfs-unmount.8 \
|
||||
zfs-upgrade.8 \
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
.\"
|
||||
.\" CDDL HEADER START
|
||||
.\"
|
||||
.\" The contents of this file are subject to the terms of the
|
||||
.\" Common Development and Distribution License (the "License").
|
||||
.\" You may not use this file except in compliance with the License.
|
||||
.\"
|
||||
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
.\" or http://www.opensolaris.org/os/licensing.
|
||||
.\" See the License for the specific language governing permissions
|
||||
.\" and limitations under the License.
|
||||
.\"
|
||||
.\" When distributing Covered Code, include this CDDL HEADER in each
|
||||
.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
.\" If applicable, add the following below this CDDL HEADER, with the
|
||||
.\" fields enclosed by brackets "[]" replaced with your own identifying
|
||||
.\" information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
.\"
|
||||
.\" CDDL HEADER END
|
||||
.\"
|
||||
.\"
|
||||
.\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
.\" Copyright 2011 Joshua M. Clulow <josh@sysmgr.org>
|
||||
.\" Copyright (c) 2011, 2019 by Delphix. All rights reserved.
|
||||
.\" Copyright (c) 2011, Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
|
||||
.\" Copyright (c) 2012, Bryan Drewery <bdrewery@FreeBSD.org>
|
||||
.\" Copyright (c) 2013, Steven Hartland <smh@FreeBSD.org>
|
||||
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
.\" Copyright (c) 2014, Joyent, Inc. All rights reserved.
|
||||
.\" Copyright (c) 2014 by Adam Stevko. All rights reserved.
|
||||
.\" Copyright (c) 2014 Integros [integros.com]
|
||||
.\" Copyright (c) 2014, Xin LI <delphij@FreeBSD.org>
|
||||
.\" Copyright (c) 2014-2015, The FreeBSD Foundation, All Rights Reserved.
|
||||
.\" Copyright (c) 2016 Nexenta Systems, Inc. All Rights Reserved.
|
||||
.\" Copyright 2019 Richard Laager. All rights reserved.
|
||||
.\" Copyright 2018 Nexenta Systems, Inc.
|
||||
.\" Copyright 2019 Joyent, Inc.
|
||||
.\"
|
||||
.Dd December 9, 2019
|
||||
.Dt ZFS-JAIL 8
|
||||
.Os FreeBSD
|
||||
.Sh NAME
|
||||
.Nm zfs Ns Pf - Cm jail
|
||||
.Nd Attaches and detaches ZFS filesystems from FreeBSD jails.
|
||||
.No A Tn ZFS
|
||||
dataset can be attached to a jail by using the
|
||||
.Qq Nm Cm jail
|
||||
subcommand. You cannot attach a dataset to one jail and the children of the
|
||||
same dataset to another jail. You can also not attach the root file system
|
||||
of the jail or any dataset which needs to be mounted before the zfs rc script
|
||||
is run inside the jail, as it would be attached unmounted until it is
|
||||
mounted from the rc script inside the jail. To allow management of the
|
||||
dataset from within a jail, the
|
||||
.Sy jailed
|
||||
property has to be set and the jail needs access to the
|
||||
.Pa /dev/zfs
|
||||
device. The
|
||||
.Sy quota
|
||||
property cannot be changed from within a jail. See
|
||||
.Xr jail 8
|
||||
for information on how to allow mounting
|
||||
.Tn ZFS
|
||||
datasets from within a jail.
|
||||
.Pp
|
||||
.No A Tn ZFS
|
||||
dataset can be detached from a jail using the
|
||||
.Qq Nm Cm unjail
|
||||
subcommand.
|
||||
.Pp
|
||||
After a dataset is attached to a jail and the jailed property is set, a jailed
|
||||
file system cannot be mounted outside the jail, since the jail administrator
|
||||
might have set the mount point to an unacceptable value.
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Cm jail
|
||||
.Ar jailid Ns | Ns Ar jailname filesystem
|
||||
.Nm
|
||||
.Cm unjail
|
||||
.Ar jailid Ns | Ns Ar jailname filesystem
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -width ""
|
||||
.It Xo
|
||||
.Nm
|
||||
.Cm jail
|
||||
.Ar jailid filesystem
|
||||
.Xc
|
||||
.Pp
|
||||
Attaches the specified
|
||||
.Ar filesystem
|
||||
to the jail identified by JID
|
||||
.Ar jailid .
|
||||
From now on this file system tree can be managed from within a jail if the
|
||||
.Sy jailed
|
||||
property has been set. To use this functuinality, the jail needs the
|
||||
.Va allow.mount
|
||||
and
|
||||
.Va allow.mount.zfs
|
||||
parameters set to 1 and the
|
||||
.Va enforce_statfs
|
||||
parameter set to a value lower than 2.
|
||||
.Pp
|
||||
See
|
||||
.Xr jail 8
|
||||
for more information on managing jails and configuring the parameters above.
|
||||
.It Xo
|
||||
.Nm
|
||||
.Cm unjail
|
||||
.Ar jailid filesystem
|
||||
.Xc
|
||||
.Pp
|
||||
Detaches the specified
|
||||
.Ar filesystem
|
||||
from the jail identified by JID
|
||||
.Ar jailid .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr jail 8 ,
|
||||
.Xr zfsprops 8
|
|
@ -0,0 +1 @@
|
|||
zfs-jail.8
|
|
@ -22,10 +22,17 @@
|
|||
.\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
.\" Copyright 2011 Joshua M. Clulow <josh@sysmgr.org>
|
||||
.\" Copyright (c) 2011, 2019 by Delphix. All rights reserved.
|
||||
.\" Copyright (c) 2011, Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
|
||||
.\" Copyright (c) 2012, Bryan Drewery <bdrewery@FreeBSD.org>
|
||||
.\" Copyright (c) 2013, Steven Hartland <smh@FreeBSD.org>
|
||||
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
.\" Copyright (c) 2014, Joyent, Inc. All rights reserved.
|
||||
.\" Copyright (c) 2014 by Adam Stevko. All rights reserved.
|
||||
.\" Copyright (c) 2014 Integros [integros.com]
|
||||
.\" Copyright (c) 2014, Xin LI <delphij@FreeBSD.org>
|
||||
.\" Copyright (c) 2014-2015, The FreeBSD Foundation, All Rights Reserved.
|
||||
.\" Copyright (c) 2016 Nexenta Systems, Inc. All Rights Reserved.
|
||||
.\" Copyright 2019 Richard Laager. All rights reserved.
|
||||
.\" Copyright 2018 Nexenta Systems, Inc.
|
||||
.\" Copyright 2019 Joyent, Inc.
|
||||
|
@ -267,6 +274,13 @@ Unload a key for the specified dataset, removing the ability to access the datas
|
|||
Execute ZFS administrative operations
|
||||
programmatically via a Lua script-language channel program.
|
||||
.El
|
||||
.Ss Jails
|
||||
.Bl -tag -width ""
|
||||
.It Xr zfs-jail 8
|
||||
Attaches a filesystem to a jail.
|
||||
.It Xr zfs-unjail 8
|
||||
Detaches a filesystem from a jail.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
.Nm
|
||||
|
|
|
@ -22,10 +22,17 @@
|
|||
.\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
.\" Copyright 2011 Joshua M. Clulow <josh@sysmgr.org>
|
||||
.\" Copyright (c) 2011, 2019 by Delphix. All rights reserved.
|
||||
.\" Copyright (c) 2011, Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
|
||||
.\" Copyright (c) 2012, Bryan Drewery <bdrewery@FreeBSD.org>
|
||||
.\" Copyright (c) 2013, Steven Hartland <smh@FreeBSD.org>
|
||||
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
.\" Copyright (c) 2014, Joyent, Inc. All rights reserved.
|
||||
.\" Copyright (c) 2014 by Adam Stevko. All rights reserved.
|
||||
.\" Copyright (c) 2014 Integros [integros.com]
|
||||
.\" Copyright (c) 2016 Nexenta Systems, Inc. All Rights Reserved.
|
||||
.\" Copyright (c) 2014, Xin LI <delphij@FreeBSD.org>
|
||||
.\" Copyright (c) 2014-2015, The FreeBSD Foundation, All Rights Reserved.
|
||||
.\" Copyright 2019 Richard Laager. All rights reserved.
|
||||
.\" Copyright 2018 Nexenta Systems, Inc.
|
||||
.\" Copyright 2019 Joyent, Inc.
|
||||
|
@ -1709,9 +1716,17 @@ are equivalent to the
|
|||
and
|
||||
.Sy noxattr
|
||||
mount options.
|
||||
.It Sy jailed Ns = Ns Cm off | on
|
||||
Controls whether the dataset is managed from a jail. See the
|
||||
.Qq Sx Jails
|
||||
section in
|
||||
.Xr zfs 8
|
||||
for more information. Jails are a FreeBSD feature and are not relevant on
|
||||
other platforms. The default value is
|
||||
.Cm off .
|
||||
.It Sy zoned Ns = Ns Sy on Ns | Ns Sy off
|
||||
Controls whether the dataset is managed from a non-global zone. Zones are a
|
||||
Solaris feature and are not relevant on Linux. The default value is
|
||||
Solaris feature and are not relevant on other platforms. The default value is
|
||||
.Sy off .
|
||||
.El
|
||||
.Pp
|
||||
|
|
|
@ -379,8 +379,13 @@ zfs_prop_init(void)
|
|||
zprop_register_index(ZFS_PROP_READONLY, "readonly", 0, PROP_INHERIT,
|
||||
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "on | off", "RDONLY",
|
||||
boolean_table);
|
||||
#ifdef __FreeBSD__
|
||||
zprop_register_index(ZFS_PROP_ZONED, "jailed", 0, PROP_INHERIT,
|
||||
ZFS_TYPE_FILESYSTEM, "on | off", "JAILED", boolean_table);
|
||||
#else
|
||||
zprop_register_index(ZFS_PROP_ZONED, "zoned", 0, PROP_INHERIT,
|
||||
ZFS_TYPE_FILESYSTEM, "on | off", "ZONED", boolean_table);
|
||||
#endif
|
||||
zprop_register_index(ZFS_PROP_VSCAN, "vscan", 0, PROP_INHERIT,
|
||||
ZFS_TYPE_FILESYSTEM, "on | off", "VSCAN", boolean_table);
|
||||
zprop_register_index(ZFS_PROP_NBMAND, "nbmand", 0, PROP_INHERIT,
|
||||
|
|
|
@ -743,6 +743,7 @@ dsl_enforce_ds_ss_limits(dsl_dir_t *dd, zfs_prop_t prop, cred_t *cr)
|
|||
uint64_t obj;
|
||||
dsl_dataset_t *ds;
|
||||
uint64_t zoned;
|
||||
const char *zonedstr;
|
||||
|
||||
ASSERT(prop == ZFS_PROP_FILESYSTEM_LIMIT ||
|
||||
prop == ZFS_PROP_SNAPSHOT_LIMIT);
|
||||
|
@ -763,7 +764,8 @@ dsl_enforce_ds_ss_limits(dsl_dir_t *dd, zfs_prop_t prop, cred_t *cr)
|
|||
if (dsl_dataset_hold_obj(dd->dd_pool, obj, FTAG, &ds) != 0)
|
||||
return (ENFORCE_ALWAYS);
|
||||
|
||||
if (dsl_prop_get_ds(ds, "zoned", 8, 1, &zoned, NULL) || zoned) {
|
||||
zonedstr = zfs_prop_to_name(ZFS_PROP_ZONED);
|
||||
if (dsl_prop_get_ds(ds, zonedstr, 8, 1, &zoned, NULL) || zoned) {
|
||||
/* Only root can access zoned fs's from the GZ */
|
||||
enforce = ENFORCE_ALWAYS;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue