github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+incompatible/pkg/boot/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  )
    14  
    15  // Device contains the path to a block filesystem along with its type
    16  type Device struct {
    17  	*mount.MountPoint
    18  	Configs []*Config
    19  }
    20  
    21  // fstypes returns all block file system supported by the linuxboot kernel
    22  
    23  /*
    24   * FindDevicesRW is identical to FindDevices, except the "RW" one
    25   * calls FindDevice with 0 (read write flag option)
    26   * In comparison, FindDevices calls FindDevice with unix.MS_RDONLY
    27   * which mounts the device as read only.
    28   */
    29  func FindDevicesRW(devicesGlob string) (devices []*Device) {
    30  	sysList, err := filepath.Glob(devicesGlob)
    31  	if err != nil {
    32  		return nil
    33  	}
    34  	// The Linux /sys file system is a bit, er, awkward. You can't find
    35  	// the device special in there; just everything else.
    36  	for _, sys := range sysList {
    37  		blk := filepath.Join("/dev", filepath.Base(sys))
    38  
    39  		dev, _ := FindDevice(blk, 0)
    40  		if dev != nil && len(dev.Configs) > 0 {
    41  			devices = append(devices, dev)
    42  		}
    43  	}
    44  	return devices
    45  }
    46  
    47  // FindDevices searches for devices with bootable configs
    48  func FindDevices(devicesGlob string) (devices []*Device) {
    49  	sysList, err := filepath.Glob(devicesGlob)
    50  	if err != nil {
    51  		return nil
    52  	}
    53  	// The Linux /sys file system is a bit, er, awkward. You can't find
    54  	// the device special in there; just everything else.
    55  	for _, sys := range sysList {
    56  		blk := filepath.Join("/dev", filepath.Base(sys))
    57  
    58  		dev, _ := FindDevice(blk, mount.MS_RDONLY)
    59  		if dev != nil && len(dev.Configs) > 0 {
    60  			devices = append(devices, dev)
    61  		}
    62  	}
    63  	return devices
    64  }
    65  
    66  // FindDevice attempts to construct a boot device at the given path
    67  func FindDevice(devPath string, flags uintptr) (*Device, error) {
    68  	mountPath, err := ioutil.TempDir("/tmp", "boot-")
    69  	if err != nil {
    70  		return nil, fmt.Errorf("failed to create tmp mount directory: %v", err)
    71  	}
    72  	mp, err := mount.TryMount(devPath, mountPath, flags)
    73  	if err != nil {
    74  		return nil, fmt.Errorf("failed to find a valid boot device: %v", err)
    75  	}
    76  	configs := FindConfigs(mountPath)
    77  	if len(configs) == 0 {
    78  		return nil, fmt.Errorf("no configs on %s", devPath)
    79  	}
    80  
    81  	return &Device{
    82  		MountPoint: mp,
    83  		Configs:    configs,
    84  	}, nil
    85  }