diff --git a/fmd-adm/examples/inventory_preview.rs b/fmd-adm/examples/inventory_preview.rs index c945e07..feb8f8c 100644 --- a/fmd-adm/examples/inventory_preview.rs +++ b/fmd-adm/examples/inventory_preview.rs @@ -4,7 +4,7 @@ //! cases are collected with their full event nvlists serialized to JSON, //! and resources are collected with their fault status flags. -use fmd_adm::{FmdAdm, NvList, NvValue}; +use fmd_adm::{FmdAdm, InvisibleResources, NvList, NvValue}; fn nvvalue_to_json(value: &NvValue) -> serde_json::Value { match value { @@ -72,7 +72,9 @@ fn main() { .collect(); // Collect resources — same as omicron's FmdResource - let resources = adm.resources(true).expect("failed to list resources"); + let resources = adm + .resources(InvisibleResources::Included) + .expect("failed to list resources"); let resources_json: Vec = resources .iter() .map(|r| { diff --git a/fmd-adm/examples/list_modules.rs b/fmd-adm/examples/list_modules.rs index d68db56..6c1474a 100644 --- a/fmd-adm/examples/list_modules.rs +++ b/fmd-adm/examples/list_modules.rs @@ -1,4 +1,4 @@ -use fmd_adm::{FmdAdm, NvValue}; +use fmd_adm::{FmdAdm, InvisibleResources, NvValue}; fn main() { let adm = FmdAdm::open().expect("failed to open fmd adm handle"); @@ -17,7 +17,9 @@ fn main() { println!("({} modules total)", modules.len()); println!("\n=== Faulty Resources ==="); - let resources = adm.resources(true).expect("failed to list resources"); + let resources = adm + .resources(InvisibleResources::Included) + .expect("failed to list resources"); if resources.is_empty() { println!(" (none)"); } else { diff --git a/fmd-adm/examples/stats.rs b/fmd-adm/examples/stats.rs index 4df0ed6..6d95c5a 100644 --- a/fmd-adm/examples/stats.rs +++ b/fmd-adm/examples/stats.rs @@ -1,14 +1,18 @@ -use fmd_adm::FmdAdm; +use fmd_adm::{FmdAdm, InvisibleResources}; fn main() { let adm = FmdAdm::open().expect("failed to open fmd adm handle"); // Validate resource_count against resources().len() - let resources = adm.resources(true).expect("failed to list resources"); - let count = adm.resource_count(true).expect("failed to count resources"); + let resources = adm + .resources(InvisibleResources::Included) + .expect("failed to list resources"); + let count = adm + .resource_count(InvisibleResources::Included) + .expect("failed to count resources"); println!("=== Resources ==="); println!( - " resources(all=true).len() = {}, resource_count(all=true) = {}", + " resources(Included).len() = {}, resource_count(Included) = {}", resources.len(), count, ); diff --git a/fmd-adm/src/lib.rs b/fmd-adm/src/lib.rs index 68bde49..7c1077e 100644 --- a/fmd-adm/src/lib.rs +++ b/fmd-adm/src/lib.rs @@ -25,6 +25,27 @@ pub enum Error { Uuid(#[from] uuid::Error), } +/// Whether to include resources flagged as invisible when listing or counting. +/// +/// FMD marks some resources as "invisible" — they exist in the daemon's +/// internal model but aren't exposed to typical administrative tools. Callers +/// usually want only directly-visible resources; pass `Included` to also +/// surface the invisible ones. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum InvisibleResources { + Included, + Excluded, +} + +impl InvisibleResources { + fn as_c_int(self) -> std::os::raw::c_int { + match self { + InvisibleResources::Included => 1, + InvisibleResources::Excluded => 0, + } + } +} + /// A handle to the Fault Management Daemon administrative interface. /// /// This handle wraps a C `fmd_adm_t` pointer that is not thread-safe. @@ -109,8 +130,9 @@ impl FmdAdm { /// Iterate over faulty resources. /// - /// If `all` is true, includes resources that are not directly visible. - pub fn resources(&self, all: bool) -> Result, Error> { + /// `include` controls whether resources flagged as invisible are surfaced + /// alongside directly-visible ones. + pub fn resources(&self, include: InvisibleResources) -> Result, Error> { // Collect raw strings from the callback, then parse UUIDs // afterwards so we can propagate errors. struct RawResourceInfo { @@ -142,7 +164,7 @@ impl FmdAdm { let rc = unsafe { fmd_adm_sys::fmd_adm_rsrc_iter( self.handle, - if all { 1 } else { 0 }, + include.as_c_int(), Some(callback), &mut raw as *mut _ as *mut c_void, ) @@ -166,11 +188,10 @@ impl FmdAdm { } /// Get the count of faulty resources. - pub fn resource_count(&self, all: bool) -> Result { + pub fn resource_count(&self, include: InvisibleResources) -> Result { let mut count: u32 = 0; - let rc = unsafe { - fmd_adm_sys::fmd_adm_rsrc_count(self.handle, if all { 1 } else { 0 }, &mut count) - }; + let rc = + unsafe { fmd_adm_sys::fmd_adm_rsrc_count(self.handle, include.as_c_int(), &mut count) }; if rc != 0 { return Err(Error::Fmd(self.errmsg())); } @@ -616,17 +637,23 @@ mod tests { #[test] fn list_resources() { let adm = FmdAdm::open().expect("failed to open fmd handle"); - let _resources = adm.resources(false).expect("failed to list resources"); - let _all = adm.resources(true).expect("failed to list all resources"); + let _resources = adm + .resources(InvisibleResources::Excluded) + .expect("failed to list resources"); + let _all = adm + .resources(InvisibleResources::Included) + .expect("failed to list all resources"); } #[test] fn resource_count_matches_resources() { let adm = FmdAdm::open().expect("failed to open fmd handle"); let count = adm - .resource_count(false) + .resource_count(InvisibleResources::Excluded) .expect("failed to get resource count"); - let resources = adm.resources(false).expect("failed to list resources"); + let resources = adm + .resources(InvisibleResources::Excluded) + .expect("failed to list resources"); assert_eq!( count as usize, resources.len(),