@@ -12,6 +12,7 @@ use std::collections::BTreeMap;
1212use std:: ffi:: OsStr ;
1313use std:: ffi:: OsString ;
1414use std:: path:: PathBuf ;
15+ use std:: str:: FromStr ;
1516
1617#[ derive( Clone , Debug , MeshPayload ) ]
1718pub enum TestScenarioConfig {
@@ -20,7 +21,7 @@ pub enum TestScenarioConfig {
2021 SaveStuck ,
2122}
2223
23- impl std :: str :: FromStr for TestScenarioConfig {
24+ impl FromStr for TestScenarioConfig {
2425 type Err = anyhow:: Error ;
2526
2627 fn from_str ( s : & str ) -> Result < TestScenarioConfig , anyhow:: Error > {
@@ -33,6 +34,28 @@ impl std::str::FromStr for TestScenarioConfig {
3334 }
3435}
3536
37+ #[ derive( Clone , Debug , MeshPayload ) ]
38+ pub enum GuestStateLifetimeCli {
39+ Default ,
40+ ReprovisionOnFailure ,
41+ Reprovision ,
42+ Ephemeral ,
43+ }
44+
45+ impl FromStr for GuestStateLifetimeCli {
46+ type Err = anyhow:: Error ;
47+
48+ fn from_str ( s : & str ) -> Result < GuestStateLifetimeCli , anyhow:: Error > {
49+ match s {
50+ "DEFAULT" | "0" => Ok ( GuestStateLifetimeCli :: Default ) ,
51+ "REPROVISION_ON_FAILURE" | "1" => Ok ( GuestStateLifetimeCli :: ReprovisionOnFailure ) ,
52+ "REPROVISION" | "2" => Ok ( GuestStateLifetimeCli :: Reprovision ) ,
53+ "EPHEMERAL" | "3" => Ok ( GuestStateLifetimeCli :: Ephemeral ) ,
54+ _ => Err ( anyhow:: anyhow!( "Invalid lifetime: {}" , s) ) ,
55+ }
56+ }
57+ }
58+
3659#[ derive( Clone , Debug , MeshPayload ) ]
3760pub enum GuestStateEncryptionPolicyCli {
3861 Auto ,
@@ -41,7 +64,7 @@ pub enum GuestStateEncryptionPolicyCli {
4164 GspKey ,
4265}
4366
44- impl std :: str :: FromStr for GuestStateEncryptionPolicyCli {
67+ impl FromStr for GuestStateEncryptionPolicyCli {
4568 type Err = anyhow:: Error ;
4669
4770 fn from_str ( s : & str ) -> Result < GuestStateEncryptionPolicyCli , anyhow:: Error > {
@@ -178,12 +201,23 @@ pub struct Options {
178201 /// (OPENHCL_DISABLE_UEFI_FRONTPAGE=1) Disable the frontpage in UEFI which
179202 /// will result in UEFI terminating, shutting down the guest instead of
180203 /// showing the frontpage.
181- pub disable_uefi_frontpage : bool ,
204+ pub disable_uefi_frontpage : Option < bool > ,
205+
206+ /// (HCL_DEFAULT_BOOT_ALWAYS_ATTEMPT=1) Instruct UEFI to always attempt a
207+ /// default boot, even if existing boot entries fail.
208+ pub default_boot_always_attempt : Option < bool > ,
209+
210+ /// (HCL_GUEST_STATE_LIFETIME=\<GuestStateLifetimeCli\>)
211+ /// Specify which guest state lifetime to use.
212+ pub guest_state_lifetime : Option < GuestStateLifetimeCli > ,
182213
183214 /// (HCL_GUEST_STATE_ENCRYPTION_POLICY=\<GuestStateEncryptionPolicyCli\>)
184215 /// Specify which guest state encryption policy to use.
185216 pub guest_state_encryption_policy : Option < GuestStateEncryptionPolicyCli > ,
186217
218+ /// (HCL_STRICT_ENCRYPTION_POLICY=1) Strict guest state encryption policy.
219+ pub strict_encryption_policy : Option < bool > ,
220+
187221 /// (HCL_ATTEMPT_AK_CERT_CALLBACK=1) Attempt to renew the AK cert.
188222 /// If not specified, use the configuration in DPSv2 ManagementVtlFeatures.
189223 pub attempt_ak_cert_callback : Option < bool > ,
@@ -208,7 +242,7 @@ impl Options {
208242
209243 // Reads an environment variable, falling back to a legacy variable (replacing
210244 // "OPENHCL_" with "UNDERHILL_") if the original is not set.
211- let legacy_openhcl_env = |name : & str | -> Option < & OsString > {
245+ let read_legacy_openhcl_env = |name : & str | -> Option < & OsString > {
212246 env. get :: < OsStr > ( name. as_ref ( ) ) . or_else ( || {
213247 env. get :: < OsStr > (
214248 format ! (
@@ -221,8 +255,7 @@ impl Options {
221255 } ;
222256
223257 // Reads an environment variable strings.
224- let parse_env_string =
225- |name : & str | -> Option < & OsString > { env. get :: < OsStr > ( name. as_ref ( ) ) } ;
258+ let read_env = |name : & str | -> Option < & OsString > { env. get :: < OsStr > ( name. as_ref ( ) ) } ;
226259
227260 fn parse_bool_opt ( value : Option < & OsString > ) -> anyhow:: Result < Option < bool > > {
228261 value
@@ -245,9 +278,14 @@ impl Options {
245278 parse_bool_opt ( value) . ok ( ) . flatten ( ) . unwrap_or_default ( )
246279 }
247280
248- let parse_legacy_env_bool = |name| parse_bool ( legacy_openhcl_env ( name) ) ;
249- let parse_env_bool = |name : & str | parse_bool ( parse_env_string ( name) ) ;
250- let parse_env_bool_opt = |name : & str | parse_bool_opt ( parse_env_string ( name) ) ;
281+ let parse_legacy_env_bool = |name| parse_bool ( read_legacy_openhcl_env ( name) ) ;
282+ let parse_env_bool = |name : & str | parse_bool ( read_env ( name) ) ;
283+ let parse_env_bool_opt = |name : & str | {
284+ parse_bool_opt ( read_env ( name) )
285+ . map_err ( |e| tracing:: warn!( "failed to parse {name}: {e:#}" ) )
286+ . ok ( )
287+ . flatten ( )
288+ } ;
251289
252290 fn parse_number ( value : Option < & OsString > ) -> anyhow:: Result < Option < u64 > > {
253291 value
@@ -260,29 +298,29 @@ impl Options {
260298 }
261299
262300 let parse_legacy_env_number = |name| {
263- parse_number ( legacy_openhcl_env ( name) )
301+ parse_number ( read_legacy_openhcl_env ( name) )
264302 . context ( format ! ( "parsing legacy env number: {name}" ) )
265303 } ;
266304
267305 let mut wait_for_start = parse_legacy_env_bool ( "OPENHCL_WAIT_FOR_START" ) ;
268306 let mut reformat_vmgs = parse_legacy_env_bool ( "OPENHCL_REFORMAT_VMGS" ) ;
269- let mut pid = legacy_openhcl_env ( "OPENHCL_PID_FILE_PATH" )
307+ let mut pid = read_legacy_openhcl_env ( "OPENHCL_PID_FILE_PATH" )
270308 . map ( |x| x. to_string_lossy ( ) . into_owned ( ) . into ( ) ) ;
271- let vmbus_max_version = legacy_openhcl_env ( "OPENHCL_VMBUS_MAX_VERSION" )
309+ let vmbus_max_version = read_legacy_openhcl_env ( "OPENHCL_VMBUS_MAX_VERSION" )
272310 . map ( |x| {
273311 vmbus_core:: parse_vmbus_version ( & ( x. to_string_lossy ( ) ) )
274312 . map_err ( |x| anyhow:: anyhow!( "Error parsing vmbus max version: {}" , x) )
275313 } )
276314 . transpose ( ) ?;
277315 let vmbus_enable_mnf =
278- legacy_openhcl_env ( "OPENHCL_VMBUS_ENABLE_MNF" ) . map ( |v| parse_bool ( Some ( v) ) ) ;
316+ read_legacy_openhcl_env ( "OPENHCL_VMBUS_ENABLE_MNF" ) . map ( |v| parse_bool ( Some ( v) ) ) ;
279317 let vmbus_force_confidential_external_memory =
280318 parse_env_bool ( "OPENHCL_VMBUS_FORCE_CONFIDENTIAL_EXTERNAL_MEMORY" ) ;
281319 let vmbus_channel_unstick_delay_ms =
282320 parse_legacy_env_number ( "OPENHCL_VMBUS_CHANNEL_UNSTICK_DELAY_MS" ) ?;
283- let cmdline_append =
284- legacy_openhcl_env ( "OPENHCL_CMDLINE_APPEND" ) . map ( |x| x. to_string_lossy ( ) . into_owned ( ) ) ;
285- let force_load_vtl0_image = legacy_openhcl_env ( "OPENHCL_FORCE_LOAD_VTL0_IMAGE" )
321+ let cmdline_append = read_legacy_openhcl_env ( "OPENHCL_CMDLINE_APPEND" )
322+ . map ( |x| x. to_string_lossy ( ) . into_owned ( ) ) ;
323+ let force_load_vtl0_image = read_legacy_openhcl_env ( "OPENHCL_FORCE_LOAD_VTL0_IMAGE" )
286324 . map ( |x| x. to_string_lossy ( ) . into_owned ( ) ) ;
287325 let mut vnc_port = parse_legacy_env_number ( "OPENHCL_VNC_PORT" ) ?. map ( |x| x as u32 ) ;
288326 let framebuffer_gpa_base = parse_legacy_env_number ( "OPENHCL_FRAMEBUFFER_GPA_BASE" ) ?;
@@ -299,7 +337,7 @@ impl Options {
299337 let gdbstub_port = parse_legacy_env_number ( "OPENHCL_GDBSTUB_PORT" ) ?. map ( |x| x as u32 ) ;
300338 let nvme_keep_alive = parse_env_bool ( "OPENHCL_NVME_KEEP_ALIVE" ) ;
301339 let nvme_always_flr = parse_env_bool ( "OPENHCL_NVME_ALWAYS_FLR" ) ;
302- let test_configuration = parse_env_string ( "OPENHCL_TEST_CONFIG" ) . and_then ( |x| {
340+ let test_configuration = read_env ( "OPENHCL_TEST_CONFIG" ) . and_then ( |x| {
303341 x. to_string_lossy ( )
304342 . parse :: < TestScenarioConfig > ( )
305343 . map_err ( |e| {
@@ -310,24 +348,27 @@ impl Options {
310348 } )
311349 . ok ( )
312350 } ) ;
313- let disable_uefi_frontpage = parse_env_bool ( "OPENHCL_DISABLE_UEFI_FRONTPAGE" ) ;
351+ let disable_uefi_frontpage = parse_env_bool_opt ( "OPENHCL_DISABLE_UEFI_FRONTPAGE" ) ;
314352 let signal_vtl0_started = parse_env_bool ( "OPENHCL_SIGNAL_VTL0_STARTED" ) ;
315- let guest_state_encryption_policy = parse_env_string ( "HCL_GUEST_STATE_ENCRYPTION_POLICY" )
316- . and_then ( |x| {
353+ let default_boot_always_attempt = parse_env_bool_opt ( "HCL_DEFAULT_BOOT_ALWAYS_ATTEMPT" ) ;
354+ let guest_state_lifetime = read_env ( "HCL_GUEST_STATE_LIFETIME" ) . and_then ( |x| {
355+ x. to_string_lossy ( )
356+ . parse :: < GuestStateLifetimeCli > ( )
357+ . map_err ( |e| tracing:: warn!( "failed to parse HCL_GUEST_STATE_LIFETIME: {:#}" , e) )
358+ . ok ( )
359+ } ) ;
360+ let guest_state_encryption_policy =
361+ read_env ( "HCL_GUEST_STATE_ENCRYPTION_POLICY" ) . and_then ( |x| {
317362 x. to_string_lossy ( )
318363 . parse :: < GuestStateEncryptionPolicyCli > ( )
319364 . map_err ( |e| {
320365 tracing:: warn!( "failed to parse HCL_GUEST_STATE_ENCRYPTION_POLICY: {:#}" , e)
321366 } )
322367 . ok ( )
323368 } ) ;
324- let attempt_ak_cert_callback = parse_env_bool_opt ( "HCL_ATTEMPT_AK_CERT_CALLBACK" )
325- . map_err ( |e| tracing:: warn!( "failed to parse HCL_ATTEMPT_AK_CERT_CALLBACK: {:#}" , e) )
326- . ok ( )
327- . flatten ( ) ;
328- let enable_vpci_relay = parse_env_bool_opt ( "OPENHCL_ENABLE_VPCI_RELAY" )
329- . ok ( )
330- . flatten ( ) ;
369+ let strict_encryption_policy = parse_env_bool_opt ( "HCL_STRICT_ENCRYPTION_POLICY" ) ;
370+ let attempt_ak_cert_callback = parse_env_bool_opt ( "HCL_ATTEMPT_AK_CERT_CALLBACK" ) ;
371+ let enable_vpci_relay = parse_env_bool_opt ( "OPENHCL_ENABLE_VPCI_RELAY" ) ;
331372
332373 let mut args = std:: env:: args ( ) . chain ( extra_args) ;
333374 // Skip our own filename.
@@ -385,7 +426,10 @@ impl Options {
385426 nvme_always_flr,
386427 test_configuration,
387428 disable_uefi_frontpage,
429+ default_boot_always_attempt,
430+ guest_state_lifetime,
388431 guest_state_encryption_policy,
432+ strict_encryption_policy,
389433 attempt_ak_cert_callback,
390434 enable_vpci_relay,
391435 } )
0 commit comments