-
Notifications
You must be signed in to change notification settings - Fork 40
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
Import maghemite mg-ddm service #1249
Changes from 4 commits
3b4f3ec
667e1cc
bbc8bb0
42cbfe3
6309c7b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
|
||
//! Starting the mg-ddm service. | ||
|
||
use crate::illumos::addrobj::AddrObject; | ||
use slog::Logger; | ||
use thiserror::Error; | ||
|
||
const SERVICE_FMRI: &str = "svc:/system/illumos/mg-ddm"; | ||
const MANIFEST_PATH: &str = "/opt/oxide/mg-ddm/pkg/ddm/manifest.xml"; | ||
|
||
#[derive(Debug, Error)] | ||
pub enum Error { | ||
#[error("Error configuring service: {0}")] | ||
Config(#[from] smf::ConfigError), | ||
|
||
#[error("Error administering service: {0}")] | ||
Adm(#[from] smf::AdmError), | ||
|
||
#[error("Error starting service: {0}")] | ||
Join(#[from] tokio::task::JoinError), | ||
} | ||
|
||
pub async fn enable_mg_ddm_service( | ||
log: Logger, | ||
interface: AddrObject, | ||
) -> Result<(), Error> { | ||
tokio::task::spawn_blocking(|| { | ||
enable_mg_ddm_service_blocking(log, interface) | ||
}) | ||
.await? | ||
} | ||
|
||
fn enable_mg_ddm_service_blocking( | ||
log: Logger, | ||
interface: AddrObject, | ||
) -> Result<(), Error> { | ||
info!(log, "Importing mg-ddm service"; "path" => MANIFEST_PATH); | ||
smf::Config::import().run(MANIFEST_PATH)?; | ||
|
||
// TODO-cleanup mg-ddm supports multiple interfaces, but `smf` currently | ||
// doesn't expose an equivalent of `svccfg addpropvalue`. If we need | ||
// multiple interfaces we'll need to extend smf. | ||
let interface = interface.to_string(); | ||
info!(log, "Setting mg-ddm interface"; "interface" => interface.as_str()); | ||
smf::Config::set_property(SERVICE_FMRI).run(smf::Property::new( | ||
smf::PropertyName::new("config", "interfaces").unwrap(), | ||
smf::PropertyValue::Astring(interface), | ||
))?; | ||
|
||
info!(log, "Enabling mg-ddm service"); | ||
smf::Adm::new() | ||
.enable() | ||
.temporary() | ||
.run(smf::AdmSelection::ByPattern(&[SERVICE_FMRI]))?; | ||
|
||
Ok(()) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,10 @@ use super::params::RequestEnvelope; | |
use super::trust_quorum::ShareDistribution; | ||
use super::views::Response; | ||
use super::views::ResponseEnvelope; | ||
use crate::bootstrap::maghemite; | ||
use crate::config::Config as SledConfig; | ||
use crate::illumos::addrobj::AddrObject; | ||
use crate::illumos::dladm::VnicSource; | ||
use crate::sp::AsyncReadWrite; | ||
use crate::sp::SpHandle; | ||
use crate::sp::SprocketsRole; | ||
|
@@ -63,6 +66,23 @@ impl Server { | |
debug!(log, "registered DTrace probes"); | ||
} | ||
|
||
// Turn on the maghemite routing service. | ||
info!(log, "Starting mg-ddm service"); | ||
let link = sled_config | ||
.get_link() | ||
.map_err(|err| format!("Failed to find physical link: {err}"))?; | ||
|
||
// TODO-correctness (a) Is "linklocal" always right? (b) Do we need | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to be correct with regards to RFD 63 section 6.3.1:
I don't see why it would break single node behavior. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I should've been more specific. IIUC the name The breakage is that starting the service fails if the address object we specify here doesn't exist. I think that failure is correct (since we won't be able to route off node without mg-ddm), but I don't want it to fail based on a bad assumption about this name. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah. I was assuming this created the addrconf object. In production we should definitely fail if the link-local address doesn't exist right? I'd prefer not to qualify this for test only in that case as it's mighty easy to create a link-local address. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We definitely have to have a link-local address, yes. I don't know who or when should create that - should bootstrap-agent do that here if doesn't exist? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure as to who creates the address, but I believe the intention is for that to be over the loopback interface There are multiple Chelsio physical links on the sled, both of which provide a potential path to talk to the bootstrap server. Maghemite is responsible for advertising the prefix over both Chelio links, and updating the OS's routing tables accordingly. Although @rcgoodfellow can talk in much more depth about it, my understanding is that traffic will be dynamically routed through one or the other Chelsio depending on the expected delay sending a packet down each of them. But it expects to be able to reach the bootstrap address through either link. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maghemite needs link-local/addrconf addresses to be set up for both sled physical interfaces it will route over. So if our interfaces on the sled are
Then the addrconf addresses
should be set up (not advocating specifically for "linklocal" there, but that seems to be the trend so rolling with it, I don't have a good name to suggest) early in the sled initialization process. I don't have an opinion on who sets those up, only that they are set up before Maghemite starts so the address object names (i.e. "cxgbe0/linklocal") can be provided to Maghemite on startup. If the addrconf addresses are set up as temporary, this ordering of addresses before Maghemite will need to be ensured on each boot. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's correct, but in order to do that, we need a distinct link-local address on each physical interface which provides a path to the interface-independent underlay ULA /64 prefix of the host. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @rcgoodfellow! I think the main followup question comes from
i.e., should sled-agent set up the addrconf addresses itself, or assume they already exist? Here in the code I'm assuming both that (a) it already exists and (b) it has the name There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Poking around, we don't need to extend |
||
// mg-ddm to listen on multiple addresses? | ||
let mg_interface = AddrObject::new(link.name(), "linklocal") | ||
.expect("unexpected failure creating AddrObject"); | ||
|
||
// TODO-cleanup Should we `tokio::spawn()` this so we can proceed | ||
jgallagher marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// concurrently with mg-ddm starting up? | ||
maghemite::enable_mg_ddm_service(log.clone(), mg_interface) | ||
.await | ||
.map_err(|err| format!("Failed to start mg-ddm: {err}"))?; | ||
|
||
info!(log, "detecting (real or simulated) SP"); | ||
let sp = SpHandle::detect( | ||
config.sp_config.as_ref().map(|c| &c.local_sp), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, this library is just a wrapper around the
/usr/sbin/svccfg
command - if it's too inflexible, it's totally okay to call out to that command manually.(extending the library is also a viable option, as you suggested).