diff --git a/sources/Cargo.lock b/sources/Cargo.lock index ef4ae85ff..b69115f58 100644 --- a/sources/Cargo.lock +++ b/sources/Cargo.lock @@ -2114,6 +2114,7 @@ dependencies = [ "gptman", "hex-literal", "lazy_static", + "pciclient", "signpost", "snafu", ] diff --git a/sources/ghostdog/Cargo.toml b/sources/ghostdog/Cargo.toml index 2722c0a03..2a6ff89de 100644 --- a/sources/ghostdog/Cargo.toml +++ b/sources/ghostdog/Cargo.toml @@ -13,6 +13,7 @@ argh.workspace = true gptman.workspace = true hex-literal.workspace = true lazy_static.workspace = true +pciclient.workspace = true signpost.workspace = true snafu.workspace = true diff --git a/sources/ghostdog/README.md b/sources/ghostdog/README.md index 0f070a9fd..c83f330d5 100644 --- a/sources/ghostdog/README.md +++ b/sources/ghostdog/README.md @@ -4,6 +4,7 @@ Current version: 0.1.0 ghostdog is a tool to manage ephemeral disks. It can be called as a udev helper program to identify ephemeral disks. +It can also be called for EFA device detection which can be used for ExecCondition in systemd units. ## Colophon diff --git a/sources/ghostdog/src/main.rs b/sources/ghostdog/src/main.rs index e1f9c3402..d9636082d 100644 --- a/sources/ghostdog/src/main.rs +++ b/sources/ghostdog/src/main.rs @@ -1,6 +1,7 @@ /*! ghostdog is a tool to manage ephemeral disks. It can be called as a udev helper program to identify ephemeral disks. +It can also be called for EFA device detection which can be used for ExecCondition in systemd units. */ use argh::FromArgs; @@ -10,7 +11,7 @@ use lazy_static::lazy_static; use signpost::uuid_to_guid; use snafu::{ensure, ResultExt}; use std::collections::HashSet; -use std::fs; +use std::{fs, process}; use std::io::{Read, Seek}; use std::path::PathBuf; use std::process::Command; @@ -30,8 +31,14 @@ struct Args { enum SubCommand { Scan(ScanArgs), EbsDeviceName(EbsDeviceNameArgs), + DetectEfaDevice(DetectEfaDeviceArgs), } +#[derive(FromArgs, PartialEq, Debug)] +#[argh(subcommand, name = "detect-efa")] +/// Detect if EFA is attached. +struct DetectEfaDeviceArgs {} + #[derive(FromArgs, PartialEq, Debug)] #[argh(subcommand, name = "scan")] /// Scan a device to see if it is an ephemeral disk. @@ -63,10 +70,21 @@ fn run() -> Result<()> { let device_name = find_device_name(format!("{}", path.display()))?; emit_device_name(&device_name); } + SubCommand::DetectEfaDevice(_) => { + is_efa_attached()?; + } } Ok(()) } +fn is_efa_attached() -> Result<()> { + if pciclient::is_efa_attached().context(error::CheckEfaFailureSnafu)? { + process::exit(0); + } else { + process::exit(1); + } +} + /// Find the device type by examining the partition table, if present. fn find_device_type(reader: &mut R) -> Result where @@ -176,6 +194,8 @@ mod error { }, #[snafu(display("Invalid device info for device '{}'", path.display()))] InvalidDeviceInfo { path: std::path::PathBuf }, + #[snafu(display("Failed to check if EFA device is attached: {}", source))] + CheckEfaFailure { source: pciclient::Error }, } }