deb: unmount and remove the ephemeral chroot on Ctrl-C
The SIGINT handler libc::_exit(130)s, skipping EphemeralContextGuard's drop and leaking the freshly bootstrapped chroot with its bind-mounted /proc and overlay mounts. Resources now register a self-contained cleanup hook in a process-global registry that the handler drains right before exiting: the hook unmounts everything under the chroot path (children first, lazy fallback) and removes the tree, using only stored paths and direct umount/rm subprocesses so it cannot deadlock on a lock the interrupted thread may hold; sudo -n keeps it from ever hanging on a password prompt. Drop deregisters the hook first, so the normal cleanup path is unchanged. Also fixes the hex grouping of the CRC-24 polynomial in apt::release.
This commit is contained in:
@@ -563,6 +563,22 @@ extern "C" fn on_sigint(_sig: libc::c_int) {
|
||||
{
|
||||
eprintln!("\nInterrupted — full log: {}", path.display());
|
||||
}
|
||||
// Run the registered cleanup hooks (currently: unmount and remove the
|
||||
// ephemeral build chroot, see `deb::ephemeral::sigint_cleanup_chroot`),
|
||||
// then exit with the conventional 130 status.
|
||||
//
|
||||
// Like the terminal restoration above, this is NOT strictly
|
||||
// async-signal-safe: it locks a mutex, spawns subprocesses and does I/O.
|
||||
// That is a deliberate tradeoff, no worse than the rest of this handler:
|
||||
// exiting immediately would skip all destructors and leak the chroot
|
||||
// together with its bind-mounted /proc and overlay mounts. The hooks are
|
||||
// self-contained (they only touch stored paths and spawn umount/rm
|
||||
// directly), so they cannot deadlock on a lock the interrupted thread
|
||||
// might have held; the hook registry itself is only ever taken with
|
||||
// try_lock plus a bounded retry for the same reason. Note that SIGINT
|
||||
// stays blocked for the duration of the handler, so a second Ctrl-C will
|
||||
// not interrupt a slow cleanup — send SIGTERM/SIGKILL if it ever hangs.
|
||||
crate::deb::ephemeral::run_cleanup_hooks();
|
||||
// SAFETY: raw exit bypassing destructors, intended in a signal handler
|
||||
unsafe {
|
||||
libc::_exit(130);
|
||||
|
||||
Reference in New Issue
Block a user