From c7c02eea8117347c5ebd43ef3b9192d43bcdd10b Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 8 Oct 2022 21:20:29 +0200 Subject: [PATCH] pkg/loopback: use ioctl helpers from x/sys/unix Use the IoctlRetInt, IoctlSetInt and IoctlLoopSetStatus64 helper functions defined in the golang.org/x/sys/unix package instead of manually wrapping these using a locally defined function. Inspired by https://github.com/containerd/containerd/commit/3cc3d8a560a9d070466d7d58010beda61db5c1ba Signed-off-by: Sebastiaan van Stijn --- pkg/loopback/attach_loopback.go | 23 ++++++-------- pkg/loopback/ioctl.go | 53 --------------------------------- pkg/loopback/loop_wrapper.go | 25 ---------------- pkg/loopback/loopback.go | 7 ++--- 4 files changed, 12 insertions(+), 96 deletions(-) delete mode 100644 pkg/loopback/ioctl.go delete mode 100644 pkg/loopback/loop_wrapper.go diff --git a/pkg/loopback/attach_loopback.go b/pkg/loopback/attach_loopback.go index c9e1d0f72c..11de15236d 100644 --- a/pkg/loopback/attach_loopback.go +++ b/pkg/loopback/attach_loopback.go @@ -15,12 +15,12 @@ import ( // Loopback related errors var ( ErrAttachLoopbackDevice = errors.New("loopback attach failed") - ErrGetLoopbackBackingFile = errors.New("Unable to get loopback backing file") - ErrSetCapacity = errors.New("Unable set loopback capacity") + ErrGetLoopbackBackingFile = errors.New("unable to get loopback backing file") + ErrSetCapacity = errors.New("unable set loopback capacity") ) -func stringToLoopName(src string) [LoNameSize]uint8 { - var dst [LoNameSize]uint8 +func stringToLoopName(src string) [unix.LO_NAME_SIZE]uint8 { + var dst [unix.LO_NAME_SIZE]uint8 copy(dst[:], src[:]) return dst } @@ -31,12 +31,7 @@ func getNextFreeLoopbackIndex() (int, error) { return 0, err } defer f.Close() - - index, err := ioctlLoopCtlGetFree(f.Fd()) - if index < 0 { - index = 0 - } - return index, err + return unix.IoctlRetInt(int(f.Fd()), unix.LOOP_CTL_GET_FREE) } func openNextAvailableLoopback(index int, sparseFile *os.File) (loopFile *os.File, err error) { @@ -66,7 +61,7 @@ func openNextAvailableLoopback(index int, sparseFile *os.File) (loopFile *os.Fil } // Try to attach to the loop file - if err := ioctlLoopSetFd(loopFile.Fd(), sparseFile.Fd()); err != nil { + if err = unix.IoctlSetInt(int(loopFile.Fd()), unix.LOOP_SET_FD, int(sparseFile.Fd())); err != nil { loopFile.Close() // If the error is EBUSY, then try the next loopback @@ -119,14 +114,14 @@ func AttachLoopDevice(sparseName string) (loop *os.File, err error) { loopInfo := &unix.LoopInfo64{ File_name: stringToLoopName(loopFile.Name()), Offset: 0, - Flags: LoFlagsAutoClear, + Flags: unix.LO_FLAGS_AUTOCLEAR, } - if err := ioctlLoopSetStatus64(loopFile.Fd(), loopInfo); err != nil { + if err = unix.IoctlLoopSetStatus64(int(loopFile.Fd()), loopInfo); err != nil { logrus.Errorf("Cannot set up loopback device info: %s", err) // If the call failed, then free the loopback device - if err := ioctlLoopClrFd(loopFile.Fd()); err != nil { + if err = unix.IoctlSetInt(int(loopFile.Fd()), unix.LOOP_CLR_FD, 0); err != nil { logrus.Error("Error while cleaning up the loopback device") } loopFile.Close() diff --git a/pkg/loopback/ioctl.go b/pkg/loopback/ioctl.go deleted file mode 100644 index 8087b187cd..0000000000 --- a/pkg/loopback/ioctl.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build linux -// +build linux - -package loopback // import "github.com/docker/docker/pkg/loopback" - -import ( - "unsafe" - - "golang.org/x/sys/unix" -) - -func ioctlLoopCtlGetFree(fd uintptr) (int, error) { - // The ioctl interface for /dev/loop-control (since Linux 3.1) is a bit - // off compared to what you'd expect: instead of writing an integer to a - // parameter pointer like unix.IoctlGetInt() expects, it returns the first - // available loop device index directly. - ioctlReturn, _, err := unix.Syscall(unix.SYS_IOCTL, fd, LoopCtlGetFree, 0) - if err != 0 { - return 0, err - } - return int(ioctlReturn), nil -} - -func ioctlLoopSetFd(loopFd, sparseFd uintptr) error { - return unix.IoctlSetInt(int(loopFd), unix.LOOP_SET_FD, int(sparseFd)) -} - -func ioctlLoopSetStatus64(loopFd uintptr, loopInfo *unix.LoopInfo64) error { - if _, _, err := unix.Syscall(unix.SYS_IOCTL, loopFd, unix.LOOP_SET_STATUS64, uintptr(unsafe.Pointer(loopInfo))); err != 0 { - return err - } - return nil -} - -func ioctlLoopClrFd(loopFd uintptr) error { - if _, _, err := unix.Syscall(unix.SYS_IOCTL, loopFd, unix.LOOP_CLR_FD, 0); err != 0 { - return err - } - return nil -} - -func ioctlLoopGetStatus64(loopFd uintptr) (*unix.LoopInfo64, error) { - loopInfo := &unix.LoopInfo64{} - - if _, _, err := unix.Syscall(unix.SYS_IOCTL, loopFd, unix.LOOP_GET_STATUS64, uintptr(unsafe.Pointer(loopInfo))); err != 0 { - return nil, err - } - return loopInfo, nil -} - -func ioctlLoopSetCapacity(loopFd uintptr, value int) error { - return unix.IoctlSetInt(int(loopFd), unix.LOOP_SET_CAPACITY, value) -} diff --git a/pkg/loopback/loop_wrapper.go b/pkg/loopback/loop_wrapper.go deleted file mode 100644 index 10ef1985e8..0000000000 --- a/pkg/loopback/loop_wrapper.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build linux -// +build linux - -package loopback // import "github.com/docker/docker/pkg/loopback" - -import "golang.org/x/sys/unix" - -// IOCTL consts -const ( - LoopSetFd = unix.LOOP_SET_FD - LoopCtlGetFree = unix.LOOP_CTL_GET_FREE - LoopGetStatus64 = unix.LOOP_GET_STATUS64 - LoopSetStatus64 = unix.LOOP_SET_STATUS64 - LoopClrFd = unix.LOOP_CLR_FD - LoopSetCapacity = unix.LOOP_SET_CAPACITY -) - -// LOOP consts. -const ( - LoFlagsAutoClear = unix.LO_FLAGS_AUTOCLEAR - LoFlagsReadOnly = unix.LO_FLAGS_READ_ONLY - LoFlagsPartScan = unix.LO_FLAGS_PARTSCAN - LoKeySize = unix.LO_KEY_SIZE - LoNameSize = unix.LO_NAME_SIZE -) diff --git a/pkg/loopback/loopback.go b/pkg/loopback/loopback.go index ecdb398727..dc3fc4ae9c 100644 --- a/pkg/loopback/loopback.go +++ b/pkg/loopback/loopback.go @@ -12,7 +12,7 @@ import ( ) func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) { - loopInfo, err := ioctlLoopGetStatus64(file.Fd()) + loopInfo, err := unix.IoctlLoopGetStatus64(int(file.Fd())) if err != nil { logrus.Errorf("Error get loopback backing file: %s", err) return 0, 0, ErrGetLoopbackBackingFile @@ -22,7 +22,7 @@ func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) { // SetCapacity reloads the size for the loopback device. func SetCapacity(file *os.File) error { - if err := ioctlLoopSetCapacity(file.Fd(), 0); err != nil { + if err := unix.IoctlSetInt(int(file.Fd()), unix.LOOP_SET_CAPACITY, 0); err != nil { logrus.Errorf("Error loopbackSetCapacity: %s", err) return ErrSetCapacity } @@ -38,8 +38,7 @@ func FindLoopDeviceFor(file *os.File) *os.File { return nil } targetInode := stat.Ino - // the type is 32bit on mips - targetDevice := uint64(stat.Dev) //nolint: unconvert + targetDevice := uint64(stat.Dev) //nolint: unconvert // the type is 32bit on mips for i := 0; true; i++ { path := fmt.Sprintf("/dev/loop%d", i)