Documentation
¶
Overview ¶
Package cloudhv is the Cloud Hypervisor backend: every fiber is a cloud-hypervisor process holding one micro-VM, restored from a snapshot of the warm guest. fiberd drives each VMM over its API socket with plain HTTP, and talks to the guest init over the VM's hybrid vsock socket (hack/cloudhv/PROTOCOL.md). hack/cloudhv/fakevmm speaks the same API subset and plays the guest without KVM, for conformance in CI.
How it maps onto the seam:
- Warm: start a VMM in the warm leaf, vm.create with the kernel, the read-only rootfs and vsock, vm.boot, wait for the guest init's ready line, vm.pause and vm.snapshot, end the VMM. The snapshot is the warm instance. No process stays behind.
- Clone: start a VMM in the fiber's leaf restoring the warm snapshot copy-on-write, vm.resume, send INCARNATE on the control port and wait for served. The fiber's unix endpoint is spliced to guest port 1024.
- Park: the guest stops serving, vm.pause, vm.snapshot, the images move to the park directory, and the VMM ends unless the park is Sync.
- Resume: as Clone, restoring the park instead.
- Kill: vmm.shutdown, then the host kills the leaf.
Each VMM runs in its own mount namespace as an unprivileged uid with /dev/kvm alone (jail_linux.go), so every snapshot names the same paths and two restores of one snapshot never meet. A VMM sits in its fiber's leaf, so W is the leaf's memory.current less what the restore cost, which Fiber.Footprint reports. A clone shares the warm guest's pages until it writes them, so W counts the pages the fiber writes, as it does for proc. Tier FIBER_SNAPSHOT. No delta codec, no pool, no workspaces, and no handoff grants, since a passed TCP socket cannot cross into a VM.
Index ¶
- Variables
- func New(o Options) backend.Backend
- type Backend
- func (b *Backend) Clone(ctx context.Context, warmID string, sp backend.FiberSpec) (backend.Fiber, error)
- func (b *Backend) Close()
- func (b *Backend) DefaultDeadlines(string) (time.Duration, time.Duration)
- func (b *Backend) Exits() <-chan backend.Exit
- func (b *Backend) FiberOverheadBytes() uint64
- func (b *Backend) Handoff() bool
- func (b *Backend) IsolatesTenants() bool
- func (b *Backend) Kill(fiberID string) error
- func (b *Backend) Name() string
- func (b *Backend) Park(ctx context.Context, fiberID string, sp backend.ParkSpec) error
- func (b *Backend) Platform() artifact.Platform
- func (b *Backend) ProbeErr() error
- func (b *Backend) Resume(ctx context.Context, sp backend.ResumeSpec) (backend.Fiber, error)
- func (b *Backend) Tier() core.Tier
- func (b *Backend) Unwarm(id string)
- func (b *Backend) Warm(ctx context.Context, sp backend.WarmSpec) (backend.Warm, error)
- type Options
Constants ¶
This section is empty.
Variables ¶
var ( ErrVMM = errors.New("cloudhv: VMM error") ErrGuest = errors.New("cloudhv: guest error") )
ErrVMM is a refusal or failure of the VMM's API, and ErrGuest one of the guest init's control lines.
Functions ¶
Types ¶
type Backend ¶
type Backend struct {
// contains filtered or unexported fields
}
Backend implements backend.Backend, Isolator, Platformer, Prober, DeadlineAdvisor, Overheader and Handoffer (to refuse handoff by name).
func (*Backend) Clone ¶
func (b *Backend) Clone(ctx context.Context, warmID string, sp backend.FiberSpec) (backend.Fiber, error)
Clone restores the warm snapshot in the fiber's leaf and hands the guest its incarnation.
func (*Backend) Close ¶
func (b *Backend) Close()
Close ends every VMM. The warm snapshots stay until the next open.
func (*Backend) DefaultDeadlines ¶
DefaultDeadlines are fixed. Every guest has the same size, so no warm instance needs floors of its own.
func (*Backend) FiberOverheadBytes ¶
FiberOverheadBytes is the VMM, what a fiber costs besides the guest pages it shares with the warm snapshot. The host only checks that the backend is an Overheader and takes the numbers it sizes leaves by from Warm. W itself is measured from the footprint each Clone reports.
func (*Backend) Handoff ¶
Handoff is false. A handoff fiber takes TCP sockets over SCM_RIGHTS, which cannot cross into a VM, so the host refuses a handoff grant on this backend and names it.
func (*Backend) IsolatesTenants ¶
IsolatesTenants is true because a fiber runs on a guest kernel of its own behind KVM.
func (*Backend) Kill ¶
Kill shuts the VMM down, and kills it when it does not go. The host kills the leaf as well.
func (*Backend) Park ¶
Park asks the guest to stop serving, as SIGUSR1 does for gVisor, and only then pauses and snapshots the VM into the park directory. Without Sync the VMM then ends, and its Exit follows. With Sync the VM runs on, not serving, until the host ends it. A park that fails after the guest stopped serving resumes the VM and has the guest serve again, so the fiber runs on as after any other failed park.
func (*Backend) Platform ¶
Platform replaces the host's kernel facts with the VM's. The VMM release goes where a kernel release goes, so kernel=series relaxes it to a minor series. The images and the CPU go, exact, where libc goes. A backend that cannot warm says so here.
func (*Backend) Resume ¶
Resume restores a park in the new leaf and hands the guest its new incarnation. The endpoint and engine paths are the same in every VM, so nothing in the guest is rewritten. The engine link comes from this home's warm instance of the grant, or from ResumeSpec.EnginePath when the home has none.
type Options ¶
type Options struct {
// VMM is the cloud-hypervisor executable, or hack/cloudhv/fakevmm,
// which speaks the same API subset without KVM. Required.
VMM string
// Kernel is the guest vmlinux and Rootfs the guest's read-only root
// image, both built by hack/cloudhv/build.sh. The fake VMM takes a
// directory as its rootfs. Required.
Kernel string
Rootfs string
// StateDir holds the warm snapshots and each VMM's run directory.
// Required.
StateDir string
// MemoryMiB is each guest's memory, 256 when zero.
MemoryMiB uint64
// VCPUs is each guest's vCPU count, 1 when zero.
VCPUs int
// RestoreMode is how a Clone restores the warm snapshot's memory.
// "" or "copyonwrite", the default, maps it copy-on-write, so a clone
// owns only the pages it writes. "copy" copies it in whole, and
// "ondemand" faults it in lazily through userfaultfd.
// A Resume always copies, since a park directory is not fiberd's to
// keep unchanged for the VM's lifetime.
RestoreMode string
// UsernsPool is fiberd's -userns-pool (START:SLOTS, the runc backend's
// syntax) and EngineUID its -engine-uid. New refuses to open when
// either reaches into the VMM uid range (jailIDs), since a VMM must
// share no id with a container or the engine. "" is the default pool,
// and 0 names no engine.
UsernsPool string
EngineUID uint32
}
Options configure the Cloud Hypervisor backend.