Skip to content

Commit 7b7abe2

Browse files
bnaeckerNieuwejaar
authored andcommitted
Move management mode to the QSFP ports, not the transceiver (#1108)
- Moves the management mode subcommands to be directly under `swadm switch-port`, rather than `swadm switch-port transceiver`. - Do not alter the management mode in the transceiver monitoring loop. This ensures that if an operator changes the mode, the loop doesn't change it back when the transceiver is deemed absent. - Fixes #1106
1 parent a91cca3 commit 7b7abe2

File tree

3 files changed

+55
-46
lines changed

3 files changed

+55
-46
lines changed

dpd/src/transceivers/tofino_impl.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,13 +1094,10 @@ impl Switch {
10941094

10951095
// If the module is now absent or faulted, let's reflect that in
10961096
// the switch port's transceiver object.
1097-
//
1098-
// TODO-correctness: This overrides whether a switch port has
1099-
// been disabled. Is that the correct thing to do? It might be
1100-
// better to only do that if the module is now absent.
11011097
if absent.is_set(index).unwrap() {
1102-
port.set_management_mode(ManagementMode::Automatic)
1103-
.unwrap();
1098+
// NOTE: Do not modify the management mode itself, see
1099+
// https://github.com/oxidecomputer/dendrite/issues/1106 for
1100+
// context.
11041101
port.as_qsfp_mut().unwrap().transceiver = None;
11051102
} else if timeout_fault.is_set(index).unwrap() {
11061103
port.as_qsfp_mut().unwrap().transceiver =

swadm/src/main.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::io;
99
use std::str::FromStr;
1010

1111
use anyhow::Context;
12+
use common::ports::QsfpPort;
1213
use structopt::*;
1314

1415
use common::ports::PortId;
@@ -128,6 +129,12 @@ impl FromStr for IpFamily {
128129
}
129130
}
130131

132+
pub fn parse_qsfp_port_id(value: &str) -> Result<QsfpPort, String> {
133+
value.parse().map_err(|_| {
134+
format!("'{}' is invalid; QSFP ports are named qsfp<0-31>", value)
135+
})
136+
}
137+
131138
pub fn parse_port_id(value: &str) -> Result<PortId, String> {
132139
value.parse().map_err(|_| {
133140
format!("'{}' is invalid; valid port-ids include qsfp<0-31>, rear<0-31>, or int0", value)

swadm/src/switchport.rs

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ use colored::*;
1515
use structopt::*;
1616
use tabwriter::TabWriter;
1717

18-
use common::ports::PortId;
18+
use common::ports::{PortId, QsfpPort};
1919
use dpd_client::types::{
2020
self, CmisDatapath, CmisLaneStatus, Sff8636Datapath, SffComplianceCode,
2121
};
2222
use dpd_client::Client;
2323

24-
use crate::parse_port_id;
2524
use crate::LinkPath;
25+
use crate::{parse_port_id, parse_qsfp_port_id};
2626

2727
// Newtype needed to convince `structopt` to parse a list of fields.
2828
#[derive(Clone, Debug)]
@@ -164,6 +164,37 @@ pub enum SwitchPort {
164164
Transceiver(Transceiver),
165165
/// Manage the attention LEDs on the Sidecar QSFP switch ports.
166166
Led(Led),
167+
/// Get the management mode for a switch port's transceiver.
168+
///
169+
/// In most situations, QSFP switch ports are managed automatically, meaning
170+
/// their power is controlled autonomously. The modules will remain in low
171+
/// power until a link is created on them. Modules will also be turned off
172+
/// if they cannot be supported.
173+
///
174+
/// Modules may be turned to manual management mode, which allows the
175+
/// operator to explicitly control their power. The software will not change
176+
/// the power of such a module automatically.
177+
#[structopt(visible_aliases = &["mgmt", "mode"])]
178+
ManagementMode {
179+
/// The QSFP port to operate on.
180+
#[structopt(parse(try_from_str = parse_qsfp_port_id))]
181+
port_id: QsfpPort,
182+
},
183+
/// Set the management mode for a switch port's transceiver.
184+
///
185+
/// See the help for `management-mode` for details.
186+
#[structopt(visible_aliases = &["set-mgmt", "set-mode"])]
187+
SetManagementMode {
188+
/// The QSFP port to operate on.
189+
#[structopt(parse(try_from_str = parse_qsfp_port_id))]
190+
port_id: QsfpPort,
191+
/// The management mode to set the port to.
192+
#[structopt(
193+
possible_values = &["automatic", "auto", "manual"],
194+
parse(try_from_str = parse_management_mode)
195+
)]
196+
mode: types::ManagementMode,
197+
},
167198
/// Return the backplane map.
168199
BackplaneMap {
169200
/// If true, provide parseable ouptut, separated by a `,`.
@@ -222,37 +253,6 @@ pub enum Transceiver {
222253
#[structopt(parse(try_from_str = parse_port_id))]
223254
port_id: PortId,
224255
},
225-
/// Get the management mode for the transceiver.
226-
///
227-
/// In most situations, QSFP switch ports are managed automatically, meaning
228-
/// their power is controlled autonomously. The modules will remain in low
229-
/// power until a link is created on them. Modules will also be turned off
230-
/// if they cannot be supported.
231-
///
232-
/// Modules may be turned to manual management mode, which allows the
233-
/// operator to explicitly control their power. The software will not change
234-
/// the power of such a module automatically.
235-
#[structopt(visible_alias = "mgmt")]
236-
ManagementMode {
237-
/// The QSFP port to operate on.
238-
#[structopt(parse(try_from_str = parse_port_id))]
239-
port_id: PortId,
240-
},
241-
/// Set the management mode for the transceiver.
242-
///
243-
/// See the help for `management-mode` for details.
244-
#[structopt(visible_alias = "set-mgmt")]
245-
SetManagementMode {
246-
/// The QSFP port to operate on.
247-
#[structopt(parse(try_from_str = parse_port_id))]
248-
port_id: PortId,
249-
/// The management mode to set the port to.
250-
#[structopt(
251-
possible_values = &["automatic", "auto", "manual"],
252-
parse(try_from_str = parse_management_mode)
253-
)]
254-
mode: types::ManagementMode,
255-
},
256256
}
257257

258258
fn parse_management_mode(s: &str) -> anyhow::Result<types::ManagementMode> {
@@ -614,13 +614,6 @@ async fn transceivers_cmd(
614614
println!("{:>WIDTH$}: {UNSUPPORTED}", "Aux 3");
615615
}
616616
}
617-
Transceiver::ManagementMode { port_id } => {
618-
let mode = client.management_mode_get(&port_id).await?.into_inner();
619-
println!("{mode:?}");
620-
}
621-
Transceiver::SetManagementMode { port_id, mode } => {
622-
client.management_mode_set(&port_id, mode).await?;
623-
}
624617
Transceiver::Datapath { port_id } => {
625618
let datapath = client
626619
.transceiver_datapath_get(&port_id)
@@ -932,6 +925,18 @@ pub async fn switch_cmd(
932925
}
933926
}
934927
SwitchPort::Transceiver(xcvr) => transceivers_cmd(client, xcvr).await?,
928+
SwitchPort::ManagementMode { port_id } => {
929+
let mode = client
930+
.management_mode_get(&PortId::Qsfp(port_id))
931+
.await?
932+
.into_inner();
933+
println!("{mode:?}");
934+
}
935+
SwitchPort::SetManagementMode { port_id, mode } => {
936+
client
937+
.management_mode_set(&PortId::Qsfp(port_id), mode)
938+
.await?;
939+
}
935940
SwitchPort::Led(led) => led_cmd(client, led).await?,
936941
SwitchPort::BackplaneMap {
937942
parseable,

0 commit comments

Comments
 (0)