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:
2026-05-20 14:00:49 +03:00
parent 40ba2caaf6
commit 0834c21607
@@ -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> {