1+ use alloc:: borrow:: ToOwned ;
12use alloc:: boxed:: Box ;
23use alloc:: ffi:: CString ;
34use alloc:: string:: { String , ToString } ;
@@ -14,9 +15,11 @@ use uhyve_interface::parameters::{
1415use uhyve_interface:: { GuestPhysAddr , GuestVirtAddr , Hypercall } ;
1516
1617use crate :: arch:: mm:: paging;
18+ use crate :: env:: fdt;
1719use crate :: errno:: Errno ;
1820use crate :: fs:: {
1921 self , AccessPermission , FileAttr , NodeKind , ObjectInterface , OpenOption , SeekWhence , VfsNode ,
22+ create_dir_recursive,
2023} ;
2124use crate :: io;
2225use crate :: syscalls:: interfaces:: uhyve:: uhyve_hypercall;
@@ -229,14 +232,48 @@ impl VfsNode for UhyveDirectory {
229232
230233pub ( 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