summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@noreply.codeberg.org>2023-11-03 08:28:54 +0000
committerLars Wirzenius <liw@noreply.codeberg.org>2023-11-03 08:28:54 +0000
commitabc6c7aa30ce179c5b5d43598bfa612491a89faa (patch)
tree5c2186c20e8a4342ebb19358997e42b6a692ecb9
parent272c6028d827acfcb64ab38955be2b73952dcc5e (diff)
parent7b158c56dd8ff355cb87f57bb4e7a26c76e8acb2 (diff)
downloadambient-run-abc6c7aa30ce179c5b5d43598bfa612491a89faa.tar.gz
Merge pull request 'feat: set up a serial port just for build log' (#27) from liw/build-log-serial-port into main
Reviewed-on: https://codeberg.org/ambient/ambient-run/pulls/27
-rw-r--r--src/qemu.rs54
1 files changed, 34 insertions, 20 deletions
diff --git a/src/qemu.rs b/src/qemu.rs
index 62a3470..a3e344d 100644
--- a/src/qemu.rs
+++ b/src/qemu.rs
@@ -85,6 +85,7 @@ impl Qemu {
let image = tmp.path().join("vm.qcow2");
let vars = tmp.path().join("vars.fd");
+ let console_log = tmp.path().join("console.log");
eprintln!("copy image and vars");
copy(&self.image, &image).map_err(|e| QemuError::Copy(self.image.clone(), e))?;
@@ -135,12 +136,18 @@ impl Qemu {
".ambient-script",
)?;
+ eprintln!("system console log file");
+ Self::create_file(&Some(console_log.clone()))?;
+
+ eprintln!("build log file");
+ let build_log = Self::create_file(&self.log)?;
+
let args = QemuArgs::default()
- .with_valued_arg("-m", "16384")
+ .with_valued_arg("-m", "1024")
.with_valued_arg("-smp", "cpus=4")
.with_valued_arg("-display", "none")
- .with_valued_arg("-chardev", "stdio,id=serial0")
- .with_valued_arg("-serial", "chardev:serial0")
+ .with_valued_arg("-serial", &format!("file:/{}", console_log.display())) // ttyS0
+ .with_valued_arg("-serial", &format!("file:{}", build_log.display())) // ttyS1
.with_ipflash(0, OVMF_FD, true)
.with_ipflash(1, vars.to_str().unwrap(), false)
.with_qcow2(image.to_str().unwrap())
@@ -149,18 +156,13 @@ impl Qemu {
.with_raw(cache_drive.filename(), false)
.with_raw(deps_drive.filename(), true)
.with_arg("-nodefaults");
-
- eprintln!("log file");
- let log = Self::create_file(&self.log)?;
+ eprintln!("Args: {:#?}", args);
eprintln!("spawn qemu");
let child = Command::new("kvm")
.args(args.iter())
- .stdin(Stdio::null())
- .stdout(Stdio::from(log))
- .stderr(Stdio::null())
.spawn()
- .map_err(QemuError::Run)?;
+ .map_err(QemuError::Invoke)?;
eprintln!("wait for qemu");
let output = child.wait_with_output().map_err(QemuError::Run)?;
@@ -180,21 +182,27 @@ impl Qemu {
}
Ok(())
} else {
- let out = String::from_utf8_lossy(&output.stdout);
- let err = String::from_utf8_lossy(&output.stderr);
- eprintln!("kvm ERROR\n{}\n{}", out, err);
- Err(QemuError::Kvm)
+ 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();
+ let log = std::fs::read(&console_log).map_err(QemuError::TemporaryLog)?;
+ let log = String::from_utf8_lossy(&log).to_string();
+ eprintln!(
+ "kvm failed: exit={}\nstdout: {:?}\nstderr: {:?}\nVM console: {:?}",
+ exit, out, err, log
+ );
+ Err(QemuError::Kvm(exit, err, log))
}
}
- fn create_file(filename: &Option<PathBuf>) -> Result<File, QemuError> {
+ fn create_file(filename: &Option<PathBuf>) -> Result<PathBuf, QemuError> {
let filename = if let Some(filename) = filename {
filename
} else {
Path::new("/dev/null")
};
- let file = File::create(filename).map_err(|e| QemuError::Log(filename.into(), e))?;
- Ok(file)
+ File::create(filename).map_err(|e| QemuError::Log(filename.into(), e))?;
+ Ok(filename.into())
}
fn create_tar(tar_filename: PathBuf, dirname: &Path) -> Result<VirtualDrive, QemuError> {
@@ -289,11 +297,14 @@ impl QemuArgs {
#[allow(missing_docs)]
#[derive(Debug, thiserror::Error)]
pub enum QemuError {
- #[error("failed to run QEMU")]
+ #[error("failed to invoke QEMU")]
+ Invoke(#[source] std::io::Error),
+
+ #[error("QEMU failed")]
Run(#[source] std::io::Error),
- #[error("failed to run QEMU")]
- Kvm,
+ #[error("failed to run QEMU (kvm): exit code {0}, stderr:\n{1}\nconsole: {2}")]
+ Kvm(i32, String, String),
#[error("failed to create a temporary directory")]
TempDir(#[source] std::io::Error),
@@ -315,6 +326,9 @@ pub enum QemuError {
#[error("failed to extract cache drive to {0}")]
ExtractCache(PathBuf, #[source] VirtualDriveError),
+
+ #[error("failed to read temporary file for logging")]
+ TemporaryLog(#[source] std::io::Error),
}
#[cfg(test)]