diff --git a/libcontainer/notify_v2_linux.go b/libcontainer/notify_v2_linux.go index 821536c8da0..8d15833ab43 100644 --- a/libcontainer/notify_v2_linux.go +++ b/libcontainer/notify_v2_linux.go @@ -2,6 +2,7 @@ package libcontainer import ( "fmt" + "os" "path/filepath" "unsafe" @@ -40,7 +41,11 @@ func registerMemoryEventV2(cgDir, evName, cgEvName string) (<-chan struct{}, err for { n, err := unix.Read(fd, buffer[:]) + if err == unix.EINTR { //nolint:errorlint // unix errors are bare + continue + } if err != nil { + err = os.NewSyscallError("read", err) logrus.Warnf("unable to read event data from inotify, got error: %v", err) return } diff --git a/libcontainer/sync_unix.go b/libcontainer/sync_unix.go index c5d8f55ec95..69c0228dbe1 100644 --- a/libcontainer/sync_unix.go +++ b/libcontainer/sync_unix.go @@ -42,9 +42,20 @@ func (s *syncSocket) WritePacket(b []byte) (int, error) { } func (s *syncSocket) ReadPacket() ([]byte, error) { - size, _, err := unix.Recvfrom(int(s.f.Fd()), nil, unix.MSG_TRUNC|unix.MSG_PEEK) + var ( + size int + err error + ) + + for { + size, _, err = unix.Recvfrom(int(s.f.Fd()), nil, unix.MSG_TRUNC|unix.MSG_PEEK) + if err != unix.EINTR { //nolint:errorlint // unix errors are bare + break + } + } + if err != nil { - return nil, fmt.Errorf("fetch packet length from socket: %w", err) + return nil, fmt.Errorf("fetch packet length from socket: %w", os.NewSyscallError("recvfrom", err)) } // We will only get a zero size if the socket has been closed from the // other end (otherwise recvfrom(2) will block until a packet is ready). In diff --git a/libcontainer/utils/cmsg.go b/libcontainer/utils/cmsg.go index 2edd1417af3..3aca5bdaccd 100644 --- a/libcontainer/utils/cmsg.go +++ b/libcontainer/utils/cmsg.go @@ -42,9 +42,20 @@ func RecvFile(socket *os.File) (_ *os.File, Err error) { oob := make([]byte, oobSpace) sockfd := socket.Fd() - n, oobn, _, _, err := unix.Recvmsg(int(sockfd), name, oob, unix.MSG_CMSG_CLOEXEC) + var ( + n, oobn int + err error + ) + + for { + n, oobn, _, _, err = unix.Recvmsg(int(sockfd), name, oob, unix.MSG_CMSG_CLOEXEC) + if err != unix.EINTR { //nolint:errorlint // unix errors are bare + break + } + } + if err != nil { - return nil, err + return nil, os.NewSyscallError("recvmsg", err) } if n >= MaxNameLen || oobn != oobSpace { return nil, fmt.Errorf("recvfile: incorrect number of bytes read (n=%d oobn=%d)", n, oobn) @@ -115,5 +126,10 @@ func SendFile(socket *os.File, file *os.File) error { // SendRawFd sends a specific file descriptor over the given AF_UNIX socket. func SendRawFd(socket *os.File, msg string, fd uintptr) error { oob := unix.UnixRights(int(fd)) - return unix.Sendmsg(int(socket.Fd()), []byte(msg), oob, nil, 0) + for { + err := unix.Sendmsg(int(socket.Fd()), []byte(msg), oob, nil, 0) + if err != unix.EINTR { //nolint:errorlint // unix errors are bare + return os.NewSyscallError("sendmsg", err) + } + } }