mirror of
https://github.com/opencontainers/runc.git
synced 2025-10-05 23:46:57 +08:00
Retry direct unix package calls if observing EINTR
Retry Recvfrom, Sendmsg, Readmsg, and Read as they can return EINTR. Signed-off-by: Evan Phoenix <evan@phx.io>
This commit is contained in:
@@ -2,6 +2,7 @@ package libcontainer
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@@ -40,7 +41,11 @@ func registerMemoryEventV2(cgDir, evName, cgEvName string) (<-chan struct{}, err
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
n, err := unix.Read(fd, buffer[:])
|
n, err := unix.Read(fd, buffer[:])
|
||||||
|
if err == unix.EINTR { //nolint:errorlint // unix errors are bare
|
||||||
|
continue
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
err = os.NewSyscallError("read", err)
|
||||||
logrus.Warnf("unable to read event data from inotify, got error: %v", err)
|
logrus.Warnf("unable to read event data from inotify, got error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -42,9 +42,20 @@ func (s *syncSocket) WritePacket(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *syncSocket) ReadPacket() ([]byte, 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 {
|
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
|
// 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
|
// other end (otherwise recvfrom(2) will block until a packet is ready). In
|
||||||
|
@@ -42,9 +42,20 @@ func RecvFile(socket *os.File) (_ *os.File, Err error) {
|
|||||||
oob := make([]byte, oobSpace)
|
oob := make([]byte, oobSpace)
|
||||||
|
|
||||||
sockfd := socket.Fd()
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, os.NewSyscallError("recvmsg", err)
|
||||||
}
|
}
|
||||||
if n >= MaxNameLen || oobn != oobSpace {
|
if n >= MaxNameLen || oobn != oobSpace {
|
||||||
return nil, fmt.Errorf("recvfile: incorrect number of bytes read (n=%d oobn=%d)", n, oobn)
|
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.
|
// SendRawFd sends a specific file descriptor over the given AF_UNIX socket.
|
||||||
func SendRawFd(socket *os.File, msg string, fd uintptr) error {
|
func SendRawFd(socket *os.File, msg string, fd uintptr) error {
|
||||||
oob := unix.UnixRights(int(fd))
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user