diff --git a/hypervisor/src/hypervisor/config.rs b/hypervisor/src/hypervisor/config.rs index 4fd0f22..1ec5ed9 100644 --- a/hypervisor/src/hypervisor/config.rs +++ b/hypervisor/src/hypervisor/config.rs @@ -38,6 +38,8 @@ pub struct Partition { pub devices: Vec, #[serde(default)] pub hm_table: PartitionHMTable, + #[serde(default)] + pub mounts: Vec<(PathBuf, PathBuf)>, } #[derive(Debug, Serialize, Deserialize, Clone)] diff --git a/hypervisor/src/hypervisor/partition.rs b/hypervisor/src/hypervisor/partition.rs index 5901078..c006647 100644 --- a/hypervisor/src/hypervisor/partition.rs +++ b/hypervisor/src/hypervisor/partition.rs @@ -5,7 +5,7 @@ use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::time::Duration; -use anyhow::anyhow; +use anyhow::{anyhow, bail}; use apex_rs::bindings::PortDirection; use apex_rs::prelude::{OperatingMode, StartCondition}; use clone3::Clone3; @@ -99,6 +99,36 @@ impl FileMounter { } } +impl TryFrom<&(PathBuf, PathBuf)> for FileMounter { + type Error = anyhow::Error; + + fn try_from(paths: &(PathBuf, PathBuf)) -> Result { + let source = &paths.0; + let mut target = paths.1.clone(); + + if !source.exists() { + bail!("File/Directory {} not existent", source.display()) + } + + if target.is_absolute() { + // Convert absolute paths into relative ones. + // Otherwise we will receive a permission error. + // TODO: Make this a function? + target = target.strip_prefix("/")?.into(); + assert!(target.is_relative()); + } + + Ok(Self { + source: Some(source.clone()), + target: target, + fstype: None, + flags: MsFlags::MS_BIND, + data: None, + is_dir: source.is_dir(), + }) + } +} + impl Run { pub fn new(base: &Base, condition: StartCondition, warm_start: bool) -> TypedResult { let cgroup_main = base.cgroup.new("main").typ(SystemError::CGroup)?; @@ -174,7 +204,7 @@ impl Run { Partition::release_fds(&keep).unwrap(); // Mount the required mounts - let mounts = [ + let mut mounts = vec![ // Mount working directory as tmpfs FileMounter { source: None, @@ -222,6 +252,12 @@ impl Run { }, ]; + for m in &base.mounts { + mounts.push(m.try_into().unwrap()); + } + + // TODO: Check for duplicate mounts + for m in mounts { debug!("mounting {:?}", &m); m.mount(base.working_dir.path()).unwrap(); @@ -449,6 +485,7 @@ pub(crate) struct Base { hm: PartitionHMTable, id: i64, bin: PathBuf, + mounts: Vec<(PathBuf, PathBuf)>, cgroup: CGroup, sampling_channel: HashMap, duration: Duration, @@ -517,6 +554,7 @@ impl Partition { id: config.id, cgroup, bin: config.image, + mounts: config.mounts, duration: config.duration, period: config.period, working_dir,