Hyper.Node.FireVMM.Jailer (Hyper v0.1.0)

Copy Markdown View Source

Builds the hyper-suidhelper jailer command for one VM.

The BEAM does not invoke the jailer directly. Instead it calls the setuid helper with the jailer subcommand; the helper reads the firecracker binary path, chroot base, parent cgroup, and cgroup version from its trusted /etc/hyper/config.toml, re-acquires root, and execves the jailer (same pid, so MuonTrap.Daemon keeps supervising it).

This means the BEAM passes only untrusted-origin values: --id, --uid, --gid, repeated --cgroup KEY=VALUE, and --api-sock. The helper derives and validates everything else; it also inserts the -- separator between its own flags and firecracker's flags.

Because firecracker is chrooted to <chroot_base>/<exec>/<id>/root, the API socket it opens at /api.socket lives at host_socket on the host — that's the path the controller connects to.

Summary

Functions

Host path of the VM's cgroup leaf (/sys/fs/cgroup/<parent>/<id>), the cgroup the jailer creates for firecracker. Reconstructed (the jailer owns its placement) so a relaunch can clear the stale leaf left by a prior incarnation.

Host path of the cgroup dir holding every VM's leaf (/sys/fs/cgroup/<parent>). Its immediate subdir names are vm_ids - the leaves the jailer creates for firecracker - so listing it (directories only; the dir also holds cgroup control files) enumerates the cgroup leaves on this host.

Host path of the VM's per-VM jail dir (<chroot_base>/<exec>/<id>).

Host path of the VM's chroot root (<chroot_base>/<exec>/<id>/root).

Host-side path of the API socket firecracker opens inside the jail.

Host-side path of the vsock Unix-domain socket firecracker opens inside the jail.

Test whether the jailer and system pre-requisites are available.

Types

t()

@type t() :: %{binary: String.t(), args: [String.t()], host_socket: Path.t()}

Functions

cgroup_dir(id)

@spec cgroup_dir(Hyper.Vm.Id.t()) :: Path.t()

Host path of the VM's cgroup leaf (/sys/fs/cgroup/<parent>/<id>), the cgroup the jailer creates for firecracker. Reconstructed (the jailer owns its placement) so a relaunch can clear the stale leaf left by a prior incarnation.

cgroup_parent_dir()

@spec cgroup_parent_dir() :: Path.t()

Host path of the cgroup dir holding every VM's leaf (/sys/fs/cgroup/<parent>). Its immediate subdir names are vm_ids - the leaves the jailer creates for firecracker - so listing it (directories only; the dir also holds cgroup control files) enumerates the cgroup leaves on this host.

Note the cgroup hierarchy has NO <exec> level: the jailer (cgroup v2, --parent-cgroup <parent>) places firecracker directly at <parent>/<id>, unlike the chroot (<chroot_base>/<exec>/<id>). Confirmed via /proc/<pid>/cgroup = 0::/<parent>/<id>.

chroot_dir(id)

@spec chroot_dir(Hyper.Vm.Id.t()) :: Path.t()

Host path of the VM's per-VM jail dir (<chroot_base>/<exec>/<id>).

chroot_root(id)

@spec chroot_root(Hyper.Vm.Id.t()) :: Path.t()

Host path of the VM's chroot root (<chroot_base>/<exec>/<id>/root).

command(opts)

@spec command(Hyper.Node.FireVMM.Opts.t()) :: t()

host_socket(id)

@spec host_socket(Hyper.Vm.Id.t()) :: Path.t()

Host-side path of the API socket firecracker opens inside the jail.

Deterministic in id alone, so the controller and the API client can each derive it independently and are guaranteed to agree. We do not control where the jailer places the socket, so the path is reconstructed here.

host_vsock(id)

@spec host_vsock(Hyper.Vm.Id.t()) :: Path.t()

Host-side path of the vsock Unix-domain socket firecracker opens inside the jail.

Firecracker creates the vsock UDS at uds_path relative to its chroot root, so on the host it lives at <chroot_root>/vsock.sock. Deterministic in id alone, mirroring host_socket/1.

test_system()

@spec test_system() :: :ok | {:error, term()}

Test whether the jailer and system pre-requisites are available.