summaryrefslogtreecommitdiff
path: root/pkg/systemd
diff options
context:
space:
mode:
authorTycho Andersen <tycho@tycho.pizza>2021-05-20 13:01:21 -0600
committerTycho Andersen <tycho@tycho.pizza>2021-06-24 09:01:39 -0600
commit364e8a26da2d49c3ea06cc9c0470e47925dcd192 (patch)
tree59224623eef2451b217356fdb5b05968ede3b299 /pkg/systemd
parent21d80faa0b30a042b62566a2ffdff5510a92b9e6 (diff)
downloadpodman-364e8a26da2d49c3ea06cc9c0470e47925dcd192.tar.gz
podman-364e8a26da2d49c3ea06cc9c0470e47925dcd192.tar.bz2
podman-364e8a26da2d49c3ea06cc9c0470e47925dcd192.zip
pkg/systemd: don't require LISTEN_FDNAMES for socket activation
LISTEN_FDNAMES is optional, the docs for sd_listen_fds() says: This information is read from the $LISTEN_FDNAMES variable, which **may** contain a colon-separated list of names. emphasis mine (indeed, the cited coreos code also suggests it is optional). This actually results in bug, since the default /contrib/systemd/system/podman.socket file doesn't set a FileDescriptorName=. podman when run with this systemd configuration *always* starts in unix socket mode since SocketActivated() will return false because the name is missing. The bug is a race with a very small window: between when podman does the unlink() and when it re-binds the socket later in the code, requests made during this time will fail since nothing is listening. There's another small race when the service stops and systemd realizes it and starts listening again. However, small this window we managed to hit it :). Let's fix this by ignoring LISTEN_FDNAMES. Since the code in cmd/podman/system/service_abi.go:restService() ignores this value anyway when setting up the socket activated stuff, there's no real loss here. Signed-off-by: Tycho Andersen <tycho@tycho.pizza>
Diffstat (limited to 'pkg/systemd')
-rw-r--r--pkg/systemd/activation.go6
-rw-r--r--pkg/systemd/activation_test.go32
2 files changed, 32 insertions, 6 deletions
diff --git a/pkg/systemd/activation.go b/pkg/systemd/activation.go
index 8f75f9cca..9fcfed771 100644
--- a/pkg/systemd/activation.go
+++ b/pkg/systemd/activation.go
@@ -25,11 +25,5 @@ func SocketActivated() bool {
if err != nil || nfds == 0 {
return false
}
-
- // "github.com/coreos/go-systemd/v22/activation" will use and validate this variable's
- // value. We're just providing a fast fail
- if _, found = os.LookupEnv("LISTEN_FDNAMES"); !found {
- return false
- }
return true
}
diff --git a/pkg/systemd/activation_test.go b/pkg/systemd/activation_test.go
new file mode 100644
index 000000000..d2553777b
--- /dev/null
+++ b/pkg/systemd/activation_test.go
@@ -0,0 +1,32 @@
+package systemd
+
+import (
+ "fmt"
+ "os"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestSocketActivated(t *testing.T) {
+ assert := assert.New(t)
+
+ assert.False(SocketActivated())
+
+ // different pid
+ assert.NoError(os.Setenv("LISTEN_PID", "1"))
+ assert.False(SocketActivated())
+
+ // same pid no fds
+ assert.NoError(os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid())))
+ assert.NoError(os.Setenv("LISTEN_FDS", "0"))
+ assert.False(SocketActivated())
+
+ // same pid some fds
+ assert.NoError(os.Setenv("LISTEN_FDS", "1"))
+ assert.True(SocketActivated())
+
+ // FDNAME is ok too (but not required)
+ assert.NoError(os.Setenv("LISTEN_FDNAMES", "/meshuggah/rocks"))
+ assert.True(SocketActivated())
+}