From b7004e85d80ae7bb3deea0c09bfb06aa48b674c9 Mon Sep 17 00:00:00 2001 From: "Rivas Paz, Jose L" Date: Fri, 21 Aug 2026 11:16:00 +0200 Subject: [PATCH] lib: introduce `rearm` control command This patch includes support for the `rearm` Crash Log control command. This command rearms the Crash Log trigger, it can be used for any Crash Log source that supports that capability, and can be called from the CLI: $ iclg rearm Signed-off-by: Rivas Paz, Jose L --- README.md | 28 ++++++++++++++++++++-------- app/src/control.rs | 4 ++++ app/src/main.rs | 6 ++++++ lib/src/source.rs | 9 +++++++++ lib/src/source/capability.rs | 3 +++ lib/src/source/pmt.rs | 13 +++++++++++++ lib/src/source/pmt/sysfs.rs | 31 ++++++++++++++++++++++++++++++- 7 files changed, 85 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e66102c..c8a072c 100644 --- a/README.md +++ b/README.md @@ -135,14 +135,15 @@ $ iclg extract -s acpi,pmt:crashlog0 ``` - **List** all available Crash Log sources in the platform. Each source -supports different capabilities like `extract`, `trigger`, or `enable/disable`. +supports different capabilities like `extract`, `trigger`, `enable/disable`, +or `rearm`. ```console $ iclg list Source Description Capabilities -------------- ---------------------- --------------------------------- +------------- ---------------------- --------------------------------------- acpi ACPI BERT extract -pmt:crashlog0 PMT endpoint crashlog0 extract, trigger, enable/disable +pmt:crashlog0 PMT endpoint crashlog0 extract, trigger, enable/disable, rearm ``` - **Trigger** a Crash Log collection on-demand. Like the `extract` command, @@ -153,6 +154,16 @@ command is only supported on Linux. $ iclg trigger ``` +- **Rearm** a Crash Log trigger. A source can trigger a Crash Log collection +only once per reset cycle; after a collection has been captured, the source +must be reset and rearmed before it will trigger again. Like the `trigger` +command, you can specify individual sources or rearm all sources by default. +This command is only supported on Linux. + +```console +$ iclg rearm +``` + - **Enable** or **Disable** the Crash Log collection in the platform. Individual sources can be specified in the CLI as well. These commands are only supported on Linux. @@ -189,18 +200,19 @@ $ iclg decode sample.crashlog $ iclg --help Extract and decode Intel Crash Log records. -Usage: iclg [OPTIONS] [COMMAND] +Usage: iclg [OPTIONS] Commands: - enable Enable the Crash Log collection in the platform + enable Enable Crash Log collection in the platform extract Extract the Crash Log records from the platform decode Decode Crash Log records into JSON - disable Disable the Crash Log collection in the platform + disable Disable Crash Log collection in the platform info List the Crash Log records stored in the input file - list List the Crash Log sources that are present in the platform + list List the Crash Log sources that are available in the platform + rearm Rearm a Crash Log trigger in the platform + trigger Trigger an on-demand Crash Log collection in the platform unpack Unpack the Crash Log records stored in the input file triage Triage the Crash Log records stored in the input files - trigger Trigger an on-demand collection of Crash Log in the platform help Print this message or the help of the given subcommand(s) Options: diff --git a/app/src/control.rs b/app/src/control.rs index b092fae..0967408 100644 --- a/app/src/control.rs +++ b/app/src/control.rs @@ -3,6 +3,10 @@ use intel_crashlog::prelude::*; +pub fn rearm(sources: Vec) -> Result<(), Error> { + control_command(sources, CrashLogSource::rearm) +} + pub fn trigger(sources: Vec) -> Result<(), Error> { control_command(sources, CrashLogSource::trigger) } diff --git a/app/src/main.rs b/app/src/main.rs index 1d732f4..a5be611 100644 --- a/app/src/main.rs +++ b/app/src/main.rs @@ -67,6 +67,11 @@ enum Command { }, /// List the Crash Log sources that are available in the platform with their capabilities List, + /// Rearm a Crash Log trigger in the platform + Rearm { + #[arg(short, long, value_delimiter = ',')] + sources: Vec, + }, /// Trigger an on-demand Crash Log collection in the platform Trigger { #[arg(short, long, value_delimiter = ',')] @@ -100,6 +105,7 @@ impl Command { format, } => info::info(&cm, input_files, *format), Command::List => list::list(), + Command::Rearm { sources } => control::rearm(sources.clone())?, Command::Trigger { sources } => control::trigger(sources.clone())?, Command::Clear { sources } => control::clear(sources.clone())?, Command::Unpack { input_files } => { diff --git a/lib/src/source.rs b/lib/src/source.rs index d2b1bf0..ab1c9f9 100644 --- a/lib/src/source.rs +++ b/lib/src/source.rs @@ -182,6 +182,15 @@ impl CrashLogSource { } } + /// Rearms a Crash Log trigger on this source + #[cfg(feature = "control_commands")] + pub fn rearm(&self) -> Result<(), Error> { + match self { + Self::PmtDevice(dev) => Pmt::default().rearm(dev), + _ => Err(Error::Unsupported), + } + } + /// Clears the Crash Log storage on this source #[cfg(feature = "control_commands")] pub fn clear(&self) -> Result<(), Error> { diff --git a/lib/src/source/capability.rs b/lib/src/source/capability.rs index 3423644..4bc95d0 100644 --- a/lib/src/source/capability.rs +++ b/lib/src/source/capability.rs @@ -17,6 +17,8 @@ pub enum Capability { EnableDisable, /// Clearing of the Crash Log storage Clear, + /// Rearming of the Crash Log trigger + Rearm, } impl fmt::Display for Capability { @@ -26,6 +28,7 @@ impl fmt::Display for Capability { Self::Trigger => write!(f, "trigger"), Self::EnableDisable => write!(f, "enable/disable"), Self::Clear => write!(f, "clear"), + Self::Rearm => write!(f, "rearm"), } } } diff --git a/lib/src/source/pmt.rs b/lib/src/source/pmt.rs index f25c623..cc4ea9f 100644 --- a/lib/src/source/pmt.rs +++ b/lib/src/source/pmt.rs @@ -111,6 +111,19 @@ impl Pmt { Err(Error::Unsupported) } + #[cfg(all(target_os = "linux", feature = "control_commands"))] + pub fn rearm(&self, dev: &PmtDeviceId) -> Result<(), Error> { + for endpoint in self.sysfs.get_endpoints(dev) { + endpoint.rearm()?; + } + Ok(()) + } + + #[cfg(all(not(target_os = "linux"), feature = "control_commands"))] + pub fn rearm(&self, _dev: &PmtDeviceId) -> Result<(), Error> { + Err(Error::Unsupported) + } + #[cfg(all(target_os = "linux", feature = "control_commands"))] pub fn trigger(&self, dev: &PmtDeviceId) -> Result<(), Error> { for endpoint in self.sysfs.get_endpoints(dev) { diff --git a/lib/src/source/pmt/sysfs.rs b/lib/src/source/pmt/sysfs.rs index 96111b8..3dceff7 100644 --- a/lib/src/source/pmt/sysfs.rs +++ b/lib/src/source/pmt/sysfs.rs @@ -248,6 +248,11 @@ impl PmtSysFsEndpoint { self.write_command("trigger", b"1") } + #[cfg(feature = "control_commands")] + pub fn rearm(&self) -> Result<(), Error> { + self.write_command("rearm", b"1") + } + #[cfg(feature = "control_commands")] pub fn clear(&self) -> Result<(), Error> { self.write_command("clear", b"1") @@ -295,6 +300,10 @@ impl PmtSysFsEndpoint { capabilities.insert(Capability::Clear); } + if self.path.join("rearm").exists() { + capabilities.insert(Capability::Rearm); + } + capabilities } @@ -435,6 +444,21 @@ mod tests { assert_eq!(&std::fs::read_to_string(&path).unwrap(), "1"); } + #[test] + fn rearm() { + let root = tempfile::tempdir().unwrap(); + + let dev = PmtSysFsEndpoint::new(root.path()).unwrap(); + assert!(matches!(dev.rearm(), Err(Error::IOError(_)))); + + let mut path = root.path().to_owned(); + path.push("rearm"); + std::fs::write(&path, b"0").unwrap(); + + dev.rearm().unwrap(); + assert_eq!(&std::fs::read_to_string(&path).unwrap(), "1"); + } + #[test] fn enable_disable() { let root = tempfile::tempdir().unwrap(); @@ -475,13 +499,18 @@ mod tests { trigger_path.push("trigger"); std::fs::create_dir(&trigger_path).unwrap(); + let mut rearm_path = dev_path.to_owned(); + rearm_path.push("rearm"); + std::fs::create_dir(&rearm_path).unwrap(); + let devices = sysfs.discover(); let dev = sysfs.get_endpoints(&devices[0]); let dev_capabilities = dev[0].capabilities(); - assert_eq!(dev_capabilities.len(), 2); + assert_eq!(dev_capabilities.len(), 3); assert!(dev_capabilities.contains(&Capability::Extract)); assert!(dev_capabilities.contains(&Capability::Trigger)); + assert!(dev_capabilities.contains(&Capability::Rearm)); } #[test]