diff --git a/package/src/bin/omicron-package.rs b/package/src/bin/omicron-package.rs index cfefad592d9..8042b00bba8 100644 --- a/package/src/bin/omicron-package.rs +++ b/package/src/bin/omicron-package.rs @@ -363,9 +363,10 @@ fn do_install( } fn uninstall_all_omicron_zones() -> Result<()> { - for zone in zone::Zones::get()? { + zone::Zones::get()?.into_par_iter().try_for_each(|zone| -> Result<()> { zone::Zones::halt_and_remove(zone.name())?; - } + Ok(()) + })?; Ok(()) } diff --git a/sled-agent/src/sled_agent.rs b/sled-agent/src/sled_agent.rs index 6ee109d442b..f15f5e0eec4 100644 --- a/sled-agent/src/sled_agent.rs +++ b/sled-agent/src/sled_agent.rs @@ -19,6 +19,7 @@ use crate::params::{ }; use crate::services::ServiceManager; use crate::storage_manager::StorageManager; +use futures::stream::{self, StreamExt, TryStreamExt}; use omicron_common::api::{ internal::nexus::DiskRuntimeState, internal::nexus::InstanceRuntimeState, internal::nexus::UpdateArtifact, @@ -169,10 +170,18 @@ impl SledAgent { // re-establish contact (i.e., if the Sled Agent crashed, but we wanted // to leave the running Zones intact). let zones = Zones::get()?; - for z in zones { - warn!(log, "Deleting existing zone"; "zone_name" => z.name()); - Zones::halt_and_remove_logged(&log, z.name())?; - } + stream::iter(zones) + .zip(stream::iter(std::iter::repeat(log.clone()))) + .map(Ok::<_, crate::zone::AdmError>) + .try_for_each_concurrent( + None, + |(zone, log)| async { + tokio::task::spawn_blocking(move || { + warn!(log, "Deleting existing zone"; "zone_name" => zone.name()); + Zones::halt_and_remove_logged(&log, zone.name()) + }).await.unwrap() + } + ).await?; // Identify all VNICs which should be managed by the Sled Agent. // @@ -187,15 +196,24 @@ impl SledAgent { // Note that we don't currently delete the VNICs in any particular // order. That should be OK, since we're definitely deleting the guest // VNICs before the xde devices, which is the main constraint. - for vnic in Dladm::get_vnics()? { - warn!( - log, - "Deleting existing VNIC"; - "vnic_name" => &vnic, - "vnic_kind" => ?VnicKind::from_name(&vnic).unwrap(), - ); - Dladm::delete_vnic(&vnic)?; - } + let vnics = Dladm::get_vnics()?; + stream::iter(vnics) + .zip(stream::iter(std::iter::repeat(log.clone()))) + .map(Ok::<_, crate::illumos::dladm::DeleteVnicError>) + .try_for_each_concurrent(None, |(vnic, log)| async { + tokio::task::spawn_blocking(move || { + warn!( + log, + "Deleting existing VNIC"; + "vnic_name" => &vnic, + "vnic_kind" => ?VnicKind::from_name(&vnic).unwrap(), + ); + Dladm::delete_vnic(&vnic) + }) + .await + .unwrap() + }) + .await?; // Also delete any extant xde devices. These should also eventually be // recovered / tracked, to avoid interruption of any guests that are