build(deps): bump github.com/intel/goresctrl from 0.3.0 to 0.5.0

Bumps [github.com/intel/goresctrl](https://github.com/intel/goresctrl) from 0.3.0 to 0.5.0.
- [Release notes](https://github.com/intel/goresctrl/releases)
- [Commits](https://github.com/intel/goresctrl/compare/v0.3.0...v0.5.0)

---
updated-dependencies:
- dependency-name: github.com/intel/goresctrl
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2023-12-14 03:37:26 +00:00
committed by GitHub
parent a901236bf0
commit fc4b78c05c
25 changed files with 215 additions and 1671 deletions

View File

@@ -23,84 +23,86 @@ limitations under the License.
// Outputs:
// Option 1: Write blockio parameters of a class to a cgroup directory.
// Option 2: Return blockio parameters of a class in a OCI LinuxBlockIO
// structure, that can be passed to OCI-compliant container
// runtime.
//
// structure, that can be passed to OCI-compliant container
// runtime.
//
// Notes:
// - Using Weight requires bfq or cfq I/O scheduler to be
// effective for the block devices where Weight is used.
// - Using Weight requires bfq or cfq I/O scheduler to be
// effective for the block devices where Weight is used.
//
// Configuration example:
//
// Classes:
// Classes:
//
// # Define a blockio class "LowPrioThrottled".
// # Containers in this class will be throttled and handled as
// # low priority in the I/O scheduler.
// # Define a blockio class "LowPrioThrottled".
// # Containers in this class will be throttled and handled as
// # low priority in the I/O scheduler.
//
// LowPrioThrottled:
// LowPrioThrottled:
//
// # Weight without a Devices list specifies the default
// # I/O scheduler weight for all devices
// # that are not explicitly mentioned in following items.
// # This will be written to cgroups(.bfq).weight.
// # Weights range from 10 to 1000, the default is 100.
// # Weight without a Devices list specifies the default
// # I/O scheduler weight for all devices
// # that are not explicitly mentioned in following items.
// # This will be written to cgroups(.bfq).weight.
// # Weights range from 10 to 1000, the default is 100.
//
// - Weight: 80
// - Weight: 80
//
// # Set all parameters for all /dev/sd* and /dev/vd* block
// # devices.
// # Set all parameters for all /dev/sd* and /dev/vd* block
// # devices.
//
// - Devices:
// - /dev/sd[a-z]
// - /dev/vd[a-z]
// ThrottleReadBps: 50M # max read bytes per second
// ThrottleWriteBps: 10M # max write bytes per second
// ThrottleReadIOPS: 10k # max read io operations per second
// ThrottleWriteIOPS: 5k # max write io operations per second
// Weight: 50 # I/O scheduler (cfq/bfq) weight for
// # these devices will be written to
// # cgroups(.bfq).weight_device
// - Devices:
// - /dev/sd[a-z]
// - /dev/vd[a-z]
// ThrottleReadBps: 50M # max read bytes per second
// ThrottleWriteBps: 10M # max write bytes per second
// ThrottleReadIOPS: 10k # max read io operations per second
// ThrottleWriteIOPS: 5k # max write io operations per second
// Weight: 50 # I/O scheduler (cfq/bfq) weight for
// # these devices will be written to
// # cgroups(.bfq).weight_device
//
// # Set parameters particularly for SSD devices.
// # This configuration overrides above configurations for those
// # /dev/sd* and /dev/vd* devices whose disk id contains "SSD".
// # Set parameters particularly for SSD devices.
// # This configuration overrides above configurations for those
// # /dev/sd* and /dev/vd* devices whose disk id contains "SSD".
//
// - Devices:
// - /dev/disk/by-id/*SSD*
// ThrottleReadBps: 100M
// ThrottleWriteBps: 40M
// # Not mentioning Throttle*IOPS means no I/O operations
// # throttling on matching devices.
// Weight: 50
// - Devices:
// - /dev/disk/by-id/*SSD*
// ThrottleReadBps: 100M
// ThrottleWriteBps: 40M
// # Not mentioning Throttle*IOPS means no I/O operations
// # throttling on matching devices.
// Weight: 50
//
// # Define a blockio class "HighPrioFullSpeed".
// # There is no throttling on these containers, and
// # they will be prioritized by the I/O scheduler.
// # Define a blockio class "HighPrioFullSpeed".
// # There is no throttling on these containers, and
// # they will be prioritized by the I/O scheduler.
//
// HighPrioFullSpeed:
// - Weight: 400
// HighPrioFullSpeed:
// - Weight: 400
//
// Usage example:
// blockio.SetLogger(logrus.New())
// if err := blockio.SetConfigFromFile("/etc/containers/blockio.yaml", false); err != nil {
// return err
// }
// // Output option 1: write directly to cgroup "/mytestgroup"
// if err := blockio.SetCgroupClass("/mytestgroup", "LowPrioThrottled"); err != nil {
// return err
// }
// // Output option 2: OCI LinuxBlockIO of a blockio class
// if lbio, err := blockio.OciLinuxBlockIO("LowPrioThrottled"); err != nil {
// return err
// } else {
// fmt.Printf("OCI LinuxBlockIO for LowPrioThrottled:\n%+v\n", lbio)
// }
//
// blockio.SetLogger(logrus.New())
// if err := blockio.SetConfigFromFile("/etc/containers/blockio.yaml", false); err != nil {
// return err
// }
// // Output option 1: write directly to cgroup "/mytestgroup"
// if err := blockio.SetCgroupClass("/mytestgroup", "LowPrioThrottled"); err != nil {
// return err
// }
// // Output option 2: OCI LinuxBlockIO of a blockio class
// if lbio, err := blockio.OciLinuxBlockIO("LowPrioThrottled"); err != nil {
// return err
// } else {
// fmt.Printf("OCI LinuxBlockIO for LowPrioThrottled:\n%+v\n", lbio)
// }
package blockio
import (
"errors"
"fmt"
"io/ioutil"
stdlog "log"
"os"
"path/filepath"
@@ -113,10 +115,9 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
"sigs.k8s.io/yaml"
"github.com/hashicorp/go-multierror"
"github.com/intel/goresctrl/pkg/cgroups"
grclog "github.com/intel/goresctrl/pkg/log"
goresctrlpath "github.com/intel/goresctrl/pkg/path"
)
const (
@@ -146,11 +147,12 @@ var classBlockIO = map[string]cgroups.BlockIOParameters{}
// SetLogger sets the logger instance to be used by the package.
// Examples:
// // Log to standard logger:
// stdlog := log.New(os.Stderr, "blockio:", 0)
// blockio.SetLogger(goresctrllog.NewLoggerWrapper(stdlog))
// // Log to logrus:
// blockio.SetLogger(logrus.New())
//
// // Log to standard logger:
// stdlog := log.New(os.Stderr, "blockio:", 0)
// blockio.SetLogger(goresctrllog.NewLoggerWrapper(stdlog))
// // Log to logrus:
// blockio.SetLogger(logrus.New())
func SetLogger(l grclog.Logger) {
log = l
}
@@ -158,7 +160,7 @@ func SetLogger(l grclog.Logger) {
// SetConfigFromFile reads and applies blockio configuration from the
// filesystem.
func SetConfigFromFile(filename string, force bool) error {
if data, err := ioutil.ReadFile(filename); err == nil {
if data, err := os.ReadFile(filename); err == nil {
if err = SetConfigFromData(data, force); err != nil {
return fmt.Errorf("failed to set configuration from file %q: %s", filename, err)
}
@@ -237,13 +239,14 @@ func SetCgroupClass(group string, class string) error {
// Returns schedulers in a map: {"/dev/sda": "bfq"}
func getCurrentIOSchedulers() (map[string]string, error) {
var ios = map[string]string{}
schedulerFiles, err := filepath.Glob(sysfsBlockDeviceIOSchedulerPaths)
glob := goresctrlpath.Path(sysfsBlockDeviceIOSchedulerPaths)
schedulerFiles, err := filepath.Glob(glob)
if err != nil {
return ios, fmt.Errorf("error in I/O scheduler wildcards %#v: %w", sysfsBlockDeviceIOSchedulerPaths, err)
return ios, fmt.Errorf("error in I/O scheduler wildcards %#v: %w", glob, err)
}
for _, schedulerFile := range schedulerFiles {
devName := strings.SplitN(schedulerFile, "/", 5)[3]
schedulerDataB, err := ioutil.ReadFile(schedulerFile)
schedulerDataB, err := os.ReadFile(schedulerFile)
if err != nil {
// A block device may be disconnected.
log.Errorf("failed to read current I/O scheduler %#v: %v\n", schedulerFile, err)
@@ -272,27 +275,27 @@ func getCurrentIOSchedulers() (map[string]string, error) {
// deviceParametersToCgBlockIO converts single blockio class parameters into cgroups blkio format.
func devicesParametersToCgBlockIO(dps []DevicesParameters, currentIOSchedulers map[string]string) (cgroups.BlockIOParameters, error) {
var errors *multierror.Error
errs := []error{}
blkio := cgroups.NewBlockIOParameters()
for _, dp := range dps {
var err error
var weight, throttleReadBps, throttleWriteBps, throttleReadIOPS, throttleWriteIOPS int64
weight, err = parseAndValidateQuantity("Weight", dp.Weight, -1, 10, 1000)
errors = multierror.Append(errors, err)
errs = append(errs, err)
throttleReadBps, err = parseAndValidateQuantity("ThrottleReadBps", dp.ThrottleReadBps, -1, 0, -1)
errors = multierror.Append(errors, err)
errs = append(errs, err)
throttleWriteBps, err = parseAndValidateQuantity("ThrottleWriteBps", dp.ThrottleWriteBps, -1, 0, -1)
errors = multierror.Append(errors, err)
errs = append(errs, err)
throttleReadIOPS, err = parseAndValidateQuantity("ThrottleReadIOPS", dp.ThrottleReadIOPS, -1, 0, -1)
errors = multierror.Append(errors, err)
errs = append(errs, err)
throttleWriteIOPS, err = parseAndValidateQuantity("ThrottleWriteIOPS", dp.ThrottleWriteIOPS, -1, 0, -1)
errors = multierror.Append(errors, err)
errs = append(errs, err)
if dp.Devices == nil {
if weight > -1 {
blkio.Weight = weight
}
if throttleReadBps > -1 || throttleWriteBps > -1 || throttleReadIOPS > -1 || throttleWriteIOPS > -1 {
errors = multierror.Append(errors, fmt.Errorf("ignoring throttling (rbps=%#v wbps=%#v riops=%#v wiops=%#v): Devices not listed",
errs = append(errs, fmt.Errorf("ignoring throttling (rbps=%#v wbps=%#v riops=%#v wiops=%#v): Devices not listed",
dp.ThrottleReadBps, dp.ThrottleWriteBps, dp.ThrottleReadIOPS, dp.ThrottleWriteIOPS))
}
} else {
@@ -330,7 +333,7 @@ func devicesParametersToCgBlockIO(dps []DevicesParameters, currentIOSchedulers m
}
}
}
return blkio, errors.ErrorOrNil()
return blkio, errors.Join(errs...)
}
// parseAndValidateQuantity parses quantities, like "64 M", and validates that they are in given range.
@@ -369,7 +372,7 @@ var currentPlatform platformInterface = defaultPlatform{}
func (dpm defaultPlatform) configurableBlockDevices(devWildcards []string) ([]tBlockDeviceInfo, error) {
// Return map {devNode: tBlockDeviceInfo}
// Example: {"/dev/sda": {Major:8, Minor:0, Origin:"from symlink /dev/disk/by-id/ata-VendorXSSD from wildcard /dev/disk/by-id/*SSD*"}}
var errors *multierror.Error
errs := []error{}
blockDevices := []tBlockDeviceInfo{}
var origin string
@@ -379,11 +382,11 @@ func (dpm defaultPlatform) configurableBlockDevices(devWildcards []string) ([]tB
for _, devWildcard := range devWildcards {
devWildcardMatches, err := filepath.Glob(devWildcard)
if err != nil {
errors = multierror.Append(errors, fmt.Errorf("bad device wildcard %#v: %w", devWildcard, err))
errs = append(errs, fmt.Errorf("bad device wildcard %#v: %w", devWildcard, err))
continue
}
if len(devWildcardMatches) == 0 {
errors = multierror.Append(errors, fmt.Errorf("device wildcard %#v does not match any device nodes", devWildcard))
errs = append(errs, fmt.Errorf("device wildcard %#v does not match any device nodes", devWildcard))
continue
}
for _, devMatch := range devWildcardMatches {
@@ -402,7 +405,7 @@ func (dpm defaultPlatform) configurableBlockDevices(devWildcards []string) ([]tB
for devMatch, devOrigin := range devMatches {
realDevNode, err := filepath.EvalSymlinks(devMatch)
if err != nil {
errors = multierror.Append(errors, fmt.Errorf("cannot filepath.EvalSymlinks(%#v): %w", devMatch, err))
errs = append(errs, fmt.Errorf("cannot filepath.EvalSymlinks(%#v): %w", devMatch, err))
continue
}
if realDevNode != devMatch {
@@ -422,27 +425,23 @@ func (dpm defaultPlatform) configurableBlockDevices(devWildcards []string) ([]tB
}
fileInfo, err := os.Stat(devRealpath)
if err != nil {
errors = multierror.Append(errors, fmt.Errorf("cannot os.Stat(%#v): %w%s", devRealpath, err, origin))
errs = append(errs, fmt.Errorf("cannot os.Stat(%#v): %w%s", devRealpath, err, origin))
continue
}
fileMode := fileInfo.Mode()
if fileMode&os.ModeDevice == 0 {
errors = multierror.Append(errors, fmt.Errorf("file %#v is not a device%s", devRealpath, origin))
errs = append(errs, fmt.Errorf("file %#v is not a device%s", devRealpath, origin))
continue
}
if fileMode&os.ModeCharDevice != 0 {
errors = multierror.Append(errors, fmt.Errorf("file %#v is a character device%s", devRealpath, origin))
errs = append(errs, fmt.Errorf("file %#v is a character device%s", devRealpath, origin))
continue
}
sys, ok := fileInfo.Sys().(*syscall.Stat_t)
major := unix.Major(uint64(sys.Rdev))
minor := unix.Minor(uint64(sys.Rdev))
if !ok {
errors = multierror.Append(errors, fmt.Errorf("cannot get syscall stat_t from %#v: %w%s", devRealpath, err, origin))
continue
}
if minor&0xf != 0 {
errors = multierror.Append(errors, fmt.Errorf("skipping %#v: cannot weight/throttle partitions%s", devRealpath, origin))
errs = append(errs, fmt.Errorf("cannot get syscall stat_t from %#v: %w%s", devRealpath, err, origin))
continue
}
blockDevices = append(blockDevices, tBlockDeviceInfo{
@@ -452,5 +451,5 @@ func (dpm defaultPlatform) configurableBlockDevices(devWildcards []string) ([]tB
Origin: devOrigin,
})
}
return blockDevices, errors.ErrorOrNil()
return blockDevices, errors.Join(errs...)
}