> For the complete documentation index, see [llms.txt](https://handbook.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://handbook.bsdcn.org/di-17-zhang-jail-yu-rong-qi/17.15.-jail-yu-zfs.md).

# 17.15.jail 与 ZFS

可向 jail 委托一个或多个 ZFS 数据集的控制权，使 jail 中的 `root` 用户能够创建、快照、克隆和回滚子数据集，而无需宿主管理员介入。这是为 jail 提供可写、可快照存储的推荐方式。

宿主保留数据集的所有权，仅将所委托的树及其后代的管理权委托给 jail。`jailed` 属性、`zfs jail` 子命令以及二者之间的交互在 [ZFS 和 Jail](/di-23-zhang-z-wen-jian-xi-tong-zfs/23.4.-zfs-guan-li.md) 中说明。

## 17.15.1. 手动委托数据集

此方法适用于所有受支持的 FreeBSD 发行版本。

在宿主上，创建要委托的数据集并将其标记为 jailed：

```sh
# zfs create zroot/jails/data
# zfs set jailed=on zroot/jails/data
```

设置 `jailed` 属性会通知 ZFS 该数据集将从 jail 内部管理，因此宿主不再自动挂载它。

接下来，允许 jail 挂载 ZFS 文件系统，并在创建 jail 时附加数据集。在 **/etc/jail.conf** 中 jail 的节中添加以下内容：

```sh
allow.mount;
allow.mount.zfs;
enforce_statfs = 1;
exec.created += "zfs jail ${name} zroot/jails/data";
```

`allow.mount.zfs` 权限仅在配合 `allow.mount` 且 `enforce_statfs` 值低于 2 时才生效；挂载权限及其与 `enforce_statfs` 的交互参见 [更多 jail 选项](/di-17-zhang-jail-yu-rong-qi/17.14.-geng-duo-jail-xuan-xiang.md)。由于委托的数据集在 jail 停止时会分离，`exec.created` 钩子会在每次启动时重新附加它，其中 `${name}` 会展开为 jail 名称。同样的附加操作可对正在运行的 jail 执行 `zfs jail <jid|name> zroot/jails/data`。

> **注意**
>
> jail 需要访问 **/dev/zfs**。jail 的默认 devfs 规则集（`devfsrules_jail`，规则集 4）已经将其解除隐藏，因此 ZFS 委托无需自定义 devfs 规则集。

在 jail 内部，挂载已委托的数据集并像对待其他数据集一样管理它们：

```sh
# zfs mount -a
# zfs create zroot/jails/data/work
# zfs snapshot zroot/jails/data/work@monday
```

jail 中的 `root` 用户可在委托的树之下创建、快照、克隆和回滚数据集，但委托数据集的 `quota` 属性只能从宿主设置。

## 17.15.2. 自动附加数据集

> **注意**
>
> `zfs.dataset` 参数需要 FreeBSD 15.0。它不存在于 FreeBSD 14.3 的 [jail(8)](https://man.freebsd.org/cgi/man.cgi?query=jail\&sektion=8\&format=html) 中。

从 FreeBSD 15.0 开始，[jail(8)](https://man.freebsd.org/cgi/man.cgi?query=jail\&sektion=8\&format=html) 可自行附加数据集，无需手动 `jailed` 和 `zfs jail` 步骤。在 `zfs.dataset` 参数中列出要委托的数据集：

```sh
allow.mount;
allow.mount.zfs;
enforce_statfs = 1;
zfs.dataset = "zroot/jails/data";
```

[jail(8)](https://man.freebsd.org/cgi/man.cgi?query=jail\&sektion=8\&format=html) 会在 jail 启动时附加每个列出的数据集，因此上面所示的 `exec.created` 钩子不再需要。此参数要求设置 `allow.mount.zfs`。

对于尚不支持 `zfs.dataset` 的未维护 jail 管理器，rc.d/jail 启动脚本也支持 **/etc/rc.conf** 中的遗留变量 `jail_<jailname>_zfs_dataset`。

## 17.15.3. 从 jail 内访问快照

`zfs.mount_snapshot` 参数在 FreeBSD 14.x 和 15.x 上可用，让 jail 中的用户无需委托整个数据集即可访问快照内容。设置为 `1` 时，jail 中的用户可在文件系统的 **.zfs/snapshot** 目录下读取其快照内容：

```sh
zfs.mount_snapshot = 1;
```

这对于从宿主拍摄的快照中恢复单个文件非常方便。如果同时设置了 `allow.mount.zfs`，快照还可在 jail 内挂载。数据集的 `snapdir` 属性控制 **.zfs** 目录是否可见。

> **警告**
>
> 委托的数据集配合 `allow.mount.zfs` 会让 jail 中的 `root` 用户设置与挂载相关的 ZFS 属性并在 jail 内挂载文件系统。请慎重授予这些权限，仅授予受信任管理自己存储的 jail。
