Bead: m80-q420k.5.7.
This guide shows a staged migration for existing m80 consumers. Keep the migration split: first add read-only pmem layers without changing warm strategy, then move from boot-fill warm slots to snapshot-template restore.
The examples use the planned BootSpec shape from docs/examples/. Parser and
CLI hardening are separate Phase E leaves.
Start by moving large read-only artifacts, such as toolchains, into erofs pmem layers while keeping the existing warm strategy.
Before:
rootfs:
base: "sha256:rootfs-base"
warm_strategy:
boot_fill: {}After:
rootfs:
base: "sha256:rootfs-base"
pmem_layers:
- image: "sha256:toolchain-erofs"
sharing:
per_vm: {}
mount_at: "/opt/m80-layers/toolchain"
warm_strategy:
boot_fill: {}Operator flow:
- Build or import the erofs image with
m80 image build. - Verify it with
m80 image verify sha256:toolchain-erofs. - Deploy the BootSpec with
PmemSharing::PerVm. - Run real-KVM smoke for the consumer workload.
- Watch
m80_pmem_layers_per_vm_count{sharing="per_vm"}and guest DAX mount diagnostics.
This stage should not change restore behavior, template stores, or hook
execution. Rollback is to remove pmem_layers and redeploy the old BootSpec.
Switch from PerVm to Shared only for same-trust-domain guests. Shared is a
capacity optimization, not an isolation feature. The side channel is cache
timing via shared DAX-backed pages, and the assumption is documented in
docs/positioning.md "Trust-Domain Assumption for Shared Pmem".
Before:
pmem_layers:
- image: "sha256:toolchain-erofs"
sharing:
per_vm: {}
mount_at: "/opt/m80-layers/toolchain"After:
pmem_layers:
- image: "sha256:toolchain-erofs"
sharing:
shared:
trust_reason: "same_operator"
mount_at: "/opt/m80-layers/toolchain"Operator flow:
- Confirm the guests sharing the layer are inside one trust domain.
- Record the reason as the typed trust witness, not a free-form note.
- Verify the image with
m80 image verify. - Use
m80 image showandm80 warm statusto confirm the expected image and active leases. - Wait for the verified density artifact before treating memory savings as a production claim.
Rollback is to switch the same image digest back to PerVm. Do not delete the
canonical image-store artifact as part of rollback.
After pmem layers are stable, move warm slots from boot-fill to snapshot-template restore.
Before:
warm_strategy:
boot_fill: {}After:
warm_strategy:
snapshot_restore:
template: "sha256:template-fingerprint"
hooks:
- reseed_systemd_random_seed: {}
- regen_machine_id: {}
- set_hostname:
value: "m80-template"Operator flow:
- Build a template with
m80 template build. - Inspect it with
m80 template show sha256:template-fingerprint. - Start or restart the explicit warm owner with
m80 warm enable. - Use
m80 warm statusand Prometheusm80_restore_latency_secondsto check the restore path. - Use
m80 logs <vm-id>when a post-restore hook fails; hook failure rejects the lease and tears the VM down.
Rollback is to set warm_strategy back to boot_fill and drain the warm owner:
m80 warm drain
m80 warm disableThen redeploy the BootSpec with boot_fill and start the owner again if needed.
Snapshot templates are tied to fingerprint inputs:
- host kernel version;
- Firecracker version;
- guest kernel digest;
- pmem image digest set;
- post-init state digest;
- hook-spec-set digest.
During a host kernel, Firecracker, or guest kernel rollout, expect old templates to become invalidated. This is intentional. Do not build compatibility shims that restore stale templates across incompatible inputs.
Recommended window:
- Keep the current warm owner running while new hosts are prepared.
- Stop new lease admission or drain the owner.
- Upgrade the host/Firecracker/guest artifacts.
- Run
m80 preflight. - Use
m80 template prune --boot-spec <file>to remove unpinned templates in the same conservative family scope whose fingerprint no longer matches the current host/kernel/Firecracker tuple. Inspect anything outside that scope withm80 template listandm80 template show <fingerprint>, then remove known-stale templates withm80 template rm <fingerprint>. - Build new templates and restart warm owners.
If the rollout fails, roll back host artifacts and use boot_fill until a new
template can be built and measured.
After a host kernel bump, template fingerprints should change. Use this flow:
m80 warm drain
m80 preflight
m80 template list
m80 template prune --boot-spec ./boot-spec.yaml
m80 template build <name> --boot-spec ./boot-spec.yaml
m80 warm enable --foreground --size 4Do not close measurement-shaped beads from this operator flow unless the run also writes the required committed real-substrate artifact.
- Pmem layer behavior:
docs/behaviors/rootfs/pmem-layers.md. - Shared pmem behavior:
docs/behaviors/rootfs/pmem-shared.md. - Template lifecycle:
docs/decisions/0007-snapshot-template-lifecycle.md. - Post-restore hooks:
docs/behaviors/warm-pool/post-restore-hooks.md. - Restore latency measurement:
docs/perf/snapshot-template-restore.md. - Composed e2e measurement: future
docs/perf/composed-e2e.md.