Skip to content

Commit

Permalink
Store NVMe firmware metadata in inventory collection (#6275)
Browse files Browse the repository at this point in the history
With #5706 merged and later reenabled in #6026 we now want to store this
data in CRDB so that it can be used by blueprints and reconfigurator.

`nexus_types::inventory::PhysicalDisk` now has a `firmware` field that
is exposed as an enum called `PhysicalDiskFirmware`. Today we only have
`Unknown` and `Nvme` variants but this can later be expanded upon if we
ever start using additional disk types such as SCSI/SATA etc.

Finally I have included an updated version of `omdb db inventory
physical-disks` that will include the currently active firmware as well
as the next active firmware if a new version has been staged.
  • Loading branch information
papertigers authored Sep 25, 2024
1 parent c394189 commit 356c9bf
Show file tree
Hide file tree
Showing 20 changed files with 807 additions and 43 deletions.
54 changes: 41 additions & 13 deletions dev-tools/omdb/src/bin/omdb/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ use nexus_db_model::HwBaseboardId;
use nexus_db_model::Image;
use nexus_db_model::Instance;
use nexus_db_model::InvCollection;
use nexus_db_model::InvNvmeDiskFirmware;
use nexus_db_model::InvPhysicalDisk;
use nexus_db_model::IpAttachState;
use nexus_db_model::IpKind;
Expand Down Expand Up @@ -4666,36 +4667,62 @@ async fn cmd_db_inventory_physical_disks(
model: String,
serial: String,
variant: String,
firmware: String,
next_firmware: String,
}

use db::schema::inv_physical_disk::dsl;
let mut query = dsl::inv_physical_disk.into_boxed();
use db::schema::inv_nvme_disk_firmware::dsl as firmware_dsl;
use db::schema::inv_physical_disk::dsl as disk_dsl;

let mut query = disk_dsl::inv_physical_disk.into_boxed();
query = query.limit(i64::from(u32::from(limit)));

if let Some(collection_id) = args.collection_id {
query = query.filter(
dsl::inv_collection_id.eq(collection_id.into_untyped_uuid()),
disk_dsl::inv_collection_id.eq(collection_id.into_untyped_uuid()),
);
}

if let Some(sled_id) = args.sled_id {
query = query.filter(dsl::sled_id.eq(sled_id.into_untyped_uuid()));
query = query.filter(disk_dsl::sled_id.eq(sled_id.into_untyped_uuid()));
}

let disks = query
.select(InvPhysicalDisk::as_select())
.left_join(
firmware_dsl::inv_nvme_disk_firmware.on(
firmware_dsl::inv_collection_id
.eq(disk_dsl::inv_collection_id)
.and(firmware_dsl::sled_id.eq(disk_dsl::sled_id))
.and(firmware_dsl::slot.eq(disk_dsl::slot)),
),
)
.select((
InvPhysicalDisk::as_select(),
Option::<InvNvmeDiskFirmware>::as_select(),
))
.load_async(&**conn)
.await
.context("loading physical disks")?;

let rows = disks.into_iter().map(|disk| DiskRow {
inv_collection_id: disk.inv_collection_id.into_untyped_uuid(),
sled_id: disk.sled_id.into_untyped_uuid(),
slot: disk.slot,
vendor: disk.vendor,
model: disk.model.clone(),
serial: disk.serial.clone(),
variant: format!("{:?}", disk.variant),
let rows = disks.into_iter().map(|(disk, firmware)| {
let (active_firmware, next_firmware) =
if let Some(firmware) = firmware.as_ref() {
(firmware.current_version(), firmware.next_version())
} else {
(None, None)
};

DiskRow {
inv_collection_id: disk.inv_collection_id.into_untyped_uuid(),
sled_id: disk.sled_id.into_untyped_uuid(),
slot: disk.slot,
vendor: disk.vendor,
model: disk.model.clone(),
serial: disk.serial.clone(),
variant: format!("{:?}", disk.variant),
firmware: active_firmware.unwrap_or("UNKNOWN").to_string(),
next_firmware: next_firmware.unwrap_or("").to_string(),
}
});

let table = tabled::Table::new(rows)
Expand Down Expand Up @@ -5101,6 +5128,7 @@ fn inv_collection_print_sleds(collection: &Collection) {
identity,
variant,
slot,
..
} = disk;
println!(" {variant:?}: {identity:?} in {slot}");
}
Expand Down
8 changes: 8 additions & 0 deletions nexus-sled-agent-shared/src/inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ pub struct InventoryDisk {
pub identity: omicron_common::disk::DiskIdentity,
pub variant: DiskVariant,
pub slot: i64,
// Today we only have NVMe disks so we embedded the firmware metadata here.
// In the future we can track firmware metadata in a unique type if we
// support more than one disk format.
pub active_firmware_slot: u8,
pub next_active_firmware_slot: Option<u8>,
pub number_of_firmware_slots: u8,
pub slot1_is_read_only: bool,
pub slot_firmware_versions: Vec<Option<String>>,
}

/// Identifies information about zpools managed by the control plane
Expand Down
Loading

0 comments on commit 356c9bf

Please sign in to comment.