Skip to content

Commit 1196d42

Browse files
leftwoAlan Hanson
andauthored
Show more information in omdb db snapshots (#7504)
Now we print, when available, the region snapshot info as well as the datasets that make up the source. Changed the output a little to fit in fewer columns. Having this info available in omdb allows us to write tests to find an replace a specific part of a downstairs in a snapshot. --------- Co-authored-by: Alan Hanson <[email protected]>
1 parent 8e0bed8 commit 1196d42

File tree

1 file changed

+111
-29
lines changed
  • dev-tools/omdb/src/bin/omdb

1 file changed

+111
-29
lines changed

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

Lines changed: 111 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,7 +1563,7 @@ async fn cmd_db_disk_info(
15631563
struct DownstairsRow {
15641564
host_serial: String,
15651565
region: String,
1566-
zone: String,
1566+
dataset: String,
15671567
physical_disk: String,
15681568
}
15691569

@@ -1688,7 +1688,7 @@ async fn cmd_db_disk_info(
16881688
rows.push(DownstairsRow {
16891689
host_serial: my_sled.serial_number().to_string(),
16901690
region: region.id().to_string(),
1691-
zone: format!("oxz_crucible_{}", dataset.id()),
1691+
dataset: dataset.id().to_string(),
16921692
physical_disk: my_zpool.physical_disk_id.to_string(),
16931693
});
16941694
}
@@ -1724,7 +1724,7 @@ async fn get_and_display_vcr(
17241724
for v in volumes {
17251725
match serde_json::from_str(&v.data()) {
17261726
Ok(vcr) => {
1727-
println!("\nVCR from volume ID {volume_id}");
1727+
println!("VCR from volume ID {volume_id}");
17281728
print_vcr(vcr, 0);
17291729
}
17301730
Err(e) => {
@@ -2125,45 +2125,88 @@ async fn cmd_db_snapshot_info(
21252125
struct DownstairsRow {
21262126
host_serial: String,
21272127
region: String,
2128-
zone: String,
2128+
dataset: String,
21292129
physical_disk: String,
21302130
}
21312131

21322132
use db::schema::snapshot::dsl as snapshot_dsl;
2133-
let snapshots = snapshot_dsl::snapshot
2133+
let mut snapshots = snapshot_dsl::snapshot
21342134
.filter(snapshot_dsl::id.eq(args.uuid))
21352135
.limit(1)
21362136
.select(Snapshot::as_select())
21372137
.load_async(&*datastore.pool_connection_for_tests().await?)
21382138
.await
21392139
.context("loading requested snapshot")?;
21402140

2141-
let mut dest_volume_ids = Vec::new();
2142-
let mut source_volume_ids = Vec::new();
2143-
let rows = snapshots.into_iter().map(|snapshot| {
2144-
dest_volume_ids.push(snapshot.destination_volume_id());
2145-
source_volume_ids.push(snapshot.volume_id());
2146-
SnapshotRow::from(snapshot)
2147-
});
2148-
if rows.len() == 0 {
2149-
bail!("No snapshout with UUID: {} found", args.uuid);
2141+
if snapshots.is_empty() {
2142+
bail!("No snapshot with UUID: {} found", args.uuid);
21502143
}
2144+
let snap = snapshots.pop().expect("Found more that one snapshot");
21512145

2152-
let table = tabled::Table::new(rows)
2153-
.with(tabled::settings::Style::empty())
2154-
.with(tabled::settings::Padding::new(0, 1, 0, 0))
2155-
.to_string();
2146+
let dest_vol_id = snap.destination_volume_id;
2147+
let source_vol_id = snap.volume_id;
2148+
let snap = SnapshotRow::from(snap);
21562149

2157-
println!("{}", table);
2150+
println!(" Name: {}", snap.snap_name);
2151+
println!(" id: {}", snap.id);
2152+
println!(" state: {}", snap.state);
2153+
println!(" size: {}", snap.size);
2154+
println!(" source_disk_id: {}", snap.source_disk_id);
2155+
println!(" source_volume_id: {}", snap.source_volume_id);
2156+
println!("destination_volume_id: {}", snap.destination_volume_id);
21582157

2159-
println!("SOURCE VOLUME VCR:");
2160-
for vol in source_volume_ids {
2161-
get_and_display_vcr(vol, datastore).await?;
2158+
use db::schema::region_snapshot::dsl as region_snapshot_dsl;
2159+
let region_snapshots = region_snapshot_dsl::region_snapshot
2160+
.filter(region_snapshot_dsl::snapshot_id.eq(args.uuid))
2161+
.select(RegionSnapshot::as_select())
2162+
.load_async(&*datastore.pool_connection_for_tests().await?)
2163+
.await
2164+
.context("loading region snapshots")?;
2165+
2166+
println!();
2167+
if region_snapshots.is_empty() {
2168+
println!("No region snapshot info found");
2169+
} else {
2170+
// The row describing the region_snapshot.
2171+
#[derive(Tabled)]
2172+
#[tabled(rename_all = "SCREAMING_SNAKE_CASE")]
2173+
struct RegionSnapshotRow {
2174+
dataset_id: String,
2175+
region_id: String,
2176+
snapshot_id: String,
2177+
snapshot_addr: String,
2178+
volume_references: String,
2179+
}
2180+
let mut rsnap = Vec::new();
2181+
2182+
// From each region snapshot:
2183+
// Collect the snapshot IDs for later use.
2184+
// Display the region snapshot rows.
2185+
let mut snapshot_ids = HashSet::new();
2186+
for rs in region_snapshots {
2187+
snapshot_ids.insert(rs.snapshot_id);
2188+
let rs = RegionSnapshotRow {
2189+
dataset_id: rs.dataset_id.to_string(),
2190+
region_id: rs.region_id.to_string(),
2191+
snapshot_id: rs.snapshot_id.to_string(),
2192+
snapshot_addr: rs.snapshot_addr.to_string(),
2193+
volume_references: rs.volume_references.to_string(),
2194+
};
2195+
rsnap.push(rs);
2196+
}
2197+
let table = tabled::Table::new(rsnap)
2198+
.with(tabled::settings::Style::empty())
2199+
.with(tabled::settings::Padding::new(0, 1, 0, 0))
2200+
.to_string();
2201+
2202+
println!("REGION SNAPSHOT INFO:");
2203+
println!("{}", table);
21622204
}
2163-
for vol_id in dest_volume_ids {
2164-
// Get the dataset backing this volume.
2165-
let regions = datastore.get_allocated_regions(vol_id).await?;
21662205

2206+
let regions = datastore.get_allocated_regions(source_vol_id.into()).await?;
2207+
if regions.is_empty() {
2208+
println!("\nNo source region info found");
2209+
} else {
21672210
let mut rows = Vec::with_capacity(3);
21682211
for (dataset, region) in regions {
21692212
let my_pool_id = dataset.pool_id;
@@ -2184,7 +2227,7 @@ async fn cmd_db_snapshot_info(
21842227
rows.push(DownstairsRow {
21852228
host_serial: my_sled.serial_number().to_string(),
21862229
region: region.id().to_string(),
2187-
zone: format!("oxz_crucible_{}", dataset.id()),
2230+
dataset: dataset.id().to_string(),
21882231
physical_disk: my_zpool.physical_disk_id.to_string(),
21892232
});
21902233
}
@@ -2194,12 +2237,51 @@ async fn cmd_db_snapshot_info(
21942237
.with(tabled::settings::Padding::new(0, 1, 0, 0))
21952238
.to_string();
21962239

2197-
println!("DESTINATION REGION INFO:");
2240+
println!("\nSOURCE REGION INFO:");
21982241
println!("{}", table);
2199-
println!("DESTINATION VOLUME VCR:");
2200-
get_and_display_vcr(vol_id, datastore).await?;
22012242
}
22022243

2244+
println!("SOURCE VOLUME VCR:");
2245+
get_and_display_vcr(source_vol_id.into(), datastore).await?;
2246+
2247+
// Get the dataset backing this volume.
2248+
let regions = datastore.get_allocated_regions(dest_vol_id.into()).await?;
2249+
2250+
let mut rows = Vec::with_capacity(3);
2251+
for (dataset, region) in regions {
2252+
let my_pool_id = dataset.pool_id;
2253+
let (_, my_zpool) = LookupPath::new(opctx, datastore)
2254+
.zpool_id(my_pool_id)
2255+
.fetch()
2256+
.await
2257+
.context("failed to look up zpool")?;
2258+
2259+
let my_sled_id = my_zpool.sled_id;
2260+
2261+
let (_, my_sled) = LookupPath::new(opctx, datastore)
2262+
.sled_id(my_sled_id)
2263+
.fetch()
2264+
.await
2265+
.context("failed to look up sled")?;
2266+
2267+
rows.push(DownstairsRow {
2268+
host_serial: my_sled.serial_number().to_string(),
2269+
region: region.id().to_string(),
2270+
dataset: dataset.id().to_string(),
2271+
physical_disk: my_zpool.physical_disk_id.to_string(),
2272+
});
2273+
}
2274+
2275+
let table = tabled::Table::new(rows)
2276+
.with(tabled::settings::Style::empty())
2277+
.with(tabled::settings::Padding::new(0, 1, 0, 0))
2278+
.to_string();
2279+
2280+
println!("DESTINATION REGION INFO:");
2281+
println!("{}", table);
2282+
println!("DESTINATION VOLUME VCR:");
2283+
get_and_display_vcr(dest_vol_id.into(), datastore).await?;
2284+
22032285
Ok(())
22042286
}
22052287

0 commit comments

Comments
 (0)