Refactor PCIe device management logic to improve readability and error handling

This commit is contained in:
Edgar P. Burkhart 2025-05-13 21:36:55 +02:00
parent 2e7fe1afd3
commit 4029adc3ff
Signed by: edpibu
GPG key ID: 9833D3C5A25BD227

View file

@ -1,47 +1,56 @@
#![feature(file_buffered)] #![feature(file_buffered)]
#![feature(buf_read_has_data_left)]
use regex::Regex;
use std::fs::File; use std::fs::File;
use std::io::BufRead; use std::io::BufRead;
use std::io::prelude::*; use std::io::Write;
use std::time::Duration;
fn main() { fn main() {
println!("Reading kernel messages..."); println!("Reading kernel messages...");
let re = Regex::new( let kmsg_file =
r"(?P<priority>\d+),(?P<sequence>\d+),(?P<timestamp>\d+),-;igb (?P<id>\d{4}:\d{2}:\d{2}.\d).*: PCIe link lost" File::open_buffered("/dev/kmsg").expect("Failed to open /dev/kmsg");
).unwrap();
let kmsg_file = File::open_buffered("/dev/kmsg").expect("Failed to open /dev/kmsg");
for line in kmsg_file.lines() { let lines = kmsg_file.lines();
if let Ok(line) = line { for line in lines {
let caps = re.captures(line.as_str()); match line {
if let Some(caps) = caps { Err(e) => println!("Error reading line: {e}"),
let timestamp = &caps["timestamp"]; Ok(line) => manage_line(line),
let id = &caps["id"]; }
println!("Resetting {id}"); }
}
let rm_file_path = format!("/sys/bus/pci/devices/{id}/remove"); fn manage_line(line: String) {
let mut rm_file = File::create(&rm_file_path) if let Some((prefix, line)) = line.split_once(";") {
.expect(format!("Failed to open remove file at {rm_file_path}").as_str()); if line.ends_with("PCIe link lost") {
rm_file println!("PCIe link lost {prefix}");
.write_all(b"1")
.expect("Failed to write to remove file");
println!("Removed device {id}");
let mut rescan_file = let id = line.splitn(3, " ").nth(1);
File::create("/sys/bus/pci/rescan").expect("Failed to open rescan file"); if let Some(id) = id {
rescan_file reset_device(id);
.write_all(b"1")
.expect("Failed to write to rescan file");
println!("Rescanned PCI bus");
let time = Duration::from_millis(
timestamp.parse::<u64>().expect("Failed to parse timestamp"),
);
println!("Device {id} reset at {time:#?}");
} }
} }
} }
} }
fn reset_device(id: &str) {
println!("Resetting {id}");
echo1(rm_file_path(&id));
echo1(String::from("/sys/bus/pci/rescan"));
println!("Rescanned PCI bus");
}
fn echo1(path: String) {
let rm_file = File::create(&path);
match rm_file {
Err(e) => println!("Failed to open remove file at {path}: {e}"),
Ok(mut file) => {
file
.write_all(b"1")
.expect("Failed to write to remove file");
println!("Removed device {path}");
}
}
}
fn rm_file_path(id: &str) -> String {
format!("/sys/bus/pci/devices/{id}/remove")
}