#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
fn main() {
use std::time::Duration;
use supermachine::{Image, VmConfig};
let base_dir = "/tmp/sm-diff-base";
let diff_dir = "/tmp/sm-diff-delta";
let _ = std::fs::remove_dir_all(base_dir);
let _ = std::fs::remove_dir_all(diff_dir);
let image = Image::from_oci("alpine").expect("from_oci");
eprintln!("=== capture BASE snapshot ===");
let vm0 = image.start(&VmConfig::new()).expect("start0");
std::thread::sleep(Duration::from_millis(5000));
let base = vm0.snapshot(base_dir).expect("base snapshot");
let base_sz = std::fs::metadata(format!("{base_dir}/vm.snap"))
.map(|m| m.len())
.unwrap_or(0);
eprintln!("base vm.snap = {} MiB", base_sz / (1024 * 1024));
eprintln!("=== restore base, write a marker, capture DIFF ===");
let vm1 = base.start(&VmConfig::new()).expect("start1");
std::thread::sleep(Duration::from_millis(3000));
let w = vm1
.exec_builder()
.argv([
"/bin/sh",
"-c",
"echo diff-marker-9f3a > /root/marker && sync && cat /root/marker",
])
.output()
.expect("exec write");
eprintln!(
"wrote marker: success={} out={:?}",
w.success(),
String::from_utf8_lossy(&w.stdout).trim_end()
);
let diff = vm1.snapshot_diff(diff_dir, &base).expect("snapshot_diff");
let diff_sz = std::fs::metadata(format!("{diff_dir}/vm.snap"))
.map(|m| m.len())
.unwrap_or(0);
eprintln!(
"diff vm.snap = {} MiB ({} KiB) — {:.1}% of base",
diff_sz / (1024 * 1024),
diff_sz / 1024,
100.0 * diff_sz as f64 / base_sz.max(1) as f64
);
eprintln!("=== restore from DIFF, read the marker back ===");
let vm2 = diff.start(&VmConfig::new()).expect("start2");
std::thread::sleep(Duration::from_millis(3000));
let r = vm2
.exec_builder()
.argv(["/bin/cat", "/root/marker"])
.output()
.expect("exec read");
let got = String::from_utf8_lossy(&r.stdout).trim_end().to_string();
eprintln!("diff-restore read: success={} out={:?}", r.success(), got);
vm2.stop().ok();
let pass = got == "diff-marker-9f3a" && diff_sz > 0 && diff_sz < base_sz;
eprintln!(
"=== SNAPSHOT_DIFF: {} ===",
if pass { "PASS" } else { "FAIL" }
);
}
#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
fn main() {
eprintln!("kvm_snapshot_diff is Linux/x86_64 only");
}