#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
fn main() {
use std::time::Duration;
use supermachine::vmm::resources::VolumeSpec;
use supermachine::{Image, VmConfig};
let backing = std::env::args()
.nth(1)
.unwrap_or_else(|| "/tmp/sm-vol.img".to_string());
let _ = std::fs::remove_file(&backing); let cfg = || {
VmConfig::new().with_volume(VolumeSpec {
host_path: backing.clone(),
guest_path: "/data".to_string(),
size_bytes: 64 * 1024 * 1024,
})
};
let image = Image::from_oci("alpine").expect("from_oci");
eprintln!("=== VM #1: mount /data (vol), write a file ===");
let vm = image.start(&cfg()).expect("start1");
std::thread::sleep(Duration::from_millis(5000));
let w = vm
.exec_builder()
.argv([
"/bin/sh",
"-c",
"mount | grep -q ' /data ' && V=persisted-$(date +%s) && echo $V > /data/probe && sync && cat /data/probe",
])
.output()
.expect("exec write");
let written = String::from_utf8_lossy(&w.stdout).trim_end().to_string();
eprintln!("VM#1: success={} out={:?}", w.success(), written);
vm.stop().expect("stop1");
eprintln!("=== VM #2: same volume, read the file back (persistence) ===");
let vm2 = image.start(&cfg()).expect("start2");
std::thread::sleep(Duration::from_millis(5000));
let r = vm2
.exec_builder()
.argv(["/bin/sh", "-c", "cat /data/probe 2>&1"])
.output()
.expect("exec read");
let read_back = String::from_utf8_lossy(&r.stdout).trim_end().to_string();
eprintln!("VM#2: success={} read={:?}", r.success(), read_back);
vm2.stop().expect("stop2");
let persisted =
written.contains("persisted-") && read_back == written.lines().next().unwrap_or("X");
let probe_val = written.lines().next().unwrap_or("");
eprintln!(
"=== VOLUME PERSISTENCE: {} (wrote {:?}, read {:?}) ===",
if read_back == probe_val {
"PASS"
} else {
"FAIL"
},
probe_val,
read_back
);
let _ = persisted;
}
#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
fn main() {
eprintln!("kvm_volume is Linux/x86_64 only");
}