@@ -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,10 @@ impl PassthroughFs {
456460 } )
457461 }
458462
463+ fn init_payload ( & self ) -> io:: Result < & [ u8 ] > {
464+ self . cfg . init_payload . ok_or_else ( ebadf)
465+ }
466+
459467 fn open_inode ( & self , inode : Inode , mut flags : i32 ) -> io:: Result < File > {
460468 let data = self
461469 . inodes
@@ -996,7 +1004,7 @@ impl FileSystem for PassthroughFs {
9961004
9971005 if self . init_inode != 0 && name == init_name {
9981006 let mut st: libc:: stat64 = unsafe { mem:: zeroed ( ) } ;
999- st. st_size = INIT_BINARY . len ( ) as i64 ;
1007+ st. st_size = self . init_payload ( ) ? . len ( ) as i64 ;
10001008 st. st_ino = self . init_inode ;
10011009 st. st_mode = 0o100_755 ;
10021010
@@ -1235,13 +1243,16 @@ impl FileSystem for PassthroughFs {
12351243 ) -> io:: Result < usize > {
12361244 debug ! ( "read: {inode:?}" ) ;
12371245 if inode == self . init_inode {
1246+ let init_payload = self . init_payload ( ) ?;
12381247 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) ] ) ;
1248+ if off >= init_payload. len ( ) {
1249+ // Read past EOF should return 0 bytes.
1250+ return Ok ( 0 ) ;
1251+ }
1252+
1253+ let remaining = init_payload. len ( ) - off;
1254+ let len = remaining. min ( size as usize ) ;
1255+ return w. write ( & init_payload[ off..( off + len) ] ) ;
12451256 }
12461257
12471258 let data = self
@@ -2088,6 +2099,7 @@ impl FileSystem for PassthroughFs {
20882099 debug ! ( "setupmapping: ino {inode:?} addr={addr:x} len={len}" ) ;
20892100
20902101 if inode == self . init_inode {
2102+ let init_payload = self . init_payload ( ) ?;
20912103 let ret = unsafe {
20922104 libc:: mmap (
20932105 addr as * mut libc:: c_void ,
@@ -2102,15 +2114,15 @@ impl FileSystem for PassthroughFs {
21022114 return Err ( io:: Error :: last_os_error ( ) ) ;
21032115 }
21042116
2105- let to_copy = if len as usize > INIT_BINARY . len ( ) {
2106- INIT_BINARY . len ( )
2117+ let to_copy = if len as usize > init_payload . len ( ) {
2118+ init_payload . len ( )
21072119 } else {
21082120 len as usize
21092121 } ;
21102122 unsafe {
21112123 libc:: memcpy (
21122124 addr as * mut libc:: c_void ,
2113- INIT_BINARY . as_ptr ( ) as * const _ ,
2125+ init_payload . as_ptr ( ) as * const _ ,
21142126 to_copy,
21152127 )
21162128 } ;
0 commit comments