diff --git a/dev-tools/omdb/src/bin/omdb/sled_agent.rs b/dev-tools/omdb/src/bin/omdb/sled_agent.rs index fcba039ac7..e73f9e4bba 100644 --- a/dev-tools/omdb/src/bin/omdb/sled_agent.rs +++ b/dev-tools/omdb/src/bin/omdb/sled_agent.rs @@ -12,6 +12,8 @@ use anyhow::bail; use clap::Args; use clap::Subcommand; use sled_agent_client::types::ChickenSwitchDestroyOrphanedDatasets; +use sled_agent_client::types::Flow; +use uuid::Uuid; /// Arguments to the "omdb sled-agent" subcommand #[derive(Debug, Args)] @@ -36,6 +38,10 @@ enum SledAgentCommands { #[clap(subcommand)] Zones(ZoneCommands), + /// print information about network interfaces + #[clap(subcommand)] + Nics(NicCommands), + /// print information about the local bootstore node #[clap(subcommand)] Bootstore(BootstoreCommands), @@ -52,6 +58,19 @@ enum ZoneCommands { List, } +#[derive(Debug, Subcommand)] +enum NicCommands { + /// Print list of all known OPTE ports + List, + /// Print all flow stats currently seen on a given OPTE port + Flows(FlowStatsArgs), +} + +#[derive(Debug, Args)] +pub struct FlowStatsArgs { + nic_id: Uuid, +} + #[derive(Debug, Subcommand)] enum BootstoreCommands { /// Show the internal state of the local bootstore node @@ -102,6 +121,12 @@ impl SledAgentArgs { SledAgentCommands::Zones(ZoneCommands::List) => { cmd_zones_list(&client).await } + SledAgentCommands::Nics(NicCommands::List) => { + cmd_nics_list(&client).await + } + SledAgentCommands::Nics(NicCommands::Flows(args)) => { + cmd_nics_flows(&client, args).await + } SledAgentCommands::Bootstore(BootstoreCommands::Status) => { cmd_bootstore_status(&client).await } @@ -151,6 +176,53 @@ async fn cmd_zones_list( Ok(()) } +/// Runs `omdb sled-agent nics list` +async fn cmd_nics_list( + client: &sled_agent_client::Client, +) -> Result<(), anyhow::Error> { + let response = client.nic_ids_list().await.context("listing nics")?; + let nics = response.into_inner(); + + println!("nics:"); + if nics.is_empty() { + println!(" "); + } + for nic in &nics { + println!(" {}", nic); + } + + Ok(()) +} + +/// Runs `omdb sled-agent nics list` +async fn cmd_nics_flows( + client: &sled_agent_client::Client, + FlowStatsArgs { nic_id }: &FlowStatsArgs, +) -> Result<(), anyhow::Error> { + let response = + client.nic_flows_list(nic_id).await.context("listing nics")?; + let flows = response.into_inner(); + + println!("flows:"); + if flows.is_empty() { + println!(" "); + } + for Flow { metadata, in_stat, out_stat } in &flows { + println!(" {} ({}):", metadata.flow_id, metadata.created_at); + println!(" internal key {:?}", metadata.internal_key); + println!(" external key {:?}", metadata.external_key); + println!(" opened on {:?}", metadata.initial_packet); + println!(" forwarded via {:?}", metadata.forwarded); + println!(" allowed in by {:?}", metadata.admitted_by_in); + println!(" allowed out by {:?}", metadata.admitted_by_out); + println!(" in_stats {:?}", in_stat); + println!(" out_stats {:?}", out_stat); + println!("+---------------------+"); + } + + Ok(()) +} + /// Runs `omdb sled-agent bootstore status` async fn cmd_bootstore_status( client: &sled_agent_client::Client, diff --git a/dev-tools/omdb/tests/usage_errors.out b/dev-tools/omdb/tests/usage_errors.out index ddb4b2bba1..5f32b169a4 100644 --- a/dev-tools/omdb/tests/usage_errors.out +++ b/dev-tools/omdb/tests/usage_errors.out @@ -1058,6 +1058,7 @@ Usage: omdb sled-agent [OPTIONS] Commands: zones print information about zones + nics print information about network interfaces bootstore print information about the local bootstore node chicken-switch control "chicken switches" (potentially-destructive sled-agent behavior that can be toggled on or off via `omdb`) diff --git a/illumos-utils/src/opte/stat.rs b/illumos-utils/src/opte/stat.rs index 449c76eac5..76c540a908 100644 --- a/illumos-utils/src/opte/stat.rs +++ b/illumos-utils/src/opte/stat.rs @@ -298,7 +298,6 @@ async fn run_port_stat(state: Arc) { return; } - // TODO: log on error. tokio::select! { _ = flow_collect.tick() => { if let Err(e) = state.collect_flows() {