From d38eb9758b71f5982f1aebb0663f0ebe5be7a74c Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 27 Jul 2022 12:58:21 +0800 Subject: [PATCH 1/5] Preserve unix socket file https://github.com/go-gitea/gitea/issues/20490 --- modules/graceful/net_unix.go | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/graceful/net_unix.go b/modules/graceful/net_unix.go index 680ff529af885..ff3fc3714f96f 100644 --- a/modules/graceful/net_unix.go +++ b/modules/graceful/net_unix.go @@ -168,7 +168,6 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener, providedListeners = append(providedListeners[:i], providedListeners[i+1:]...) activeListeners = append(activeListeners, l) unixListener := l.(*net.UnixListener) - unixListener.SetUnlinkOnClose(true) return unixListener, nil } } From 2c27018426eb5d45fd12d61f76c69c4aa425c042 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 28 Jul 2022 18:21:37 +0800 Subject: [PATCH 2/5] unlink socket only if `IsChild()` --- modules/graceful/net_unix.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/graceful/net_unix.go b/modules/graceful/net_unix.go index ff3fc3714f96f..1583300150d7e 100644 --- a/modules/graceful/net_unix.go +++ b/modules/graceful/net_unix.go @@ -168,6 +168,9 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener, providedListeners = append(providedListeners[:i], providedListeners[i+1:]...) activeListeners = append(activeListeners, l) unixListener := l.(*net.UnixListener) + if GetManager().IsChild() { + unixListener.SetUnlinkOnClose(true) + } return unixListener, nil } } From db92f0613100e2d3967045c4d4edda370ff5ae2e Mon Sep 17 00:00:00 2001 From: zeripath Date: Thu, 28 Jul 2022 20:43:25 +0800 Subject: [PATCH 3/5] implement UNLINK_FDS --- modules/graceful/net_unix.go | 36 +++++++++++++++++++++++++++++--- modules/graceful/restart_unix.go | 15 +++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/modules/graceful/net_unix.go b/modules/graceful/net_unix.go index 1583300150d7e..21c1b31ca445a 100644 --- a/modules/graceful/net_unix.go +++ b/modules/graceful/net_unix.go @@ -23,6 +23,7 @@ import ( const ( listenFDs = "LISTEN_FDS" startFD = 3 + unlinkFDs = "UNLINK_FDS" ) // In order to keep the working directory the same as when we started we record @@ -33,8 +34,10 @@ var ( once = sync.Once{} mutex = sync.Mutex{} - providedListeners = []net.Listener{} - activeListeners = []net.Listener{} + providedListenersToUnlink = []bool{} + activeListenersToUnlink = []bool{} + providedListeners = []net.Listener{} + activeListeners = []net.Listener{} ) func getProvidedFDs() (savedErr error) { @@ -53,6 +56,16 @@ func getProvidedFDs() (savedErr error) { return } + fdsToUnlinkStr := strings.Split(os.Getenv(unlinkFDs), ",") + providedListenersToUnlink = make([]bool, n) + for _, fdStr := range fdsToUnlinkStr { + i, err := strconv.Atoi(fdStr) + if err == nil || i < 0 || i >= n+startFD { + continue + } + providedListenersToUnlink[i-startFD] = true + } + for i := startFD; i < n+startFD; i++ { file := os.NewFile(uintptr(i), fmt.Sprintf("listener_FD%d", i)) @@ -136,8 +149,11 @@ func GetListenerTCP(network string, address *net.TCPAddr) (*net.TCPListener, err for i, l := range providedListeners { if isSameAddr(l.Addr(), address) { providedListeners = append(providedListeners[:i], providedListeners[i+1:]...) + needsUnlink := providedListenersToUnlink[i] + providedListenersToUnlink = append(providedListenersToUnlink[:i], providedListenersToUnlink[i+1:]...) activeListeners = append(activeListeners, l) + activeListenersToUnlink = append(activeListenersToUnlink, needsUnlink) return l.(*net.TCPListener), nil } } @@ -148,6 +164,7 @@ func GetListenerTCP(network string, address *net.TCPAddr) (*net.TCPListener, err return nil, err } activeListeners = append(activeListeners, l) + activeListenersToUnlink = append(activeListenersToUnlink, false) return l, nil } @@ -166,9 +183,13 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener, for i, l := range providedListeners { if isSameAddr(l.Addr(), address) { providedListeners = append(providedListeners[:i], providedListeners[i+1:]...) + needsUnlink := providedListenersToUnlink[i] + providedListenersToUnlink = append(providedListenersToUnlink[:i], providedListenersToUnlink[i+1:]...) + + activeListenersToUnlink = append(activeListenersToUnlink, needsUnlink) activeListeners = append(activeListeners, l) unixListener := l.(*net.UnixListener) - if GetManager().IsChild() { + if needsUnlink { unixListener.SetUnlinkOnClose(true) } return unixListener, nil @@ -191,6 +212,7 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener, } activeListeners = append(activeListeners, l) + activeListenersToUnlink = append(activeListenersToUnlink, true) return l, nil } @@ -225,3 +247,11 @@ func getActiveListeners() []net.Listener { copy(listeners, activeListeners) return listeners } + +func getActiveListenersToUnlink() []bool { + mutex.Lock() + defer mutex.Unlock() + listenersToUnlink := make([]bool, len(activeListenersToUnlink)) + copy(listenersToUnlink, activeListenersToUnlink) + return listenersToUnlink +} diff --git a/modules/graceful/restart_unix.go b/modules/graceful/restart_unix.go index 2654ddfb94d84..1d0d1059e9fd1 100644 --- a/modules/graceful/restart_unix.go +++ b/modules/graceful/restart_unix.go @@ -12,6 +12,7 @@ import ( "net" "os" "os/exec" + "strconv" "strings" "sync" "syscall" @@ -75,6 +76,20 @@ func RestartProcess() (int, error) { } env = append(env, fmt.Sprintf("%s=%d", listenFDs, len(listeners))) + sb := &strings.Builder{} + for i, unlink := range getActiveListenersToUnlink() { + if !unlink { + continue + } + _, _ = sb.WriteString(strconv.Itoa(i)) + _, _ = sb.WriteString(",") + } + unlinkStr := sb.String() + if len(unlinkStr) > 0 { + unlinkStr = unlinkStr[:len(unlinkStr)-1] + env = append(env, fmt.Sprintf("%s=%s", unlinkFDs, unlinkStr)) + } + allFiles := append([]*os.File{os.Stdin, os.Stdout, os.Stderr}, files...) process, err := os.StartProcess(argv0, os.Args, &os.ProcAttr{ Dir: originalWD, From 5c4e9f95c2a4907433b8710b43a5f5fc86e40afe Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 28 Jul 2022 20:45:21 +0800 Subject: [PATCH 4/5] rename env --- modules/graceful/net_unix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/graceful/net_unix.go b/modules/graceful/net_unix.go index 21c1b31ca445a..2d2f23dbf4a5d 100644 --- a/modules/graceful/net_unix.go +++ b/modules/graceful/net_unix.go @@ -23,7 +23,7 @@ import ( const ( listenFDs = "LISTEN_FDS" startFD = 3 - unlinkFDs = "UNLINK_FDS" + unlinkFDs = "GITEA_UNLINK_FDS" ) // In order to keep the working directory the same as when we started we record From d64482800bc86c24d6d8ee252646526dedd1aa30 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 28 Jul 2022 23:32:57 +0800 Subject: [PATCH 5/5] fix unlink index --- modules/graceful/net_unix.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/graceful/net_unix.go b/modules/graceful/net_unix.go index 2d2f23dbf4a5d..c7524a79dbc94 100644 --- a/modules/graceful/net_unix.go +++ b/modules/graceful/net_unix.go @@ -60,10 +60,10 @@ func getProvidedFDs() (savedErr error) { providedListenersToUnlink = make([]bool, n) for _, fdStr := range fdsToUnlinkStr { i, err := strconv.Atoi(fdStr) - if err == nil || i < 0 || i >= n+startFD { + if err != nil || i < 0 || i >= n { continue } - providedListenersToUnlink[i-startFD] = true + providedListenersToUnlink[i] = true } for i := startFD; i < n+startFD; i++ {