Skip to content

Commit 1fe5ef5

Browse files
committed
instances with linked VMMs are Stopping
As pointed out by @gjcolombo in [this comment][1]. Incidentally, this fixes #6274 (if it doesn't get fixed on `main` before this PR merges...). [1]: #5749 (comment)
1 parent 2ea3fe6 commit 1fe5ef5

File tree

1 file changed

+31
-37
lines changed

1 file changed

+31
-37
lines changed

nexus/src/app/instance.rs

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -578,49 +578,43 @@ impl super::Nexus {
578578
.db_datastore
579579
.instance_fetch_with_vmm(opctx, &authz_instance)
580580
.await?;
581-
let (instance, vmm) = (state.instance(), state.vmm());
582-
583-
if let Some(vmm) = vmm {
584-
match vmm.runtime.state {
585-
DbVmmState::Starting
586-
| DbVmmState::Running
587-
| DbVmmState::Rebooting => {
588-
debug!(self.log, "asked to start an active instance";
589-
"instance_id" => %authz_instance.id());
590581

591-
return Ok(state);
592-
}
593-
// If there's a previous VMM left behind by an unwinding start
594-
// saga, no big deal. We can still start the instance, and the
595-
// start saga will remove the dead VMM, allowing it to be reaped.
596-
DbVmmState::SagaUnwound => {}
597-
DbVmmState::Stopped => {
598-
let propolis_id = instance
599-
.runtime()
600-
.propolis_id
601-
.expect("needed a VMM ID to fetch a VMM record");
602-
error!(self.log,
603-
"instance is stopped but still has an active VMM";
604-
"instance_id" => %authz_instance.id(),
605-
"propolis_id" => %propolis_id);
582+
match state.effective_state() {
583+
s @ InstanceState::Starting
584+
| s @ InstanceState::Running
585+
| s @ InstanceState::Rebooting
586+
| s @ InstanceState::Migrating => {
587+
debug!(self.log, "asked to start an active instance";
588+
"instance_id" => %authz_instance.id(),
589+
"state" => ?s);
606590

607-
return Err(Error::internal_error(
608-
"instance is stopped but still has an active VMM",
609-
));
610-
}
611-
_ => {
612-
return Err(Error::conflict(&format!(
613-
"instance is in state {} but must be {} to be started",
614-
vmm.runtime.state,
615-
InstanceState::Stopped
616-
)));
617-
}
591+
return Ok(state);
618592
}
619-
}
593+
InstanceState::Stopping => {
594+
let (propolis_id, propolis_state) = match state.vmm() {
595+
Some(vmm) => (Some(vmm.id), Some(vmm.runtime.state)),
596+
None => (None, None),
597+
};
598+
debug!(self.log, "instance's VMM is still in the process of stopping";
599+
"instance_id" => %authz_instance.id(),
600+
"propolis_id" => ?propolis_id,
601+
"propolis_state" => ?propolis_state);
602+
return Err(Error::conflict(
603+
"instance must finish stopping before it can be started",
604+
));
605+
}
606+
InstanceState::Stopped => {}
607+
s => {
608+
return Err(Error::conflict(&format!(
609+
"instance is in state {s} but it must be {} to be started",
610+
InstanceState::Stopped
611+
)))
612+
}
613+
};
620614

621615
let saga_params = sagas::instance_start::Params {
622616
serialized_authn: authn::saga::Serialized::for_opctx(opctx),
623-
db_instance: instance.clone(),
617+
db_instance: state.instance.clone(),
624618
};
625619

626620
self.sagas

0 commit comments

Comments
 (0)