Skip to content

Commit 3ce6ebf

Browse files
committed
Add code to trigger module reinitialization on SIGUSR2
1 parent 503c9f8 commit 3ce6ebf

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

maddy.go

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,12 @@ func moduleStop(c *container.C) {
376376
func moduleMain(configPath string) error {
377377
log.DefaultLogger.Msg("loading configuration...")
378378

379+
// Make path absolute to make sure we can still read it if current directory changes (in moduleConfigure).
380+
configPath, err := filepath.Abs(configPath)
381+
if err != nil {
382+
return err
383+
}
384+
379385
c, err := moduleConfigure(configPath)
380386
if err != nil {
381387
return err
@@ -389,7 +395,12 @@ func moduleMain(configPath string) error {
389395
c.DefaultLogger.Msg("server started", "version", Version)
390396

391397
systemdStatus(SDReady, "Listening for incoming connections...")
392-
handleSignals()
398+
for handleSignals() {
399+
systemdStatus(SDReloading, "Reloading state...")
400+
hooks.RunHooks(hooks.EventReload)
401+
402+
c = moduleReload(c, configPath)
403+
}
393404

394405
c.DefaultLogger.Msg("server stopping...")
395406
systemdStatus(SDStopping, "Waiting for running transactions to complete...")
@@ -399,6 +410,33 @@ func moduleMain(configPath string) error {
399410
return nil
400411
}
401412

413+
func moduleReload(oldContainer *container.C, configPath string) *container.C {
414+
oldContainer.DefaultLogger.Msg("reloading server...")
415+
416+
oldContainer.DefaultLogger.Msg("loading new configuration...")
417+
newContainer, err := moduleConfigure(configPath)
418+
if err != nil {
419+
oldContainer.DefaultLogger.Error("failed to load new configuration", err)
420+
return oldContainer
421+
}
422+
423+
oldContainer.DefaultLogger.Msg("configuration loaded")
424+
425+
oldContainer.DefaultLogger.Msg("starting new server")
426+
if err := moduleStart(newContainer); err != nil {
427+
oldContainer.DefaultLogger.Error("failed to start new server", err)
428+
container.Global = oldContainer
429+
return oldContainer
430+
}
431+
432+
newContainer.DefaultLogger.Msg("server started", "version", Version)
433+
oldContainer.DefaultLogger.Msg("stopping server")
434+
moduleStop(oldContainer)
435+
oldContainer.DefaultLogger.Msg("server stopped")
436+
437+
return newContainer
438+
}
439+
402440
func RegisterModules(c *container.C, globals map[string]interface{}, nodes []config.Node) (err error) {
403441
var endpoints []struct {
404442
Endpoint module.LifetimeModule

signal.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ import (
3636
// (SIGTERM, SIGHUP, SIGINT) will cause this function to return.
3737
//
3838
// SIGUSR1 will call reinitLogging without returning.
39-
func handleSignals() os.Signal {
39+
func handleSignals() (reload bool) {
4040
sig := make(chan os.Signal, 5)
4141
signal.Notify(sig, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGINT, syscall.SIGUSR1, syscall.SIGUSR2)
42+
defer signal.Stop(sig)
4243

4344
for {
4445
switch s := <-sig; s {
@@ -48,10 +49,8 @@ func handleSignals() os.Signal {
4849
hooks.RunHooks(hooks.EventLogRotate)
4950
systemdStatus(SDReady, "Listening for incoming connections...")
5051
case syscall.SIGUSR2:
51-
log.Printf("signal received (%s), reloading state", s.String())
52-
systemdStatus(SDReloading, "Reloading state...")
53-
hooks.RunHooks(hooks.EventReload)
54-
systemdStatus(SDReady, "Listening for incoming connections...")
52+
log.Printf("signal received (%s), reloading configuration", s.String())
53+
return true
5554
default:
5655
go func() {
5756
s := handleSignals()
@@ -60,7 +59,7 @@ func handleSignals() os.Signal {
6059
}()
6160

6261
log.Printf("signal received (%v), next signal will force immediate shutdown.", s)
63-
return s
62+
return false
6463
}
6564
}
6665
}

0 commit comments

Comments
 (0)