diff options
| author | tv <tv@krebsco.de> | 2026-10-21 14:14:15 +0200 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-21 14:14:15 +0200 |
| commit | a2815e3eec7f080ae44e7b43ba697bd0cc13da08 (patch) | |
| tree | 41905cb488f528adfbf0fb9947080b92c22bd56d | |
| parent | c9279e4907ceb3cab2abd3ad6e62d011d7d8a1c2 (diff) | |
let linux signal supervised mycelium when we die
| -rw-r--r-- | src/transport/mycelium.rs | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/src/transport/mycelium.rs b/src/transport/mycelium.rs index d2deebe..9147a5d 100644 --- a/src/transport/mycelium.rs +++ b/src/transport/mycelium.rs @@ -280,15 +280,29 @@ impl SupervisedMycelium { let mut cmd = Command::new("mycelium"); let fds_to_inherit: Vec<i32> = [node_fd, net_fd].iter().filter_map(|&x| x).collect(); - if !fds_to_inherit.is_empty() { - unsafe { - cmd.pre_exec(move || { - for &fd in &fds_to_inherit { - libc::fcntl(fd, libc::F_SETFD, 0); + // The child must never outlive us. An orphaned Mycelium keeps running with our + // key; the next one we start then shares its address, and replies (including + // Mycelium's own message ACKs) go to whichever instance the routers picked, + // leaving our messages pending forever. Drop only runs on a clean shutdown, so + // let the kernel signal the child when we die, however we die. + let parent_pid = std::process::id() as libc::pid_t; + unsafe { + cmd.pre_exec(move || { + for &fd in &fds_to_inherit { + libc::fcntl(fd, libc::F_SETFD, 0); + } + #[cfg(target_os = "linux")] + { + if libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGTERM) != 0 { + return Err(std::io::Error::last_os_error()); } - Ok(()) - }); - } + // We may have died between fork and prctl. + if libc::getppid() != parent_pid { + libc::_exit(1); + } + } + Ok(()) + }); } cmd.arg("--key-file") |
