github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/vpd/vpd.go (about) 1 // Copyright 2017-2019 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 vpd 6 7 import ( 8 "io/ioutil" 9 "os" 10 "path" 11 "path/filepath" 12 ) 13 14 // VpdDir points to the base directory where the VPD sysfs interface is located. 15 // It is an exported variable to allow for testing 16 var ( 17 VpdDir = "/sys/firmware/vpd" 18 MaxBootEntry = 9999 19 ) 20 21 func getBaseDir(readOnly bool) string { 22 var baseDir string 23 if readOnly { 24 baseDir = path.Join(VpdDir, "ro") 25 } else { 26 baseDir = path.Join(VpdDir, "rw") 27 } 28 return baseDir 29 } 30 31 // Get reads a VPD variable by name and returns its value as a sequence of 32 // bytes. The `readOnly` flag specifies whether the variable is read-only or 33 // read-write. 34 func Get(key string, readOnly bool) ([]byte, error) { 35 buf, err := ioutil.ReadFile(path.Join(getBaseDir(readOnly), key)) 36 if err != nil { 37 return []byte{}, err 38 } 39 return buf, nil 40 } 41 42 // Set sets a VPD variable with `key` as name and `value` as its byte-stream 43 // value. The `readOnly` flag specifies whether the variable is read-only or 44 // read-write. 45 // NOTE Unfortunately Set doesn't currently work, because the sysfs interface 46 // does not support writing. To write, this library needs a backend able to 47 // write to flash chips, like the command line tool flashrom or flashtools. 48 func Set(key string, value []byte, readOnly bool) error { 49 // NOTE this is not implemented yet in the kernel interface, and will always 50 // return a permission denied error 51 return ioutil.WriteFile(path.Join(getBaseDir(readOnly), key), value, 0644) 52 } 53 54 // GetAll reads all the VPD variables and returns a map contaiing each 55 // name:value couple. The `readOnly` flag specifies whether the variable is 56 // read-only or read-write. 57 func GetAll(readOnly bool) (map[string][]byte, error) { 58 vpdMap := make(map[string][]byte) 59 baseDir := getBaseDir(readOnly) 60 err := filepath.Walk(baseDir, func(fpath string, info os.FileInfo, _ error) error { 61 key := path.Base(fpath) 62 if key == "." || key == "/" || fpath == baseDir { 63 // empty or all slashes? 64 return nil 65 } 66 value, err := Get(key, readOnly) 67 if err != nil { 68 return err 69 } 70 vpdMap[key] = value 71 return nil 72 }) 73 return vpdMap, err 74 }