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  }