# HG changeset patch # User Kim Alvefur # Date 1709382204 -3600 # Node ID 69faf3552d524777e1fbbb6afa76a3a41acaf5c0 # Parent 4a9a6965972757370de9845b25ad98db8fe38609 mod_posix: Move POSIX signal handling into util.startup to avoid race When libunbound is initialized, it spawns a thread to work in. In case a module initializes libunbound, e.g. by triggering a s2s connection, Prosody would not handle signals, instead immediately quit on e.g. the reload (SIGHUP) signal. Likely because the libunbound thread would not have inherited the signal mask from the main Prosody thread. Thanks Menel, riau and franck-x for reporting and help narrowing down diff -r 4a9a69659727 -r 69faf3552d52 plugins/mod_posix.lua --- a/plugins/mod_posix.lua Fri Mar 01 19:22:49 2024 +0100 +++ b/plugins/mod_posix.lua Sat Mar 02 13:23:24 2024 +0100 @@ -15,10 +15,6 @@ .. "Perhaps you need to recompile?", tostring(pposix._VERSION), want_pposix_version); end -local have_signal, signal = pcall(require, "prosody.util.signal"); -if not have_signal then - module:log("warn", "Couldn't load signal library, won't respond to SIGTERM"); -end local lfs = require "lfs"; local stat = lfs.attributes; @@ -124,49 +120,3 @@ end module:hook("server-stopped", remove_pidfile); - --- Set signal handlers -if have_signal then - module:add_timer(0, function () - signal.signal("SIGTERM", function () - module:log("warn", "Received SIGTERM"); - prosody.main_thread:run(function () - prosody.unlock_globals(); - prosody.shutdown("Received SIGTERM"); - prosody.lock_globals(); - end); - end); - - signal.signal("SIGHUP", function () - module:log("info", "Received SIGHUP"); - prosody.main_thread:run(function () - prosody.reload_config(); - end); - -- this also reloads logging - end); - - signal.signal("SIGINT", function () - module:log("info", "Received SIGINT"); - prosody.main_thread:run(function () - prosody.unlock_globals(); - prosody.shutdown("Received SIGINT"); - prosody.lock_globals(); - end); - end); - - signal.signal("SIGUSR1", function () - module:log("info", "Received SIGUSR1"); - module:fire_event("signal/SIGUSR1"); - end); - - signal.signal("SIGUSR2", function () - module:log("info", "Received SIGUSR2"); - module:fire_event("signal/SIGUSR2"); - end); - end); -end - --- For other modules to reference -features = { - signal_events = true; -}; diff -r 4a9a69659727 -r 69faf3552d52 util/startup.lua --- a/util/startup.lua Fri Mar 01 19:22:49 2024 +0100 +++ b/util/startup.lua Sat Mar 02 13:23:24 2024 +0100 @@ -671,6 +671,48 @@ end end +function startup.hook_posix_signals() + if prosody.platform ~= "posix" then return end + local have_signal, signal = pcall(require, "prosody.util.signal"); + if not have_signal then + log("warn", "Couldn't load signal library, won't respond to SIGTERM"); + return + end + signal.signal("SIGTERM", function() + log("warn", "Received SIGTERM"); + prosody.main_thread:run(function() + prosody.unlock_globals(); + prosody.shutdown("Received SIGTERM"); + prosody.lock_globals(); + end); + end); + + signal.signal("SIGHUP", function() + log("info", "Received SIGHUP"); + prosody.main_thread:run(function() prosody.reload_config(); end); + -- this also reloads logging + end); + + signal.signal("SIGINT", function() + log("info", "Received SIGINT"); + prosody.main_thread:run(function() + prosody.unlock_globals(); + prosody.shutdown("Received SIGINT"); + prosody.lock_globals(); + end); + end); + + signal.signal("SIGUSR1", function() + log("info", "Received SIGUSR1"); + fire_event("signal/SIGUSR1"); + end); + + signal.signal("SIGUSR2", function() + log("info", "Received SIGUSR2"); + fire_event("signal/SIGUSR2"); + end); +end + function startup.cleanup() prosody.log("info", "Shutdown status: Cleaning up"); prosody.events.fire_event("server-cleanup"); @@ -748,6 +790,7 @@ startup.init_http_client(); startup.init_data_store(); startup.init_global_protection(); + startup.hook_posix_signals(); startup.prepare_to_start(); startup.notify_started(); end