Use LOOP_CONFIGURE when creating loop devices
LOOP_CONFIGURE is a new ioctl that is a lot faster than the LOOP_SET_FD+LOOP_SET_STATUS64 calls Signed-off-by: Alexandru Matei <alexandru.matei@uipath.com>
This commit is contained in:
parent
c33249cbe6
commit
a782fd6da2
@ -21,8 +21,11 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
kernel "github.com/containerd/containerd/contrib/seccomp/kernelversion"
|
||||
"github.com/containerd/containerd/pkg/randutil"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@ -32,8 +35,26 @@ const (
|
||||
loopDevFormat = "/dev/loop%d"
|
||||
|
||||
ebusyString = "device or resource busy"
|
||||
|
||||
loopConfigureIoctl = 0x4c0a
|
||||
)
|
||||
|
||||
type LoopConfig struct {
|
||||
Fd uint32
|
||||
BlockSize uint32
|
||||
Info unix.LoopInfo64
|
||||
Reserved [8]uint64
|
||||
}
|
||||
|
||||
func ioctlConfigure(fd int, value *LoopConfig) error {
|
||||
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(loopConfigureIoctl), uintptr(unsafe.Pointer(value)))
|
||||
if err == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// LoopParams parameters to control loop device setup
|
||||
type LoopParams struct {
|
||||
// Loop device should forbid write
|
||||
@ -84,6 +105,32 @@ func setupLoopDev(backingFile, loopDev string, param LoopParams) (_ *os.File, re
|
||||
}
|
||||
}()
|
||||
|
||||
fiveDotEight := kernel.KernelVersion{Kernel: 5, Major: 8}
|
||||
if ok, err := kernel.GreaterEqualThan(fiveDotEight); err == nil && ok {
|
||||
config := LoopConfig{
|
||||
Fd: uint32(back.Fd()),
|
||||
}
|
||||
|
||||
copy(config.Info.File_name[:], backingFile)
|
||||
if param.Readonly {
|
||||
config.Info.Flags |= unix.LO_FLAGS_READ_ONLY
|
||||
}
|
||||
|
||||
if param.Autoclear {
|
||||
config.Info.Flags |= unix.LO_FLAGS_AUTOCLEAR
|
||||
}
|
||||
|
||||
if param.Direct {
|
||||
config.Info.Flags |= unix.LO_FLAGS_DIRECT_IO
|
||||
}
|
||||
|
||||
if err := ioctlConfigure(int(loop.Fd()), &config); err != nil {
|
||||
return nil, fmt.Errorf("failed to configure loop device: %s: %w", loopDev, err)
|
||||
}
|
||||
|
||||
return loop, nil
|
||||
}
|
||||
|
||||
// 2. Set FD
|
||||
if err := unix.IoctlSetInt(int(loop.Fd()), unix.LOOP_SET_FD, int(back.Fd())); err != nil {
|
||||
return nil, fmt.Errorf("could not set loop fd for device: %s: %w", loopDev, err)
|
||||
|
Loading…
Reference in New Issue
Block a user