github.com/ratrocket/u-root@v0.0.0-20180201221235-1cf9f48ee2cf/cmds/losetup/losetup.go (about) 1 // Copyright 2012-2017 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Setup loop devices. 6 // 7 // Synopsis: 8 // losetup [-Ad] FILE 9 // losetup [-Ad] DEV FILE 10 // 11 // Options: 12 // -A: pick any device 13 // -d: detach the device 14 package main 15 16 import ( 17 "flag" 18 "fmt" 19 "log" 20 "os" 21 "syscall" 22 ) 23 24 const ( 25 /* 26 * IOCTL commands --- we will commandeer 0x4C ('L') 27 */ 28 LOOP_SET_CAPACITY = 0x4C07 29 LOOP_CHANGE_FD = 0x4C06 30 LOOP_GET_STATUS64 = 0x4C05 31 LOOP_SET_STATUS64 = 0x4C04 32 LOOP_GET_STATUS = 0x4C03 33 LOOP_SET_STATUS = 0x4C02 34 LOOP_CLR_FD = 0x4C01 35 LOOP_SET_FD = 0x4C00 36 LO_NAME_SIZE = 64 37 LO_KEY_SIZE = 32 38 /* /dev/loop-control interface */ 39 LOOP_CTL_ADD = 0x4C80 40 LOOP_CTL_REMOVE = 0x4C81 41 LOOP_CTL_GET_FREE = 0x4C82 42 SYS_ioctl = 16 43 ) 44 45 var ( 46 anyLoop = flag.Bool("A", true, "Pick any device") 47 detach = flag.Bool("d", false, "Detach the device") 48 l = log.New(os.Stdout, "tcz: ", 0) 49 ) 50 51 // consider making this a goroutine which pushes the string down the channel. 52 func findloop() (name string, err error) { 53 cfd, err := syscall.Open("/dev/loop-control", syscall.O_RDWR, 0) 54 if err != nil { 55 log.Fatalf("/dev/loop-control: %v", err) 56 } 57 defer syscall.Close(cfd) 58 a, b, errno := syscall.Syscall(SYS_ioctl, uintptr(cfd), LOOP_CTL_GET_FREE, 0) 59 if errno != 0 { 60 log.Fatalf("ioctl: %v\n", err) 61 } 62 log.Printf("a %v b %v err %v\n", a, b, err) 63 name = fmt.Sprintf("/dev/loop%d", a) 64 return name, nil 65 } 66 67 func main() { 68 flag.Parse() 69 args := flag.Args() 70 if *detach { 71 l.Fatalf("detach: not yet") 72 os.Exit(1) 73 } 74 var file, dev string 75 var err error 76 if len(args) == 1 { 77 dev, err = findloop() 78 if err != nil { 79 l.Fatalf("can't find a loop: %v\n", err) 80 os.Exit(1) 81 } 82 file = args[0] 83 } else if len(args) == 2 { 84 dev = args[0] 85 file = args[1] 86 } else { 87 l.Fatalf("usage\n") 88 os.Exit(1) 89 } 90 91 ffd, err := syscall.Open(file, syscall.O_RDONLY, 0) 92 if err != nil { 93 l.Fatalf("file: %v, %v\n", file, err) 94 } 95 lfd, err := syscall.Open(dev, syscall.O_RDONLY, 0) 96 if err != nil { 97 l.Fatalf("dev: %v, %v\n", dev, err) 98 } 99 l.Printf("ffd %v lfd %v\n", ffd, lfd) 100 a, b, errno := syscall.Syscall(SYS_ioctl, uintptr(lfd), LOOP_SET_FD, uintptr(ffd)) 101 if errno != 0 { 102 l.Fatalf("loop set fd ioctl: %v, %v, %v\n", a, b, errno) 103 } 104 }