Skip to content

Commit 364e8a2

Browse files
committed
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 <[email protected]>
1 parent 21d80fa commit 364e8a2

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

pkg/systemd/activation.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,5 @@ func SocketActivated() bool {
2525
if err != nil || nfds == 0 {
2626
return false
2727
}
28-
29-
// "github.com/coreos/go-systemd/v22/activation" will use and validate this variable's
30-
// value. We're just providing a fast fail
31-
if _, found = os.LookupEnv("LISTEN_FDNAMES"); !found {
32-
return false
33-
}
3428
return true
3529
}

pkg/systemd/activation_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package systemd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestSocketActivated(t *testing.T) {
12+
assert := assert.New(t)
13+
14+
assert.False(SocketActivated())
15+
16+
// different pid
17+
assert.NoError(os.Setenv("LISTEN_PID", "1"))
18+
assert.False(SocketActivated())
19+
20+
// same pid no fds
21+
assert.NoError(os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid())))
22+
assert.NoError(os.Setenv("LISTEN_FDS", "0"))
23+
assert.False(SocketActivated())
24+
25+
// same pid some fds
26+
assert.NoError(os.Setenv("LISTEN_FDS", "1"))
27+
assert.True(SocketActivated())
28+
29+
// FDNAME is ok too (but not required)
30+
assert.NoError(os.Setenv("LISTEN_FDNAMES", "/meshuggah/rocks"))
31+
assert.True(SocketActivated())
32+
}

0 commit comments

Comments
 (0)