Skip to content
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
16 changes: 7 additions & 9 deletions nvx-rs/src/host/cli/sandbox/lifecycle/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
use std::path::{Path, PathBuf};

use crate::ErrorCode;
use crate::host::cli::sandbox::error_with_cause;
use crate::host::cli::store::StateDir;
use crate::host::cli::{Exit, Result, io_error};
use crate::host::paths;
use crate::host::store::SandboxStore;

/// Returns the error for an I/O error that an operation on `path` met.
pub(super) fn os_error(error: &std::io::Error, path: &Path) -> Exit {
Expand Down Expand Up @@ -57,10 +56,11 @@ fn parent(path: &Path) -> Option<&Path> {
}

/// Creates the state directory at `path`, as provision does. An existing directory stays as it is,
/// and the store then refuses one that is not private to the current user; any other existing
/// path fails as creating a directory fails for a path that exists. A new directory is created as
/// the store creates it, private to the current user, below parents that are created as needed,
/// even when an existing one goes meanwhile: nothing else creates the directory itself.
/// and the CLI's store then refuses one that is not private to the current user; any other
/// existing path fails as creating a directory fails for a path that exists. A new directory is
/// created as [`StateDir::create`] creates it, private to the current user, below parents that
/// are created as needed, even when an existing one goes meanwhile: nothing else creates the
/// directory itself.
pub(crate) fn create_state_directory(path: &Path) -> Result {
if path.is_dir() {
return Ok(());
Expand All @@ -71,9 +71,7 @@ pub(crate) fn create_state_directory(path: &Path) -> Result {
if let Some(parent) = parent(path) {
make_directories(parent, 0o777)?;
}
SandboxStore::create(path)
.map(drop)
.map_err(error_with_cause)
StateDir::create(path).map(drop)
}

/// Returns the error with which creating a directory fails for a path that exists.
Expand Down
13 changes: 12 additions & 1 deletion nvx-rs/src/host/cli/sandbox/lifecycle/stop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,20 @@ use crate::host::cli::{Exit, Result, check_interrupt, output};
use crate::host::process::Process;
use crate::host::runtime::IdentityPart;
use crate::host::snapshot::OPENVMM_DIR;
use crate::host::supervisor::StopOutcome;
use crate::host::vm::{self, SavedVm, VmDir, VmOutputs};

/// How the stop of a sandbox's OpenVMM ended.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum StopOutcome {
/// OpenVMM exited without a forced termination: by the end of its graceful stop, or before
/// a termination began.
Graceful,
/// A forced termination through OpenVMM's verified process ended it within its bound.
Forced,
/// OpenVMM still runs: it did not exit within the bound of its stop or termination.
TimedOut,
}

/// Stops a running sandbox, and checks the outcome report that its OpenVMM wrote, unless another
/// runtime identity than the artifacts' started the VM.
///
Expand Down
3 changes: 1 addition & 2 deletions nvx-rs/src/host/cli/sandbox/lifecycle/tests.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use std::cell::{Cell, RefCell};

use super::stop::terminate_within;
use super::stop::{StopOutcome, terminate_within};
use super::*;
use crate::host::cli::deadline::Deadline;
use crate::host::supervisor::StopOutcome;

/// An OpenVMM of another runtime identity whose termination a test scripts, without a process.
struct Scripted {
Expand Down
8 changes: 1 addition & 7 deletions nvx-rs/src/host/instance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,7 @@ use self::locked::check_timeout;

/// Returns a fresh launch capability, which is never all zero.
pub fn generate_capability() -> Result<[u8; CAPABILITY_LEN]> {
let mut capability = [0u8; CAPABILITY_LEN];
while capability == [0; CAPABILITY_LEN] {
getrandom::fill(&mut capability).map_err(|error| {
Error::other("cannot generate a control capability").with_source(error)
})?;
}
Ok(capability)
crate::host::vm::generate_capability()
}

/// Returns a control endpoint of an instance whose Linux control socket is `socket`: the socket
Expand Down
6 changes: 3 additions & 3 deletions nvx-rs/src/host/restore/tests/live_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ use crate::activation::{
ActivationRecord, Configuration, ExpectedResources, Export, ExportKind, Image, MachineIdMode,
Network, OverlayMode, Publication, ReadyActivation, RestoreSection, TransactionId, Upper, View,
};
use crate::host::instance::generate_capability;
use crate::host::nvxs::HostConnection;
use crate::host::session;
use crate::host::snapshot::SnapshotManifest;
use crate::host::supervisor::{Launched, VmmCommand, spawn};
use crate::protocol::{
APP_ERROR, APP_EXEC, APP_EXIT, APP_MAPS, APP_READY, APP_STDERR, APP_STDOUT, APP_STOP,
APP_STOPPED, HostMap, Workload, WorkloadEnvironment, decode_app, encode_app,
APP_STOPPED, CAPABILITY_LEN, HostMap, Workload, WorkloadEnvironment, decode_app, encode_app,
encode_exec_payload, encode_maps_payloads,
};

Expand Down Expand Up @@ -295,7 +294,8 @@ fn run() -> Result<(), AnyError> {
"--microvm-report".into(),
report.as_os_str().to_owned(),
];
let capability = generate_capability()?;
let mut capability = [0; CAPABILITY_LEN];
getrandom::fill(&mut capability)?;
let command = VmmCommand::new(vmm, options, &root);
let mut owned = OwnedVm(Some(spawn(&command, &capability, log)?));
let running = owned.0.as_ref().ok_or("missing owned VM")?;
Expand Down
13 changes: 12 additions & 1 deletion nvx-rs/src/host/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ impl fmt::Debug for Capability {
}
}

/// Returns a fresh launch capability, which is never all zero.
pub(crate) fn generate_capability() -> Result<[u8; CAPABILITY_LEN]> {
let mut capability = [0u8; CAPABILITY_LEN];
while capability == [0; CAPABILITY_LEN] {
getrandom::fill(&mut capability).map_err(|error| {
Error::other("cannot generate a control capability").with_source(error)
})?;
}
Ok(capability)
}

/// Launch values that the caller saves and reloads to verify or reattach its VM.
///
/// The library never serializes, stores or locates them. The endpoint is the name chosen at
Expand Down Expand Up @@ -640,7 +651,7 @@ pub fn create(
unused_output(Path::new(console))?;
}
}
let capability = Capability(crate::host::instance::generate_capability()?);
let capability = Capability(generate_capability()?);
if let Some(snapshot) = from {
unused_output(&view)?;
if let Some(endpoint) = &ready_endpoint {
Expand Down
4 changes: 2 additions & 2 deletions nvx-rs/tests/managed_lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ use std::sync::mpsc;
use std::thread;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};

use nvx::host::instance::generate_capability;
use nvx::host::platform::process_start_time;
use nvx::host::session::{self, ControlSession, ExecEvent};
use nvx::protocol::{
Expand Down Expand Up @@ -509,7 +508,8 @@ fn a_managed_guest_runs_request_scoped_workloads_until_it_stops() {
let output_dir = PathBuf::from(variable("NVX_MANAGED_LIFECYCLE_OUTPUT_DIR"));
fs::create_dir_all(&output_dir).unwrap();
let log = File::create(output_dir.join("managed-lifecycle.log")).unwrap();
let capability = generate_capability().unwrap();
let mut capability = [0; CAPABILITY_LEN];
getrandom::fill(&mut capability).unwrap();
// OpenVMM reads its capability as soon as it starts, so its input already holds the
// capability and its end, as `nvx::host::supervisor::spawn` prepares it.
let (input, mut writer) = io::pipe().unwrap();
Expand Down
Loading