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  }