use std::path::{Path, PathBuf};
use ktstr::cli;
use crate::kernel::resolve_kernel_image;
#[allow(clippy::too_many_arguments)]
pub(crate) fn run_shell(
kernel: Option<String>,
topology: String,
include_files: Vec<PathBuf>,
memory_mb: Option<u32>,
dmesg: bool,
exec: Option<String>,
no_perf_mode: bool,
cpu_cap: Option<usize>,
disk: Option<String>,
) -> Result<(), String> {
if no_perf_mode {
unsafe { std::env::set_var("KTSTR_NO_PERF_MODE", "1") };
}
if let Some(cap) = cpu_cap {
if std::env::var("KTSTR_BYPASS_LLC_LOCKS")
.ok()
.is_some_and(|v| !v.is_empty())
{
return Err(
"--cpu-cap conflicts with KTSTR_BYPASS_LLC_LOCKS=1; unset one of them. \
--cpu-cap is a resource contract; bypass disables the contract entirely."
.to_string(),
);
}
cli::CpuCap::new(cap).map_err(|e| format!("{e:#}"))?;
unsafe { std::env::set_var("KTSTR_CPU_CAP", cap.to_string()) };
}
let disk_cfg = cli::parse_disk_arg(disk.as_deref()).map_err(|e| format!("{e:#}"))?;
cli::check_kvm().map_err(|e| format!("{e:#}"))?;
let kernel_path = resolve_kernel_image(kernel.as_deref())?;
let (numa_nodes, llcs, cores, threads) =
cli::parse_topology_string(&topology).map_err(|e| format!("{e:#}"))?;
let resolved_includes =
cli::resolve_include_files(&include_files).map_err(|e| format!("{e:#}"))?;
let include_refs: Vec<(&str, &Path)> = resolved_includes
.iter()
.map(|(a, p)| (a.as_str(), p.as_path()))
.collect();
ktstr::run_shell(
kernel_path,
numa_nodes,
llcs,
cores,
threads,
&include_refs,
memory_mb,
dmesg,
exec.as_deref(),
disk_cfg,
)
.map_err(|e| format!("{e:#}"))
}