From e3be524447a136241301723b1057bd1c73be5788 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Thu, 29 Oct 2015 17:23:20 -0600 Subject: [PATCH] core: Fix for graceful reload after first reload signal The file path of the originally-loaded Caddyfile must be piped to the forked process; previously it was using stdin after the first fork, which wouldn't load the newest Caddyfile from disk, which is the point of SIGUSR1. --- caddy/caddy.go | 5 +---- caddy/helpers.go | 2 +- caddy/restart.go | 13 +++++++++++-- caddy/sigtrap_posix.go | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/caddy/caddy.go b/caddy/caddy.go index 022cbb909..578b894b2 100644 --- a/caddy/caddy.go +++ b/caddy/caddy.go @@ -264,10 +264,7 @@ func LoadCaddyfile(loader func() (Input, error)) (cdyfile Input, err error) { if err != nil { return nil, err } - cdyfile = CaddyfileInput{ - Filepath: os.Stdin.Name(), - Contents: loadedGob.Caddyfile, - } + cdyfile = loadedGob.Caddyfile } // Otherwise, we first try to get from stdin pipe diff --git a/caddy/helpers.go b/caddy/helpers.go index a22e7f5cc..c606f941e 100644 --- a/caddy/helpers.go +++ b/caddy/helpers.go @@ -43,7 +43,7 @@ func checkFdlimit() { // the caddyfile contents. Used only during graceful restarts. type caddyfileGob struct { ListenerFds map[string]uintptr - Caddyfile []byte + Caddyfile Input } // isRestart returns whether this process is, according diff --git a/caddy/restart.go b/caddy/restart.go index 1c61c5a03..7921f3754 100644 --- a/caddy/restart.go +++ b/caddy/restart.go @@ -10,6 +10,10 @@ import ( "syscall" ) +func init() { + gob.Register(CaddyfileInput{}) +} + // Restart restarts the entire application; gracefully with zero // downtime if on a POSIX-compatible system, or forcefully if on // Windows but with imperceptibly-short downtime. @@ -17,6 +21,11 @@ import ( // The restarted application will use newCaddyfile as its input // configuration. If newCaddyfile is nil, the current (existing) // Caddyfile configuration will be used. +// +// Note: The process must exist in the same place on the disk in +// order for this to work. Thus, multiple graceful restarts don't +// work if executing with `go run`, since the binary is cleaned up +// when `go run` sees the initial parent process exit. func Restart(newCaddyfile Input) error { if newCaddyfile == nil { caddyfileMu.Lock() @@ -24,7 +33,7 @@ func Restart(newCaddyfile Input) error { caddyfileMu.Unlock() } - if len(os.Args) == 0 { // this should never happen, but just in case... + if len(os.Args) == 0 { // this should never happen... os.Args = []string{""} } @@ -34,7 +43,7 @@ func Restart(newCaddyfile Input) error { // Prepare our payload to the child process cdyfileGob := caddyfileGob{ ListenerFds: make(map[string]uintptr), - Caddyfile: newCaddyfile.Body(), + Caddyfile: newCaddyfile, } // Prepare a pipe to the fork's stdin so it can get the Caddyfile diff --git a/caddy/sigtrap_posix.go b/caddy/sigtrap_posix.go index 122adf2c3..521866fd1 100644 --- a/caddy/sigtrap_posix.go +++ b/caddy/sigtrap_posix.go @@ -36,7 +36,7 @@ func init() { err := Restart(updatedCaddyfile) if err != nil { - log.Println(err) + log.Println("error at restart:", err) } } }()