From 85574c22f103abf456e0bcf3f15a08a940e7c47c Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Wed, 15 Jul 2026 23:27:40 +0900 Subject: [PATCH] daemon: drop cmd before readiness wait so early child exit yields EOF (fix hwd/acpid spawn deadlock) --- daemon/src/lib.rs | 15 ++++++++++++--- drivers/hwd/src/backend/acpi.rs | 8 +++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs index aa7063828c..a97fefd0d1 100644 --- a/daemon/src/lib.rs +++ b/daemon/src/lib.rs @@ -72,19 +72,28 @@ impl Daemon { unsafe { pass_fd(&mut cmd, "INIT_NOTIFY", write_pipe.into()) }; + let desc = format!("{cmd:?}"); if let Err(err) = cmd.spawn() { - eprintln!("daemon: failed to execute {cmd:?}: {err}"); + eprintln!("daemon: failed to execute {desc}: {err}"); return; } + // Release this process's copy of the INIT_NOTIFY write end. pass_fd + // moved it into cmd's pre_exec closure, so while cmd is alive the + // parent keeps the write end open and read_exact below never sees EOF + // if the child exits without notifying readiness — a deadlock (e.g. + // hwd spawning a duplicate acpid that exits early on EEXIST). Dropping + // cmd closes the parent's copy so a child exit yields EOF. + drop(cmd); + let mut data = [0]; match read_pipe.read_exact(&mut data) { Ok(()) => {} Err(err) if err.kind() == io::ErrorKind::UnexpectedEof => { - eprintln!("daemon: {cmd:?} exited without notifying readiness"); + eprintln!("daemon: {desc} exited without notifying readiness"); } Err(err) => { - eprintln!("daemon: failed to wait for {cmd:?}: {err}"); + eprintln!("daemon: failed to wait for {desc}: {err}"); } } } diff --git a/drivers/hwd/src/backend/acpi.rs b/drivers/hwd/src/backend/acpi.rs index 675e2565e1..b3d807f626 100644 --- a/drivers/hwd/src/backend/acpi.rs +++ b/drivers/hwd/src/backend/acpi.rs @@ -27,7 +27,13 @@ impl Backend for AcpiBackend { // no acpid init unit. // TODO: rather than put it in the namespace, have init pass the acpi // handle to hwd, and then pass it to acpid? - if Fd::open("/scheme/acpi", libredox::flag::O_CLOEXEC, 0).is_err() { + if Fd::open( + "/scheme/acpi/symbols", + libredox::flag::O_DIRECTORY | libredox::flag::O_CLOEXEC, + 0, + ) + .is_err() + { #[allow(deprecated, reason = "we can't yet move this to init")] daemon::Daemon::spawn(Command::new("acpid")); }