diff options
author | Will Chandler <wchandler@gitlab.com> | 2022-07-15 23:23:49 +0300 |
---|---|---|
committer | Will Chandler <wchandler@gitlab.com> | 2022-07-18 15:42:11 +0300 |
commit | b32f0ad8f66f42057dabfac127e3d1ca75cda7e7 (patch) | |
tree | 508764c230b25f1db38a7f11b74a97be0f6bda0c | |
parent | 2ba30c8b1b5a428a645faf72881771af9a505ab2 (diff) |
config: Don't treat EPERM as error when signallingwc-prune-reused-pid
When pruning Gitaly's runtime directory we send the equivalent of
`kill -0 <PID>` to validate the process has ended. However, if the pid
has been reused by the kernel for a process owned by another user we
will receive `EPERM`, causing Gitaly to exit with an error.
On systems where dozens or hundreds of old runtime directories have
accumulated over months, the odds of our hitting a reused pid are quite
high.
Let's treat `EPERM` as acceptable in this scenario, as we know that the
process we tried to signal can't be Gitaly if it's owned by another
user.
Changelog: fixed
-rw-r--r-- | internal/gitaly/config/config.go | 4 | ||||
-rw-r--r-- | internal/gitaly/config/config_test.go | 6 |
2 files changed, 9 insertions, 1 deletions
diff --git a/internal/gitaly/config/config.go b/internal/gitaly/config/config.go index 460c6114a..0e458b0ba 100644 --- a/internal/gitaly/config/config.go +++ b/internal/gitaly/config/config.go @@ -586,7 +586,9 @@ func PruneRuntimeDirectories(log log.FieldLogger, runtimeDir string) error { }() if err := process.Signal(syscall.Signal(0)); err != nil { - if !errors.Is(err, os.ErrProcessDone) { + // Either the process does not exist, or the pid has been re-used by for a + // process owned by another user and is not a Gitaly process. + if !errors.Is(err, os.ErrProcessDone) && !errors.Is(err, syscall.EPERM) { return fmt.Errorf("signal: %w", err) } diff --git a/internal/gitaly/config/config_test.go b/internal/gitaly/config/config_test.go index b5690bf98..132bdc68d 100644 --- a/internal/gitaly/config/config_test.go +++ b/internal/gitaly/config/config_test.go @@ -1336,6 +1336,12 @@ func TestPruneRuntimeDirectories(t *testing.T) { expectedLogs[staleRuntimeDir] = "removing leftover runtime directory" } + // Setup runtime directory with pid of process not owned by git user + rootRuntimeDir, err := SetupRuntimeDirectory(cfg, 1) + require.NoError(t, err) + expectedLogs[rootRuntimeDir] = "removing leftover runtime directory" + prunableDirs = append(prunableDirs, rootRuntimeDir) + // Create an unexpected file in the runtime directory unexpectedFilePath := filepath.Join(baseDir, "unexpected-file") require.NoError(t, os.WriteFile(unexpectedFilePath, []byte(""), os.ModePerm)) |