aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/zfs
diff options
context:
space:
mode:
authorWill Andrews <[email protected]>2021-02-21 10:19:43 -0600
committerBrian Behlendorf <[email protected]>2022-06-10 09:51:46 -0700
commit4ed5e25074ffec266df38556d9b3a928c5e0dee9 (patch)
tree930f2397ca27e885ca33c05728802d7f19021f08 /cmd/zfs
parenta1aa8f14c864b6851649f9c3e74e9f12e6518edd (diff)
Add Linux namespace delegation support
This allows ZFS datasets to be delegated to a user/mount namespace Within that namespace, only the delegated datasets are visible Works very similarly to Zones/Jailes on other ZFS OSes As a user: ``` $ unshare -Um $ zfs list no datasets available $ echo $$ 1234 ``` As root: ``` # zfs list NAME ZONED MOUNTPOINT containers off /containers containers/host off /containers/host containers/host/child off /containers/host/child containers/host/child/gchild off /containers/host/child/gchild containers/unpriv on /unpriv containers/unpriv/child on /unpriv/child containers/unpriv/child/gchild on /unpriv/child/gchild # zfs zone /proc/1234/ns/user containers/unpriv ``` Back to the user namespace: ``` $ zfs list NAME USED AVAIL REFER MOUNTPOINT containers 129M 47.8G 24K /containers containers/unpriv 128M 47.8G 24K /unpriv containers/unpriv/child 128M 47.8G 128M /unpriv/child ``` Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Will Andrews <[email protected]> Signed-off-by: Allan Jude <[email protected]> Signed-off-by: Mateusz Piotrowski <[email protected]> Co-authored-by: Allan Jude <[email protected]> Co-authored-by: Mateusz Piotrowski <[email protected]> Sponsored-by: Buddy <https://buddy.works> Closes #12263
Diffstat (limited to 'cmd/zfs')
-rw-r--r--cmd/zfs/zfs_main.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c
index 6282d8946..30b2ae0c4 100644
--- a/cmd/zfs/zfs_main.c
+++ b/cmd/zfs/zfs_main.c
@@ -127,6 +127,11 @@ static int zfs_do_jail(int argc, char **argv);
static int zfs_do_unjail(int argc, char **argv);
#endif
+#ifdef __linux__
+static int zfs_do_zone(int argc, char **argv);
+static int zfs_do_unzone(int argc, char **argv);
+#endif
+
/*
* Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
*/
@@ -184,6 +189,8 @@ typedef enum {
HELP_JAIL,
HELP_UNJAIL,
HELP_WAIT,
+ HELP_ZONE,
+ HELP_UNZONE,
} zfs_help_t;
typedef struct zfs_command {
@@ -254,6 +261,11 @@ static zfs_command_t command_table[] = {
{ "jail", zfs_do_jail, HELP_JAIL },
{ "unjail", zfs_do_unjail, HELP_UNJAIL },
#endif
+
+#ifdef __linux__
+ { "zone", zfs_do_zone, HELP_ZONE },
+ { "unzone", zfs_do_unzone, HELP_UNZONE },
+#endif
};
#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
@@ -415,6 +427,10 @@ get_usage(zfs_help_t idx)
return (gettext("\tunjail <jailid|jailname> <filesystem>\n"));
case HELP_WAIT:
return (gettext("\twait [-t <activity>] <filesystem>\n"));
+ case HELP_ZONE:
+ return (gettext("\tzone <nsfile> <filesystem>\n"));
+ case HELP_UNZONE:
+ return (gettext("\tunzone <nsfile> <filesystem>\n"));
default:
__builtin_unreachable();
}
@@ -8692,6 +8708,50 @@ main(int argc, char **argv)
return (ret);
}
+/*
+ * zfs zone nsfile filesystem
+ *
+ * Add or delete the given dataset to/from the namespace.
+ */
+#ifdef __linux__
+static int
+zfs_do_zone_impl(int argc, char **argv, boolean_t attach)
+{
+ zfs_handle_t *zhp;
+ int ret;
+
+ 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);
+ }
+
+ zhp = zfs_open(g_zfs, argv[2], ZFS_TYPE_FILESYSTEM);
+ if (zhp == NULL)
+ return (1);
+
+ ret = (zfs_userns(zhp, argv[1], attach) != 0);
+
+ zfs_close(zhp);
+ return (ret);
+}
+
+static int
+zfs_do_zone(int argc, char **argv)
+{
+ return (zfs_do_zone_impl(argc, argv, B_TRUE));
+}
+
+static int
+zfs_do_unzone(int argc, char **argv)
+{
+ return (zfs_do_zone_impl(argc, argv, B_FALSE));
+}
+#endif
+
#ifdef __FreeBSD__
#include <sys/jail.h>
#include <jail.h>