summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2024-03-29 17:06:47 +0200
committerLars Wirzenius <liw@liw.fi>2024-03-29 17:06:47 +0200
commitf98a287fad7f2b46f112dac9c54ff27732e4c46b (patch)
tree866020ea132dc5833dae03fc0bb5d3119d535fa0
parent3b326caecf974071c2343db4ba280ebdd04150a8 (diff)
downloadambient-driver-f98a287fad7f2b46f112dac9c54ff27732e4c46b.tar.gz
feat: use copy-on-write qcow2 images for VM image
Previously, we made a copy. This is faster. Signed-off-by: Lars Wirzenius <liw@liw.fi> Sponsored-by: author
-rw-r--r--src/qemu.rs31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/qemu.rs b/src/qemu.rs
index 22c0bb9..4f5afff 100644
--- a/src/qemu.rs
+++ b/src/qemu.rs
@@ -115,8 +115,8 @@ impl Qemu {
let vars = tmp.path().join("vars.fd");
let console_log = tmp.path().join("console.log");
- debug!("copy image and vars");
- copy(&self.image, &image).map_err(|e| QemuError::Copy(self.image.clone(), e))?;
+ debug!("create copy-on-write image and UEFI vars file");
+ create_cow_image(&self.image, &image)?;
copy(OVMF_FD, &vars).map_err(|e| QemuError::Copy(OVMF_FD.into(), e))?;
debug!("create run-ci drive from {}", self.run_ci.display());
@@ -288,6 +288,30 @@ impl Qemu {
}
}
+fn create_cow_image(backing_file: &Path, new_file: &Path) -> Result<(), QemuError> {
+ let output = Command::new("qemu-img")
+ .arg("create")
+ .arg("-b")
+ .arg(backing_file)
+ .args(["-F", "qcow2"])
+ .args(["-f", "qcow2"])
+ .arg(new_file)
+ .output()
+ .map_err(QemuError::Run)?;
+ if !output.status.success() {
+ let exit = output.status.code().unwrap_or(255);
+ let out = String::from_utf8_lossy(&output.stdout).to_string();
+ let err = String::from_utf8_lossy(&output.stderr).to_string();
+ error!(
+ "qemu-img failed: exit={}\nstdout: {:?}\nstderr: {:?}",
+ exit, out, err,
+ );
+ Err(QemuError::QemuImg(exit, err))
+ } else {
+ Ok(())
+ }
+}
+
#[derive(Debug, Default)]
struct QemuArgs {
args: Vec<String>,
@@ -348,6 +372,9 @@ pub enum QemuError {
#[error("QEMU failed")]
Run(#[source] std::io::Error),
+ #[error("qemu-img failed: exit code {0}: stderr:\n{1}")]
+ QemuImg(i32, String),
+
#[error("failed to run QEMU (kvm): exit code {0}, stderr:\n{1}\nconsole: {2}")]
Kvm(i32, String, String),