Files
docker-cli/components/engine/pkg/loopback/loopback.go
Vincent Batts 8b5a2050f9 loopback: separate loop logic from devicemapper
The loopback logic is not technically exclusive to the devicemapper
driver. This reorganizes the code such that the loopback code is usable
outside of the devicemapper package and driver.

Signed-off-by: Vincent Batts <vbatts@redhat.com>
Upstream-commit: af597527121c0ad973e9d0ae4f9cf970da1513cc
Component: engine
2015-12-18 10:57:43 -05:00

64 lines
1.4 KiB
Go

// +build linux
package loopback
import (
"fmt"
"os"
"syscall"
"github.com/Sirupsen/logrus"
)
func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) {
loopInfo, err := ioctlLoopGetStatus64(file.Fd())
if err != nil {
logrus.Errorf("Error get loopback backing file: %s", err)
return 0, 0, ErrGetLoopbackBackingFile
}
return loopInfo.loDevice, loopInfo.loInode, nil
}
// SetCapacity reloads the size for the loopback device.
func SetCapacity(file *os.File) error {
if err := ioctlLoopSetCapacity(file.Fd(), 0); err != nil {
logrus.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.
func FindLoopDeviceFor(file *os.File) *os.File {
stat, err := file.Stat()
if err != nil {
return nil
}
targetInode := stat.Sys().(*syscall.Stat_t).Ino
targetDevice := stat.Sys().(*syscall.Stat_t).Dev
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
}