mirror of
https://github.com/opencontainers/runc.git
synced 2025-10-23 23:44:02 +08:00
Introduce and use internal/linux
This package is to provide unix.* wrappers to ensure that: - they retry on EINTR; - a "rich" error is returned on failure. A first such wrapper, Sendmsg, is introduced. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
18
internal/linux/eintr.go
Normal file
18
internal/linux/eintr.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package linux
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// retryOnEINTR takes a function that returns an error and calls it
|
||||
// until the error returned is not EINTR.
|
||||
func retryOnEINTR(fn func() error) error {
|
||||
for {
|
||||
err := fn()
|
||||
if !errors.Is(err, unix.EINTR) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
15
internal/linux/linux.go
Normal file
15
internal/linux/linux.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package linux
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Sendmsg wraps [unix.Sendmsg].
|
||||
func Sendmsg(fd int, p, oob []byte, to unix.Sockaddr, flags int) error {
|
||||
err := retryOnEINTR(func() error {
|
||||
return unix.Sendmsg(fd, p, oob, to, flags)
|
||||
})
|
||||
return os.NewSyscallError("sendmsg", err)
|
||||
}
|
@@ -21,6 +21,7 @@ import (
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/opencontainers/runc/internal/linux"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@@ -126,10 +127,5 @@ 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))
|
||||
for {
|
||||
err := unix.Sendmsg(int(socket.Fd()), []byte(msg), oob, nil, 0)
|
||||
if err != unix.EINTR {
|
||||
return os.NewSyscallError("sendmsg", err)
|
||||
}
|
||||
}
|
||||
return linux.Sendmsg(int(socket.Fd()), []byte(msg), oob, nil, 0)
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/opencontainers/runc/internal/linux"
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -181,7 +182,7 @@ func sdNotifyBarrier(client *net.UnixConn) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the FD for the unix socket file to be able to do perform syscall.Sendmsg.
|
||||
// Get the FD for the unix socket file to be able to use sendmsg.
|
||||
clientFd, err := client.File()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -189,9 +190,9 @@ func sdNotifyBarrier(client *net.UnixConn) error {
|
||||
|
||||
// Send the write end of the pipe along with a BARRIER=1 message.
|
||||
fdRights := unix.UnixRights(int(pipeW.Fd()))
|
||||
err = unix.Sendmsg(int(clientFd.Fd()), []byte("BARRIER=1"), fdRights, nil, 0)
|
||||
err = linux.Sendmsg(int(clientFd.Fd()), []byte("BARRIER=1"), fdRights, nil, 0)
|
||||
if err != nil {
|
||||
return &os.SyscallError{Syscall: "sendmsg", Err: err}
|
||||
return err
|
||||
}
|
||||
|
||||
// Close our copy of pipeW.
|
||||
|
Reference in New Issue
Block a user