github.com/jingleWang/moby@v1.13.1/pkg/loopback/loopback.go (about) 1 // +build linux 2 3 package loopback 4 5 import ( 6 "fmt" 7 "os" 8 "syscall" 9 10 "github.com/Sirupsen/logrus" 11 ) 12 13 func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) { 14 loopInfo, err := ioctlLoopGetStatus64(file.Fd()) 15 if err != nil { 16 logrus.Errorf("Error get loopback backing file: %s", err) 17 return 0, 0, ErrGetLoopbackBackingFile 18 } 19 return loopInfo.loDevice, loopInfo.loInode, nil 20 } 21 22 // SetCapacity reloads the size for the loopback device. 23 func SetCapacity(file *os.File) error { 24 if err := ioctlLoopSetCapacity(file.Fd(), 0); err != nil { 25 logrus.Errorf("Error loopbackSetCapacity: %s", err) 26 return ErrSetCapacity 27 } 28 return nil 29 } 30 31 // FindLoopDeviceFor returns a loopback device file for the specified file which 32 // is backing file of a loop back device. 33 func FindLoopDeviceFor(file *os.File) *os.File { 34 stat, err := file.Stat() 35 if err != nil { 36 return nil 37 } 38 targetInode := stat.Sys().(*syscall.Stat_t).Ino 39 targetDevice := stat.Sys().(*syscall.Stat_t).Dev 40 41 for i := 0; true; i++ { 42 path := fmt.Sprintf("/dev/loop%d", i) 43 44 file, err := os.OpenFile(path, os.O_RDWR, 0) 45 if err != nil { 46 if os.IsNotExist(err) { 47 return nil 48 } 49 50 // Ignore all errors until the first not-exist 51 // we want to continue looking for the file 52 continue 53 } 54 55 dev, inode, err := getLoopbackBackingFile(file) 56 if err == nil && dev == targetDevice && inode == targetInode { 57 return file 58 } 59 file.Close() 60 } 61 62 return nil 63 }