Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions lib/propolis/src/hw/chipset/i440fx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::hw::pci::{
self, Bdf, INTxPinID, LintrCfg, PcieCfgDecoder, PioCfgDecoder,
};
use crate::intr_pins::{IntrPin, LegacyPIC, LegacyPin, NoOpPin};
use crate::lifecycle;
use crate::migrate::*;
use crate::mmio::MmioFn;
use crate::pio::{PioBus, PioFn};
Expand Down Expand Up @@ -155,6 +156,7 @@ pub struct Opts {

pub struct I440FxHostBridge {
pci_state: pci::DeviceState,
indicator: lifecycle::Indicator,

pci_topology: Arc<pci::topology::Topology>,
pci_cfg: PioCfgDecoder,
Expand Down Expand Up @@ -189,6 +191,7 @@ impl I440FxHostBridge {

Arc::new(Self {
pci_state,
indicator: Default::default(),

pci_topology,
pci_cfg,
Expand Down Expand Up @@ -276,6 +279,19 @@ impl Lifecycle for I440FxHostBridge {
fn reset(&self) {
self.pci_state.reset(self);
}
fn start(&self) -> anyhow::Result<()> {
self.indicator.start();
Ok(())
}
fn pause(&self) {
self.indicator.pause();
}
fn resume(&self) {
self.indicator.resume();
}
fn halt(&self) {
self.indicator.halt();
}
fn migrate(&self) -> Migrator<'_> {
Migrator::Multi(self)
}
Expand Down
2 changes: 1 addition & 1 deletion lib/propolis/src/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl IndicatedState {
const fn valid_transition(old: Self, new: Self) -> bool {
use IndicatedState::*;
match (old, new) {
(Init, Run) | (Init, Halt) => true,
(Init, Run) | (Init, Pause) => true,
(Run, Pause) => true,
(Pause, Run) | (Pause, Halt) => true,
_ => false,
Expand Down
16 changes: 16 additions & 0 deletions phd-tests/tests/src/server_state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@ async fn instance_start_stop_test(ctx: &Framework) {
.await?;
}

#[phd_testcase]
async fn instance_stop_unstarted_test(ctx: &Framework) {
let mut vm = ctx.spawn_default_vm("instance_stop_unstarted_test").await?;

vm.instance_ensure().await?;
let instance = vm.get().await?.instance;
assert_eq!(instance.state, InstanceState::Creating);

// At this point the VM is created and its resources are held as
// appropriate. Stopping the VM will cause propolis-server to destroy the
// VM, releasing those resources and getting the server ready for shutdown.
vm.stop().await?;
vm.wait_for_state(InstanceState::Destroyed, Duration::from_secs(60))
.await?;
}

#[phd_testcase]
async fn instance_stop_causes_destroy_test(ctx: &Framework) {
let mut vm =
Expand Down
Loading