github.com/phobos182/packer@v0.2.3-0.20130819023704-c84d2aeffc68/builder/amazon/chroot/device.go (about) 1 package chroot 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "path/filepath" 8 "strings" 9 ) 10 11 // AvailableDevice finds an available device and returns it. Note that 12 // you should externally hold a flock or something in order to guarantee 13 // that this device is available across processes. 14 func AvailableDevice() (string, error) { 15 prefix, err := devicePrefix() 16 if err != nil { 17 return "", err 18 } 19 20 letters := "fghijklmnop" 21 for _, letter := range letters { 22 for i := 1; i < 16; i++ { 23 device := fmt.Sprintf("/dev/%s%c%d", prefix, letter, i) 24 if _, err := os.Stat(device); err != nil { 25 return device, nil 26 } 27 } 28 } 29 30 return "", errors.New("available device could not be found") 31 } 32 33 // devicePrefix returns the prefix ("sd" or "xvd" or so on) of the devices 34 // on the system. 35 func devicePrefix() (string, error) { 36 available := []string{"sd", "xvd"} 37 38 f, err := os.Open("/sys/block") 39 if err != nil { 40 return "", err 41 } 42 defer f.Close() 43 44 dirs, err := f.Readdirnames(-1) 45 if dirs != nil && len(dirs) > 0 { 46 for _, dir := range dirs { 47 dirBase := filepath.Base(dir) 48 for _, prefix := range available { 49 if strings.HasPrefix(dirBase, prefix) { 50 return prefix, nil 51 } 52 } 53 } 54 } 55 56 if err != nil { 57 return "", err 58 } 59 60 return "", errors.New("device prefix could not be detected") 61 }