udev-shim: Harden rules file write with retry loop
Handle BrokenPipe and AlreadyExists races when writing default udev rules during early boot. Retry up to 3 times with 50ms backoff.
This commit is contained in:
@@ -2,6 +2,8 @@ use std::fs;
|
||||
use std::io;
|
||||
use std::os::unix::fs::symlink;
|
||||
use std::path::Path;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
const DEFAULT_UDEV_RULES: &str = r#"# Network interface naming
|
||||
SUBSYSTEM=="net", KERNEL=="enp*", NAME="$kernel"
|
||||
@@ -74,8 +76,26 @@ pub fn write_default_rules_file() -> io::Result<&'static str> {
|
||||
fs::create_dir_all(dir)?;
|
||||
|
||||
let path = dir.join("50-default.rules");
|
||||
fs::write(&path, default_udev_rules())?;
|
||||
Ok("/etc/udev/rules.d/50-default.rules")
|
||||
let contents = default_udev_rules();
|
||||
|
||||
if fs::metadata(&path).is_ok() {
|
||||
let _ = fs::remove_file(&path);
|
||||
}
|
||||
|
||||
for attempt in 0..3 {
|
||||
match fs::write(&path, contents) {
|
||||
Ok(()) => return Ok("/etc/udev/rules.d/50-default.rules"),
|
||||
Err(e) if e.kind() == io::ErrorKind::BrokenPipe && attempt < 2 => {
|
||||
thread::sleep(Duration::from_millis(50));
|
||||
}
|
||||
Err(e) if e.kind() == io::ErrorKind::AlreadyExists => {
|
||||
return Ok("/etc/udev/rules.d/50-default.rules");
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
unreachable!("write_default_rules_file loop always returns or errors")
|
||||
}
|
||||
|
||||
fn parse_hex_byte(value: &str) -> Option<u8> {
|
||||
|
||||
Reference in New Issue
Block a user