diff --git a/main.go b/main.go index a85eab97004..b3ec8addef8 100644 --- a/main.go +++ b/main.go @@ -108,7 +108,8 @@ func main() { fs.Usage, server.PrintTLSHelpAndDie) if err != nil { - server.PrintAndDie(fmt.Sprintf("%s: %s", exe, err)) + fmt.Fprintln(os.Stderr, fmt.Sprintf("%s: %s", exe, err)) + os.Exit(1) } else if opts.CheckConfig { fmt.Fprintf(os.Stderr, "%s: configuration file %s is valid (%s)\n", exe, opts.ConfigFile, opts.ConfigDigest()) os.Exit(0) @@ -117,7 +118,8 @@ func main() { // Create the server with appropriate options. s, err := server.NewServer(opts) if err != nil { - server.PrintAndDie(fmt.Sprintf("%s: %s", exe, err)) + fmt.Fprintln(os.Stderr, fmt.Sprintf("%s: %s", exe, err)) + os.Exit(1) } // Configure the logger based on the flags. @@ -125,7 +127,7 @@ func main() { // Start things up. Block here until done. if err := server.Run(s); err != nil { - server.PrintAndDie(err.Error()) + s.PrintAndDie(err.Error()) } // Adjust MAXPROCS if running under linux/cgroups quotas. diff --git a/server/server.go b/server/server.go index ce878d74d36..bd2ecc217e6 100644 --- a/server/server.go +++ b/server/server.go @@ -178,6 +178,7 @@ type Server struct { opts *Options running atomic.Bool shutdown atomic.Bool + shutdownSignal atomic.Int32 listener net.Listener listenerErr error gacc *Account @@ -1544,6 +1545,19 @@ func (s *Server) processTrustedKeys() bool { return true } +// PrintAndDie print error message and exit +func (s *Server) PrintAndDie(msg string) { + + sig := s.shutdownSignal.Load() + if sig == 0 { + fmt.Fprintln(os.Stderr, msg) + os.Exit(1) + } else { + fmt.Fprintln(os.Stderr, fmt.Sprintf("Shutting down due to signal: %d", sig)) + os.Exit(int(sig + 128)) + } +} + // checkTrustedKeyString will check that the string is a valid array // of public operator nkeys. func checkTrustedKeyString(keys string) []string { @@ -1576,12 +1590,6 @@ func (s *Server) initStampedTrustedKeys() bool { return true } -// PrintAndDie is exported for access in other packages. -func PrintAndDie(msg string) { - fmt.Fprintln(os.Stderr, msg) - os.Exit(1) -} - // PrintServerAndExit will print our version and exit. func PrintServerAndExit() { fmt.Printf("nats-server: v%s\n", VERSION) diff --git a/server/signal.go b/server/signal.go index aef50a5b4b9..7527f95120e 100644 --- a/server/signal.go +++ b/server/signal.go @@ -49,10 +49,12 @@ func (s *Server) handleSignals() { s.Noticef("Trapped %q signal", sig) switch sig { case syscall.SIGINT: + s.shutdownSignal.CompareAndSwap(0, int32(syscall.SIGINT)) s.Shutdown() s.WaitForShutdown() - os.Exit(0) + os.Exit(128 + int(syscall.SIGINT)) case syscall.SIGTERM: + s.shutdownSignal.CompareAndSwap(0, int32(syscall.SIGTERM)) // Shutdown unless graceful shutdown already in progress. s.mu.Lock() ldm := s.ldm @@ -61,7 +63,7 @@ func (s *Server) handleSignals() { if !ldm { s.Shutdown() s.WaitForShutdown() - os.Exit(0) + os.Exit(128 + int(syscall.SIGTERM)) } case syscall.SIGUSR1: // File log re-open for rotating file logs. diff --git a/server/signal_windows.go b/server/signal_windows.go index 2f5a27c51d7..1751995bbb7 100644 --- a/server/signal_windows.go +++ b/server/signal_windows.go @@ -37,6 +37,7 @@ func (s *Server) handleSignals() { for { select { case sig := <-c: + s.shutdownSignal.CompareAndSwap(0, int32(syscall.SIGTERM)) s.Debugf("Trapped %q signal", sig) s.Shutdown() os.Exit(0)