Skip to content

Commit 987c04f

Browse files
authored
Merge pull request #1976 from hermit-os/uhyve-mounts
Uhyve mounts in arbitrary paths
2 parents 6019ba4 + 94da3dd commit 987c04f

File tree

2 files changed

+60
-10
lines changed

2 files changed

+60
-10
lines changed

src/fs/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,19 @@ pub fn create_dir(path: &str, mode: AccessPermission) -> io::Result<()> {
404404
})
405405
}
406406

407+
/// Creates a directory and creates all missing parent directories as well.
408+
fn create_dir_recursive(path: &str, mode: AccessPermission) -> io::Result<()> {
409+
trace!("create_dir_recursive: {path}");
410+
create_dir(path, mode).or_else(|errno| {
411+
if errno != Errno::Badf {
412+
return Err(errno);
413+
}
414+
let (parent_path, _file_name) = path.rsplit_once('/').unwrap();
415+
create_dir_recursive(parent_path, mode)?;
416+
create_dir(path, mode)
417+
})
418+
}
419+
407420
/// Returns an vector with all the entries within a directory.
408421
pub fn readdir(name: &str) -> io::Result<Vec<DirectoryEntry>> {
409422
debug!("Read directory {name}");

src/fs/uhyve.rs

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use alloc::borrow::ToOwned;
12
use alloc::boxed::Box;
23
use alloc::ffi::CString;
34
use alloc::string::{String, ToString};
@@ -14,9 +15,11 @@ use uhyve_interface::parameters::{
1415
use uhyve_interface::{GuestPhysAddr, GuestVirtAddr, Hypercall};
1516

1617
use crate::arch::mm::paging;
18+
use crate::env::fdt;
1719
use crate::errno::Errno;
1820
use crate::fs::{
1921
self, AccessPermission, FileAttr, NodeKind, ObjectInterface, OpenOption, SeekWhence, VfsNode,
22+
create_dir_recursive,
2023
};
2124
use crate::io;
2225
use crate::syscalls::interfaces::uhyve::uhyve_hypercall;
@@ -229,14 +232,48 @@ impl VfsNode for UhyveDirectory {
229232

230233
pub(crate) fn init() {
231234
info!("Try to initialize uhyve filesystem");
232-
let mount_point = hermit_var_or!("UHYVE_MOUNT", "/root").to_string();
233-
info!("Mounting uhyve filesystem at {mount_point}");
234-
fs::FILESYSTEM
235-
.get()
236-
.unwrap()
237-
.mount(
238-
&mount_point,
239-
Box::new(UhyveDirectory::new(Some(mount_point.clone()))),
240-
)
241-
.expect("Mount failed. Duplicate mount_point?");
235+
let mount_str = fdt().and_then(|fdt| {
236+
fdt.find_node("/uhyve,mounts")
237+
.and_then(|node| node.property("mounts"))
238+
.and_then(|property| property.as_str())
239+
});
240+
if let Some(mount_str) = mount_str {
241+
assert_ne!(mount_str.len(), 0, "Invalid /uhyve,mounts node in FDT");
242+
for mount_point in mount_str.split('\0') {
243+
info!("Mounting uhyve filesystem at {mount_point}");
244+
245+
if let Err(errno) = fs::FILESYSTEM.get().unwrap().mount(
246+
mount_point,
247+
Box::new(UhyveDirectory::new(Some(mount_point.to_owned()))),
248+
) {
249+
assert_eq!(errno, Errno::Badf);
250+
debug!(
251+
"Mounting of {mount_point} failed with {errno:?}. Creating missing parent folders"
252+
);
253+
let (parent_path, _file_name) = mount_point.rsplit_once('/').unwrap();
254+
create_dir_recursive(parent_path, AccessPermission::S_IRWXU).unwrap();
255+
256+
fs::FILESYSTEM
257+
.get()
258+
.unwrap()
259+
.mount(
260+
mount_point,
261+
Box::new(UhyveDirectory::new(Some(mount_point.to_owned()))),
262+
)
263+
.unwrap();
264+
}
265+
}
266+
} else {
267+
// No FDT -> Uhyve legacy mounting (to /root)
268+
let mount_point = hermit_var_or!("UHYVE_MOUNT", "/root").to_string();
269+
info!("Mounting uhyve filesystem at {mount_point}");
270+
fs::FILESYSTEM
271+
.get()
272+
.unwrap()
273+
.mount(
274+
&mount_point,
275+
Box::new(UhyveDirectory::new(Some(mount_point.clone()))),
276+
)
277+
.expect("Mount failed. Duplicate mount_point?");
278+
}
242279
}

0 commit comments

Comments
 (0)