diff --git a/pkg/loopback/attach_loopback.go b/pkg/loopback/attach_loopback.go deleted file mode 100644 index 2fe6528a35..0000000000 --- a/pkg/loopback/attach_loopback.go +++ /dev/null @@ -1,134 +0,0 @@ -//go:build linux - -package loopback // import "github.com/docker/docker/pkg/loopback" - -import ( - "context" - "errors" - "fmt" - "os" - - "github.com/containerd/log" - "golang.org/x/sys/unix" -) - -// 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") -) - -func stringToLoopName(src string) [unix.LO_NAME_SIZE]uint8 { - var dst [unix.LO_NAME_SIZE]uint8 - copy(dst[:], src[:]) - return dst -} - -func getNextFreeLoopbackIndex() (int, error) { - f, err := os.OpenFile("/dev/loop-control", os.O_RDONLY, 0o644) - if err != nil { - return 0, err - } - defer f.Close() - return unix.IoctlRetInt(int(f.Fd()), unix.LOOP_CTL_GET_FREE) -} - -func openNextAvailableLoopback(index int, sparseFile *os.File) (loopFile *os.File, err error) { - // Start looking for a free /dev/loop - for { - target := fmt.Sprintf("/dev/loop%d", index) - index++ - - fi, err := os.Stat(target) - if err != nil { - if os.IsNotExist(err) { - log.G(context.TODO()).Error("There are no more loopback devices available.") - } - return nil, ErrAttachLoopbackDevice - } - - if fi.Mode()&os.ModeDevice != os.ModeDevice { - log.G(context.TODO()).Errorf("Loopback device %s is not a block device.", target) - continue - } - - // OpenFile adds O_CLOEXEC - loopFile, err = os.OpenFile(target, os.O_RDWR, 0o644) - if err != nil { - log.G(context.TODO()).Errorf("Error opening loopback device: %s", err) - return nil, ErrAttachLoopbackDevice - } - - // Try to attach to the loop file - 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 - if err != unix.EBUSY { - log.G(context.TODO()).Errorf("Cannot set up loopback device %s: %s", target, err) - return nil, ErrAttachLoopbackDevice - } - - // Otherwise, we keep going with the loop - continue - } - // In case of success, we finished. Break the loop. - break - } - - // This can't happen, but let's be sure - if loopFile == nil { - log.G(context.TODO()).Errorf("Unreachable code reached! Error attaching %s to a loopback device.", sparseFile.Name()) - return nil, ErrAttachLoopbackDevice - } - - return loopFile, nil -} - -// AttachLoopDevice attaches the given sparse file to the next -// available loopback device. It returns an opened *os.File. -// -// Deprecated: the loopback package is deprected and will be removed in the next release. -func AttachLoopDevice(sparseName string) (loop *os.File, err error) { - // Try to retrieve the next available loopback device via syscall. - // If it fails, we discard error and start looping for a - // loopback from index 0. - startIndex, err := getNextFreeLoopbackIndex() - if err != nil { - log.G(context.TODO()).Debugf("Error retrieving the next available loopback: %s", err) - } - - // OpenFile adds O_CLOEXEC - sparseFile, err := os.OpenFile(sparseName, os.O_RDWR, 0o644) - if err != nil { - log.G(context.TODO()).Errorf("Error opening sparse file %s: %s", sparseName, err) - return nil, ErrAttachLoopbackDevice - } - defer sparseFile.Close() - - loopFile, err := openNextAvailableLoopback(startIndex, sparseFile) - if err != nil { - return nil, err - } - - // Set the status of the loopback device - loopInfo := &unix.LoopInfo64{ - File_name: stringToLoopName(loopFile.Name()), - Offset: 0, - Flags: unix.LO_FLAGS_AUTOCLEAR, - } - - if err = unix.IoctlLoopSetStatus64(int(loopFile.Fd()), loopInfo); err != nil { - log.G(context.TODO()).Errorf("Cannot set up loopback device info: %s", err) - - // If the call failed, then free the loopback device - if err = unix.IoctlSetInt(int(loopFile.Fd()), unix.LOOP_CLR_FD, 0); err != nil { - log.G(context.TODO()).Error("Error while cleaning up the loopback device") - } - loopFile.Close() - return nil, ErrAttachLoopbackDevice - } - - return loopFile, nil -} diff --git a/pkg/loopback/loopback.go b/pkg/loopback/loopback.go deleted file mode 100644 index b3109713f8..0000000000 --- a/pkg/loopback/loopback.go +++ /dev/null @@ -1,73 +0,0 @@ -//go:build linux && cgo - -// Package loopback provides utilities to work with loopback devices. -// -// Deprecated: this package is deprecated and will be removed in the next release. - -package loopback // import "github.com/docker/docker/pkg/loopback" - -import ( - "context" - "fmt" - "os" - - "github.com/containerd/log" - "golang.org/x/sys/unix" -) - -func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) { - loopInfo, err := unix.IoctlLoopGetStatus64(int(file.Fd())) - if err != nil { - log.G(context.TODO()).Errorf("Error get loopback backing file: %s", err) - return 0, 0, ErrGetLoopbackBackingFile - } - return loopInfo.Device, loopInfo.Inode, nil -} - -// SetCapacity reloads the size for the loopback device. -// -// Deprecated: the loopback package is deprected and will be removed in the next release. -func SetCapacity(file *os.File) error { - if err := unix.IoctlSetInt(int(file.Fd()), unix.LOOP_SET_CAPACITY, 0); err != nil { - log.G(context.TODO()).Errorf("Error loopbackSetCapacity: %s", err) - return ErrSetCapacity - } - return nil -} - -// FindLoopDeviceFor returns a loopback device file for the specified file which -// is backing file of a loop back device. -// -// Deprecated: the loopback package is deprected and will be removed in the next release. -func FindLoopDeviceFor(file *os.File) *os.File { - var stat unix.Stat_t - err := unix.Stat(file.Name(), &stat) - if err != nil { - return nil - } - targetInode := stat.Ino - targetDevice := uint64(stat.Dev) //nolint: unconvert // the type is 32bit on mips - - for i := 0; true; i++ { - path := fmt.Sprintf("/dev/loop%d", i) - - file, err := os.OpenFile(path, os.O_RDWR, 0) - if err != nil { - if os.IsNotExist(err) { - return nil - } - - // Ignore all errors until the first not-exist - // we want to continue looking for the file - continue - } - - dev, inode, err := getLoopbackBackingFile(file) - if err == nil && dev == targetDevice && inode == targetInode { - return file - } - file.Close() - } - - return nil -}