Refactor PCIe device management logic to improve readability and error handling
This commit is contained in:
parent
2e7fe1afd3
commit
4029adc3ff
1 changed files with 42 additions and 33 deletions
75
src/main.rs
75
src/main.rs
|
@ -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")
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue