From dcda127465bd1f775b131eae09228ec9782f7792 Mon Sep 17 00:00:00 2001 From: mrkmntal Date: Fri, 28 Aug 2026 18:02:05 -0400 Subject: [PATCH] tuxreaperd: send SIGWINCH instead of SIGTERM to Apache (apache2/httpd) --- DEVLOG.md | 3 +- README.md | 2 +- tuxreaperdasm.c | 261 +++++++++++++++++++++++++++++++++++++++++--- tuxreaperdgnu.c | 81 +++++++++++++- tuxreaperdpromo.jpg | Bin 0 -> 26961 bytes 5 files changed, 323 insertions(+), 24 deletions(-) create mode 100644 tuxreaperdpromo.jpg diff --git a/DEVLOG.md b/DEVLOG.md index a7426ca..d2bc0c4 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -10,7 +10,8 @@ This release introduces `tuxreaperd`, a micro init system for containers. - `tuxreaperdgnu.c`: the original standard POSIX/libc daemon used as PID 1 inside containers created by tux-dock. - `tuxreaperdasm.c`: a new freestanding `-nostdlib` syscall engine for `x86_64` and `aarch64` with a tiny static footprint. - Both run as subreapers (`PR_SET_CHILD_SUBREAPER`) with a SIGCHLD handler that reaps every reparented/terminated descendant, so orphaned processes never accumulate as zombies. -- Both forward SIGTERM/SIGINT/SIGHUP to the primary workload and propagate its exit status (128 + signal for signal deaths). +- Both proxy lifecycle signals (SIGTERM, SIGQUIT, SIGINT, SIGHUP, SIGUSR1, SIGUSR2) to the child process tree and propagate the primary workload's exit status (128 + signal for signal deaths). +- Special-cases Apache's questionable use of `SIGWINCH` for graceful shutdown: when `SIGTERM` is received, any process whose `/proc//exe` is `/usr/sbin/apache2`, `/usr/sbin/httpd`, or `/usr/local/apache2/bin/httpd` gets `SIGWINCH` instead, while every other process receives `SIGTERM`. - `compile.sh` detects the host architecture and builds the freestanding implementation when possible, falling back to `tuxreaperdgnu.c` on failure or unsupported hosts. - `DockerManager::createContainer` bind-mounts `tuxreaperd` into the container as PID 1 and resolves the binary next to the `tux-dock` executable when it is not in the current directory. diff --git a/README.md b/README.md index 1c2a6cb..00260ad 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ It gives you a guided, keyboard-first TUI for common Docker operations without m - Direct `fork`/`exec` process execution for CLI-backed streaming and interactive commands. - Persistent container listings that retain exited containers. - Robust stop handling with state polling, timeout retry, and idempotent stop responses. -- `tuxreaperd` micro init system: a tiny statically-linked C daemon mounted into created containers as PID 1, acting as a subreaper so orphaned processes never linger as zombies, forwarding signals, and propagating exit status. +- `tuxreaperd` micro init system: a tiny statically-linked C daemon mounted into created containers as PID 1, acting as a subreaper so orphaned processes never linger as zombies, broadcasting lifecycle signals (SIGTERM, SIGQUIT, SIGINT, SIGHUP, SIGUSR1, SIGUSR2) to the whole process tree via `kill(-1, sig)`, and propagating exit status. [Processes don't fear tuxreaperd!](tuxreaperdpromo.jpg) - About screen in-app with project/version/repository info. --- diff --git a/tuxreaperdasm.c b/tuxreaperdasm.c index 5f8c17e..1ec5b9b 100644 --- a/tuxreaperdasm.c +++ b/tuxreaperdasm.c @@ -5,6 +5,14 @@ struct k_sigaction { unsigned long mask; }; +#if defined(__x86_64__) +#define SA_RESTORER_FLAG 0x04000000UL +void restore_rt(void); +#elif defined(__aarch64__) +#define SA_RESTORER_FLAG 0UL +#define restore_rt ((void (*)(void))0) +#endif + #if defined(__x86_64__) static inline long sys_write(int fd, const void *buf, long n) { @@ -125,6 +133,51 @@ static inline long sys_rt_sigsuspend(const unsigned long *mask, unsigned long si return ret; } +static inline long sys_openat(int dirfd, const char *path, int flags, int mode) { + long ret; + register long r10 __asm__("r10") = mode; + __asm__ volatile ( + "syscall" + : "=a"(ret) + : "a"(257), "D"((long)dirfd), "S"(path), "d"(flags), "r"(r10) + : "rcx", "r11", "memory" + ); + return ret; +} + +static inline long sys_getdents64(int fd, void *dirp, unsigned int count) { + long ret; + __asm__ volatile ( + "syscall" + : "=a"(ret) + : "a"(217), "D"((long)fd), "S"(dirp), "d"(count) + : "rcx", "r11", "memory" + ); + return ret; +} + +static inline long sys_readlink(const char *path, char *buf, long bufsiz) { + long ret; + __asm__ volatile ( + "syscall" + : "=a"(ret) + : "a"(89), "D"(path), "S"(buf), "d"(bufsiz) + : "rcx", "r11", "memory" + ); + return ret; +} + +static inline long sys_close(int fd) { + long ret; + __asm__ volatile ( + "syscall" + : "=a"(ret) + : "a"(3), "D"((long)fd) + : "rcx", "r11", "memory" + ); + return ret; +} + __asm__( ".text\n" ".globl restore_rt\n" @@ -299,13 +352,62 @@ static inline long sys_rt_sigsuspend(const unsigned long *mask, unsigned long si return x0; } -__asm__( - ".text\n" - ".globl restore_rt\n" - "restore_rt:\n" - " mov x8, #139\n" - " svc #0\n" -); +static inline long sys_openat(int dirfd, const char *path, int flags, int mode) { + register long x8 __asm__("x8") = 56; + register long x0 __asm__("x0") = dirfd; + register long x1 __asm__("x1") = (long)path; + register long x2 __asm__("x2") = flags; + register long x3 __asm__("x3") = mode; + __asm__ volatile ( + "svc #0" + : "+r"(x0) + : "r"(x8), "r"(x1), "r"(x2), "r"(x3) + : "memory", "cc" + ); + return x0; +} + +static inline long sys_getdents64(int fd, void *dirp, unsigned int count) { + register long x8 __asm__("x8") = 61; + register long x0 __asm__("x0") = fd; + register long x1 __asm__("x1") = (long)dirp; + register long x2 __asm__("x2") = count; + __asm__ volatile ( + "svc #0" + : "+r"(x0) + : "r"(x8), "r"(x1), "r"(x2) + : "memory", "cc" + ); + return x0; +} + +static inline long sys_readlink(const char *path, char *buf, long bufsiz) { + /* AArch64 has no plain readlink syscall; readlinkat is the ABI. */ + register long x8 __asm__("x8") = 78; /* __NR_readlinkat */ + register long x0 __asm__("x0") = -100; /* AT_FDCWD */ + register long x1 __asm__("x1") = (long)path; + register long x2 __asm__("x2") = (long)buf; + register long x3 __asm__("x3") = bufsiz; + __asm__ volatile ( + "svc #0" + : "+r"(x0) + : "r"(x8), "r"(x1), "r"(x2), "r"(x3) + : "memory", "cc" + ); + return x0; +} + +static inline long sys_close(int fd) { + register long x8 __asm__("x8") = 57; + register long x0 __asm__("x0") = fd; + __asm__ volatile ( + "svc #0" + : "+r"(x0) + : "r"(x8) + : "memory", "cc" + ); + return x0; +} __asm__( ".text\n" @@ -398,14 +500,120 @@ static void my_execvp(const char *file, char *const argv[], char *const envp[]) } } +/* Apache hijacks SIGWINCH (window resize) for graceful shutdown. Yes, + really. So when the outside world sends SIGTERM, we have to translate + it to SIGWINCH for anything whose /proc//exe smells like apache2. + This is insane, but Apache is a good web server so I give it a pass. */ +static const char * const apache_exes[] = { + "/usr/sbin/apache2", + "/usr/sbin/httpd", + "/usr/local/apache2/bin/httpd", + 0 +}; +#define APACHE_IN_SIG 15 /* SIGTERM */ +#define APACHE_OUT_SIG 28 /* SIGWINCH */ + +#define AT_FDCWD -100 +#define O_RDONLY 0 +#define O_DIRECTORY 00200000 + +struct linux_dirent64 { + unsigned long long d_ino; + long long d_off; + unsigned short d_reclen; + unsigned char d_type; + char d_name[]; +}; + +static int my_strcmp(const char *a, const char *b) { + while (*a && (*a == *b)) { + a++; + b++; + } + return (unsigned char)*a - (unsigned char)*b; +} + +static int is_digit(char c) { + return c >= '0' && c <= '9'; +} + +static long parse_pid(const char *s) { + long pid = 0; + while (*s) { + if (!is_digit(*s)) return -1; + pid = pid * 10 + (*s - '0'); + s++; + } + return pid; +} + +/* Iterate /proc, read each process's /proc//exe symlink, and send + out_sig to matching process groups while sending in_sig to everyone + else. Skip PID 1 (the reaper itself). */ +static void proc_remap_signal(int in_sig, int out_sig, const char *const *target_exes) { + int procfd = (int)sys_openat(AT_FDCWD, "/proc", O_RDONLY | O_DIRECTORY, 0); + if (procfd < 0) return; + + char dirbuf[4096]; + + for (;;) { + long n = sys_getdents64(procfd, dirbuf, sizeof(dirbuf)); + if (n <= 0) break; + + for (long pos = 0; pos < n;) { + struct linux_dirent64 *de = (struct linux_dirent64 *)(dirbuf + pos); + pos += de->d_reclen; + + const char *name = de->d_name; + if (name[0] == '.') continue; + + long pid = parse_pid(name); + if (pid <= 1) continue; + + char path[32]; + char *p = path; + const char *prefix = "/proc/"; + for (long i = 0; prefix[i]; i++) *p++ = prefix[i]; + const char *np = name; + while (*np) *p++ = *np++; + const char *suffix = "/exe"; + for (long i = 0; suffix[i]; i++) *p++ = suffix[i]; + *p = '\0'; + + char linkbuf[256]; + long linklen = sys_readlink(path, linkbuf, sizeof(linkbuf) - 1); + if (linklen <= 0) continue; + linkbuf[linklen] = '\0'; + + int matched = 0; + for (int i = 0; target_exes[i]; i++) { + long target_len = my_strlen(target_exes[i]); + if (linklen == target_len && my_strcmp(linkbuf, target_exes[i]) == 0) { + matched = 1; + break; + } + } + + if (matched) { + sys_kill(pid, out_sig); + } else { + sys_kill(pid, in_sig); + } + } + } + + sys_close(procfd); +} + static volatile long g_main_child = 0; static volatile int g_child_exited = 0; static volatile int g_main_status = 0; +static volatile int g_pending_signal = 0; -static void forward_sig(int sig) { - if (g_main_child > 0) { - sys_kill(g_main_child, sig); - } +static void proxy_sig_handler(int sig) { + /* Just record the signal; the main loop does the /proc scan so we + stay async-signal-safe here. */ + g_pending_signal = sig; } static void sigchld_handler(int sig) { @@ -426,8 +634,6 @@ static void sigchld_handler(int sig) { #define WIFSIGNALED(s) ((((s) & 0x7f) != 0) && (((s) & 0x7f) != 0x7f)) #define WTERMSIG(s) ((s) & 0x7f) -void restore_rt(void); - int main(int argc, char **argv, char **envp) { if (argc < 2) { static const char usage[] = "Usage: tuxreaperd [args...]\n"; @@ -443,22 +649,30 @@ int main(int argc, char **argv, char **envp) { struct k_sigaction sa; sa.handler = sigchld_handler; - sa.flags = 0x10000000 /* SA_RESTART */ | 1 /* SA_NOCLDSTOP */ | 0x04000000 /* SA_RESTORER */; + sa.flags = 0x10000000 /* SA_RESTART */ | 1 /* SA_NOCLDSTOP */ | SA_RESTORER_FLAG; sa.restorer = restore_rt; sa.mask = 0; sys_rt_sigaction(17 /* SIGCHLD */, &sa, 0, sizeof(sa.mask)); - sa.handler = forward_sig; - sa.flags = 0x10000000 /* SA_RESTART */ | 0x04000000 /* SA_RESTORER */; + sa.handler = proxy_sig_handler; + sa.flags = 0x10000000 /* SA_RESTART */ | SA_RESTORER_FLAG; sa.restorer = restore_rt; sa.mask = 0; sys_rt_sigaction(15 /* SIGTERM */, &sa, 0, sizeof(sa.mask)); + sys_rt_sigaction(3 /* SIGQUIT */, &sa, 0, sizeof(sa.mask)); sys_rt_sigaction(2 /* SIGINT */, &sa, 0, sizeof(sa.mask)); sys_rt_sigaction(1 /* SIGHUP */, &sa, 0, sizeof(sa.mask)); + sys_rt_sigaction(10 /* SIGUSR1 */, &sa, 0, sizeof(sa.mask)); + sys_rt_sigaction(12 /* SIGUSR2 */, &sa, 0, sizeof(sa.mask)); unsigned long block_mask = - (1UL << (17 - 1)) | (1UL << (15 - 1)) | - (1UL << (2 - 1)) | (1UL << (1 - 1)); + (1UL << (17 - 1)) | /* SIGCHLD */ + (1UL << (15 - 1)) | /* SIGTERM */ + (1UL << (3 - 1)) | /* SIGQUIT */ + (1UL << (2 - 1)) | /* SIGINT */ + (1UL << (1 - 1)) | /* SIGHUP */ + (1UL << (10 - 1)) | /* SIGUSR1 */ + (1UL << (12 - 1)); /* SIGUSR2 */ unsigned long old_mask; sys_rt_sigprocmask(0 /* SIG_BLOCK */, &block_mask, &old_mask, sizeof(block_mask)); @@ -473,6 +687,17 @@ int main(int argc, char **argv, char **envp) { while (!g_child_exited) { sys_rt_sigsuspend(&old_mask, sizeof(old_mask)); + + if (g_pending_signal != 0) { + int sig = g_pending_signal; + g_pending_signal = 0; + if (sig == APACHE_IN_SIG) { + proc_remap_signal(APACHE_IN_SIG, APACHE_OUT_SIG, apache_exes); + } else { + /* Unmapped signals get the old broadcast treatment. */ + sys_kill(-1, sig); + } + } } int status; diff --git a/tuxreaperdgnu.c b/tuxreaperdgnu.c index 1f8b715..68ef093 100644 --- a/tuxreaperdgnu.c +++ b/tuxreaperdgnu.c @@ -1,15 +1,31 @@ #define _GNU_SOURCE #include #include +#include #include #include #include #include +#include #include +/* Apache hijacks SIGWINCH (window resize) for graceful shutdown. Yes, + really. So when the outside world sends SIGTERM, we have to translate + it to SIGWINCH for anything whose /proc//exe smells like apache2. + This is insane, but Apache is a good web server so I give it a pass. */ +static const char * const apache_exes[] = { + "/usr/sbin/apache2", + "/usr/sbin/httpd", + "/usr/local/apache2/bin/httpd", + 0 +}; +#define APACHE_IN_SIG SIGTERM +#define APACHE_OUT_SIG SIGWINCH + static volatile pid_t g_main_child = 0; static volatile sig_atomic_t g_child_exited = 0; static volatile int g_main_status = 0; +static volatile sig_atomic_t g_pending_signal = 0; static void sigchld_handler(int sig) { (void)sig; @@ -25,10 +41,50 @@ static void sigchld_handler(int sig) { } } -static void forward_signal(int sig) { - if (g_main_child > 0) { - kill(g_main_child, sig); +static void proxy_signal_handler(int sig) { + // Just record the signal; the main loop does the /proc scan so we + // stay async-signal-safe here. + g_pending_signal = sig; +} + +static void proc_remap_signal(int in_sig, int out_sig, const char *const *target_exes) { + DIR *proc = opendir("/proc"); + if (!proc) return; + + struct dirent *de; + + while ((de = readdir(proc)) != NULL) { + if (de->d_name[0] == '.') continue; + + char *endptr; + long pid = strtol(de->d_name, &endptr, 10); + if (*endptr != '\0' || pid <= 1) continue; + + char path[64]; + snprintf(path, sizeof(path), "/proc/%ld/exe", pid); + + char linkbuf[256]; + ssize_t linklen = readlink(path, linkbuf, sizeof(linkbuf) - 1); + if (linklen <= 0) continue; + linkbuf[linklen] = '\0'; + + int matched = 0; + for (int i = 0; target_exes[i]; i++) { + size_t target_len = strlen(target_exes[i]); + if ((size_t)linklen == target_len && strcmp(linkbuf, target_exes[i]) == 0) { + matched = 1; + break; + } + } + + if (matched) { + kill(pid, out_sig); + } else { + kill(pid, in_sig); + } } + + closedir(proc); } int main(int argc, char *argv[]) { @@ -45,12 +101,15 @@ int main(int argc, char *argv[]) { // Set up signal forwarding struct sigaction sa_forward; - sa_forward.sa_handler = forward_signal; + sa_forward.sa_handler = proxy_signal_handler; sigemptyset(&sa_forward.sa_mask); sa_forward.sa_flags = SA_RESTART; sigaction(SIGTERM, &sa_forward, NULL); + sigaction(SIGQUIT, &sa_forward, NULL); sigaction(SIGINT, &sa_forward, NULL); sigaction(SIGHUP, &sa_forward, NULL); + sigaction(SIGUSR1, &sa_forward, NULL); + sigaction(SIGUSR2, &sa_forward, NULL); // Set up SIGCHLD reaper handler struct sigaction sa_chld; @@ -64,8 +123,11 @@ int main(int argc, char *argv[]) { sigemptyset(&block_mask); sigaddset(&block_mask, SIGCHLD); sigaddset(&block_mask, SIGTERM); + sigaddset(&block_mask, SIGQUIT); sigaddset(&block_mask, SIGINT); sigaddset(&block_mask, SIGHUP); + sigaddset(&block_mask, SIGUSR1); + sigaddset(&block_mask, SIGUSR2); sigprocmask(SIG_BLOCK, &block_mask, &old_mask); // Spawn the primary workload @@ -85,6 +147,17 @@ int main(int argc, char *argv[]) { // Block until the primary process exits while (!g_child_exited) { sigsuspend(&old_mask); + + if (g_pending_signal != 0) { + int sig = g_pending_signal; + g_pending_signal = 0; + if (sig == APACHE_IN_SIG) { + proc_remap_signal(APACHE_IN_SIG, APACHE_OUT_SIG, apache_exes); + } else { + // Unmapped signals get the old broadcast treatment. + kill(-1, sig); + } + } } // Final sweep of any remaining lingering zombies diff --git a/tuxreaperdpromo.jpg b/tuxreaperdpromo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..adfc6b25257a275dbbababfda0e432e5c98518af GIT binary patch literal 26961 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 HKP>(ags#?} literal 0 HcmV?d00001