Skip to content

Commit

Permalink
feat(tempfile): allow usage of custom tempdir locations
Browse files Browse the repository at this point in the history
This is intended to let users optionally use custom tmpfs filesystems
or store unmapped files in directories that are not monitored by the
temporary file cleaner.
  • Loading branch information
n0toose committed Jan 9, 2025
1 parent da4b63e commit 03e7ca2
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 14 deletions.
12 changes: 12 additions & 0 deletions src/bin/uhyve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ struct Args {
#[clap(long)]
file_mapping: Vec<String>,

/// The path that should be used for temporary directories storing unmapped files.
///
/// This is useful for manually created tmpfs filesystems and for selecting
/// directories not managed by a temporary file cleaner, which can remove open files
/// manually. In most cases, mapping the guest path /root/ instead should be sufficient.
///
/// Defaults to /tmp.
#[clap(long)]
tempdir_path: Option<String>,

#[clap(flatten, next_help_heading = "Memory OPTIONS")]
memory_args: MemoryArgs,

Expand Down Expand Up @@ -257,6 +267,7 @@ impl From<Args> for Params {
#[cfg(target_os = "linux")]
gdb_port,
file_mapping,
tempdir_path,
kernel: _,
kernel_args,
output,
Expand All @@ -277,6 +288,7 @@ impl From<Args> for Params {
#[cfg(target_os = "macos")]
gdb_port: None,
kernel_args,
tempdir_path,
// TODO
output: if let Some(outp) = output {
Output::from_str(&outp).unwrap()
Expand Down
13 changes: 7 additions & 6 deletions src/isolation/filemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ impl UhyveFileMap {
/// Creates a UhyveFileMap.
///
/// * `mappings` - A list of host->guest path mappings with the format "./host_path.txt:guest.txt"
pub fn new(mappings: &[String]) -> UhyveFileMap {
/// * `tempdir_path` - Path to create temporary directory on
pub fn new(mappings: &[String], tempdir_path: &Option<String>) -> UhyveFileMap {
UhyveFileMap {
files: mappings
.iter()
.map(String::as_str)
.map(Self::split_guest_and_host_path)
.map(Result::unwrap)
.collect(),
tempdir: create_temp_dir(),
tempdir: create_temp_dir(tempdir_path),
}
}

Expand Down Expand Up @@ -193,7 +194,7 @@ mod tests {
path_prefix.clone() + "/this_symlink_leads_to_a_file" + ":guest_file_symlink",
];

let mut map = UhyveFileMap::new(&map_parameters);
let mut map = UhyveFileMap::new(&map_parameters, &None);

assert_eq!(
map.get_host_path("readme_file.md").unwrap(),
Expand Down Expand Up @@ -245,7 +246,7 @@ mod tests {
host_path_map.to_str().unwrap(),
guest_path_map.to_str().unwrap()
)];
let mut map = UhyveFileMap::new(&uhyvefilemap_params);
let mut map = UhyveFileMap::new(&uhyvefilemap_params, &None);

let mut found_host_path = map.get_host_path(target_guest_path.clone().to_str().unwrap());

Expand Down Expand Up @@ -276,7 +277,7 @@ mod tests {
guest_path_map.to_str().unwrap()
)];

map = UhyveFileMap::new(&uhyvefilemap_params);
map = UhyveFileMap::new(&uhyvefilemap_params, &None);

target_guest_path = PathBuf::from("/root/this_symlink_leads_to_a_file");
target_host_path = fixture_path.clone();
Expand All @@ -289,7 +290,7 @@ mod tests {

// Tests directory traversal with no maps
let empty_array: [String; 0] = [];
map = UhyveFileMap::new(&empty_array);
map = UhyveFileMap::new(&empty_array, &None);
found_host_path = map.get_host_path(target_guest_path.to_str().unwrap());
assert!(found_host_path.is_none());
}
Expand Down
29 changes: 22 additions & 7 deletions src/isolation/tempdir.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
use std::{fs::Permissions, os::unix::fs::PermissionsExt};

use tempfile::{Builder, TempDir};
use uuid::Uuid;

/// Creates a temporary directory.
pub fn create_temp_dir() -> TempDir {
let dir = Builder::new()
.permissions(Permissions::from_mode(0o700))
.prefix("uhyve-")
.tempdir()
.ok()
.unwrap_or_else(|| panic!("The temporary directory could not be created."));
///
/// * `dir_path` - The location in which the temporary directory should be created.
pub fn create_temp_dir(dir_path: &Option<String>) -> TempDir {
let dir: TempDir;
if let Some(dir_path) = dir_path {
dir = Builder::new()
.permissions(Permissions::from_mode(0o700))
.prefix("uhyve-")
.suffix(&Uuid::new_v4().to_string())
.tempdir_in(dir_path)
.ok()
.unwrap_or_else(|| panic!("The temporary directory could not be created."));
} else {
dir = Builder::new()
.permissions(Permissions::from_mode(0o700))
.prefix("uhyve-")
.suffix(&Uuid::new_v4().to_string())
.tempdir()
.ok()
.unwrap_or_else(|| panic!("The temporary directory could not be created."));
}

let dir_permissions = dir.path().metadata().unwrap().permissions();
assert!(!dir_permissions.readonly());
Expand Down
4 changes: 4 additions & 0 deletions src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ pub struct Params {
/// Mapped paths between the guest and host OS
pub file_mapping: Vec<String>,

/// Path to create temporary directory on
pub tempdir_path: Option<String>,

/// Kernel output handling
pub output: Output,

Expand All @@ -59,6 +62,7 @@ impl Default for Params {
cpu_count: Default::default(),
gdb_port: Default::default(),
file_mapping: Default::default(),
tempdir_path: Default::default(),
kernel_args: Default::default(),
output: Default::default(),
stats: false,
Expand Down
5 changes: 4 additions & 1 deletion src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,10 @@ impl<VirtBackend: VirtualizationBackend> UhyveVm<VirtBackend> {
"gdbstub is only supported with one CPU"
);

let file_mapping = Mutex::new(UhyveFileMap::new(&params.file_mapping));
let file_mapping = Mutex::new(UhyveFileMap::new(
&params.file_mapping,
&params.tempdir_path,
));

let output = match params.output {
params::Output::None => Output::None,
Expand Down

0 comments on commit 03e7ca2

Please # to comment.