mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
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 3cc3d8a560
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
6742f74e0e
commit
c7c02eea81
4 changed files with 12 additions and 96 deletions
|
@ -15,12 +15,12 @@ import (
|
||||||
// Loopback related errors
|
// Loopback related errors
|
||||||
var (
|
var (
|
||||||
ErrAttachLoopbackDevice = errors.New("loopback attach failed")
|
ErrAttachLoopbackDevice = errors.New("loopback attach failed")
|
||||||
ErrGetLoopbackBackingFile = errors.New("Unable to get loopback backing file")
|
ErrGetLoopbackBackingFile = errors.New("unable to get loopback backing file")
|
||||||
ErrSetCapacity = errors.New("Unable set loopback capacity")
|
ErrSetCapacity = errors.New("unable set loopback capacity")
|
||||||
)
|
)
|
||||||
|
|
||||||
func stringToLoopName(src string) [LoNameSize]uint8 {
|
func stringToLoopName(src string) [unix.LO_NAME_SIZE]uint8 {
|
||||||
var dst [LoNameSize]uint8
|
var dst [unix.LO_NAME_SIZE]uint8
|
||||||
copy(dst[:], src[:])
|
copy(dst[:], src[:])
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
@ -31,12 +31,7 @@ func getNextFreeLoopbackIndex() (int, error) {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
return unix.IoctlRetInt(int(f.Fd()), unix.LOOP_CTL_GET_FREE)
|
||||||
index, err := ioctlLoopCtlGetFree(f.Fd())
|
|
||||||
if index < 0 {
|
|
||||||
index = 0
|
|
||||||
}
|
|
||||||
return index, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func openNextAvailableLoopback(index int, sparseFile *os.File) (loopFile *os.File, err error) {
|
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
|
// 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()
|
loopFile.Close()
|
||||||
|
|
||||||
// If the error is EBUSY, then try the next loopback
|
// 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{
|
loopInfo := &unix.LoopInfo64{
|
||||||
File_name: stringToLoopName(loopFile.Name()),
|
File_name: stringToLoopName(loopFile.Name()),
|
||||||
Offset: 0,
|
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)
|
logrus.Errorf("Cannot set up loopback device info: %s", err)
|
||||||
|
|
||||||
// If the call failed, then free the loopback device
|
// 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")
|
logrus.Error("Error while cleaning up the loopback device")
|
||||||
}
|
}
|
||||||
loopFile.Close()
|
loopFile.Close()
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
)
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) {
|
func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) {
|
||||||
loopInfo, err := ioctlLoopGetStatus64(file.Fd())
|
loopInfo, err := unix.IoctlLoopGetStatus64(int(file.Fd()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("Error get loopback backing file: %s", err)
|
logrus.Errorf("Error get loopback backing file: %s", err)
|
||||||
return 0, 0, ErrGetLoopbackBackingFile
|
return 0, 0, ErrGetLoopbackBackingFile
|
||||||
|
@ -22,7 +22,7 @@ func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) {
|
||||||
|
|
||||||
// SetCapacity reloads the size for the loopback device.
|
// SetCapacity reloads the size for the loopback device.
|
||||||
func SetCapacity(file *os.File) error {
|
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)
|
logrus.Errorf("Error loopbackSetCapacity: %s", err)
|
||||||
return ErrSetCapacity
|
return ErrSetCapacity
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,7 @@ func FindLoopDeviceFor(file *os.File) *os.File {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
targetInode := stat.Ino
|
targetInode := stat.Ino
|
||||||
// the type is 32bit on mips
|
targetDevice := uint64(stat.Dev) //nolint: unconvert // the type is 32bit on mips
|
||||||
targetDevice := uint64(stat.Dev) //nolint: unconvert
|
|
||||||
|
|
||||||
for i := 0; true; i++ {
|
for i := 0; true; i++ {
|
||||||
path := fmt.Sprintf("/dev/loop%d", i)
|
path := fmt.Sprintf("/dev/loop%d", i)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue