Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure exitcode for reboot/halt on standalone #558

Merged
merged 1 commit into from
Oct 30, 2023
Merged
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
6 changes: 6 additions & 0 deletions bin/propolis-standalone/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ cpus = 4
bootrom = "/path/to/bootrom/OVMF_CODE.fd"
memory = 1024

# Exit propolis-standalone process with <code> if instance halts (default: 0)
# exit_on_halt = <code>

# Exit propolis-standalone process with <code> if instance reboots (default: unset)
# exit_on_reboot = <code>

[block_dev.alpine_iso]
type = "file"
path = "/path/to/alpine-extended-3.12.0-x86_64.iso"
Expand Down
27 changes: 22 additions & 5 deletions bin/propolis-standalone/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::collections::VecDeque;
use std::fs::File;
use std::io::{Error, ErrorKind, Result};
use std::path::Path;
use std::process::ExitCode;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Condvar, Mutex, MutexGuard};
use std::time::{SystemTime, UNIX_EPOCH};
Expand Down Expand Up @@ -193,6 +194,7 @@ struct InstState {
instance: Option<propolis::Instance>,
state: State,
vcpu_tasks: Vec<propolis::tasks::TaskCtrl>,
exit_code: Option<u8>,
}

struct InstInner {
Expand All @@ -216,6 +218,7 @@ impl Instance {
instance: Some(pinst),
state: State::Initialize,
vcpu_tasks: Vec::new(),
exit_code: None,
}),
boot_gen: AtomicUsize::new(0),
eq: EventQueue::new(),
Expand Down Expand Up @@ -404,8 +407,22 @@ impl Instance {
for mut vcpu_ctrl in guard.vcpu_tasks.drain(..) {
vcpu_ctrl.exit();
}
if guard.exit_code.is_none() {
guard.exit_code = Some(inner.config.main.exit_on_halt);
}
}
State::Reset => {
if let (None, Some(code)) =
(guard.exit_code, inner.config.main.exit_on_reboot)
{
// Emit the configured exit-on-reboot code if one is
// configured an no existing code would already
// supersede it.
guard.exit_code = Some(code);
pfmooney marked this conversation as resolved.
Show resolved Hide resolved
guard.state = State::Halt;
cur_ev = Some(InstEvent::ReqHalt);
continue;
}
let inst = guard.instance.as_ref().unwrap().lock();
Self::device_state_transition(State::Reset, &inst, false);
inst.machine().reinitialize().unwrap();
Expand All @@ -432,13 +449,14 @@ impl Instance {
}
}

fn wait_destroyed(&self) {
fn wait_destroyed(&self) -> ExitCode {
let guard = self.0.state.lock().unwrap();
let _guard = self
let mut guard = self
.0
.cv
.wait_while(guard, |g| !matches!(g.state, State::Destroy))
.unwrap();
ExitCode::from(guard.exit_code.take().unwrap_or(0))
}

fn vcpu_loop(
Expand Down Expand Up @@ -997,7 +1015,7 @@ struct Args {
restore: bool,
}

fn main() -> anyhow::Result<()> {
fn main() -> anyhow::Result<ExitCode> {
let Args { target, snapshot, restore } = Args::parse();

// Ensure proper setup of USDT probes
Expand Down Expand Up @@ -1058,6 +1076,5 @@ fn main() -> anyhow::Result<()> {
);

// wait for instance to be destroyed
inst.wait_destroyed();
Ok(())
Ok(inst.wait_destroyed())
}
10 changes: 10 additions & 0 deletions crates/propolis-standalone-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ pub struct Main {
pub memory: usize,
pub use_reservoir: Option<bool>,
pub cpuid_profile: Option<String>,
/// Process exitcode to emit if/when instance halts
///
/// Default: 0
#[serde(default)]
pub exit_on_halt: u8,
/// Process exitcode to emit if/when instance reboots
///
/// Default: None, does not exit on reboot
#[serde(default)]
pub exit_on_reboot: Option<u8>,
}

/// A hard-coded device, either enabled by default or accessible locally
Expand Down
Loading