diff options
author | Lars Wirzenius <liw@noreply.codeberg.org> | 2023-11-03 08:28:54 +0000 |
---|---|---|
committer | Lars Wirzenius <liw@noreply.codeberg.org> | 2023-11-03 08:28:54 +0000 |
commit | abc6c7aa30ce179c5b5d43598bfa612491a89faa (patch) | |
tree | 5c2186c20e8a4342ebb19358997e42b6a692ecb9 | |
parent | 272c6028d827acfcb64ab38955be2b73952dcc5e (diff) | |
parent | 7b158c56dd8ff355cb87f57bb4e7a26c76e8acb2 (diff) | |
download | ambient-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.rs | 54 |
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)] |