Skip to content

Commit c6d4553

Browse files
committed
PR feedback
1 parent f89793c commit c6d4553

File tree

1 file changed

+49
-14
lines changed

1 file changed

+49
-14
lines changed

bin/propolis-server/src/lib/vm/state_driver.rs

+49-14
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,28 @@ pub(super) enum VmStartReason {
141141
ExplicitRequest,
142142
}
143143

144+
/// The outcome of a request to start a VM.
144145
enum VmStartOutcome {
145146
Succeeded,
146147
Failed,
147148
Aborted,
148149
}
149150

151+
impl VmStartOutcome {
152+
/// If this start outcome implies that the state driver should return
153+
/// immediately and allow the VM to be torn down, this routine returns
154+
/// `Some(state)` where `state` is the final VM state to return from the
155+
/// driver. If the driver should continue running the VM, this routine
156+
/// returns `None`.
157+
fn final_vm_state(&self) -> Option<InstanceState> {
158+
match self {
159+
Self::Succeeded => None,
160+
Self::Failed => Some(InstanceState::Failed),
161+
Self::Aborted => Some(InstanceState::Destroyed),
162+
}
163+
}
164+
}
165+
150166
/// A kind of event the state driver can handle.
151167
#[derive(Debug)]
152168
enum InputQueueEvent {
@@ -489,10 +505,16 @@ impl StateDriver {
489505
info!(self.log, "state driver launched");
490506

491507
let final_state = if migrated_in {
492-
match self.start_vm(VmStartReason::MigratedIn).await {
493-
VmStartOutcome::Succeeded => self.event_loop().await,
494-
VmStartOutcome::Failed => InstanceState::Failed,
495-
VmStartOutcome::Aborted => InstanceState::Destroyed,
508+
// If the final state is known merely from the attempt to start the
509+
// VM, return it immediately; otherwise, run the event loop and wait
510+
// for it to return the final state.
511+
match self
512+
.start_vm(VmStartReason::MigratedIn)
513+
.await
514+
.final_vm_state()
515+
{
516+
None => self.event_loop().await,
517+
Some(s) => s,
496518
}
497519
} else {
498520
self.event_loop().await
@@ -575,7 +597,12 @@ impl StateDriver {
575597
info!(self.log, "sending start request to {}", name);
576598
let res = dev.start();
577599
if let Err(e) = res {
578-
error!(self.log, "startup failed for {}: {:?}", name, e);
600+
error!(
601+
self.log, "device start() returned an error";
602+
"device" => %name,
603+
"error" => %e
604+
);
605+
579606
return VmStartOutcome::Failed;
580607
}
581608
}
@@ -599,7 +626,9 @@ impl StateDriver {
599626
if let Err(e) = &res {
600627
error!(
601628
log,
602-
"startup failed for block backend {}: {:?}", name, e
629+
"block backend start() returned an error";
630+
"backend" => %name,
631+
"error" => %e
603632
);
604633

605634
return res;
@@ -712,6 +741,9 @@ impl StateDriver {
712741
result_tx,
713742
},
714743
) => {
744+
// The API caller who requested this operation can hang up
745+
// and drop the receiver. This isn't fatal; just keep
746+
// starting the VM if it happens.
715747
let _ = result_tx.send(
716748
self.reconfigure_crucible_volume(
717749
&backend_id,
@@ -795,14 +827,17 @@ impl StateDriver {
795827
) -> HandleEventOutcome {
796828
match request {
797829
ExternalRequest::State(StateChangeRequest::Start) => {
798-
match self.start_vm(VmStartReason::ExplicitRequest).await {
799-
VmStartOutcome::Succeeded => HandleEventOutcome::Continue,
800-
VmStartOutcome::Failed => HandleEventOutcome::Exit {
801-
final_state: InstanceState::Failed,
802-
},
803-
VmStartOutcome::Aborted => HandleEventOutcome::Exit {
804-
final_state: InstanceState::Destroyed,
805-
},
830+
// If this start attempt produces a terminal VM state, return it
831+
// to the driver and indicate that the driver should exit.
832+
match self
833+
.start_vm(VmStartReason::ExplicitRequest)
834+
.await
835+
.final_vm_state()
836+
{
837+
None => HandleEventOutcome::Continue,
838+
Some(final_state) => {
839+
HandleEventOutcome::Exit { final_state }
840+
}
806841
}
807842
}
808843
ExternalRequest::State(StateChangeRequest::MigrateAsSource {

0 commit comments

Comments
 (0)