Skip to content

Commit 46f8b06

Browse files
authored
MGS SpIdentifier slot could be a u16 (#8490)
1 parent 05b806a commit 46f8b06

File tree

24 files changed

+100
-168
lines changed

24 files changed

+100
-168
lines changed

dev-tools/omdb/src/bin/omdb/mgs.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ fn show_sp_ids(sp_ids: &[SpIdentifier]) -> Result<(), anyhow::Error> {
195195
struct SpIdRow {
196196
#[tabled(rename = "TYPE")]
197197
type_: &'static str,
198-
slot: u32,
198+
slot: u16,
199199
}
200200

201201
impl From<&SpIdentifier> for SpIdRow {
@@ -221,7 +221,7 @@ fn show_sps_from_ignition(
221221
struct IgnitionRow {
222222
#[tabled(rename = "TYPE")]
223223
type_: &'static str,
224-
slot: u32,
224+
slot: u16,
225225
system_type: String,
226226
}
227227

@@ -269,7 +269,7 @@ fn show_sp_states(
269269
struct SpStateRow<'a> {
270270
#[tabled(rename = "TYPE")]
271271
type_: &'static str,
272-
slot: u32,
272+
slot: u16,
273273
model: String,
274274
serial: String,
275275
rev: u32,

dev-tools/omdb/src/bin/omdb/mgs/sensors.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub(crate) struct SensorsArgs {
2626

2727
/// restrict to specified sled(s)
2828
#[clap(long, use_value_delimiter = true)]
29-
pub sled: Vec<u32>,
29+
pub sled: Vec<u16>,
3030

3131
/// exclude sleds rather than include them
3232
#[clap(long, short)]
@@ -256,7 +256,7 @@ struct SpInfo {
256256
async fn sp_info(
257257
mgs_client: gateway_client::Client,
258258
type_: SpType,
259-
slot: u32,
259+
slot: u16,
260260
) -> Result<SpInfo, anyhow::Error> {
261261
let mut devices = MultiMap::new();
262262
let mut timestamps = vec![];
@@ -429,7 +429,7 @@ fn sp_info_csv<R: std::io::Read>(
429429
}
430430
};
431431

432-
let slot = parts[1].parse::<u32>().or_else(|_| {
432+
let slot = parts[1].parse::<u16>().or_else(|_| {
433433
bail!("invalid slot in \"{field}\"");
434434
})?;
435435

dev-tools/reconfigurator-sp-updater/src/main.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,10 @@ impl Inventory {
213213
}),
214214
)
215215
.then(async move |sp_id| {
216-
let sp_slot = u16::try_from(sp_id.slot).with_context(|| {
217-
format!("sp slot number is out of range: {sp_id:?}")
218-
})?;
219216
c.sp_get(sp_id.type_, sp_id.slot)
220217
.await
221218
.with_context(|| format!("fetching info about SP {:?}", sp_id))
222-
.map(|s| (sp_id.type_, sp_slot, s))
219+
.map(|s| (sp_id.type_, sp_id.slot, s))
223220
})
224221
.collect::<Vec<Result<_, _>>>()
225222
.await

gateway-test-utils/src/setup.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,11 @@ pub async fn test_setup_with_config(
151151
port_description.location.get(&expected_location).unwrap();
152152
let (sp_addr, sp_ereport_addr) = match target_sp.typ {
153153
SpType::Switch => {
154-
let switch = &simrack.sidecars[target_sp.slot];
154+
let switch = &simrack.sidecars[usize::from(target_sp.slot)];
155155
(switch.local_addr(sp_port), switch.local_ereport_addr(sp_port))
156156
}
157157
SpType::Sled => {
158-
let sled = &simrack.gimlets[target_sp.slot];
158+
let sled = &simrack.gimlets[usize::from(target_sp.slot)];
159159
(sled.local_addr(sp_port), sled.local_ereport_addr(sp_port))
160160
}
161161
SpType::Power => todo!(),

gateway-types/src/component.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ pub enum SpType {
4343
pub struct SpIdentifier {
4444
#[serde(rename = "type")]
4545
pub typ: SpType,
46-
#[serde(deserialize_with = "deserializer_u32_from_string")]
47-
pub slot: u32,
46+
#[serde(deserialize_with = "deserializer_u16_from_string")]
47+
pub slot: u16,
4848
}
4949

5050
impl fmt::Display for SpIdentifier {
@@ -59,29 +59,29 @@ impl fmt::Display for SpIdentifier {
5959
// trying to deserialize the flattened struct as a map of strings to strings,
6060
// which breaks on `slot` (but not on `typ` for reasons I don't entirely
6161
// understand). We can work around by using an enum that allows either `String`
62-
// or `u32` (which gets us past the serde map of strings), and then parsing the
63-
// string into a u32 ourselves (which gets us to the `slot` we want). More
62+
// or `u16` (which gets us past the serde map of strings), and then parsing the
63+
// string into a u16 ourselves (which gets us to the `slot` we want). More
6464
// background: https://github.com/serde-rs/serde/issues/1346
65-
fn deserializer_u32_from_string<'de, D>(
65+
fn deserializer_u16_from_string<'de, D>(
6666
deserializer: D,
67-
) -> Result<u32, D::Error>
67+
) -> Result<u16, D::Error>
6868
where
6969
D: serde::Deserializer<'de>,
7070
{
7171
use serde::de::{self, Unexpected};
7272

7373
#[derive(Debug, Deserialize)]
7474
#[serde(untagged)]
75-
enum StringOrU32 {
75+
enum StringOrU16 {
7676
String(String),
77-
U32(u32),
77+
U16(u16),
7878
}
7979

80-
match StringOrU32::deserialize(deserializer)? {
81-
StringOrU32::String(s) => s
80+
match StringOrU16::deserialize(deserializer)? {
81+
StringOrU16::String(s) => s
8282
.parse()
83-
.map_err(|_| de::Error::invalid_type(Unexpected::Str(&s), &"u32")),
84-
StringOrU32::U32(n) => Ok(n),
83+
.map_err(|_| de::Error::invalid_type(Unexpected::Str(&s), &"u16")),
84+
StringOrU16::U16(n) => Ok(n),
8585
}
8686
}
8787

gateway/src/management_switch.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,34 +89,24 @@ fn default_ereport_listen_port() -> u16 {
8989
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
9090
pub struct SpIdentifier {
9191
pub typ: SpType,
92-
pub slot: usize,
92+
pub slot: u16,
9393
}
9494

9595
impl SpIdentifier {
96-
pub fn new(typ: SpType, slot: usize) -> Self {
96+
pub fn new(typ: SpType, slot: u16) -> Self {
9797
Self { typ, slot }
9898
}
9999
}
100100

101101
impl From<gateway_types::component::SpIdentifier> for SpIdentifier {
102102
fn from(id: gateway_types::component::SpIdentifier) -> Self {
103-
Self {
104-
typ: id.typ.into(),
105-
// id.slot may come from an untrusted source, but usize >= 32 bits
106-
// on any platform that will run this code, so unwrap is fine
107-
slot: usize::try_from(id.slot).unwrap(),
108-
}
103+
Self { typ: id.typ.into(), slot: id.slot }
109104
}
110105
}
111106

112107
impl From<SpIdentifier> for gateway_types::component::SpIdentifier {
113108
fn from(id: SpIdentifier) -> Self {
114-
Self {
115-
typ: id.typ.into(),
116-
// id.slot comes from a trusted source (crate::management_switch)
117-
// and will not exceed u32::MAX
118-
slot: u32::try_from(id.slot).unwrap(),
119-
}
109+
Self { typ: id.typ.into(), slot: id.slot }
120110
}
121111
}
122112

gateway/src/metrics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ impl SpPoller {
648648
hubris_archive_id: Cow::Owned(
649649
hubris_archive_id.clone(),
650650
),
651-
slot: self.spid.slot as u32,
651+
slot: u32::from(self.spid.slot),
652652
component_kind: Cow::Owned(dev.device),
653653
component_id,
654654
description: Cow::Owned(dev.description),

nexus/inventory/src/builder.rs

Lines changed: 3 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -188,26 +188,9 @@ impl CollectionBuilder {
188188
&mut self,
189189
source: &str,
190190
sp_type: SpType,
191-
slot: u32,
191+
sp_slot: u16,
192192
sp_state: SpState,
193193
) -> Option<Arc<BaseboardId>> {
194-
// Much ado about very little: MGS reports that "slot" is a u32, though
195-
// in practice this seems very unlikely to be bigger than a u8. (How
196-
// many slots can there be within one rack?) The database only supports
197-
// signed integers, so if we assumed this really could span the range of
198-
// a u32, we'd need to store it in an i64. Instead, assume here that we
199-
// can stick it into a u16 (which still seems generous). This will
200-
// allow us to store it into an Int32 in the database.
201-
let Ok(sp_slot) = u16::try_from(slot) else {
202-
self.found_error(InventoryError::from(anyhow!(
203-
"MGS {:?}: SP {:?} slot {}: slot number did not fit into u16",
204-
source,
205-
sp_type,
206-
slot
207-
)));
208-
return None;
209-
};
210-
211194
// Normalize the baseboard id: i.e., if we've seen this baseboard
212195
// before, use the same baseboard id record. Otherwise, make a new one.
213196
let baseboard = Self::normalize_item(
@@ -580,7 +563,6 @@ mod test {
580563
use super::now_db_precision;
581564
use crate::examples::Representative;
582565
use crate::examples::representative;
583-
use crate::examples::sp_state;
584566
use base64::Engine;
585567
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
586568
use gateway_client::types::PowerState;
@@ -1089,15 +1071,6 @@ mod test {
10891071
.unwrap();
10901072
assert_eq!(sled1_bb, sled1_bb_dup);
10911073

1092-
// report an SP with an impossible slot number
1093-
let sled2_sp = builder.found_sp_state(
1094-
"fake MGS 1",
1095-
SpType::Sled,
1096-
u32::from(u16::MAX) + 1,
1097-
sp_state("1"),
1098-
);
1099-
assert_eq!(sled2_sp, None);
1100-
11011074
// report SP caboose for an unknown baseboard
11021075
let bogus_baseboard = BaseboardId {
11031076
part_number: String::from("p1"),
@@ -1309,17 +1282,7 @@ mod test {
13091282
.is_none()
13101283
);
13111284

1312-
// We should see an error.
1313-
assert_eq!(
1314-
collection
1315-
.errors
1316-
.iter()
1317-
.map(|e| format!("{:#}", e))
1318-
.collect::<Vec<_>>(),
1319-
vec![
1320-
"MGS \"fake MGS 1\": SP Sled slot 65536: \
1321-
slot number did not fit into u16"
1322-
]
1323-
);
1285+
// We should see no errors.
1286+
assert!(collection.errors.is_empty());
13241287
}
13251288
}

nexus/mgs-updates/src/common_sp_update.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub trait SpComponentUpdater {
6969
fn target_sp_type(&self) -> SpType;
7070

7171
/// The slot number of the target SP.
72-
fn target_sp_slot(&self) -> u32;
72+
fn target_sp_slot(&self) -> u16;
7373

7474
/// The target firmware slot for the component.
7575
fn firmware_slot(&self) -> u16;

nexus/mgs-updates/src/driver_update.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ pub(crate) async fn apply_update(
242242
client
243243
.sp_component_update(
244244
sp_type,
245-
u32::from(sp_slot),
245+
sp_slot,
246246
component,
247247
sp_update.firmware_slot,
248248
&sp_update.update_id.as_untyped_uuid(),
@@ -450,11 +450,7 @@ async fn wait_for_delivery(
450450
let status = mgs_clients
451451
.try_all_serially(log, |client| async move {
452452
let update_status = client
453-
.sp_component_update_status(
454-
sp_type,
455-
u32::from(sp_slot),
456-
component,
457-
)
453+
.sp_component_update_status(sp_type, sp_slot, component)
458454
.await?;
459455

460456
debug!(
@@ -553,12 +549,7 @@ async fn abort_update(
553549
.try_all_serially(log, |mgs_client| async move {
554550
let arg = UpdateAbortBody { id: update_id };
555551
mgs_client
556-
.sp_component_update_abort(
557-
sp_type,
558-
u32::from(sp_slot),
559-
component,
560-
&arg,
561-
)
552+
.sp_component_update_abort(sp_type, sp_slot, component, &arg)
562553
.await
563554
})
564555
.await

0 commit comments

Comments
 (0)