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