github.com/hugelgupf/u-root@v0.0.0-20191023214958-4807c632154c/pkg/diskboot/device.go (about) 1 // Copyright 2017-2018 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 package diskboot 6 7 import ( 8 "fmt" 9 "io/ioutil" 10 "path/filepath" 11 12 "github.com/u-root/u-root/pkg/mount" 13 "github.com/u-root/u-root/pkg/storage" 14 "golang.org/x/sys/unix" 15 ) 16 17 // Device contains the path to a block filesystem along with its type 18 type Device struct { 19 DevPath string 20 MountPath string 21 Fstype string 22 Configs []*Config 23 } 24 25 // fstypes returns all block file system supported by the linuxboot kernel 26 27 // FindDevices searches for devices with bootable configs 28 func FindDevices(devicesGlob string) (devices []*Device) { 29 fstypes, err := storage.GetSupportedFilesystems() 30 if err != nil { 31 return nil 32 } 33 34 sysList, err := filepath.Glob(devicesGlob) 35 if err != nil { 36 return nil 37 } 38 // The Linux /sys file system is a bit, er, awkward. You can't find 39 // the device special in there; just everything else. 40 for _, sys := range sysList { 41 blk := filepath.Join("/dev", filepath.Base(sys)) 42 43 dev, _ := mountDevice(blk, fstypes) 44 if dev != nil && len(dev.Configs) > 0 { 45 devices = append(devices, dev) 46 } 47 } 48 49 return devices 50 } 51 52 // FindDevice attempts to construct a boot device at the given path 53 func FindDevice(devPath string) (*Device, error) { 54 fstypes, err := storage.GetSupportedFilesystems() 55 if err != nil { 56 return nil, nil 57 } 58 59 return mountDevice(devPath, fstypes) 60 } 61 62 func mountDevice(devPath string, fstypes []string) (*Device, error) { 63 mountPath, err := ioutil.TempDir("/tmp", "boot-") 64 if err != nil { 65 return nil, fmt.Errorf("failed to create tmp mount directory: %v", err) 66 } 67 for _, fstype := range fstypes { 68 if err := mount.Mount(devPath, mountPath, fstype, "", unix.MS_RDONLY); err != nil { 69 continue 70 } 71 72 configs := FindConfigs(mountPath) 73 if len(configs) == 0 { 74 continue 75 } 76 77 return &Device{devPath, mountPath, fstype, configs}, nil 78 } 79 return nil, fmt.Errorf("failed to find a valid boot device with configs") 80 }