diff --git a/illumos-utils/src/smf_helper.rs b/illumos-utils/src/smf_helper.rs index 2d29376950..9bf782ce1e 100644 --- a/illumos-utils/src/smf_helper.rs +++ b/illumos-utils/src/smf_helper.rs @@ -165,6 +165,38 @@ impl<'t> SmfHelper<'t> { Ok(()) } + pub fn delpropvalue
(&self, prop: P, val: V) -> Result<(), Error> + where + P: ToString, + V: ToString, + { + match self + .running_zone + .run_cmd(&[ + SVCCFG, + "-s", + &self.smf_name, + "delpropvalue", + &prop.to_string(), + &val.to_string(), + ]) + .map_err(|err| Error::ZoneCommand { + intent: format!("del {} smf property value", prop.to_string()), + err, + }) { + Ok(_) => (), + Err(e) => { + // If a property already doesn't exist we don't need to + // return an error + if !e.to_string().contains("No such property") { + return Err(e); + } + } + }; + + Ok(()) + } + pub fn delpropvalue_default_instance
(
&self,
prop: P,
diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs
index db250eb914..4a3a598ee2 100644
--- a/sled-agent/src/services.rs
+++ b/sled-agent/src/services.rs
@@ -54,7 +54,6 @@ use illumos_utils::running_zone::{
};
use illumos_utils::smf_helper::SmfHelper;
use illumos_utils::zfs::ZONE_ZFS_RAMDISK_DATASET_MOUNTPOINT;
-use illumos_utils::zone::AddressRequest;
use illumos_utils::zpool::{PathInPool, ZpoolName};
use illumos_utils::{execute, PFEXEC};
use internal_dns_resolver::Resolver;
@@ -541,6 +540,18 @@ struct SwitchZoneConfigLocal {
root: Utf8PathBuf,
}
+/// Service that sets up common networking across zones
+struct ZoneNetworkSetupService {}
+
+impl illumos_utils::smf_helper::Service for ZoneNetworkSetupService {
+ fn service_name(&self) -> String {
+ "zone-network-setup".to_string()
+ }
+ fn smf_name(&self) -> String {
+ format!("svc:/oxide/{}", self.service_name())
+ }
+}
+
/// Describes either an Omicron-managed zone or the switch zone, used for
/// functions that operate on either one or the other
enum ZoneArgs<'a> {
@@ -4272,59 +4283,53 @@ impl ServiceManager {
);
*request = new_request;
+ // Add SMF properties here and restart zone-network-setup service
let first_address = request.addresses.get(0);
let address = first_address
.map(|addr| addr.to_string())
.unwrap_or_else(|| "".to_string());
- for addr in &request.addresses {
- if *addr == Ipv6Addr::LOCALHOST {
- continue;
- }
- info!(
- self.inner.log,
- "Ensuring address {} exists",
- addr.to_string()
- );
- let addr_request =
- AddressRequest::new_static(IpAddr::V6(*addr), None);
- zone.ensure_address(addr_request).await?;
- info!(
- self.inner.log,
- "Ensuring address {} exists - OK",
- addr.to_string()
- );
- }
+ // Set new properties for the network set up service and refresh
+ let nw_setup_svc = ZoneNetworkSetupService {};
+ let nsmfh = SmfHelper::new(&zone, &nw_setup_svc);
+
+ nsmfh.delpropvalue("config/gateway", "*")?;
+ nsmfh.delpropvalue("config/static_addr", "*")?;
- // When the request addresses have changed this means the underlay is
- // available now as well.
if let Some(info) = self.inner.sled_info.get() {
- info!(
+ nsmfh.addpropvalue_type(
+ "config/gateway",
+ &info.underlay_address,
+ "astring",
+ )?;
+ } else {
+ // It should be impossible for the `sled_info` not to be set here.
+ // When the request addresses have changed this means the underlay is
+ // available as well.
+ error!(
self.inner.log,
- "Ensuring there is a default route";
- "gateway" => ?info.underlay_address,
+ concat!(
+ "sled agent info is not present,",
+ " even though underlay address exists"
+ )
);
- match zone.add_default_route(info.underlay_address).map_err(
- |err| Error::ZoneCommand {
- intent: "Adding Route".to_string(),
- err,
- },
- ) {
- Ok(_) => (),
- Err(e) => {
- if e.to_string().contains("entry exists") {
- info!(
- self.inner.log,
- "Default route already exists";
- "gateway" => ?info.underlay_address,
- )
- } else {
- return Err(e);
- }
- }
- };
}
+ for address in &request.addresses {
+ if *address != Ipv6Addr::LOCALHOST {
+ nsmfh.addpropvalue_type(
+ "config/static_addr",
+ &address,
+ "astring",
+ )?;
+ }
+ }
+ nsmfh.refresh()?;
+ info!(
+ self.inner.log,
+ "refreshed zone-network-setup service with new configuration"
+ );
+
for service in &request.services {
let smfh = SmfHelper::new(&zone, service);
diff --git a/smf/zone-network-setup/manifest.xml b/smf/zone-network-setup/manifest.xml
index e7dc1e496b..c78a7256e5 100644
--- a/smf/zone-network-setup/manifest.xml
+++ b/smf/zone-network-setup/manifest.xml
@@ -12,7 +12,7 @@