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