Skip to content
This repository has been archived by the owner on Dec 17, 2024. It is now read-only.

Commit

Permalink
fix: dynamic QEMU path resolution (#198)
Browse files Browse the repository at this point in the history
Prior to this commit, it is assumed that the QEMU binary resides within
the canonical Linux path. However, certain systems like NixOS may place
QEMU in a local user folder instead of the global `/usr/bin` path,
causing an error when attempting to locate the QEMU binary.

This change incorporates a `which` command, which searches through the
current `PATH` environment variable and identifies the location of the
QEMU binary.

It also creates a new CLI argument `qemu_path`.
  • Loading branch information
vlopes11 authored Jun 17, 2024
1 parent 82bff11 commit bec1cd5
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 2 deletions.
1 change: 1 addition & 0 deletions crates/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ thiserror = "1"
tokio = { version = "1", features = ["full", "io-util", "tracing"] }
tracing = "0.1"
uuid = { version = "1", features = [ "v4", "fast-rng", "macro-diagnostics", "serde" ] }
which = "6.0"

bytes = { version = "1.5", optional = true }
clap = { version = "4", features = ["derive", "env", "string"], optional = true }
Expand Down
28 changes: 28 additions & 0 deletions crates/node/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,34 @@ pub struct Config {
env = "GEVULOT_METRICS_LISTEN_ADDR"
)]
pub http_metrics_listen_addr: Option<SocketAddr>,

#[arg(
long,
long_help = "QEMU path to system-x86_64 runner",
env = "GEVULOT_QEMU_PATH",
default_value = "qemu-system-x86_64"
)]
pub qemu_path: Option<PathBuf>,
}

impl Config {
/// Resolves the provided QEMU path.
///
/// # Panics
///
/// The absence of a valid QEMU runnner is an unrecoverable error.
pub fn resolve_qemu_path(&self) -> PathBuf {
self.qemu_path
.as_ref()
.map(which::which)
.transpose()
.ok()
.flatten()
.filter(|p| p.is_file())
.expect(
"a valid QEMU binary must be provided. Check `--qemu_path` or `GEVULOT_QEMU_PATH`.",
)
}
}

#[derive(Debug, Args)]
Expand Down
1 change: 1 addition & 0 deletions crates/node/src/rpc_server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ mod tests {
http_download_port: 0,
http_healthcheck_listen_addr: "127.0.0.1:8888".parse().unwrap(),
http_metrics_listen_addr: None,
qemu_path: None,
});

let db = Arc::new(Database::new(&cfg.db_url).await.unwrap());
Expand Down
10 changes: 8 additions & 2 deletions crates/node/src/vmm/qemu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::{
any::Any,
collections::{BTreeSet, HashMap},
fs::File,
path::Path,
path::{Path, PathBuf},
process::{Child, Command, Stdio},
sync::{
atomic::{AtomicU32, Ordering},
Expand Down Expand Up @@ -71,15 +71,19 @@ pub struct Qemu {
next_cid: AtomicU32,
cid_allocations: BTreeSet<u32>,
vm_registry: HashMap<u32, QEMUVMHandle>,
qemu_path: PathBuf,
}

impl Qemu {
pub fn new(config: Arc<Config>) -> Self {
let qemu_path = config.resolve_qemu_path();

Qemu {
config,
next_cid: AtomicU32::new(4),
cid_allocations: Default::default(),
vm_registry: HashMap::new(),
qemu_path,
}
}

Expand Down Expand Up @@ -189,7 +193,9 @@ impl Provider for Qemu {

// Update the child process field.
let qemu_vm_handle = &mut self.vm_registry.get_mut(&cid).unwrap();
let mut cmd = Command::new("/usr/bin/qemu-system-x86_64");

// Resolve the QEMU system command
let mut cmd = Command::new(&self.qemu_path);

//define the VirtFs local path and create all necessary folder
let workspace_path = TaskVmFile::get_workspace_path(&self.config.data_directory, tx_hash);
Expand Down
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
buildInputs =
[
p.openssl
p.ops
p.pkg-config
p.protobuf
];
Expand Down

0 comments on commit bec1cd5

Please sign in to comment.