summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2022-01-27 18:12:12 +0100
committerLeah Neukirchen <leah@vuxu.org>2022-01-27 18:12:12 +0100
commita463eea144b9fceb44280cd3484f59f593aae5b6 (patch)
treeaa13e004caa602f5d1d90f6edf3737c6ae9ffe52
parent0f55856e02b30c9cc41df0c75bccf7f2881cfe93 (diff)
downloadrvnit-a463eea144b9fceb44280cd3484f59f593aae5b6.tar.gz
rvnit-a463eea144b9fceb44280cd3484f59f593aae5b6.tar.xz
rvnit-a463eea144b9fceb44280cd3484f59f593aae5b6.zip
shutdown on SIGTERM unless we are the real pid 1
This is useful as a supervision daemon and inside containers.

Unify signal handling into one function.
-rw-r--r--rvnit.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/rvnit.c b/rvnit.c
index ed6abd2..f7b35de 100644
--- a/rvnit.c
+++ b/rvnit.c
@@ -63,6 +63,7 @@ int newlogfd[2];
 int globallogfd[2];
 
 int pid1;
+int real_pid1;
 int use_global_log;
 
 volatile sig_atomic_t want_shutdown;
@@ -71,19 +72,21 @@ volatile sig_atomic_t want_rescandir;
 volatile sig_atomic_t want_reboot;
 
 void
-on_sigint(int sig)
+on_signal(int sig)
 {
-	(void)sig;
-	want_shutdown = 1;
-	if (pid1)
-		want_reboot = 1;
-}
-
-void
-on_sigcont(int sig)
-{
-	(void)sig;
-	/* do nothing, but interrupt the system call */
+	switch (sig) {
+	case SIGINT:
+		if (real_pid1) /* Linux Ctrl-Alt-Delete */
+			want_reboot = 1;
+		want_shutdown = 1;
+		break;
+	case SIGTERM:
+		want_shutdown = 1;
+		break;
+	case SIGCONT:
+		/* do nothing, but interrupt the system call */
+		break;
+	}
 }
 
 void
@@ -687,11 +690,15 @@ main(int argc, char *argv[])
 
 	LOG("booting");
 
-	pid1 = (getpid() == 1);
+	pid1 = real_pid1 = (getpid() == 1);
 	if (pid1) {
 		setenv("PATH", "/usr/bin:/usr/sbin", 0);
 		init_mount();
 		own_console();
+#ifdef __linux__
+		if (reboot(RB_DISABLE_CAD) < 0)
+			real_pid1 = 0;  /* we are in a container */
+#endif
 	}
 
 	if (pthread_mutex_init(&services_lock, 0) != 0) {
@@ -716,14 +723,13 @@ main(int argc, char *argv[])
 	if (pid1)
 		ioctl(0, TIOCNOTTY);
 
-	sigset_t emptyset;
-	sigemptyset(&emptyset);
-	sigaction(SIGINT,
-	    &(struct sigaction){ .sa_handler=on_sigint, .sa_mask=emptyset }, 0);
-
-#ifdef __linux__
-	reboot(RB_DISABLE_CAD);
-#endif
+	sigaction(SIGINT, &(struct sigaction){
+		    .sa_handler=on_signal, .sa_mask=allset }, 0);
+	if (!real_pid1) {
+		/* keep SIGTERM blocked on Linux for pid 1 by default. */
+		sigaction(SIGTERM, &(struct sigaction){
+			    .sa_handler=on_signal, .sa_mask=allset }, 0);
+	}
 
 	int i;
 	for (level = 0; level < 100 && !want_shutdown; level++) {
@@ -813,7 +819,7 @@ cont1:
 	}
 
 	sigaction(SIGCONT,
-	    &(struct sigaction){ .sa_handler=on_sigcont, .sa_mask=emptyset }, 0);
+	    &(struct sigaction){ .sa_handler=on_signal, .sa_mask=allset }, 0);
 
 	LOG("system up");