aboutsummaryrefslogtreecommitdiffstats
path: root/liblfjail/jail_zfs.cc
blob: 07b016927e952c5fff8615eb121eea028cfd3c1b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
 * This source code is released into the public domain.
 */

/*
 * ZFS handling.
 */

#include "config_string.hh"
#include "exec.hh"
#include "generic_error.hh"
#include "jail_zfs.hh"
#include "zfs.hh"

using namespace lfjail;
using namespace std::literals;

namespace lfjail::zfs {

config::string_option filesystem(
	"zfs.filesystem"sv,
	"The ZFS filesystem under which jails are created"sv);

config::string_option mountpoint(
	"zfs.mountpoint"sv,
	"The location where the ZFS hierarchy will be mounted"sv);

} // namespace lfjail::zfs

namespace {

/*
 * Make sure our top-level ZFS dataset exists.
 */
void ensure_jroot(context const &) {
	auto jroot = lfjail::zfs::filesystem.string();
	auto mntpt = lfjail::zfs::mountpoint.string();

	if (zfs::dataset_exists(jroot))
		return;

	auto mntptopt = std::format("mountpoint={}", mntpt);
	zfs::create_dataset(jroot, mntptopt);
}

} // anonymous namespace

namespace lfjail::zfs {

void create_for_jail(context const &ctx, jail const &jailconf) {
	if (filesystem.string().empty())
		throw generic_error("zfs.filesystem is not set");

	if (mountpoint.string().empty())
		throw generic_error("zfs.mountpoint is not set");

	ensure_jroot(ctx);

	auto const ds = filesystem.string() + "/" + jailconf.name;
	zfs::create_dataset(ds);
}

void destroy_for_jail(context const &, jail const &jailconf) {
	auto const dataset = filesystem.string() + "/" + jailconf.name;
	dataset_destroy(dataset);
}

auto jail_root(context const &ctx) -> std::string {
	std::ignore = ctx;

	auto fs = filesystem.string();
	if (fs.empty())
		throw generic_error("zfs.filesystem not set");

	return ""; // fs.mountpoint
}

} // namespace lfjail::zfs