github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/uefivars/boot/efiDppResolver.go (about)

     1  // Copyright 2020 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  // SPDX-License-Identifier: BSD-3-Clause
     6  //
     7  
     8  package boot
     9  
    10  import (
    11  	"io/ioutil"
    12  	"log"
    13  	"os"
    14  	fp "path/filepath"
    15  
    16  	"github.com/u-root/u-root/pkg/mount"
    17  	"github.com/u-root/u-root/pkg/mount/block"
    18  	"golang.org/x/sys/unix"
    19  )
    20  
    21  type EfiPathSegmentResolver interface {
    22  	//Returns description, does not require cleanup
    23  	String() string
    24  
    25  	//Mount fs, etc. You must call Cleanup() eventually.
    26  	Resolve(suggestedBasePath string) (string, error)
    27  
    28  	//For devices, returns BlockDev. Returns nil otherwise.
    29  	BlockInfo() *block.BlockDev
    30  
    31  	//For mounted devices, returns MountPoint. Returns nil otherwise.
    32  	MntPoint() *mount.MountPoint
    33  
    34  	//Unmount fs, free resources, etc
    35  	Cleanup() error
    36  }
    37  
    38  // HddResolver can identify and mount a partition.
    39  type HddResolver struct {
    40  	*block.BlockDev
    41  	*mount.MountPoint
    42  }
    43  
    44  var _ EfiPathSegmentResolver = (*HddResolver)(nil)
    45  
    46  func (r *HddResolver) String() string { return "/dev/" + r.BlockDev.Name }
    47  
    48  func (r *HddResolver) Resolve(basePath string) (string, error) {
    49  	if r.MountPoint != nil {
    50  		return r.MountPoint.Path, nil
    51  	}
    52  	var err error
    53  	if len(basePath) == 0 {
    54  		basePath, err = ioutil.TempDir("", "uefiPath")
    55  		if err != nil {
    56  			return "", err
    57  		}
    58  	} else {
    59  		fi, err := os.Stat(basePath)
    60  		if err != nil || !fi.IsDir() {
    61  			err = os.RemoveAll(basePath)
    62  			if err != nil {
    63  				return "", err
    64  			}
    65  			err = os.MkdirAll(basePath, 0755)
    66  			if err != nil {
    67  				return "", err
    68  			}
    69  		}
    70  	}
    71  	r.MountPoint, err = r.BlockDev.Mount(basePath, 0)
    72  	return r.MountPoint.Path, err
    73  }
    74  
    75  func (r *HddResolver) BlockInfo() *block.BlockDev { return r.BlockDev }
    76  
    77  func (r *HddResolver) MntPoint() *mount.MountPoint { return r.MountPoint }
    78  
    79  func (r *HddResolver) Cleanup() error {
    80  	if r.MountPoint != nil {
    81  		err := r.MountPoint.Unmount(unix.UMOUNT_NOFOLLOW | unix.MNT_DETACH)
    82  		if err == nil {
    83  			r.MountPoint = nil
    84  		}
    85  		return err
    86  	}
    87  	return nil
    88  }
    89  
    90  // PathResolver outputs a file path.
    91  type PathResolver string
    92  
    93  var _ EfiPathSegmentResolver = (*PathResolver)(nil)
    94  
    95  func (r *PathResolver) String() string { return string(*r) }
    96  
    97  func (r *PathResolver) Resolve(basePath string) (string, error) {
    98  	if len(basePath) == 0 {
    99  		log.Printf("uefi.PathResolver: empty base path")
   100  	}
   101  	return fp.Join(basePath, string(*r)), nil
   102  }
   103  
   104  func (r *PathResolver) BlockInfo() *block.BlockDev { return nil }
   105  
   106  func (r *PathResolver) MntPoint() *mount.MountPoint { return nil }
   107  
   108  func (r *PathResolver) Cleanup() error { return nil }