Skip to content

Commit

Permalink
hypervisor: support user space mounts
Browse files Browse the repository at this point in the history
This commit introduces the ability to mount custom files and folders
from the host operating system onto a partition.

The hypervisor configuration is adjusted as follows at partition layer:
```yaml
mounts:
  - [ "/dev/urandom", "/dev/urandom"]
  - [ "/dev/urandom", "/dev/random"]
  - [ "/a/file/on/the/host", "/guest" ]
```

Future features could additionally include the ability to mount things
read-only, etc.

Fixes #42
  • Loading branch information
cvengler committed Feb 27, 2023
1 parent db684ec commit b01d731
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
2 changes: 2 additions & 0 deletions hypervisor/src/hypervisor/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ pub struct Partition {
pub devices: Vec<Device>,
#[serde(default)]
pub hm_table: PartitionHMTable,
#[serde(default)]
pub mounts: Vec<(PathBuf, PathBuf)>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
Expand Down
42 changes: 40 additions & 2 deletions hypervisor/src/hypervisor/partition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -99,6 +99,36 @@ impl FileMounter {
}
}

impl TryFrom<&(PathBuf, PathBuf)> for FileMounter {
type Error = anyhow::Error;

fn try_from(paths: &(PathBuf, PathBuf)) -> Result<Self, Self::Error> {
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<Run> {
let cgroup_main = base.cgroup.new("main").typ(SystemError::CGroup)?;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -449,6 +485,7 @@ pub(crate) struct Base {
hm: PartitionHMTable,
id: i64,
bin: PathBuf,
mounts: Vec<(PathBuf, PathBuf)>,
cgroup: CGroup,
sampling_channel: HashMap<String, SamplingConstant>,
duration: Duration,
Expand Down Expand Up @@ -517,6 +554,7 @@ impl Partition {
id: config.id,
cgroup,
bin: config.image,
mounts: config.mounts,
duration: config.duration,
period: config.period,
working_dir,
Expand Down

0 comments on commit b01d731

Please sign in to comment.