@@ -33,8 +33,6 @@ const EMPTY_CSTR: &[u8] = b"\0";
3333const PROC_CSTR : & [ u8 ] = b"/proc/self/fd\0 " ;
3434const INIT_CSTR : & [ u8 ] = b"init.krun\0 " ;
3535
36- static INIT_BINARY : & [ u8 ] = include_bytes ! ( env!( "KRUN_INIT_BINARY_PATH" ) ) ;
37-
3836type Inode = u64 ;
3937type Handle = u64 ;
4038
@@ -328,6 +326,7 @@ pub struct Config {
328326 /// Table of exported FDs to share with other subsystems.
329327 pub export_table : Option < ExportTable > ,
330328 pub allow_root_dir_delete : bool ,
329+ pub init_payload : Option < & ' static [ u8 ] > ,
331330}
332331
333332impl Default for Config {
@@ -343,6 +342,7 @@ impl Default for Config {
343342 export_fsid : 0 ,
344343 export_table : None ,
345344 allow_root_dir_delete : false ,
345+ init_payload : None ,
346346 }
347347 }
348348}
@@ -439,7 +439,11 @@ impl PassthroughFs {
439439 Ok ( PassthroughFs {
440440 inodes : RwLock :: new ( MultikeyBTreeMap :: new ( ) ) ,
441441 next_inode : AtomicU64 :: new ( fuse:: ROOT_ID + 2 ) ,
442- init_inode : fuse:: ROOT_ID + 1 ,
442+ init_inode : if cfg. init_payload . is_some ( ) {
443+ fuse:: ROOT_ID + 1
444+ } else {
445+ 0
446+ } ,
443447
444448 handles : RwLock :: new ( BTreeMap :: new ( ) ) ,
445449 next_handle : AtomicU64 :: new ( 1 ) ,
@@ -456,6 +460,12 @@ impl PassthroughFs {
456460 } )
457461 }
458462
463+ fn init_payload ( & self ) -> io:: Result < & [ u8 ] > {
464+ self . cfg
465+ . init_payload
466+ . ok_or_else ( || io:: Error :: from_raw_os_error ( libc:: ENOENT ) )
467+ }
468+
459469 fn open_inode ( & self , inode : Inode , mut flags : i32 ) -> io:: Result < File > {
460470 let data = self
461471 . inodes
@@ -996,7 +1006,7 @@ impl FileSystem for PassthroughFs {
9961006
9971007 if self . init_inode != 0 && name == init_name {
9981008 let mut st: libc:: stat64 = unsafe { mem:: zeroed ( ) } ;
999- st. st_size = INIT_BINARY . len ( ) as i64 ;
1009+ st. st_size = self . init_payload ( ) ? . len ( ) as i64 ;
10001010 st. st_ino = self . init_inode ;
10011011 st. st_mode = 0o100_755 ;
10021012
@@ -1235,13 +1245,16 @@ impl FileSystem for PassthroughFs {
12351245 ) -> io:: Result < usize > {
12361246 debug ! ( "read: {inode:?}" ) ;
12371247 if inode == self . init_inode {
1248+ let init_payload = self . init_payload ( ) ?;
12381249 let off: usize = offset. try_into ( ) . map_err ( |_| einval ( ) ) ?;
1239- let len = if off + ( size as usize ) < INIT_BINARY . len ( ) {
1240- size as usize
1241- } else {
1242- INIT_BINARY . len ( ) - off
1243- } ;
1244- return w. write ( & INIT_BINARY [ off..( off + len) ] ) ;
1250+ if off >= init_payload. len ( ) {
1251+ // Read past EOF should return 0 bytes.
1252+ return Ok ( 0 ) ;
1253+ }
1254+
1255+ let remaining = init_payload. len ( ) - off;
1256+ let len = remaining. min ( size as usize ) ;
1257+ return w. write ( & init_payload[ off..( off + len) ] ) ;
12451258 }
12461259
12471260 let data = self
@@ -2088,6 +2101,7 @@ impl FileSystem for PassthroughFs {
20882101 debug ! ( "setupmapping: ino {inode:?} addr={addr:x} len={len}" ) ;
20892102
20902103 if inode == self . init_inode {
2104+ let init_payload = self . init_payload ( ) ?;
20912105 let ret = unsafe {
20922106 libc:: mmap (
20932107 addr as * mut libc:: c_void ,
@@ -2102,15 +2116,15 @@ impl FileSystem for PassthroughFs {
21022116 return Err ( io:: Error :: last_os_error ( ) ) ;
21032117 }
21042118
2105- let to_copy = if len as usize > INIT_BINARY . len ( ) {
2106- INIT_BINARY . len ( )
2119+ let to_copy = if len as usize > init_payload . len ( ) {
2120+ init_payload . len ( )
21072121 } else {
21082122 len as usize
21092123 } ;
21102124 unsafe {
21112125 libc:: memcpy (
21122126 addr as * mut libc:: c_void ,
2113- INIT_BINARY . as_ptr ( ) as * const _ ,
2127+ init_payload . as_ptr ( ) as * const _ ,
21142128 to_copy,
21152129 )
21162130 } ;
0 commit comments