]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
More predictable signal handling
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 13 May 2024 15:45:07 +0000 (09:45 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 13 May 2024 15:45:07 +0000 (09:45 -0600)
src/bin/radiusd.c
src/lib/io/schedule.c

index 8c7270d9262e270d6a1422c564a80cf67293d092..903d40a4e5c20102b67a04737e668f14d1fb2628 100644 (file)
@@ -901,7 +901,10 @@ int main(int argc, char *argv[])
         *  what to do, so we might as well do the default, and die.
         */
 #ifdef SIGPIPE
-       signal(SIGPIPE, SIG_IGN);
+       if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
+               ERROR("Failed ignoring SIGPIPE: %s", fr_syserror(errno));
+               goto cleanup;
+       }
 #endif
 
        if (fr_set_signal(SIGHUP, sig_hup) < 0) goto set_signal_error;
@@ -988,7 +991,10 @@ int main(int argc, char *argv[])
        /*
         *  Ignore the TERM signal: we're about to die.
         */
-       signal(SIGTERM, SIG_IGN);
+       if (unlikely(signal(SIGTERM, SIG_IGN) == SIG_ERR)) {
+               ERROR("Failed blocking SIGTERM, we may receive spurious signals: %s",
+                     fr_syserror(errno));
+       }
 
        /*
         *  Unprotect global memory
@@ -1060,20 +1066,8 @@ int main(int argc, char *argv[])
         *  processes created by the exec code or triggers.
         */
        if (config->spawn_workers) {
-               sigset_t mask;
-
                INFO("All threads have exited, sending SIGTERM to remaining children");
 
-               /*
-                *      If we believe the POSIX documentation, sending
-                *      a kill to a negative PGID could also signal us,
-                *      so block the signal first, we're already exiting,
-                *      so it doesn't matter if we don't get the signal.
-                */
-               sigemptyset(&mask);
-               sigaddset(&mask, SIGTERM);
-               sigprocmask(SIG_BLOCK, &mask, NULL);
-
                /*
                 *      If pid is negative, but not -1, sig
                 *      shall be sent to all processes
index eb4ec47bf0228a87b36c1f8c69b6d8e8f919a280..abdbe8cbf8ddec10f5476dc3650fc810a8964886 100644 (file)
@@ -172,6 +172,16 @@ static void *fr_schedule_worker_thread(void *arg)
        fr_schedule_child_status_t      status = FR_CHILD_FAIL;
        fr_schedule_network_t           *sn;
        char                            worker_name[32];
+       sigset_t                        sigset;
+
+       sigfillset(&sigset);
+
+       /*
+        *      Ensure workers aren't interrupted by signals.
+        *      The main thread, and main event loop are mostly
+        *      idle, so they can handle signals.
+        */
+       pthread_sigmask(SIG_BLOCK, &sigset, NULL);
 
        worker_id = sw->id;             /* Store the current worker ID */
 
@@ -293,6 +303,16 @@ static void *fr_schedule_network_thread(void *arg)
        fr_schedule_child_status_t      status = FR_CHILD_FAIL;
        fr_event_list_t                 *el;
        char                            network_name[32];
+       sigset_t                        sigset;
+
+       sigfillset(&sigset);
+
+       /*
+        *      Ensure network threads aren't interrupted by
+        *      signals. The main thread, and main event loop
+        *      are mostly idle, so they can handle signals.
+        */
+       pthread_sigmask(SIG_BLOCK, &sigset, NULL);
 
        snprintf(network_name, sizeof(network_name), "Network %d", sn->id);