daemon: drop cmd before readiness wait so early child exit yields EOF (fix hwd/acpid spawn deadlock)
This commit is contained in:
+12
-3
@@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user