@@ -44,6 +44,7 @@ use crate::settings::{
4444 Config , CustomActionEnvironment , ImageSource , KernelConfig , KernelPage , KrunLogLevel ,
4545 MountConfig , PassphrasePromptConfig , Preferences ,
4646} ;
47+ use crate :: utils:: { ToCStringVec , ToPtrVec } ;
4748use crate :: vm_image:: IsoAdd ;
4849
4950mod api;
@@ -697,11 +698,10 @@ impl Default for VMOpts {
697698
698699static KRUN_LOG_LEVEL_INIT : Once = Once :: new ( ) ;
699700
700- #[ derive( Debug , Clone ) ]
701+ #[ derive( Debug , Clone , Copy ) ]
701702struct VMContext {
702703 id : u32 ,
703704 os : OSType ,
704- root_path : Option < PathBuf > ,
705705}
706706
707707fn setup_vm (
@@ -830,20 +830,11 @@ fn setup_vm(
830830 }
831831 . context ( "Failed to set kernel" ) ?;
832832
833- let root_path = match os {
834- OSType :: Linux => Some ( config. root_path . clone ( ) ) ,
835- OSType :: FreeBSD => None , // no virtiofs => no root path
836- } ;
837-
838- Ok ( VMContext {
839- id : ctx_id,
840- os,
841- root_path,
842- } )
833+ Ok ( VMContext { id : ctx_id, os } )
843834}
844835
845836fn start_vmproxy (
846- ctx : & VMContext ,
837+ ctx : VMContext ,
847838 config : & MountConfig ,
848839 service_status : & ServiceStatus ,
849840 env : & [ BString ] ,
@@ -946,27 +937,26 @@ struct KrunConfig<'a, 'b> {
946937 process : KrunConfigProcess < ' a , ' b > ,
947938}
948939
949- fn set_vm_cmdline ( ctx : & VMContext , args : & [ BString ] , env : & [ BString ] ) -> anyhow:: Result < ( ) > {
940+ fn set_vm_cmdline ( ctx : VMContext , args : & [ BString ] , env : & [ BString ] ) -> anyhow:: Result < ( ) > {
941+ let cargs = args. to_cstring_vec ( ) ;
942+ let cenv = env. to_cstring_vec ( ) ;
943+
950944 let krun_config_tmp_dir;
951945 let mut deferred = Deferred :: new ( ) ;
952946
953- let krun_config = serde_json:: to_string ( & KrunConfig {
954- process : KrunConfigProcess { args, env } ,
955- } )
956- . context ( "Failed to serialize krun config" ) ?;
957-
958947 match ctx. os {
959948 OSType :: Linux => {
960- let krun_config_file_name = ".krun_config.json" ;
961- let krun_config_file = ctx. root_path . as_ref ( ) . unwrap ( ) . join ( krun_config_file_name) ;
962- fs:: write ( & krun_config_file, krun_config. as_bytes ( ) ) . with_context ( || {
963- format ! (
964- "Failed to write krun config file {}" ,
965- krun_config_file. display( )
966- )
967- } ) ?;
949+ let argv = cargs. to_ptr_vec ( ) ;
950+ let envp = cenv. to_ptr_vec ( ) ;
951+ unsafe { bindings:: krun_set_exec ( ctx. id , argv[ 0 ] , argv[ 1 ..] . as_ptr ( ) , envp. as_ptr ( ) ) }
952+ . context ( "Failed to set exec" ) ?;
968953 }
969954 OSType :: FreeBSD => {
955+ let krun_config = serde_json:: to_string ( & KrunConfig {
956+ process : KrunConfigProcess { args, env } ,
957+ } )
958+ . context ( "Failed to serialize krun config" ) ?;
959+
970960 krun_config_tmp_dir = PathBuf :: from ( "/tmp" ) . join ( format ! ( "alfs-{}" , rand_string( 8 ) ) ) ;
971961 fs:: create_dir_all ( & krun_config_tmp_dir)
972962 . context ( "Failed to create krun config temp directory" ) ?;
@@ -1014,7 +1004,7 @@ fn set_vm_cmdline(ctx: &VMContext, args: &[BString], env: &[BString]) -> anyhow:
10141004 Ok ( ( ) )
10151005}
10161006
1017- fn start_vm_forked ( ctx : & VMContext , cmdline : & [ BString ] , env : & [ BString ] ) -> anyhow:: Result < i32 > {
1007+ fn start_vm_forked ( ctx : VMContext , cmdline : & [ BString ] , env : & [ BString ] ) -> anyhow:: Result < i32 > {
10181008 let pid = unsafe { libc:: fork ( ) } ;
10191009 if pid < 0 {
10201010 return Err ( io:: Error :: last_os_error ( ) ) . context ( "Failed to fork process" ) ;
@@ -1032,7 +1022,7 @@ fn start_vm_forked(ctx: &VMContext, cmdline: &[BString], env: &[BString]) -> any
10321022 }
10331023}
10341024
1035- fn start_vm ( ctx : & VMContext , cmdline : & [ BString ] , env : & [ BString ] ) -> anyhow:: Result < ( ) > {
1025+ fn start_vm ( ctx : VMContext , cmdline : & [ BString ] , env : & [ BString ] ) -> anyhow:: Result < ( ) > {
10361026 set_vm_cmdline ( ctx, cmdline, env) ?;
10371027 unsafe { bindings:: krun_start_enter ( ctx. id ) } . context ( "Failed to start VM" ) ?;
10381028
@@ -1069,14 +1059,22 @@ fn run_vmcommand_short(
10691059 dev_info : & [ DevInfo ] ,
10701060 use_gvproxy : bool ,
10711061 opts : VMOpts ,
1072- args : & [ BString ] ,
1062+ args : Vec < CString > ,
10731063 process_stdin : Option < impl FnOnce ( libc:: c_int ) -> anyhow:: Result < ( ) > > ,
10741064) -> anyhow:: Result < VMOutput > {
10751065 let forked = utils:: fork_with_piped_output ( ) ?;
10761066 if forked. pid == 0 {
10771067 // child process
10781068 let ctx = setup_vm ( config, dev_info, use_gvproxy, false , opts) ?;
1079- start_vm ( & ctx, & args, & [ ] ) ?;
1069+
1070+ let argv = args. to_ptr_vec ( ) ;
1071+ let envp = vec ! [ std:: ptr:: null( ) ] ;
1072+
1073+ // this is only used with Linux so far; no need to call set_vm_cmdline
1074+ unsafe { bindings:: krun_set_exec ( ctx. id , argv[ 0 ] , argv[ 1 ..] . as_ptr ( ) , envp. as_ptr ( ) ) }
1075+ . context ( "Failed to set exec" ) ?;
1076+
1077+ unsafe { bindings:: krun_start_enter ( ctx. id ) } . context ( "Failed to start VM" ) ?;
10801078 unreachable ! ( ) ;
10811079 } else {
10821080 // parent process
@@ -1667,15 +1665,15 @@ impl AppRunner {
16671665 } else {
16681666 cmdline. push ( ( vm_prelude + " && /bin/bash -l" ) . into ( ) ) ;
16691667 }
1670- start_vm ( & ctx, & cmdline, & vm_env) . context ( "Failed to start microVM shell" ) ?;
1668+ start_vm ( ctx, & cmdline, & vm_env) . context ( "Failed to start microVM shell" ) ?;
16711669 } else {
16721670 let cmdline: Vec < BString > = if let Some ( command) = cmd. command {
16731671 vec ! [ "/bin/sh" . into( ) , "-c" . into( ) , command. into( ) ]
16741672 } else {
16751673 vec ! [ "/start-shell.sh" . into( ) ]
16761674 } ;
16771675 vm_image:: setup_gvproxy ( & config. common , || {
1678- start_vm_forked ( & ctx, & cmdline, & vm_env) . context ( "Failed to start microVM shell" )
1676+ start_vm_forked ( ctx, & cmdline, & vm_env) . context ( "Failed to start microVM shell" )
16791677 } ) ?;
16801678 }
16811679
@@ -1767,7 +1765,7 @@ impl AppRunner {
17671765 let opts = VMOpts :: new ( ) . read_only_disks ( true ) ;
17681766 let ctx = setup_vm ( & config, & [ ] , false , false , opts) . context ( "Failed to setup microVM" ) ?;
17691767 let status =
1770- start_vm_forked ( & ctx, & cmdline, & [ ] ) . context ( "Failed to start microVM shell" ) ?;
1768+ start_vm_forked ( ctx, & cmdline, & [ ] ) . context ( "Failed to start microVM shell" ) ?;
17711769
17721770 if status != 0 {
17731771 return Err ( anyhow:: anyhow!(
@@ -2141,7 +2139,7 @@ impl AppRunner {
21412139 . collect ( ) ;
21422140
21432141 start_vmproxy (
2144- & ctx,
2142+ ctx,
21452143 & config,
21462144 & service_status,
21472145 & vm_env,
0 commit comments