From 91215703bfac72717140ef09902b69e6a7ecd63f Mon Sep 17 00:00:00 2001 From: Roey Darwish Dror Date: Sun, 2 Jun 2019 14:31:19 +0300 Subject: [PATCH] Add qemu command --- src/args.rs | 14 ++++++++++++++ src/error.rs | 3 +++ src/main.rs | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/args.rs b/src/args.rs index daca627..d9e4a55 100644 --- a/src/args.rs +++ b/src/args.rs @@ -19,6 +19,9 @@ pub enum Command { #[structopt(name = "chroot", about = "Chroot into exiting Live USB")] Chroot(ChrootCommand), + + #[structopt(name = "qemu", about = "Boot the USB with Qemu")] + Qemu(QemuCommand), } #[derive(StructOpt)] @@ -54,3 +57,14 @@ pub struct ChrootCommand { #[structopt()] pub command: Vec, } + +#[derive(StructOpt)] +pub struct QemuCommand { + /// Path starting with /dev/disk/by-id for the USB drive + #[structopt(parse(from_os_str))] + pub block_device: PathBuf, + + /// Arguments to pass to qemu + #[structopt()] + pub args: Vec, +} diff --git a/src/error.rs b/src/error.rs index ca575be..fafe884 100644 --- a/src/error.rs +++ b/src/error.rs @@ -70,6 +70,9 @@ pub enum ErrorKind { #[fail(display = "Error setting the locale")] Locale, + + #[fail(display = "Failed launching Qemu")] + Qemu, } impl Fail for Error { diff --git a/src/main.rs b/src/main.rs index 6f0ec01..e20ace4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ use nix::sys::signal; use simplelog::*; use std::fs; use std::io::Write; +use std::os::unix::process::CommandExt as UnixCommandExt; use std::path::Path; use std::process::exit; use std::thread; @@ -299,6 +300,37 @@ fn chroot(command: ChrootCommand) -> Result<(), Error> { Ok(()) } +fn qemu(command: QemuCommand) -> Result<(), Error> { + let qemu = Tool::find("qemu-system-x86_64")?; + + let err = qemu + .execute() + .args(&[ + "-enable-kvm", + "-cpu", + "host", + "-m", + "4G", + "-netdev", + "user,id=user.0", + "-device", + "virtio-net-pci,netdev=user.0", + "-device", + "qemu-xhci,id=xhci", + "-device", + "usb-tablet,bus=xhci.0", + "-drive", + ]) + .arg(format!( + "file={},if=virtio,format=raw", + command.block_device.display() + )) + .args(command.args) + .exec(); + + Err(err).context(ErrorKind::Qemu)? +} + extern "C" fn handle_sigint(_: i32) { warn!("Interrupted"); } @@ -327,6 +359,7 @@ fn main() { let result = match app.cmd { Command::Create(command) => create(command), Command::Chroot(command) => chroot(command), + Command::Qemu(command) => qemu(command), }; match result {