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
79
80
81
82
83
use nix::sched::CloneFlags;
/// Namespace name to unshare
///
/// See `man 7 namespaces` for more information
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
pub enum Namespace {
/// Unshare the mount namespace. It basically means that you can now mount
/// and unmount folders without touching parent mount points.
///
/// But note that you also have to make all your mountpoints non-shareable
/// or changes will be propagated to parent namespace anyway.
///
/// This is always needed if you want `pivot_root` (but not enforced by
/// library)
Mount,
/// Unshare the UTS namespace. This allows you to change hostname of the
/// new container.
Uts,
/// Unshare the IPC namespace. This creates new namespace for System V IPC
/// POSIX message queues and similar.
Ipc,
/// Unshare user namespace. This allows unprivileged user to be root
/// user in new namespace and/or change mappings between real (outer)
/// user namespace and the inner one.
///
/// This one is required if you want to unshare any other namespace without
/// root privileges (it's not enforced by kernel not the library)
///
/// See `man 7 user_namespaces` for more information.
User,
/// Unshare pid namespace. The child process becomes PID 1 (inside
/// container) with the following rough list of consequences:
///
/// 1. All daemon processes are reparented to the process
/// 2. All signal dispositions are set to `Ignore`. E.g. process doesn't
/// get killed by `SIGINT` (Ctrl+C), unless signal handler is explicitly
/// set
/// 3. If the process is dead, all its children are killed by `SIGKILL`
/// (i.e. can't catch the death signal)
///
/// All this means that most of the time the new process having this
/// namespace must be some kind of process supervisor.
///
/// Also take a note that `/proc` is not automatically changed. So you
/// should also unshare `Mount` namespace and mount new `/proc` inside the
/// PID namespace.
///
/// See `man 7 pid_namespaces` for more information
Pid,
/// Unshare network namespace
///
/// New namespace is empty and has no conectivity, even localhost network,
/// unless some setup is done afterwards.
///
/// Note that unix sockets continue to work, but "abstract unix sockets"
/// are isolated as a result of this option. The availability of unix
/// sockets might also mean that libc is able to resolve DNS names by using
/// NSCD. You may isolate unix sockets by using any kind of filesystem
/// isolation.
Net,
/// Cgroup namespace
///
/// Creates a new namespace for CGroups.
///
/// See `man 7 cgroup_namespaces` for more information
Cgroup,
}
/// Convert namespace to a clone flag passed to syscalls
// TODO(tailhook) should this method be private?
pub fn to_clone_flag(ns: Namespace) -> CloneFlags {
match ns {
Namespace::Mount => CloneFlags::CLONE_NEWNS,
Namespace::Uts => CloneFlags::CLONE_NEWUTS,
Namespace::Ipc => CloneFlags::CLONE_NEWIPC,
Namespace::User => CloneFlags::CLONE_NEWUSER,
Namespace::Pid => CloneFlags::CLONE_NEWPID,
Namespace::Net => CloneFlags::CLONE_NEWNET,
Namespace::Cgroup => CloneFlags::CLONE_NEWCGROUP,
}
}