Skip to main content

Staging

Trait Staging 

Source
pub trait Staging: Send + Sync {
    // Required methods
    fn stage_kernel<'life0, 'life1, 'async_trait>(
        &'life0 self,
        src: &'life1 Path,
    ) -> Pin<Box<dyn Future<Output = Result<PathBuf>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn stage_disk<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        id: &'life1 str,
        source: DiskSource<'life2>,
    ) -> Pin<Box<dyn Future<Output = Result<PathBuf>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn unstage_disk<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        id: &'life1 str,
        dst: &'life2 Path,
    ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn stage_checkpoint<'life0, 'life1, 'async_trait>(
        &'life0 self,
        image: &'life1 CheckpointImage,
    ) -> Pin<Box<dyn Future<Output = Result<CheckpointImage>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
}
Expand description

Bring the files a VM boots from into the private area its VMM can reach.

A confined VMM — Firecracker under the jailer, chrooted into a per-VM directory — can open nothing outside that area, so its kernel, its disks, and a checkpoint’s files have to be inside before the VM is told about them. Which files those are is the orchestrator’s business; where they must be, and how they get there (a hard link, a private copy, a device node), is the driver’s. This capability is that split: the caller says what a file is, and gets back the path its spec must name for it. It never learns whether a confinement exists.

Present iff crate::DriverCapabilities::staging, and reachable from both grips on a VM — the prepared VM the driver spawned (PreparedVm::staging) and the handle to the VM running on it (VmHandle::staging) — naming the same area either way. That is what lets a VM this driver adopted, whose prepared half died with the process that made it, still take a disk back out. A driver whose VMs read host paths as they are still offers it, as the identity: staging such a file is a no-op that answers with the path it was given. That is what lets an orchestrator stage unconditionally instead of branching on a confinement it is not supposed to know about.

Staging a file that is already in the VM’s area leaves it alone and names it where it is — so a caller may stage what an earlier stage, or a warm slot it claimed, already put there.

Everything staged belongs to the VM’s area, so a disk that has to outlive the VM is taken back out with unstage_disk first. When that area is removed, and by which verb, is the driver’s own business — it is not PreparedVm::discard on every adapter today, so a caller may assume neither that a discard took the area with it nor that it left the area standing.

Required Methods§

Source

fn stage_kernel<'life0, 'life1, 'async_trait>( &'life0 self, src: &'life1 Path, ) -> Pin<Box<dyn Future<Output = Result<PathBuf>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Stages src as this VM’s kernel image, and returns the path the spec’s BootSpec::Kernel must name.

Source

fn stage_disk<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, source: DiskSource<'life2>, ) -> Pin<Box<dyn Future<Output = Result<PathBuf>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Stages source as this VM’s disk id, and returns the path the DiskSpec carrying that id must name.

id is the disk id the spec will carry, not a file name, and a plain one — the same rule DiskSpec::id is held to, refused rather than resolved by an adapter, since staging writes and replaces at the name it makes from it. A driver that records disk paths in its checkpoints (Firecracker does) records the name it staged the disk under, and a restore reproduces that name from the same id — so a disk staged under one id and specced under another is a checkpoint that will not restore.

Source

fn unstage_disk<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, dst: &'life2 Path, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Moves this VM’s disk id back out to dst, so it survives the VM.

The disk is gone from the VM’s area once this returns; putting it back into a later VM is DiskSource::Handover. Ok(false) means there was no such disk staged — for a driver that stages nothing, or a disk that was never brought in — which is an outcome, not a failure.

The VM must not be writing to the disk. A caller takes a disk out of a VM it is about to discard, and the guest is already stopped or Quiesced by then.

id is a disk id, held to the same rule as DiskSpec::id — a plain name. An adapter refuses anything else rather than resolving it against its own layout, because this verb moves a file.

Source

fn stage_checkpoint<'life0, 'life1, 'async_trait>( &'life0 self, image: &'life1 CheckpointImage, ) -> Pin<Box<dyn Future<Output = Result<CheckpointImage>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Stages image’s files, and returns the image as this VM must name it for PreparedVm::restore.

A warm pool stages a checkpoint into a slot long before any restore is asked for, and that — not the confinement — is what makes this a verb of its own: the memory file is the guest’s entire RAM, so bringing it in is the expensive half of a restore, and a slot that paid for it up front restores in milliseconds.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§