Merge pull request #9577 from containerd/dependabot/go_modules/github.com/intel/goresctrl-0.6.0
build(deps): bump github.com/intel/goresctrl from 0.5.0 to 0.6.0
This commit is contained in:
commit
ee9638dbba
2
go.mod
2
go.mod
@ -34,7 +34,7 @@ require (
|
||||
github.com/google/uuid v1.5.0
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/intel/goresctrl v0.5.0
|
||||
github.com/intel/goresctrl v0.6.0
|
||||
github.com/klauspost/compress v1.17.4
|
||||
github.com/minio/sha256-simd v1.0.1
|
||||
github.com/moby/locker v1.0.1
|
||||
|
4
go.sum
4
go.sum
@ -177,8 +177,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/intel/goresctrl v0.5.0 h1:kcDhjE3ZF/mNrJuRzLS3LY2Hp6atFaF1XVFBT7SVL2g=
|
||||
github.com/intel/goresctrl v0.5.0/go.mod h1:mIe63ggylWYr0cU/l8n11FAkesqfvuP3oktIsxvu0T0=
|
||||
github.com/intel/goresctrl v0.6.0 h1:lOqo9o+uXtqPwSB4vpd1greUcWlkBSTPdnbTFgRILf4=
|
||||
github.com/intel/goresctrl v0.6.0/go.mod h1:Qg+rhwvfW78p22OJi649sCH71bJIBX7zT0b+IGe69eE=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
|
29
vendor/github.com/intel/goresctrl/pkg/blockio/blockio.go
generated
vendored
29
vendor/github.com/intel/goresctrl/pkg/blockio/blockio.go
generated
vendored
@ -115,7 +115,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/intel/goresctrl/pkg/cgroups"
|
||||
grclog "github.com/intel/goresctrl/pkg/log"
|
||||
goresctrlpath "github.com/intel/goresctrl/pkg/path"
|
||||
)
|
||||
@ -143,7 +142,7 @@ var log grclog.Logger = grclog.NewLoggerWrapper(stdlog.New(os.Stderr, "[ blockio
|
||||
|
||||
// classBlockIO connects user-defined block I/O classes to
|
||||
// corresponding cgroups blockio controller parameters.
|
||||
var classBlockIO = map[string]cgroups.BlockIOParameters{}
|
||||
var classBlockIO = map[string]BlockIOParameters{}
|
||||
|
||||
// SetLogger sets the logger instance to be used by the package.
|
||||
// Examples:
|
||||
@ -173,7 +172,7 @@ func SetConfigFromFile(filename string, force bool) error {
|
||||
// SetConfigFromData parses and applies configuration from data.
|
||||
func SetConfigFromData(data []byte, force bool) error {
|
||||
config := &Config{}
|
||||
if err := yaml.Unmarshal(data, &config); err != nil {
|
||||
if err := yaml.UnmarshalStrict(data, &config); err != nil {
|
||||
return err
|
||||
}
|
||||
return SetConfig(config, force)
|
||||
@ -184,7 +183,7 @@ func SetConfig(opt *Config, force bool) error {
|
||||
if opt == nil {
|
||||
// Setting nil configuration clears current configuration.
|
||||
// SetConfigFromData([]byte(""), dontcare) arrives here.
|
||||
classBlockIO = map[string]cgroups.BlockIOParameters{}
|
||||
classBlockIO = map[string]BlockIOParameters{}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -193,7 +192,7 @@ func SetConfig(opt *Config, force bool) error {
|
||||
log.Warnf("configuration validation partly disabled due to I/O scheduler detection error %#v", ioSchedulerDetectionError.Error())
|
||||
}
|
||||
|
||||
classBlockIO = map[string]cgroups.BlockIOParameters{}
|
||||
classBlockIO = map[string]BlockIOParameters{}
|
||||
// Create cgroup blockio parameters for each blockio class
|
||||
for class := range opt.Classes {
|
||||
cgBlockIO, err := devicesParametersToCgBlockIO(opt.Classes[class], currentIOSchedulers)
|
||||
@ -219,22 +218,6 @@ func GetClasses() []string {
|
||||
return classNames
|
||||
}
|
||||
|
||||
// SetCgroupClass sets cgroup blkio controller parameters to match
|
||||
// blockio class. "group" is the cgroup directory of the container
|
||||
// without mountpoint and controller (blkio) directories:
|
||||
// "/kubepods/burstable/POD_ID/CONTAINER_ID".
|
||||
func SetCgroupClass(group string, class string) error {
|
||||
cgBlockIO, ok := classBlockIO[class]
|
||||
if !ok {
|
||||
return fmt.Errorf("no BlockIO parameters for class %#v", class)
|
||||
}
|
||||
err := cgroups.ResetBlkioParameters(group, cgBlockIO)
|
||||
if err != nil {
|
||||
return fmt.Errorf("assigning container in cgroup %q to class %#v failed: %w", group, class, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getCurrentIOSchedulers returns currently active I/O scheduler used for each block device in the system.
|
||||
// Returns schedulers in a map: {"/dev/sda": "bfq"}
|
||||
func getCurrentIOSchedulers() (map[string]string, error) {
|
||||
@ -274,9 +257,9 @@ 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) {
|
||||
func devicesParametersToCgBlockIO(dps []DevicesParameters, currentIOSchedulers map[string]string) (BlockIOParameters, error) {
|
||||
errs := []error{}
|
||||
blkio := cgroups.NewBlockIOParameters()
|
||||
blkio := NewBlockIOParameters()
|
||||
for _, dp := range dps {
|
||||
var err error
|
||||
var weight, throttleReadBps, throttleWriteBps, throttleReadIOPS, throttleWriteIOPS int64
|
||||
|
103
vendor/github.com/intel/goresctrl/pkg/blockio/cgroups.go
generated
vendored
Normal file
103
vendor/github.com/intel/goresctrl/pkg/blockio/cgroups.go
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
// Copyright 2020-2021 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package blockio
|
||||
|
||||
// BlockIOParameters contains cgroups blockio controller parameters.
|
||||
//
|
||||
// Effects of Weight and Rate values in SetBlkioParameters():
|
||||
// Value | Effect
|
||||
// -------+-------------------------------------------------------------------
|
||||
//
|
||||
// -1 | Do not write to cgroups, value is missing.
|
||||
// 0 | Write to cgroups, will clear the setting as specified in cgroups blkio interface.
|
||||
// other | Write to cgroups, sets the value.
|
||||
type BlockIOParameters struct {
|
||||
Weight int64
|
||||
WeightDevice DeviceWeights
|
||||
ThrottleReadBpsDevice DeviceRates
|
||||
ThrottleWriteBpsDevice DeviceRates
|
||||
ThrottleReadIOPSDevice DeviceRates
|
||||
ThrottleWriteIOPSDevice DeviceRates
|
||||
}
|
||||
|
||||
// DeviceWeight contains values for
|
||||
// - blkio.[io-scheduler].weight
|
||||
type DeviceWeight struct {
|
||||
Major int64
|
||||
Minor int64
|
||||
Weight int64
|
||||
}
|
||||
|
||||
// DeviceRate contains values for
|
||||
// - blkio.throttle.read_bps_device
|
||||
// - blkio.throttle.write_bps_device
|
||||
// - blkio.throttle.read_iops_device
|
||||
// - blkio.throttle.write_iops_device
|
||||
type DeviceRate struct {
|
||||
Major int64
|
||||
Minor int64
|
||||
Rate int64
|
||||
}
|
||||
|
||||
// DeviceWeights contains weights for devices.
|
||||
type DeviceWeights []DeviceWeight
|
||||
|
||||
// DeviceRates contains throttling rates for devices.
|
||||
type DeviceRates []DeviceRate
|
||||
|
||||
// NewBlockIOParameters creates new BlockIOParameters instance.
|
||||
func NewBlockIOParameters() BlockIOParameters {
|
||||
return BlockIOParameters{
|
||||
Weight: -1,
|
||||
}
|
||||
}
|
||||
|
||||
// DeviceParameters interface provides functions common to DeviceWeights and DeviceRates.
|
||||
type DeviceParameters interface {
|
||||
Append(maj, min, val int64)
|
||||
Update(maj, min, val int64)
|
||||
}
|
||||
|
||||
// Append appends (major, minor, value) to DeviceWeights slice.
|
||||
func (w *DeviceWeights) Append(maj, min, val int64) {
|
||||
*w = append(*w, DeviceWeight{Major: maj, Minor: min, Weight: val})
|
||||
}
|
||||
|
||||
// Append appends (major, minor, value) to DeviceRates slice.
|
||||
func (r *DeviceRates) Append(maj, min, val int64) {
|
||||
*r = append(*r, DeviceRate{Major: maj, Minor: min, Rate: val})
|
||||
}
|
||||
|
||||
// Update updates device weight in DeviceWeights slice, or appends it if not found.
|
||||
func (w *DeviceWeights) Update(maj, min, val int64) {
|
||||
for index, devWeight := range *w {
|
||||
if devWeight.Major == maj && devWeight.Minor == min {
|
||||
(*w)[index].Weight = val
|
||||
return
|
||||
}
|
||||
}
|
||||
w.Append(maj, min, val)
|
||||
}
|
||||
|
||||
// Update updates device rate in DeviceRates slice, or appends it if not found.
|
||||
func (r *DeviceRates) Update(maj, min, val int64) {
|
||||
for index, devRate := range *r {
|
||||
if devRate.Major == maj && devRate.Minor == min {
|
||||
(*r)[index].Rate = val
|
||||
return
|
||||
}
|
||||
}
|
||||
r.Append(maj, min, val)
|
||||
}
|
6
vendor/github.com/intel/goresctrl/pkg/blockio/oci.go
generated
vendored
6
vendor/github.com/intel/goresctrl/pkg/blockio/oci.go
generated
vendored
@ -20,8 +20,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
oci "github.com/opencontainers/runtime-spec/specs-go"
|
||||
|
||||
"github.com/intel/goresctrl/pkg/cgroups"
|
||||
)
|
||||
|
||||
// OciLinuxBlockIO returns OCI LinuxBlockIO structure corresponding to the class.
|
||||
@ -43,7 +41,7 @@ func OciLinuxBlockIO(class string) (*oci.LinuxBlockIO, error) {
|
||||
return &ociBlockio, nil
|
||||
}
|
||||
|
||||
func ociLinuxWeightDevices(dws cgroups.DeviceWeights) []oci.LinuxWeightDevice {
|
||||
func ociLinuxWeightDevices(dws DeviceWeights) []oci.LinuxWeightDevice {
|
||||
if len(dws) == 0 {
|
||||
return nil
|
||||
}
|
||||
@ -57,7 +55,7 @@ func ociLinuxWeightDevices(dws cgroups.DeviceWeights) []oci.LinuxWeightDevice {
|
||||
return olwds
|
||||
}
|
||||
|
||||
func ociLinuxThrottleDevices(drs cgroups.DeviceRates) []oci.LinuxThrottleDevice {
|
||||
func ociLinuxThrottleDevices(drs DeviceRates) []oci.LinuxThrottleDevice {
|
||||
if len(drs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
312
vendor/github.com/intel/goresctrl/pkg/cgroups/cgroupblkio.go
generated
vendored
312
vendor/github.com/intel/goresctrl/pkg/cgroups/cgroupblkio.go
generated
vendored
@ -1,312 +0,0 @@
|
||||
// Copyright 2020-2021 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cgroups
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// cgroups blkio parameter filenames.
|
||||
var blkioWeightFiles = []string{"blkio.bfq.weight", "blkio.weight"}
|
||||
var blkioWeightDeviceFiles = []string{"blkio.bfq.weight_device", "blkio.weight_device"}
|
||||
var blkioThrottleReadBpsFiles = []string{"blkio.throttle.read_bps_device"}
|
||||
var blkioThrottleWriteBpsFiles = []string{"blkio.throttle.write_bps_device"}
|
||||
var blkioThrottleReadIOPSFiles = []string{"blkio.throttle.read_iops_device"}
|
||||
var blkioThrottleWriteIOPSFiles = []string{"blkio.throttle.write_iops_device"}
|
||||
|
||||
// BlockIOParameters contains cgroups blockio controller parameters.
|
||||
//
|
||||
// Effects of Weight and Rate values in SetBlkioParameters():
|
||||
// Value | Effect
|
||||
// -------+-------------------------------------------------------------------
|
||||
//
|
||||
// -1 | Do not write to cgroups, value is missing.
|
||||
// 0 | Write to cgroups, will clear the setting as specified in cgroups blkio interface.
|
||||
// other | Write to cgroups, sets the value.
|
||||
type BlockIOParameters struct {
|
||||
Weight int64
|
||||
WeightDevice DeviceWeights
|
||||
ThrottleReadBpsDevice DeviceRates
|
||||
ThrottleWriteBpsDevice DeviceRates
|
||||
ThrottleReadIOPSDevice DeviceRates
|
||||
ThrottleWriteIOPSDevice DeviceRates
|
||||
}
|
||||
|
||||
// DeviceWeight contains values for
|
||||
// - blkio.[io-scheduler].weight
|
||||
type DeviceWeight struct {
|
||||
Major int64
|
||||
Minor int64
|
||||
Weight int64
|
||||
}
|
||||
|
||||
// DeviceRate contains values for
|
||||
// - blkio.throttle.read_bps_device
|
||||
// - blkio.throttle.write_bps_device
|
||||
// - blkio.throttle.read_iops_device
|
||||
// - blkio.throttle.write_iops_device
|
||||
type DeviceRate struct {
|
||||
Major int64
|
||||
Minor int64
|
||||
Rate int64
|
||||
}
|
||||
|
||||
// DeviceWeights contains weights for devices.
|
||||
type DeviceWeights []DeviceWeight
|
||||
|
||||
// DeviceRates contains throttling rates for devices.
|
||||
type DeviceRates []DeviceRate
|
||||
|
||||
// DeviceParameters interface provides functions common to DeviceWeights and DeviceRates.
|
||||
type DeviceParameters interface {
|
||||
Append(maj, min, val int64)
|
||||
Update(maj, min, val int64)
|
||||
}
|
||||
|
||||
// Append appends (major, minor, value) to DeviceWeights slice.
|
||||
func (w *DeviceWeights) Append(maj, min, val int64) {
|
||||
*w = append(*w, DeviceWeight{Major: maj, Minor: min, Weight: val})
|
||||
}
|
||||
|
||||
// Append appends (major, minor, value) to DeviceRates slice.
|
||||
func (r *DeviceRates) Append(maj, min, val int64) {
|
||||
*r = append(*r, DeviceRate{Major: maj, Minor: min, Rate: val})
|
||||
}
|
||||
|
||||
// Update updates device weight in DeviceWeights slice, or appends it if not found.
|
||||
func (w *DeviceWeights) Update(maj, min, val int64) {
|
||||
for index, devWeight := range *w {
|
||||
if devWeight.Major == maj && devWeight.Minor == min {
|
||||
(*w)[index].Weight = val
|
||||
return
|
||||
}
|
||||
}
|
||||
w.Append(maj, min, val)
|
||||
}
|
||||
|
||||
// Update updates device rate in DeviceRates slice, or appends it if not found.
|
||||
func (r *DeviceRates) Update(maj, min, val int64) {
|
||||
for index, devRate := range *r {
|
||||
if devRate.Major == maj && devRate.Minor == min {
|
||||
(*r)[index].Rate = val
|
||||
return
|
||||
}
|
||||
}
|
||||
r.Append(maj, min, val)
|
||||
}
|
||||
|
||||
// NewBlockIOParameters creates new BlockIOParameters instance.
|
||||
func NewBlockIOParameters() BlockIOParameters {
|
||||
return BlockIOParameters{
|
||||
Weight: -1,
|
||||
}
|
||||
}
|
||||
|
||||
// NewDeviceWeight creates new DeviceWeight instance.
|
||||
func NewDeviceWeight() DeviceWeight {
|
||||
return DeviceWeight{
|
||||
Major: -1,
|
||||
Minor: -1,
|
||||
Weight: -1,
|
||||
}
|
||||
}
|
||||
|
||||
// NewDeviceRate creates new DeviceRate instance.
|
||||
func NewDeviceRate() DeviceRate {
|
||||
return DeviceRate{
|
||||
Major: -1,
|
||||
Minor: -1,
|
||||
Rate: -1,
|
||||
}
|
||||
}
|
||||
|
||||
type devMajMin struct {
|
||||
Major int64
|
||||
Minor int64
|
||||
}
|
||||
|
||||
// ResetBlkioParameters adds new, changes existing and removes missing blockIO parameters in cgroupsDir.
|
||||
func ResetBlkioParameters(groupDir string, blockIO BlockIOParameters) error {
|
||||
errs := []error{}
|
||||
oldBlockIO, _ := GetBlkioParameters(groupDir)
|
||||
newBlockIO := NewBlockIOParameters()
|
||||
newBlockIO.Weight = blockIO.Weight
|
||||
newBlockIO.WeightDevice = resetDevWeights(oldBlockIO.WeightDevice, blockIO.WeightDevice)
|
||||
newBlockIO.ThrottleReadBpsDevice = resetDevRates(oldBlockIO.ThrottleReadBpsDevice, blockIO.ThrottleReadBpsDevice)
|
||||
newBlockIO.ThrottleWriteBpsDevice = resetDevRates(oldBlockIO.ThrottleWriteBpsDevice, blockIO.ThrottleWriteBpsDevice)
|
||||
newBlockIO.ThrottleReadIOPSDevice = resetDevRates(oldBlockIO.ThrottleReadIOPSDevice, blockIO.ThrottleReadIOPSDevice)
|
||||
newBlockIO.ThrottleWriteIOPSDevice = resetDevRates(oldBlockIO.ThrottleWriteIOPSDevice, blockIO.ThrottleWriteIOPSDevice)
|
||||
errs = append(errs, SetBlkioParameters(groupDir, newBlockIO))
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
// resetDevWeights adds wanted weight parameters to new and resets unwanted weights.
|
||||
func resetDevWeights(old, wanted []DeviceWeight) []DeviceWeight {
|
||||
new := []DeviceWeight{}
|
||||
seenDev := map[devMajMin]bool{}
|
||||
for _, wdp := range wanted {
|
||||
seenDev[devMajMin{wdp.Major, wdp.Minor}] = true
|
||||
new = append(new, wdp)
|
||||
}
|
||||
for _, wdp := range old {
|
||||
if !seenDev[devMajMin{wdp.Major, wdp.Minor}] {
|
||||
new = append(new, DeviceWeight{wdp.Major, wdp.Minor, 0})
|
||||
}
|
||||
}
|
||||
return new
|
||||
}
|
||||
|
||||
// resetDevRates adds wanted rate parameters to new and resets unwanted rates.
|
||||
func resetDevRates(old, wanted []DeviceRate) []DeviceRate {
|
||||
new := []DeviceRate{}
|
||||
seenDev := map[devMajMin]bool{}
|
||||
for _, rdp := range wanted {
|
||||
new = append(new, rdp)
|
||||
seenDev[devMajMin{rdp.Major, rdp.Minor}] = true
|
||||
}
|
||||
for _, rdp := range old {
|
||||
if !seenDev[devMajMin{rdp.Major, rdp.Minor}] {
|
||||
new = append(new, DeviceRate{rdp.Major, rdp.Minor, 0})
|
||||
}
|
||||
}
|
||||
return new
|
||||
}
|
||||
|
||||
// GetBlkioParameters returns BlockIO parameters from files in cgroups blkio controller directory.
|
||||
func GetBlkioParameters(group string) (BlockIOParameters, error) {
|
||||
errs := []error{}
|
||||
blockIO := NewBlockIOParameters()
|
||||
|
||||
errs = append(errs, readWeight(group, blkioWeightFiles, &blockIO.Weight))
|
||||
errs = append(errs, readDeviceParameters(group, blkioWeightDeviceFiles, &blockIO.WeightDevice))
|
||||
errs = append(errs, readDeviceParameters(group, blkioThrottleReadBpsFiles, &blockIO.ThrottleReadBpsDevice))
|
||||
errs = append(errs, readDeviceParameters(group, blkioThrottleWriteBpsFiles, &blockIO.ThrottleWriteBpsDevice))
|
||||
errs = append(errs, readDeviceParameters(group, blkioThrottleReadIOPSFiles, &blockIO.ThrottleReadIOPSDevice))
|
||||
errs = append(errs, readDeviceParameters(group, blkioThrottleWriteIOPSFiles, &blockIO.ThrottleWriteIOPSDevice))
|
||||
return blockIO, errors.Join(errs...)
|
||||
}
|
||||
|
||||
// readWeight parses int64 from a cgroups entry.
|
||||
func readWeight(groupDir string, filenames []string, rv *int64) error {
|
||||
contents, err := readFirstFile(groupDir, filenames)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parsed, err := strconv.ParseInt(strings.TrimSuffix(contents, "\n"), 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing weight from %#v found in %v failed: %w", contents, filenames, err)
|
||||
}
|
||||
*rv = parsed
|
||||
return nil
|
||||
}
|
||||
|
||||
// readDeviceParameters parses device lines used for weights and throttling rates.
|
||||
func readDeviceParameters(groupDir string, filenames []string, params DeviceParameters) error {
|
||||
errs := []error{}
|
||||
contents, err := readFirstFile(groupDir, filenames)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, line := range strings.Split(contents, "\n") {
|
||||
// Device weight files may have "default NNN" line at the beginning. Skip it.
|
||||
if line == "" || strings.HasPrefix(line, "default ") {
|
||||
continue
|
||||
}
|
||||
// Expect syntax MAJOR:MINOR VALUE
|
||||
devVal := strings.Split(line, " ")
|
||||
if len(devVal) != 2 {
|
||||
errs = append(errs, fmt.Errorf("invalid line %q, single space expected", line))
|
||||
continue
|
||||
}
|
||||
majMin := strings.Split(devVal[0], ":")
|
||||
if len(majMin) != 2 {
|
||||
errs = append(errs, fmt.Errorf("invalid line %q, single colon expected before space", line))
|
||||
continue
|
||||
}
|
||||
major, majErr := strconv.ParseInt(majMin[0], 10, 64)
|
||||
minor, minErr := strconv.ParseInt(majMin[1], 10, 64)
|
||||
value, valErr := strconv.ParseInt(devVal[1], 10, 64)
|
||||
if majErr != nil || minErr != nil || valErr != nil {
|
||||
errs = append(errs, fmt.Errorf("invalid number when parsing \"major:minor value\" from \"%s:%s %s\"", majMin[0], majMin[1], devVal[1]))
|
||||
continue
|
||||
}
|
||||
params.Append(major, minor, value)
|
||||
}
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
// readFirstFile returns contents of the first successfully read entry.
|
||||
func readFirstFile(groupDir string, filenames []string) (string, error) {
|
||||
errs := []error{}
|
||||
// If reading all the files fails, return list of read errors.
|
||||
for _, filename := range filenames {
|
||||
content, err := Blkio.Group(groupDir).Read(filename)
|
||||
if err == nil {
|
||||
return content, nil
|
||||
}
|
||||
errs = append(errs, err)
|
||||
}
|
||||
err := errors.Join(errs...)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not read any of files %q: %w", filenames, err)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// SetBlkioParameters writes BlockIO parameters to files in cgroups blkio contoller directory.
|
||||
func SetBlkioParameters(group string, blockIO BlockIOParameters) error {
|
||||
errs := []error{}
|
||||
if blockIO.Weight >= 0 {
|
||||
errs = append(errs, writeFirstFile(group, blkioWeightFiles, "%d", blockIO.Weight))
|
||||
}
|
||||
for _, wd := range blockIO.WeightDevice {
|
||||
errs = append(errs, writeFirstFile(group, blkioWeightDeviceFiles, "%d:%d %d", wd.Major, wd.Minor, wd.Weight))
|
||||
}
|
||||
for _, rd := range blockIO.ThrottleReadBpsDevice {
|
||||
errs = append(errs, writeFirstFile(group, blkioThrottleReadBpsFiles, "%d:%d %d", rd.Major, rd.Minor, rd.Rate))
|
||||
}
|
||||
for _, rd := range blockIO.ThrottleWriteBpsDevice {
|
||||
errs = append(errs, writeFirstFile(group, blkioThrottleWriteBpsFiles, "%d:%d %d", rd.Major, rd.Minor, rd.Rate))
|
||||
}
|
||||
for _, rd := range blockIO.ThrottleReadIOPSDevice {
|
||||
errs = append(errs, writeFirstFile(group, blkioThrottleReadIOPSFiles, "%d:%d %d", rd.Major, rd.Minor, rd.Rate))
|
||||
}
|
||||
for _, rd := range blockIO.ThrottleWriteIOPSDevice {
|
||||
errs = append(errs, writeFirstFile(group, blkioThrottleWriteIOPSFiles, "%d:%d %d", rd.Major, rd.Minor, rd.Rate))
|
||||
}
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
// writeFirstFile writes content to the first existing file in the list under groupDir.
|
||||
func writeFirstFile(groupDir string, filenames []string, format string, args ...interface{}) error {
|
||||
errs := []error{}
|
||||
// Returns list of errors from writes, list of single error due to all filenames missing or nil on success.
|
||||
for _, filename := range filenames {
|
||||
if err := Blkio.Group(groupDir).Write(filename, format, args...); err != nil {
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err := errors.Join(errs...)
|
||||
if err != nil {
|
||||
data := fmt.Sprintf(format, args...)
|
||||
return fmt.Errorf("writing all files %v failed, errors: %w, content %q", filenames, err, data)
|
||||
}
|
||||
return nil
|
||||
}
|
237
vendor/github.com/intel/goresctrl/pkg/cgroups/cgroupcontrol.go
generated
vendored
237
vendor/github.com/intel/goresctrl/pkg/cgroups/cgroupcontrol.go
generated
vendored
@ -1,237 +0,0 @@
|
||||
// Copyright 2020-2021 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cgroups
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Controller is our enumerated type for cgroup controllers.
|
||||
type Controller int
|
||||
|
||||
// Group represents a control group.
|
||||
type Group string
|
||||
|
||||
// nolint
|
||||
const (
|
||||
// UnkownController represents a controller of unknown type.
|
||||
UnknownController Controller = iota
|
||||
// blkio cgroup controller.
|
||||
Blkio
|
||||
// cpu cgroup controller.
|
||||
Cpu
|
||||
// cpuacct cgroup controller.
|
||||
Cpuacct
|
||||
// cpuset cgroup controller.
|
||||
Cpuset
|
||||
// devices cgroup controller.
|
||||
Devices
|
||||
// freezer cgroup controller.
|
||||
Freezer
|
||||
// hugetlb cgroup controller.
|
||||
Hugetlb
|
||||
// memory cgroup controller.
|
||||
Memory
|
||||
// net_cls cgroup controller.
|
||||
NetCls
|
||||
// net_prio cgroup controller.
|
||||
NetPrio
|
||||
// per_event cgroup controller.
|
||||
PerfEvent
|
||||
// pids cgroup controller.
|
||||
Pids
|
||||
)
|
||||
|
||||
var (
|
||||
// controllerNames maps controllers to names/relative paths.
|
||||
controllerNames = map[Controller]string{
|
||||
Blkio: "blkio",
|
||||
Cpu: "cpu",
|
||||
Cpuacct: "cpuacct",
|
||||
Cpuset: "cpuset",
|
||||
Devices: "devices",
|
||||
Freezer: "freezer",
|
||||
Hugetlb: "hugetlb",
|
||||
Memory: "memory",
|
||||
NetCls: "net_cls",
|
||||
NetPrio: "net_prio",
|
||||
PerfEvent: "perf_event",
|
||||
Pids: "pids",
|
||||
}
|
||||
|
||||
// controllerNames maps controllers to names/relative paths.
|
||||
controllerDirs = map[string]Controller{
|
||||
"blkio": Blkio,
|
||||
"cpu": Cpu,
|
||||
"cpuacct": Cpuacct,
|
||||
"cpuset": Cpuset,
|
||||
"devices": Devices,
|
||||
"freezer": Freezer,
|
||||
"hugetlb": Hugetlb,
|
||||
"memory": Memory,
|
||||
"net_cls": NetCls,
|
||||
"net_prio": NetPrio,
|
||||
"perf_event": PerfEvent,
|
||||
"pids": Pids,
|
||||
}
|
||||
)
|
||||
|
||||
// String returns the name of the given controller.
|
||||
func (c Controller) String() string {
|
||||
if name, ok := controllerNames[c]; ok {
|
||||
return name
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
// Path returns the absolute path of the given controller.
|
||||
func (c Controller) Path() string {
|
||||
return cgroupPath(c.String())
|
||||
}
|
||||
|
||||
// RelPath returns the relative path of the given controller.
|
||||
func (c Controller) RelPath() string {
|
||||
return c.String()
|
||||
}
|
||||
|
||||
// Group returns the given group for the controller.
|
||||
func (c Controller) Group(group string) Group {
|
||||
return Group(cgroupPath(c.String(), group))
|
||||
}
|
||||
|
||||
// AsGroup returns the group for the given absolute directory path.
|
||||
func AsGroup(absDir string) Group {
|
||||
return Group(absDir)
|
||||
}
|
||||
|
||||
// Controller returns the controller for the group.
|
||||
func (g Group) Controller() Controller {
|
||||
relPath := strings.TrimPrefix(string(g), cgroupPath()+"/")
|
||||
split := strings.SplitN(relPath, "/", 2)
|
||||
if len(split) > 0 {
|
||||
return controllerDirs[split[0]]
|
||||
}
|
||||
return UnknownController
|
||||
}
|
||||
|
||||
// GetTasks reads the pids of threads currently assigned to the group.
|
||||
func (g Group) GetTasks() ([]string, error) {
|
||||
return g.readPids(Tasks)
|
||||
}
|
||||
|
||||
// GetProcesses reads the pids of processes currently assigned to the group.
|
||||
func (g Group) GetProcesses() ([]string, error) {
|
||||
return g.readPids(Procs)
|
||||
}
|
||||
|
||||
// AddTasks writes the given thread pids to the group.
|
||||
func (g Group) AddTasks(pids ...string) error {
|
||||
return g.writePids(Tasks, pids...)
|
||||
}
|
||||
|
||||
// AddProcesses writes the given process pids to the group.
|
||||
func (g Group) AddProcesses(pids ...string) error {
|
||||
return g.writePids(Procs, pids...)
|
||||
}
|
||||
|
||||
// Write writes the formatted data to the groups entry.
|
||||
func (g Group) Write(entry, format string, args ...interface{}) error {
|
||||
entryPath := path.Join(string(g), entry)
|
||||
f, err := fsi.OpenFile(entryPath, os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return g.errorf("%q: failed to open for writing: %v", entry, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
data := fmt.Sprintf(format, args...)
|
||||
if _, err := f.Write([]byte(data)); err != nil {
|
||||
return g.errorf("%q: failed to write %q: %v", entry, data, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Read the groups entry and return contents in a string
|
||||
func (g Group) Read(entry string) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
entryPath := path.Join(string(g), entry)
|
||||
f, err := fsi.OpenFile(entryPath, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
return "", g.errorf("%q: failed to open for reading: %v", entry, err)
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := buf.ReadFrom(f); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// readPids reads pids from a cgroup's tasks or procs entry.
|
||||
func (g Group) readPids(entry string) ([]string, error) {
|
||||
var pids []string
|
||||
|
||||
pidFile := path.Join(string(g), entry)
|
||||
|
||||
f, err := fsi.OpenFile(pidFile, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
return nil, g.errorf("failed to open %q: %v", entry, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
s := bufio.NewScanner(f)
|
||||
for s.Scan() {
|
||||
pids = append(pids, s.Text())
|
||||
}
|
||||
if s.Err() != nil {
|
||||
return nil, g.errorf("failed to read %q: %v", entry, err)
|
||||
}
|
||||
|
||||
return pids, nil
|
||||
}
|
||||
|
||||
// writePids writes pids to a cgroup's tasks or procs entry.
|
||||
func (g Group) writePids(entry string, pids ...string) error {
|
||||
pidFile := path.Join(string(g), entry)
|
||||
|
||||
f, err := fsi.OpenFile(pidFile, os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return g.errorf("failed to write pids to %q: %v", pidFile, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
for _, pid := range pids {
|
||||
if _, err := f.Write([]byte(pid)); err != nil {
|
||||
if !errors.Is(err, syscall.ESRCH) {
|
||||
return g.errorf("failed to write pid %s to %q: %v",
|
||||
pidFile, pid, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// error returns a formatted group-specific error.
|
||||
func (g Group) errorf(format string, args ...interface{}) error {
|
||||
name := strings.TrimPrefix(string(g), cgroupPath()+"/")
|
||||
return fmt.Errorf("cgroup "+name+": "+format, args...)
|
||||
}
|
65
vendor/github.com/intel/goresctrl/pkg/cgroups/cgroupid.go
generated
vendored
65
vendor/github.com/intel/goresctrl/pkg/cgroups/cgroupid.go
generated
vendored
@ -1,65 +0,0 @@
|
||||
package cgroups
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// CgroupID implements mapping kernel cgroup IDs to cgroupfs paths with transparent caching.
|
||||
type CgroupID struct {
|
||||
root string
|
||||
cache map[uint64]string
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
// NewCgroupID creates a new CgroupID map/cache.
|
||||
func NewCgroupID(root string) *CgroupID {
|
||||
return &CgroupID{
|
||||
root: root,
|
||||
cache: make(map[uint64]string),
|
||||
}
|
||||
}
|
||||
|
||||
// Find finds the path for the given cgroup id.
|
||||
func (cgid *CgroupID) Find(id uint64) (string, error) {
|
||||
found := false
|
||||
var p string
|
||||
|
||||
cgid.Lock()
|
||||
defer cgid.Unlock()
|
||||
|
||||
if path, ok := cgid.cache[id]; ok {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
err := fsi.Walk(cgid.root, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if found {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
|
||||
if info.IsDir() && id == getID(path) {
|
||||
found = true
|
||||
p = path
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if !found {
|
||||
return "", fmt.Errorf("cgroupid %v not found", id)
|
||||
} else {
|
||||
cgid.cache[id] = p
|
||||
return p, nil
|
||||
}
|
||||
}
|
18
vendor/github.com/intel/goresctrl/pkg/cgroups/cgroupid_linux.go
generated
vendored
18
vendor/github.com/intel/goresctrl/pkg/cgroups/cgroupid_linux.go
generated
vendored
@ -1,18 +0,0 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package cgroups
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func getID(path string) uint64 {
|
||||
h, _, err := unix.NameToHandleAt(unix.AT_FDCWD, path, 0)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return binary.LittleEndian.Uint64(h.Bytes())
|
||||
}
|
8
vendor/github.com/intel/goresctrl/pkg/cgroups/cgroupid_other.go
generated
vendored
8
vendor/github.com/intel/goresctrl/pkg/cgroups/cgroupid_other.go
generated
vendored
@ -1,8 +0,0 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
package cgroups
|
||||
|
||||
func getID(path string) uint64 {
|
||||
return 0
|
||||
}
|
53
vendor/github.com/intel/goresctrl/pkg/cgroups/cgrouppath.go
generated
vendored
53
vendor/github.com/intel/goresctrl/pkg/cgroups/cgrouppath.go
generated
vendored
@ -1,53 +0,0 @@
|
||||
// Copyright 2020 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cgroups
|
||||
|
||||
import (
|
||||
goresctrlpath "github.com/intel/goresctrl/pkg/path"
|
||||
)
|
||||
|
||||
// nolint
|
||||
const (
|
||||
// Tasks is a cgroup's "tasks" entry.
|
||||
Tasks = "tasks"
|
||||
// Procs is cgroup's "cgroup.procs" entry.
|
||||
Procs = "cgroup.procs"
|
||||
// CpuShares is the cpu controller's "cpu.shares" entry.
|
||||
CpuShares = "cpu.shares"
|
||||
// CpuPeriod is the cpu controller's "cpu.cfs_period_us" entry.
|
||||
CpuPeriod = "cpu.cfs_period_us"
|
||||
// CpuQuota is the cpu controller's "cpu.cfs_quota_us" entry.
|
||||
CpuQuota = "cpu.cfs_quota_us"
|
||||
// CpusetCpus is the cpuset controller's cpuset.cpus entry.
|
||||
CpusetCpus = "cpuset.cpus"
|
||||
// CpusetMems is the cpuset controller's cpuset.mems entry.
|
||||
CpusetMems = "cpuset.mems"
|
||||
)
|
||||
|
||||
const cgroupBasePath = "sys/fs/cgroup"
|
||||
|
||||
// GetMountDir returns the common mount point for cgroup v1 controllers.
|
||||
func GetMountDir() string {
|
||||
return cgroupPath()
|
||||
}
|
||||
|
||||
// GetV2Dir returns the cgroup v2 unified mount directory.
|
||||
func GetV2Dir() string {
|
||||
return cgroupPath("unified")
|
||||
}
|
||||
|
||||
func cgroupPath(elems ...string) string {
|
||||
return goresctrlpath.Path(append([]string{cgroupBasePath}, elems...)...)
|
||||
}
|
39
vendor/github.com/intel/goresctrl/pkg/cgroups/fsi.go
generated
vendored
39
vendor/github.com/intel/goresctrl/pkg/cgroups/fsi.go
generated
vendored
@ -1,39 +0,0 @@
|
||||
// Copyright 2021 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This module defines filesystem interface (fsi) through which
|
||||
// cgroups package accesses files.
|
||||
|
||||
package cgroups
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type fsiIface interface {
|
||||
Open(name string) (fileIface, error)
|
||||
OpenFile(name string, flag int, perm os.FileMode) (fileIface, error)
|
||||
Walk(string, filepath.WalkFunc) error
|
||||
Lstat(path string) (os.FileInfo, error)
|
||||
}
|
||||
|
||||
type fileIface interface {
|
||||
Close() error
|
||||
Read(p []byte) (n int, err error)
|
||||
Write(b []byte) (n int, err error)
|
||||
}
|
||||
|
||||
// Set the default filesystem interface
|
||||
var fsi fsiIface = newFsiOS()
|
230
vendor/github.com/intel/goresctrl/pkg/cgroups/fsimock.go
generated
vendored
230
vendor/github.com/intel/goresctrl/pkg/cgroups/fsimock.go
generated
vendored
@ -1,230 +0,0 @@
|
||||
// Copyright 2021 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This module implements a mock filesystem that can be used as a
|
||||
// replacement for the native filesystem interface (fsi).
|
||||
|
||||
package cgroups
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type fsMock struct {
|
||||
files map[string]*mockFile // filesystem contents
|
||||
}
|
||||
|
||||
type mockFile struct {
|
||||
// User-defined file properties
|
||||
data []byte // contents of the file
|
||||
|
||||
// User/fsimock-defined properties
|
||||
info *mockFileInfo
|
||||
|
||||
// File-specific user-overrides for the default file behavior
|
||||
open func(string) (fileIface, error)
|
||||
read func([]byte) (int, error)
|
||||
write func([]byte) (int, error)
|
||||
|
||||
// fsimock-defined properties
|
||||
fs *fsMock
|
||||
filename string
|
||||
handle *mockFileHandle
|
||||
writeHistory [][]byte
|
||||
}
|
||||
|
||||
type mockFileHandle struct {
|
||||
pos int
|
||||
}
|
||||
|
||||
type mockFileInfo struct {
|
||||
mode os.FileMode
|
||||
name string
|
||||
mf *mockFile
|
||||
}
|
||||
|
||||
func NewFsiMock(files map[string]mockFile) fsiIface {
|
||||
mfs := fsMock{}
|
||||
mfs.files = map[string]*mockFile{}
|
||||
for filename, usermf := range files {
|
||||
mf := usermf
|
||||
if mf.info == nil {
|
||||
mf.info = &mockFileInfo{}
|
||||
}
|
||||
if mf.info.name == "" {
|
||||
mf.info.name = filepath.Base(filename)
|
||||
}
|
||||
mf.filename = filename
|
||||
mf.info.mf = &mf
|
||||
mf.fs = &mfs
|
||||
mfs.files[filename] = &mf
|
||||
}
|
||||
return &mfs
|
||||
}
|
||||
|
||||
func (mfs fsMock) OpenFile(name string, flag int, perm os.FileMode) (fileIface, error) {
|
||||
fsmockLog("OpenFile(%q, %d, %d)", name, flag, perm)
|
||||
if mf, ok := mfs.files[name]; ok {
|
||||
mf.handle = &mockFileHandle{}
|
||||
if mf.open != nil {
|
||||
return mf.open(name)
|
||||
}
|
||||
return *mf, nil
|
||||
}
|
||||
return nil, fsmockErrorf("%q: file not found", name)
|
||||
}
|
||||
|
||||
func (mfs fsMock) Open(name string) (fileIface, error) {
|
||||
return mfs.OpenFile(name, 0, 0)
|
||||
}
|
||||
|
||||
func (mfs fsMock) Walk(path string, walkFn filepath.WalkFunc) error {
|
||||
dirPath := strings.TrimSuffix(path, "/")
|
||||
info, err := mfs.Lstat(dirPath)
|
||||
if err != nil {
|
||||
err = walkFn(path, nil, err)
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return walkFn(path, info, nil)
|
||||
}
|
||||
err = walkFn(path, info, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, name := range mfs.dirContents(dirPath) {
|
||||
if err = mfs.Walk(dirPath+"/"+name, walkFn); err != nil && err != filepath.SkipDir {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mfs fsMock) dirContents(path string) []string {
|
||||
dirPathS := strings.TrimSuffix(path, "/") + "/"
|
||||
contentSet := map[string]struct{}{}
|
||||
for filename := range mfs.files {
|
||||
if !strings.HasPrefix(filename, dirPathS) {
|
||||
continue
|
||||
}
|
||||
relToDirPath := strings.TrimPrefix(filename, dirPathS)
|
||||
names := strings.SplitN(relToDirPath, "/", 2)
|
||||
contentSet[names[0]] = struct{}{}
|
||||
}
|
||||
contents := make([]string, 0, len(contentSet))
|
||||
for name := range contentSet {
|
||||
contents = append(contents, name)
|
||||
}
|
||||
return contents
|
||||
}
|
||||
|
||||
func (mfs fsMock) Lstat(path string) (os.FileInfo, error) {
|
||||
if mf, ok := mfs.files[path]; ok {
|
||||
return *mf.info, nil
|
||||
}
|
||||
if len(mfs.dirContents(path)) > 0 {
|
||||
return mockFileInfo{
|
||||
name: filepath.Base(path),
|
||||
mode: os.ModeDir,
|
||||
}, nil
|
||||
}
|
||||
return mockFileInfo{}, fsmockErrorf("%q: file not found", path)
|
||||
}
|
||||
|
||||
func (mfi mockFileInfo) Name() string {
|
||||
return mfi.name
|
||||
}
|
||||
func (mfi mockFileInfo) Size() int64 {
|
||||
if mfi.mf != nil {
|
||||
return int64(len(mfi.mf.data))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func (mfi mockFileInfo) Mode() os.FileMode {
|
||||
return mfi.mode
|
||||
}
|
||||
|
||||
func (mfi mockFileInfo) ModTime() time.Time {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func (mfi mockFileInfo) IsDir() bool {
|
||||
return mfi.mode&os.ModeDir != 0
|
||||
}
|
||||
|
||||
func (mfi mockFileInfo) Sys() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mf mockFile) Write(b []byte) (n int, err error) {
|
||||
pos := mf.handle.pos
|
||||
if mf.write != nil {
|
||||
n, err = mf.write(b)
|
||||
if err == nil {
|
||||
mf.fs.files[mf.filename].writeHistory = append(mf.fs.files[mf.filename].writeHistory, b)
|
||||
}
|
||||
} else {
|
||||
newpos := pos + len(b)
|
||||
if newpos > cap(mf.data) {
|
||||
newdata := make([]byte, newpos)
|
||||
copy(newdata, mf.data)
|
||||
mf.data = newdata
|
||||
}
|
||||
copy(mf.data[pos:newpos], b)
|
||||
mf.handle.pos = newpos
|
||||
if f, ok := mf.fs.files[mf.filename]; ok {
|
||||
f.data = mf.data
|
||||
}
|
||||
mf.fs.files[mf.filename].writeHistory = append(mf.fs.files[mf.filename].writeHistory, b)
|
||||
}
|
||||
fsmockLog("{%q, pos=%d}.Write([%d]byte(%q)) = (%d, %v) %q", mf.filename, pos, len(b), string(b), n, err, mf.fs.files[mf.filename].data)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (mf mockFile) Read(b []byte) (n int, err error) {
|
||||
pos := mf.handle.pos
|
||||
if mf.read != nil {
|
||||
n, err = mf.read(b)
|
||||
} else {
|
||||
n = len(mf.data) - pos
|
||||
err = nil
|
||||
if n <= 0 {
|
||||
err = io.EOF
|
||||
}
|
||||
if n > cap(b) {
|
||||
n = cap(b)
|
||||
}
|
||||
copy(b, mf.data[pos:pos+n])
|
||||
mf.handle.pos += n
|
||||
}
|
||||
fsmockLog("{%q, pos=%d}.Read([%d]byte) = (%d, %v)\n", mf.filename, pos, len(b), n, err)
|
||||
return
|
||||
}
|
||||
|
||||
func (mf mockFile) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func fsmockLog(format string, args ...interface{}) {
|
||||
fmt.Printf("fsmock: "+format+"\n", args...)
|
||||
}
|
||||
|
||||
func fsmockErrorf(format string, args ...interface{}) error {
|
||||
return fmt.Errorf("fsmock: "+format, args...)
|
||||
}
|
63
vendor/github.com/intel/goresctrl/pkg/cgroups/fsios.go
generated
vendored
63
vendor/github.com/intel/goresctrl/pkg/cgroups/fsios.go
generated
vendored
@ -1,63 +0,0 @@
|
||||
// Copyright 2021 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This module provides the native implementation of the filesystem
|
||||
// interface (fsi).
|
||||
|
||||
package cgroups
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type fsOs struct{}
|
||||
|
||||
type osFile struct {
|
||||
file *os.File
|
||||
}
|
||||
|
||||
func newFsiOS() fsiIface {
|
||||
return fsOs{}
|
||||
}
|
||||
|
||||
func (fsOs) OpenFile(name string, flag int, perm os.FileMode) (fileIface, error) {
|
||||
f, err := os.OpenFile(name, flag, perm)
|
||||
return osFile{f}, err
|
||||
}
|
||||
|
||||
func (fsOs) Open(name string) (fileIface, error) {
|
||||
f, err := os.Open(name)
|
||||
return osFile{f}, err
|
||||
}
|
||||
|
||||
func (fsOs) Lstat(name string) (os.FileInfo, error) {
|
||||
return os.Lstat(name)
|
||||
}
|
||||
|
||||
func (fsOs) Walk(root string, walkFn filepath.WalkFunc) error {
|
||||
return filepath.Walk(root, walkFn)
|
||||
}
|
||||
|
||||
func (osf osFile) Write(b []byte) (n int, err error) {
|
||||
return osf.file.Write(b)
|
||||
}
|
||||
|
||||
func (osf osFile) Read(b []byte) (n int, err error) {
|
||||
return osf.file.Read(b)
|
||||
}
|
||||
|
||||
func (osf osFile) Close() error {
|
||||
return osf.file.Close()
|
||||
}
|
2
vendor/github.com/intel/goresctrl/pkg/rdt/rdt.go
generated
vendored
2
vendor/github.com/intel/goresctrl/pkg/rdt/rdt.go
generated
vendored
@ -234,7 +234,7 @@ func SetConfig(c *Config, force bool) error {
|
||||
// reconfigures the resctrl filesystem.
|
||||
func SetConfigFromData(data []byte, force bool) error {
|
||||
cfg := &Config{}
|
||||
if err := yaml.Unmarshal(data, &cfg); err != nil {
|
||||
if err := yaml.UnmarshalStrict(data, cfg); err != nil {
|
||||
return fmt.Errorf("failed to parse configuration data: %v", err)
|
||||
}
|
||||
|
||||
|
2
vendor/github.com/intel/goresctrl/pkg/utils/idset.go
generated
vendored
2
vendor/github.com/intel/goresctrl/pkg/utils/idset.go
generated
vendored
@ -169,7 +169,7 @@ func (s *IDSet) UnmarshalJSON(data []byte) error {
|
||||
}
|
||||
|
||||
for _, idstr := range strings.Split(str, ",") {
|
||||
id, err := strconv.ParseUint(idstr, 10, 0)
|
||||
id, err := strconv.ParseInt(idstr, 10, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid IDSet entry '%s': %v", idstr, err)
|
||||
}
|
||||
|
3
vendor/modules.txt
vendored
3
vendor/modules.txt
vendored
@ -256,10 +256,9 @@ github.com/grpc-ecosystem/go-grpc-prometheus
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/runtime
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/utilities
|
||||
# github.com/intel/goresctrl v0.5.0
|
||||
# github.com/intel/goresctrl v0.6.0
|
||||
## explicit; go 1.20
|
||||
github.com/intel/goresctrl/pkg/blockio
|
||||
github.com/intel/goresctrl/pkg/cgroups
|
||||
github.com/intel/goresctrl/pkg/kubernetes
|
||||
github.com/intel/goresctrl/pkg/log
|
||||
github.com/intel/goresctrl/pkg/path
|
||||
|
Loading…
Reference in New Issue
Block a user