Skip to content

Commit

Permalink
rootlessport: allow socket paths with more than 108 chars
Browse files Browse the repository at this point in the history
Creating the rootlessport socket can fail with `bind: invalid argument`
when the socket path is longer than 108 chars. This is the case for
users with a long runtime directory.
Since the kernel does not allow to use socket paths with more then 108
chars use a workaround to open the socket path.

[NO TESTS NEEDED]

Signed-off-by: Paul Holzinger <[email protected]>
  • Loading branch information
Luap99 committed Sep 1, 2021
1 parent bebaef2 commit abdedc3
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 11 deletions.
11 changes: 1 addition & 10 deletions libpod/networking_slirp4netns.go
Original file line number Diff line number Diff line change
Expand Up @@ -632,16 +632,7 @@ func (c *Container) reloadRootlessRLKPortMapping() error {
childIP := getRootlessPortChildIP(c)
logrus.Debugf("reloading rootless ports for container %s, childIP is %s", c.config.ID, childIP)

var conn net.Conn
var err error
// try three times to connect to the socket, maybe it is not ready yet
for i := 0; i < 3; i++ {
conn, err = net.Dial("unix", filepath.Join(c.runtime.config.Engine.TmpDir, "rp", c.config.ID))
if err == nil {
break
}
time.Sleep(250 * time.Millisecond)
}
conn, err := openUnixSocket(filepath.Join(c.runtime.config.Engine.TmpDir, "rp", c.config.ID))
if err != nil {
// This is not a hard error for backwards compatibility. A container started
// with an old version did not created the rootlessport socket.
Expand Down
12 changes: 11 additions & 1 deletion pkg/rootlessport/rootlessport_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,20 @@ outer:

// we only need to have a socket to reload ports when we run under rootless cni
if cfg.RootlessCNI {
socket, err := net.Listen("unix", filepath.Join(socketDir, cfg.ContainerID))
// workaround to bypass the 108 char socket path limit
// open the fd and use the path to the fd as bind argument
fd, err := unix.Open(socketDir, unix.O_PATH, 0)
if err != nil {
return err
}
socket, err := net.ListenUnix("unixpacket", &net.UnixAddr{Name: fmt.Sprintf("/proc/self/fd/%d/%s", fd, cfg.ContainerID), Net: "unixpacket"})
if err != nil {
return err
}
err = unix.Close(fd)
if err != nil {
logrus.Warnf("failed to close the socketDir fd: %v", err)
}
defer socket.Close()
go serve(socket, driver)
}
Expand Down

0 comments on commit abdedc3

Please sign in to comment.