Merge pull request #9540 from containerd/dependabot/go_modules/github.com/intel/goresctrl-0.5.0

build(deps): bump github.com/intel/goresctrl from 0.3.0 to 0.5.0
This commit is contained in:
Akihiro Suda 2023-12-15 01:14:35 +00:00 committed by GitHub
commit 1da783894b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 215 additions and 1671 deletions

4
go.mod
View File

@ -35,7 +35,7 @@ require (
github.com/google/uuid v1.3.1
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.3.0
github.com/intel/goresctrl v0.5.0
github.com/klauspost/compress v1.17.4
github.com/minio/sha256-simd v1.0.1
github.com/moby/locker v1.0.1
@ -97,8 +97,6 @@ require (
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect

5
go.sum
View File

@ -397,7 +397,6 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2/go.mod h1:Ap9RLCIJVtgQg1/BBgVE
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
@ -411,8 +410,8 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/intel/goresctrl v0.3.0 h1:K2D3GOzihV7xSBedGxONSlaw/un1LZgWsc9IfqipN4c=
github.com/intel/goresctrl v0.3.0/go.mod h1:fdz3mD85cmP9sHD8JUlrNWAxvwM86CrbmVXltEKd7zk=
github.com/intel/goresctrl v0.5.0 h1:kcDhjE3ZF/mNrJuRzLS3LY2Hp6atFaF1XVFBT7SVL2g=
github.com/intel/goresctrl v0.5.0/go.mod h1:mIe63ggylWYr0cU/l8n11FAkesqfvuP3oktIsxvu0T0=
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=

View File

@ -1,354 +0,0 @@
Mozilla Public License, version 2.0
1. Definitions
1.1. “Contributor”
means each individual or legal entity that creates, contributes to the
creation of, or owns Covered Software.
1.2. “Contributor Version”
means the combination of the Contributions of others (if any) used by a
Contributor and that particular Contributors Contribution.
1.3. “Contribution”
means Covered Software of a particular Contributor.
1.4. “Covered Software”
means Source Code Form to which the initial Contributor has attached the
notice in Exhibit A, the Executable Form of such Source Code Form, and
Modifications of such Source Code Form, in each case including portions
thereof.
1.5. “Incompatible With Secondary Licenses”
means
a. that the initial Contributor has attached the notice described in
Exhibit B to the Covered Software; or
b. that the Covered Software was made available under the terms of version
1.1 or earlier of the License, but not also under the terms of a
Secondary License.
1.6. “Executable Form”
means any form of the work other than Source Code Form.
1.7. “Larger Work”
means a work that combines Covered Software with other material, in a separate
file or files, that is not Covered Software.
1.8. “License”
means this document.
1.9. “Licensable”
means having the right to grant, to the maximum extent possible, whether at the
time of the initial grant or subsequently, any and all of the rights conveyed by
this License.
1.10. “Modifications”
means any of the following:
a. any file in Source Code Form that results from an addition to, deletion
from, or modification of the contents of Covered Software; or
b. any new file in Source Code Form that contains any Covered Software.
1.11. “Patent Claims” of a Contributor
means any patent claim(s), including without limitation, method, process,
and apparatus claims, in any patent Licensable by such Contributor that
would be infringed, but for the grant of the License, by the making,
using, selling, offering for sale, having made, import, or transfer of
either its Contributions or its Contributor Version.
1.12. “Secondary License”
means either the GNU General Public License, Version 2.0, the GNU Lesser
General Public License, Version 2.1, the GNU Affero General Public
License, Version 3.0, or any later versions of those licenses.
1.13. “Source Code Form”
means the form of the work preferred for making modifications.
1.14. “You” (or “Your”)
means an individual or a legal entity exercising rights under this
License. For legal entities, “You” includes any entity that controls, is
controlled by, or is under common control with You. For purposes of this
definition, “control” means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (b) ownership of more than fifty percent (50%) of the
outstanding shares or beneficial ownership of such entity.
2. License Grants and Conditions
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
a. under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or as
part of a Larger Work; and
b. under Patent Claims of such Contributor to make, use, sell, offer for
sale, have made, import, and otherwise transfer either its Contributions
or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution become
effective for each Contribution on the date the Contributor first distributes
such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under this
License. No additional rights or licenses will be implied from the distribution
or licensing of Covered Software under this License. Notwithstanding Section
2.1(b) above, no patent license is granted by a Contributor:
a. for any code that a Contributor has removed from Covered Software; or
b. for infringements caused by: (i) Your and any other third partys
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
c. under Patent Claims infringed by Covered Software in the absence of its
Contributions.
This License does not grant any rights in the trademarks, service marks, or
logos of any Contributor (except as may be necessary to comply with the
notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this License
(see Section 10.2) or under the terms of a Secondary License (if permitted
under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its Contributions
are its original creation(s) or it has sufficient rights to grant the
rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under applicable
copyright doctrines of fair use, fair dealing, or other equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
Section 2.1.
3. Responsibilities
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under the
terms of this License. You must inform recipients that the Source Code Form
of the Covered Software is governed by the terms of this License, and how
they can obtain a copy of this License. You may not attempt to alter or
restrict the recipients rights in the Source Code Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
a. such Covered Software must also be made available in Source Code Form,
as described in Section 3.1, and You must inform recipients of the
Executable Form how they can obtain a copy of such Source Code Form by
reasonable means in a timely manner, at a charge no more than the cost
of distribution to the recipient; and
b. You may distribute such Executable Form under the terms of this License,
or sublicense it under different terms, provided that the license for
the Executable Form does not attempt to limit or alter the recipients
rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for the
Covered Software. If the Larger Work is a combination of Covered Software
with a work governed by one or more Secondary Licenses, and the Covered
Software is not Incompatible With Secondary Licenses, this License permits
You to additionally distribute such Covered Software under the terms of
such Secondary License(s), so that the recipient of the Larger Work may, at
their option, further distribute the Covered Software under the terms of
either this License or such Secondary License(s).
3.4. Notices
You may not remove or alter the substance of any license notices (including
copyright notices, patent notices, disclaimers of warranty, or limitations
of liability) contained within the Source Code Form of the Covered
Software, except that You may alter any license notices to the extent
required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on behalf
of any Contributor. You must make it absolutely clear that any such
warranty, support, indemnity, or liability obligation is offered by You
alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this License
with respect to some or all of the Covered Software due to statute, judicial
order, or regulation then You must: (a) comply with the terms of this License
to the maximum extent possible; and (b) describe the limitations and the code
they affect. Such description must be placed in a text file included with all
distributions of the Covered Software under this License. Except to the
extent prohibited by statute or regulation, such description must be
sufficiently detailed for a recipient of ordinary skill to be able to
understand it.
5. Termination
5.1. The rights granted under this License will terminate automatically if You
fail to comply with any of its terms. However, if You become compliant,
then the rights granted under this License from a particular Contributor
are reinstated (a) provisionally, unless and until such Contributor
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
if such Contributor fails to notify You of the non-compliance by some
reasonable means prior to 60 days after You have come back into compliance.
Moreover, Your grants from a particular Contributor are reinstated on an
ongoing basis if such Contributor notifies You of the non-compliance by
some reasonable means, this is the first time You have received notice of
non-compliance with this License from such Contributor, and You become
compliant prior to 30 days after Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions, counter-claims,
and cross-claims) alleging that a Contributor Version directly or
indirectly infringes any patent, then the rights granted to You by any and
all Contributors for the Covered Software under Section 2.1 of this License
shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
license agreements (excluding distributors and resellers) which have been
validly granted by You or Your distributors under this License prior to
termination shall survive termination.
6. Disclaimer of Warranty
Covered Software is provided under this License on an “as is” basis, without
warranty of any kind, either expressed, implied, or statutory, including,
without limitation, warranties that the Covered Software is free of defects,
merchantable, fit for a particular purpose or non-infringing. The entire
risk as to the quality and performance of the Covered Software is with You.
Should any Covered Software prove defective in any respect, You (not any
Contributor) assume the cost of any necessary servicing, repair, or
correction. This disclaimer of warranty constitutes an essential part of this
License. No use of any Covered Software is authorized under this License
except under this disclaimer.
7. Limitation of Liability
Under no circumstances and under no legal theory, whether tort (including
negligence), contract, or otherwise, shall any Contributor, or anyone who
distributes Covered Software as permitted above, be liable to You for any
direct, indirect, special, incidental, or consequential damages of any
character including, without limitation, damages for lost profits, loss of
goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses, even if such party shall have been
informed of the possibility of such damages. This limitation of liability
shall not apply to liability for death or personal injury resulting from such
partys negligence to the extent applicable law prohibits such limitation.
Some jurisdictions do not allow the exclusion or limitation of incidental or
consequential damages, so this exclusion and limitation may not apply to You.
8. Litigation
Any litigation relating to this License may be brought only in the courts of
a jurisdiction where the defendant maintains its principal place of business
and such litigation shall be governed by laws of that jurisdiction, without
reference to its conflict-of-law provisions. Nothing in this Section shall
prevent a partys ability to bring cross-claims or counter-claims.
9. Miscellaneous
This License represents the complete agreement concerning the subject matter
hereof. If any provision of this License is held to be unenforceable, such
provision shall be reformed only to the extent necessary to make it
enforceable. Any law or regulation which provides that the language of a
contract shall be construed against the drafter shall not be used to construe
this License against a Contributor.
10. Versions of the License
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version of
the License under which You originally received the Covered Software, or
under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a modified
version of this License if you rename the license and remove any
references to the name of the license steward (except to note that such
modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file, then
You may include the notice in a location (such as a LICENSE file in a relevant
directory) where a recipient would be likely to look for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - “Incompatible With Secondary Licenses” Notice
This Source Code Form is “Incompatible
With Secondary Licenses”, as defined by
the Mozilla Public License, v. 2.0.

View File

@ -1,89 +0,0 @@
# errwrap
`errwrap` is a package for Go that formalizes the pattern of wrapping errors
and checking if an error contains another error.
There is a common pattern in Go of taking a returned `error` value and
then wrapping it (such as with `fmt.Errorf`) before returning it. The problem
with this pattern is that you completely lose the original `error` structure.
Arguably the _correct_ approach is that you should make a custom structure
implementing the `error` interface, and have the original error as a field
on that structure, such [as this example](http://golang.org/pkg/os/#PathError).
This is a good approach, but you have to know the entire chain of possible
rewrapping that happens, when you might just care about one.
`errwrap` formalizes this pattern (it doesn't matter what approach you use
above) by giving a single interface for wrapping errors, checking if a specific
error is wrapped, and extracting that error.
## Installation and Docs
Install using `go get github.com/hashicorp/errwrap`.
Full documentation is available at
http://godoc.org/github.com/hashicorp/errwrap
## Usage
#### Basic Usage
Below is a very basic example of its usage:
```go
// A function that always returns an error, but wraps it, like a real
// function might.
func tryOpen() error {
_, err := os.Open("/i/dont/exist")
if err != nil {
return errwrap.Wrapf("Doesn't exist: {{err}}", err)
}
return nil
}
func main() {
err := tryOpen()
// We can use the Contains helpers to check if an error contains
// another error. It is safe to do this with a nil error, or with
// an error that doesn't even use the errwrap package.
if errwrap.Contains(err, "does not exist") {
// Do something
}
if errwrap.ContainsType(err, new(os.PathError)) {
// Do something
}
// Or we can use the associated `Get` functions to just extract
// a specific error. This would return nil if that specific error doesn't
// exist.
perr := errwrap.GetType(err, new(os.PathError))
}
```
#### Custom Types
If you're already making custom types that properly wrap errors, then
you can get all the functionality of `errwraps.Contains` and such by
implementing the `Wrapper` interface with just one function. Example:
```go
type AppError {
Code ErrorCode
Err error
}
func (e *AppError) WrappedErrors() []error {
return []error{e.Err}
}
```
Now this works:
```go
err := &AppError{Err: fmt.Errorf("an error")}
if errwrap.ContainsType(err, fmt.Errorf("")) {
// This will work!
}
```

View File

@ -1,178 +0,0 @@
// Package errwrap implements methods to formalize error wrapping in Go.
//
// All of the top-level functions that take an `error` are built to be able
// to take any error, not just wrapped errors. This allows you to use errwrap
// without having to type-check and type-cast everywhere.
package errwrap
import (
"errors"
"reflect"
"strings"
)
// WalkFunc is the callback called for Walk.
type WalkFunc func(error)
// Wrapper is an interface that can be implemented by custom types to
// have all the Contains, Get, etc. functions in errwrap work.
//
// When Walk reaches a Wrapper, it will call the callback for every
// wrapped error in addition to the wrapper itself. Since all the top-level
// functions in errwrap use Walk, this means that all those functions work
// with your custom type.
type Wrapper interface {
WrappedErrors() []error
}
// Wrap defines that outer wraps inner, returning an error type that
// can be cleanly used with the other methods in this package, such as
// Contains, GetAll, etc.
//
// This function won't modify the error message at all (the outer message
// will be used).
func Wrap(outer, inner error) error {
return &wrappedError{
Outer: outer,
Inner: inner,
}
}
// Wrapf wraps an error with a formatting message. This is similar to using
// `fmt.Errorf` to wrap an error. If you're using `fmt.Errorf` to wrap
// errors, you should replace it with this.
//
// format is the format of the error message. The string '{{err}}' will
// be replaced with the original error message.
//
// Deprecated: Use fmt.Errorf()
func Wrapf(format string, err error) error {
outerMsg := "<nil>"
if err != nil {
outerMsg = err.Error()
}
outer := errors.New(strings.Replace(
format, "{{err}}", outerMsg, -1))
return Wrap(outer, err)
}
// Contains checks if the given error contains an error with the
// message msg. If err is not a wrapped error, this will always return
// false unless the error itself happens to match this msg.
func Contains(err error, msg string) bool {
return len(GetAll(err, msg)) > 0
}
// ContainsType checks if the given error contains an error with
// the same concrete type as v. If err is not a wrapped error, this will
// check the err itself.
func ContainsType(err error, v interface{}) bool {
return len(GetAllType(err, v)) > 0
}
// Get is the same as GetAll but returns the deepest matching error.
func Get(err error, msg string) error {
es := GetAll(err, msg)
if len(es) > 0 {
return es[len(es)-1]
}
return nil
}
// GetType is the same as GetAllType but returns the deepest matching error.
func GetType(err error, v interface{}) error {
es := GetAllType(err, v)
if len(es) > 0 {
return es[len(es)-1]
}
return nil
}
// GetAll gets all the errors that might be wrapped in err with the
// given message. The order of the errors is such that the outermost
// matching error (the most recent wrap) is index zero, and so on.
func GetAll(err error, msg string) []error {
var result []error
Walk(err, func(err error) {
if err.Error() == msg {
result = append(result, err)
}
})
return result
}
// GetAllType gets all the errors that are the same type as v.
//
// The order of the return value is the same as described in GetAll.
func GetAllType(err error, v interface{}) []error {
var result []error
var search string
if v != nil {
search = reflect.TypeOf(v).String()
}
Walk(err, func(err error) {
var needle string
if err != nil {
needle = reflect.TypeOf(err).String()
}
if needle == search {
result = append(result, err)
}
})
return result
}
// Walk walks all the wrapped errors in err and calls the callback. If
// err isn't a wrapped error, this will be called once for err. If err
// is a wrapped error, the callback will be called for both the wrapper
// that implements error as well as the wrapped error itself.
func Walk(err error, cb WalkFunc) {
if err == nil {
return
}
switch e := err.(type) {
case *wrappedError:
cb(e.Outer)
Walk(e.Inner, cb)
case Wrapper:
cb(err)
for _, err := range e.WrappedErrors() {
Walk(err, cb)
}
case interface{ Unwrap() error }:
cb(err)
Walk(e.Unwrap(), cb)
default:
cb(err)
}
}
// wrappedError is an implementation of error that has both the
// outer and inner errors.
type wrappedError struct {
Outer error
Inner error
}
func (w *wrappedError) Error() string {
return w.Outer.Error()
}
func (w *wrappedError) WrappedErrors() []error {
return []error{w.Outer, w.Inner}
}
func (w *wrappedError) Unwrap() error {
return w.Inner
}

View File

@ -1,353 +0,0 @@
Mozilla Public License, version 2.0
1. Definitions
1.1. “Contributor”
means each individual or legal entity that creates, contributes to the
creation of, or owns Covered Software.
1.2. “Contributor Version”
means the combination of the Contributions of others (if any) used by a
Contributor and that particular Contributors Contribution.
1.3. “Contribution”
means Covered Software of a particular Contributor.
1.4. “Covered Software”
means Source Code Form to which the initial Contributor has attached the
notice in Exhibit A, the Executable Form of such Source Code Form, and
Modifications of such Source Code Form, in each case including portions
thereof.
1.5. “Incompatible With Secondary Licenses”
means
a. that the initial Contributor has attached the notice described in
Exhibit B to the Covered Software; or
b. that the Covered Software was made available under the terms of version
1.1 or earlier of the License, but not also under the terms of a
Secondary License.
1.6. “Executable Form”
means any form of the work other than Source Code Form.
1.7. “Larger Work”
means a work that combines Covered Software with other material, in a separate
file or files, that is not Covered Software.
1.8. “License”
means this document.
1.9. “Licensable”
means having the right to grant, to the maximum extent possible, whether at the
time of the initial grant or subsequently, any and all of the rights conveyed by
this License.
1.10. “Modifications”
means any of the following:
a. any file in Source Code Form that results from an addition to, deletion
from, or modification of the contents of Covered Software; or
b. any new file in Source Code Form that contains any Covered Software.
1.11. “Patent Claims” of a Contributor
means any patent claim(s), including without limitation, method, process,
and apparatus claims, in any patent Licensable by such Contributor that
would be infringed, but for the grant of the License, by the making,
using, selling, offering for sale, having made, import, or transfer of
either its Contributions or its Contributor Version.
1.12. “Secondary License”
means either the GNU General Public License, Version 2.0, the GNU Lesser
General Public License, Version 2.1, the GNU Affero General Public
License, Version 3.0, or any later versions of those licenses.
1.13. “Source Code Form”
means the form of the work preferred for making modifications.
1.14. “You” (or “Your”)
means an individual or a legal entity exercising rights under this
License. For legal entities, “You” includes any entity that controls, is
controlled by, or is under common control with You. For purposes of this
definition, “control” means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (b) ownership of more than fifty percent (50%) of the
outstanding shares or beneficial ownership of such entity.
2. License Grants and Conditions
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
a. under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or as
part of a Larger Work; and
b. under Patent Claims of such Contributor to make, use, sell, offer for
sale, have made, import, and otherwise transfer either its Contributions
or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution become
effective for each Contribution on the date the Contributor first distributes
such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under this
License. No additional rights or licenses will be implied from the distribution
or licensing of Covered Software under this License. Notwithstanding Section
2.1(b) above, no patent license is granted by a Contributor:
a. for any code that a Contributor has removed from Covered Software; or
b. for infringements caused by: (i) Your and any other third partys
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
c. under Patent Claims infringed by Covered Software in the absence of its
Contributions.
This License does not grant any rights in the trademarks, service marks, or
logos of any Contributor (except as may be necessary to comply with the
notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this License
(see Section 10.2) or under the terms of a Secondary License (if permitted
under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its Contributions
are its original creation(s) or it has sufficient rights to grant the
rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under applicable
copyright doctrines of fair use, fair dealing, or other equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
Section 2.1.
3. Responsibilities
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under the
terms of this License. You must inform recipients that the Source Code Form
of the Covered Software is governed by the terms of this License, and how
they can obtain a copy of this License. You may not attempt to alter or
restrict the recipients rights in the Source Code Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
a. such Covered Software must also be made available in Source Code Form,
as described in Section 3.1, and You must inform recipients of the
Executable Form how they can obtain a copy of such Source Code Form by
reasonable means in a timely manner, at a charge no more than the cost
of distribution to the recipient; and
b. You may distribute such Executable Form under the terms of this License,
or sublicense it under different terms, provided that the license for
the Executable Form does not attempt to limit or alter the recipients
rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for the
Covered Software. If the Larger Work is a combination of Covered Software
with a work governed by one or more Secondary Licenses, and the Covered
Software is not Incompatible With Secondary Licenses, this License permits
You to additionally distribute such Covered Software under the terms of
such Secondary License(s), so that the recipient of the Larger Work may, at
their option, further distribute the Covered Software under the terms of
either this License or such Secondary License(s).
3.4. Notices
You may not remove or alter the substance of any license notices (including
copyright notices, patent notices, disclaimers of warranty, or limitations
of liability) contained within the Source Code Form of the Covered
Software, except that You may alter any license notices to the extent
required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on behalf
of any Contributor. You must make it absolutely clear that any such
warranty, support, indemnity, or liability obligation is offered by You
alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this License
with respect to some or all of the Covered Software due to statute, judicial
order, or regulation then You must: (a) comply with the terms of this License
to the maximum extent possible; and (b) describe the limitations and the code
they affect. Such description must be placed in a text file included with all
distributions of the Covered Software under this License. Except to the
extent prohibited by statute or regulation, such description must be
sufficiently detailed for a recipient of ordinary skill to be able to
understand it.
5. Termination
5.1. The rights granted under this License will terminate automatically if You
fail to comply with any of its terms. However, if You become compliant,
then the rights granted under this License from a particular Contributor
are reinstated (a) provisionally, unless and until such Contributor
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
if such Contributor fails to notify You of the non-compliance by some
reasonable means prior to 60 days after You have come back into compliance.
Moreover, Your grants from a particular Contributor are reinstated on an
ongoing basis if such Contributor notifies You of the non-compliance by
some reasonable means, this is the first time You have received notice of
non-compliance with this License from such Contributor, and You become
compliant prior to 30 days after Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions, counter-claims,
and cross-claims) alleging that a Contributor Version directly or
indirectly infringes any patent, then the rights granted to You by any and
all Contributors for the Covered Software under Section 2.1 of this License
shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
license agreements (excluding distributors and resellers) which have been
validly granted by You or Your distributors under this License prior to
termination shall survive termination.
6. Disclaimer of Warranty
Covered Software is provided under this License on an “as is” basis, without
warranty of any kind, either expressed, implied, or statutory, including,
without limitation, warranties that the Covered Software is free of defects,
merchantable, fit for a particular purpose or non-infringing. The entire
risk as to the quality and performance of the Covered Software is with You.
Should any Covered Software prove defective in any respect, You (not any
Contributor) assume the cost of any necessary servicing, repair, or
correction. This disclaimer of warranty constitutes an essential part of this
License. No use of any Covered Software is authorized under this License
except under this disclaimer.
7. Limitation of Liability
Under no circumstances and under no legal theory, whether tort (including
negligence), contract, or otherwise, shall any Contributor, or anyone who
distributes Covered Software as permitted above, be liable to You for any
direct, indirect, special, incidental, or consequential damages of any
character including, without limitation, damages for lost profits, loss of
goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses, even if such party shall have been
informed of the possibility of such damages. This limitation of liability
shall not apply to liability for death or personal injury resulting from such
partys negligence to the extent applicable law prohibits such limitation.
Some jurisdictions do not allow the exclusion or limitation of incidental or
consequential damages, so this exclusion and limitation may not apply to You.
8. Litigation
Any litigation relating to this License may be brought only in the courts of
a jurisdiction where the defendant maintains its principal place of business
and such litigation shall be governed by laws of that jurisdiction, without
reference to its conflict-of-law provisions. Nothing in this Section shall
prevent a partys ability to bring cross-claims or counter-claims.
9. Miscellaneous
This License represents the complete agreement concerning the subject matter
hereof. If any provision of this License is held to be unenforceable, such
provision shall be reformed only to the extent necessary to make it
enforceable. Any law or regulation which provides that the language of a
contract shall be construed against the drafter shall not be used to construe
this License against a Contributor.
10. Versions of the License
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version of
the License under which You originally received the Covered Software, or
under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a modified
version of this License if you rename the license and remove any
references to the name of the license steward (except to note that such
modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file, then
You may include the notice in a location (such as a LICENSE file in a relevant
directory) where a recipient would be likely to look for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - “Incompatible With Secondary Licenses” Notice
This Source Code Form is “Incompatible
With Secondary Licenses”, as defined by
the Mozilla Public License, v. 2.0.

View File

@ -1,31 +0,0 @@
TEST?=./...
default: test
# test runs the test suite and vets the code.
test: generate
@echo "==> Running tests..."
@go list $(TEST) \
| grep -v "/vendor/" \
| xargs -n1 go test -timeout=60s -parallel=10 ${TESTARGS}
# testrace runs the race checker
testrace: generate
@echo "==> Running tests (race)..."
@go list $(TEST) \
| grep -v "/vendor/" \
| xargs -n1 go test -timeout=60s -race ${TESTARGS}
# updatedeps installs all the dependencies needed to run and build.
updatedeps:
@sh -c "'${CURDIR}/scripts/deps.sh' '${NAME}'"
# generate runs `go generate` to build the dynamically generated source files.
generate:
@echo "==> Generating..."
@find . -type f -name '.DS_Store' -delete
@go list ./... \
| grep -v "/vendor/" \
| xargs -n1 go generate
.PHONY: default test testrace updatedeps generate

View File

@ -1,150 +0,0 @@
# go-multierror
[![CircleCI](https://img.shields.io/circleci/build/github/hashicorp/go-multierror/master)](https://circleci.com/gh/hashicorp/go-multierror)
[![Go Reference](https://pkg.go.dev/badge/github.com/hashicorp/go-multierror.svg)](https://pkg.go.dev/github.com/hashicorp/go-multierror)
![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/hashicorp/go-multierror)
[circleci]: https://app.circleci.com/pipelines/github/hashicorp/go-multierror
[godocs]: https://pkg.go.dev/github.com/hashicorp/go-multierror
`go-multierror` is a package for Go that provides a mechanism for
representing a list of `error` values as a single `error`.
This allows a function in Go to return an `error` that might actually
be a list of errors. If the caller knows this, they can unwrap the
list and access the errors. If the caller doesn't know, the error
formats to a nice human-readable format.
`go-multierror` is fully compatible with the Go standard library
[errors](https://golang.org/pkg/errors/) package, including the
functions `As`, `Is`, and `Unwrap`. This provides a standardized approach
for introspecting on error values.
## Installation and Docs
Install using `go get github.com/hashicorp/go-multierror`.
Full documentation is available at
https://pkg.go.dev/github.com/hashicorp/go-multierror
### Requires go version 1.13 or newer
`go-multierror` requires go version 1.13 or newer. Go 1.13 introduced
[error wrapping](https://golang.org/doc/go1.13#error_wrapping), which
this library takes advantage of.
If you need to use an earlier version of go, you can use the
[v1.0.0](https://github.com/hashicorp/go-multierror/tree/v1.0.0)
tag, which doesn't rely on features in go 1.13.
If you see compile errors that look like the below, it's likely that
you're on an older version of go:
```
/go/src/github.com/hashicorp/go-multierror/multierror.go:112:9: undefined: errors.As
/go/src/github.com/hashicorp/go-multierror/multierror.go:117:9: undefined: errors.Is
```
## Usage
go-multierror is easy to use and purposely built to be unobtrusive in
existing Go applications/libraries that may not be aware of it.
**Building a list of errors**
The `Append` function is used to create a list of errors. This function
behaves a lot like the Go built-in `append` function: it doesn't matter
if the first argument is nil, a `multierror.Error`, or any other `error`,
the function behaves as you would expect.
```go
var result error
if err := step1(); err != nil {
result = multierror.Append(result, err)
}
if err := step2(); err != nil {
result = multierror.Append(result, err)
}
return result
```
**Customizing the formatting of the errors**
By specifying a custom `ErrorFormat`, you can customize the format
of the `Error() string` function:
```go
var result *multierror.Error
// ... accumulate errors here, maybe using Append
if result != nil {
result.ErrorFormat = func([]error) string {
return "errors!"
}
}
```
**Accessing the list of errors**
`multierror.Error` implements `error` so if the caller doesn't know about
multierror, it will work just fine. But if you're aware a multierror might
be returned, you can use type switches to access the list of errors:
```go
if err := something(); err != nil {
if merr, ok := err.(*multierror.Error); ok {
// Use merr.Errors
}
}
```
You can also use the standard [`errors.Unwrap`](https://golang.org/pkg/errors/#Unwrap)
function. This will continue to unwrap into subsequent errors until none exist.
**Extracting an error**
The standard library [`errors.As`](https://golang.org/pkg/errors/#As)
function can be used directly with a multierror to extract a specific error:
```go
// Assume err is a multierror value
err := somefunc()
// We want to know if "err" has a "RichErrorType" in it and extract it.
var errRich RichErrorType
if errors.As(err, &errRich) {
// It has it, and now errRich is populated.
}
```
**Checking for an exact error value**
Some errors are returned as exact errors such as the [`ErrNotExist`](https://golang.org/pkg/os/#pkg-variables)
error in the `os` package. You can check if this error is present by using
the standard [`errors.Is`](https://golang.org/pkg/errors/#Is) function.
```go
// Assume err is a multierror value
err := somefunc()
if errors.Is(err, os.ErrNotExist) {
// err contains os.ErrNotExist
}
```
**Returning a multierror only if there are errors**
If you build a `multierror.Error`, you can use the `ErrorOrNil` function
to return an `error` implementation only if there are errors to return:
```go
var result *multierror.Error
// ... accumulate errors here
// Return the `error` only if errors were added to the multierror, otherwise
// return nil since there are no errors.
return result.ErrorOrNil()
```

View File

@ -1,43 +0,0 @@
package multierror
// Append is a helper function that will append more errors
// onto an Error in order to create a larger multi-error.
//
// If err is not a multierror.Error, then it will be turned into
// one. If any of the errs are multierr.Error, they will be flattened
// one level into err.
// Any nil errors within errs will be ignored. If err is nil, a new
// *Error will be returned.
func Append(err error, errs ...error) *Error {
switch err := err.(type) {
case *Error:
// Typed nils can reach here, so initialize if we are nil
if err == nil {
err = new(Error)
}
// Go through each error and flatten
for _, e := range errs {
switch e := e.(type) {
case *Error:
if e != nil {
err.Errors = append(err.Errors, e.Errors...)
}
default:
if e != nil {
err.Errors = append(err.Errors, e)
}
}
}
return err
default:
newErrs := make([]error, 0, len(errs)+1)
if err != nil {
newErrs = append(newErrs, err)
}
newErrs = append(newErrs, errs...)
return Append(&Error{}, newErrs...)
}
}

View File

@ -1,26 +0,0 @@
package multierror
// Flatten flattens the given error, merging any *Errors together into
// a single *Error.
func Flatten(err error) error {
// If it isn't an *Error, just return the error as-is
if _, ok := err.(*Error); !ok {
return err
}
// Otherwise, make the result and flatten away!
flatErr := new(Error)
flatten(err, flatErr)
return flatErr
}
func flatten(err error, flatErr *Error) {
switch err := err.(type) {
case *Error:
for _, e := range err.Errors {
flatten(e, flatErr)
}
default:
flatErr.Errors = append(flatErr.Errors, err)
}
}

View File

@ -1,27 +0,0 @@
package multierror
import (
"fmt"
"strings"
)
// ErrorFormatFunc is a function callback that is called by Error to
// turn the list of errors into a string.
type ErrorFormatFunc func([]error) string
// ListFormatFunc is a basic formatter that outputs the number of errors
// that occurred along with a bullet point list of the errors.
func ListFormatFunc(es []error) string {
if len(es) == 1 {
return fmt.Sprintf("1 error occurred:\n\t* %s\n\n", es[0])
}
points := make([]string, len(es))
for i, err := range es {
points[i] = fmt.Sprintf("* %s", err)
}
return fmt.Sprintf(
"%d errors occurred:\n\t%s\n\n",
len(es), strings.Join(points, "\n\t"))
}

View File

@ -1,38 +0,0 @@
package multierror
import "sync"
// Group is a collection of goroutines which return errors that need to be
// coalesced.
type Group struct {
mutex sync.Mutex
err *Error
wg sync.WaitGroup
}
// Go calls the given function in a new goroutine.
//
// If the function returns an error it is added to the group multierror which
// is returned by Wait.
func (g *Group) Go(f func() error) {
g.wg.Add(1)
go func() {
defer g.wg.Done()
if err := f(); err != nil {
g.mutex.Lock()
g.err = Append(g.err, err)
g.mutex.Unlock()
}
}()
}
// Wait blocks until all function calls from the Go method have returned, then
// returns the multierror.
func (g *Group) Wait() *Error {
g.wg.Wait()
g.mutex.Lock()
defer g.mutex.Unlock()
return g.err
}

View File

@ -1,121 +0,0 @@
package multierror
import (
"errors"
"fmt"
)
// Error is an error type to track multiple errors. This is used to
// accumulate errors in cases and return them as a single "error".
type Error struct {
Errors []error
ErrorFormat ErrorFormatFunc
}
func (e *Error) Error() string {
fn := e.ErrorFormat
if fn == nil {
fn = ListFormatFunc
}
return fn(e.Errors)
}
// ErrorOrNil returns an error interface if this Error represents
// a list of errors, or returns nil if the list of errors is empty. This
// function is useful at the end of accumulation to make sure that the value
// returned represents the existence of errors.
func (e *Error) ErrorOrNil() error {
if e == nil {
return nil
}
if len(e.Errors) == 0 {
return nil
}
return e
}
func (e *Error) GoString() string {
return fmt.Sprintf("*%#v", *e)
}
// WrappedErrors returns the list of errors that this Error is wrapping. It is
// an implementation of the errwrap.Wrapper interface so that multierror.Error
// can be used with that library.
//
// This method is not safe to be called concurrently. Unlike accessing the
// Errors field directly, this function also checks if the multierror is nil to
// prevent a null-pointer panic. It satisfies the errwrap.Wrapper interface.
func (e *Error) WrappedErrors() []error {
if e == nil {
return nil
}
return e.Errors
}
// Unwrap returns an error from Error (or nil if there are no errors).
// This error returned will further support Unwrap to get the next error,
// etc. The order will match the order of Errors in the multierror.Error
// at the time of calling.
//
// The resulting error supports errors.As/Is/Unwrap so you can continue
// to use the stdlib errors package to introspect further.
//
// This will perform a shallow copy of the errors slice. Any errors appended
// to this error after calling Unwrap will not be available until a new
// Unwrap is called on the multierror.Error.
func (e *Error) Unwrap() error {
// If we have no errors then we do nothing
if e == nil || len(e.Errors) == 0 {
return nil
}
// If we have exactly one error, we can just return that directly.
if len(e.Errors) == 1 {
return e.Errors[0]
}
// Shallow copy the slice
errs := make([]error, len(e.Errors))
copy(errs, e.Errors)
return chain(errs)
}
// chain implements the interfaces necessary for errors.Is/As/Unwrap to
// work in a deterministic way with multierror. A chain tracks a list of
// errors while accounting for the current represented error. This lets
// Is/As be meaningful.
//
// Unwrap returns the next error. In the cleanest form, Unwrap would return
// the wrapped error here but we can't do that if we want to properly
// get access to all the errors. Instead, users are recommended to use
// Is/As to get the correct error type out.
//
// Precondition: []error is non-empty (len > 0)
type chain []error
// Error implements the error interface
func (e chain) Error() string {
return e[0].Error()
}
// Unwrap implements errors.Unwrap by returning the next error in the
// chain or nil if there are no more errors.
func (e chain) Unwrap() error {
if len(e) == 1 {
return nil
}
return e[1:]
}
// As implements errors.As by attempting to map to the current value.
func (e chain) As(target interface{}) bool {
return errors.As(e[0], target)
}
// Is implements errors.Is by comparing the current value directly.
func (e chain) Is(target error) bool {
return errors.Is(e[0], target)
}

View File

@ -1,37 +0,0 @@
package multierror
import (
"fmt"
"github.com/hashicorp/errwrap"
)
// Prefix is a helper function that will prefix some text
// to the given error. If the error is a multierror.Error, then
// it will be prefixed to each wrapped error.
//
// This is useful to use when appending multiple multierrors
// together in order to give better scoping.
func Prefix(err error, prefix string) error {
if err == nil {
return nil
}
format := fmt.Sprintf("%s {{err}}", prefix)
switch err := err.(type) {
case *Error:
// Typed nils can reach here, so initialize if we are nil
if err == nil {
err = new(Error)
}
// Wrap each of the errors
for i, e := range err.Errors {
err.Errors[i] = errwrap.Wrapf(format, e)
}
return err
default:
return errwrap.Wrapf(format, err)
}
}

View File

@ -1,16 +0,0 @@
package multierror
// Len implements sort.Interface function for length
func (err Error) Len() int {
return len(err.Errors)
}
// Swap implements sort.Interface function for swapping elements
func (err Error) Swap(i, j int) {
err.Errors[i], err.Errors[j] = err.Errors[j], err.Errors[i]
}
// Less implements sort.Interface function for determining order
func (err Error) Less(i, j int) bool {
return err.Errors[i].Error() < err.Errors[j].Error()
}

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...)
}

View File

@ -15,11 +15,10 @@
package cgroups
import (
"errors"
"fmt"
"strconv"
"strings"
"github.com/hashicorp/go-multierror"
)
// cgroups blkio parameter filenames.
@ -35,9 +34,10 @@ var blkioThrottleWriteIOPSFiles = []string{"blkio.throttle.write_iops_device"}
// 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.
//
// -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
@ -142,7 +142,7 @@ type devMajMin struct {
// ResetBlkioParameters adds new, changes existing and removes missing blockIO parameters in cgroupsDir.
func ResetBlkioParameters(groupDir string, blockIO BlockIOParameters) error {
var errors *multierror.Error
errs := []error{}
oldBlockIO, _ := GetBlkioParameters(groupDir)
newBlockIO := NewBlockIOParameters()
newBlockIO.Weight = blockIO.Weight
@ -151,8 +151,8 @@ func ResetBlkioParameters(groupDir string, blockIO BlockIOParameters) error {
newBlockIO.ThrottleWriteBpsDevice = resetDevRates(oldBlockIO.ThrottleWriteBpsDevice, blockIO.ThrottleWriteBpsDevice)
newBlockIO.ThrottleReadIOPSDevice = resetDevRates(oldBlockIO.ThrottleReadIOPSDevice, blockIO.ThrottleReadIOPSDevice)
newBlockIO.ThrottleWriteIOPSDevice = resetDevRates(oldBlockIO.ThrottleWriteIOPSDevice, blockIO.ThrottleWriteIOPSDevice)
errors = multierror.Append(errors, SetBlkioParameters(groupDir, newBlockIO))
return errors.ErrorOrNil()
errs = append(errs, SetBlkioParameters(groupDir, newBlockIO))
return errors.Join(errs...)
}
// resetDevWeights adds wanted weight parameters to new and resets unwanted weights.
@ -189,16 +189,16 @@ func resetDevRates(old, wanted []DeviceRate) []DeviceRate {
// GetBlkioParameters returns BlockIO parameters from files in cgroups blkio controller directory.
func GetBlkioParameters(group string) (BlockIOParameters, error) {
var errors *multierror.Error
errs := []error{}
blockIO := NewBlockIOParameters()
errors = multierror.Append(errors, readWeight(group, blkioWeightFiles, &blockIO.Weight))
errors = multierror.Append(errors, readDeviceParameters(group, blkioWeightDeviceFiles, &blockIO.WeightDevice))
errors = multierror.Append(errors, readDeviceParameters(group, blkioThrottleReadBpsFiles, &blockIO.ThrottleReadBpsDevice))
errors = multierror.Append(errors, readDeviceParameters(group, blkioThrottleWriteBpsFiles, &blockIO.ThrottleWriteBpsDevice))
errors = multierror.Append(errors, readDeviceParameters(group, blkioThrottleReadIOPSFiles, &blockIO.ThrottleReadIOPSDevice))
errors = multierror.Append(errors, readDeviceParameters(group, blkioThrottleWriteIOPSFiles, &blockIO.ThrottleWriteIOPSDevice))
return blockIO, errors.ErrorOrNil()
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.
@ -217,7 +217,7 @@ func readWeight(groupDir string, filenames []string, rv *int64) error {
// readDeviceParameters parses device lines used for weights and throttling rates.
func readDeviceParameters(groupDir string, filenames []string, params DeviceParameters) error {
var errors *multierror.Error
errs := []error{}
contents, err := readFirstFile(groupDir, filenames)
if err != nil {
return err
@ -230,38 +230,38 @@ func readDeviceParameters(groupDir string, filenames []string, params DevicePara
// Expect syntax MAJOR:MINOR VALUE
devVal := strings.Split(line, " ")
if len(devVal) != 2 {
errors = multierror.Append(errors, fmt.Errorf("invalid line %q, single space expected", line))
errs = append(errs, fmt.Errorf("invalid line %q, single space expected", line))
continue
}
majMin := strings.Split(devVal[0], ":")
if len(majMin) != 2 {
errors = multierror.Append(errors, fmt.Errorf("invalid line %q, single colon expected before space", line))
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 {
errors = multierror.Append(errors, fmt.Errorf("invalid number when parsing \"major:minor value\" from \"%s:%s %s\"", majMin[0], majMin[1], devVal[1]))
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.ErrorOrNil()
return errors.Join(errs...)
}
// readFirstFile returns contents of the first successfully read entry.
func readFirstFile(groupDir string, filenames []string) (string, error) {
var errors *multierror.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
}
errors = multierror.Append(errors, err)
errs = append(errs, err)
}
err := errors.ErrorOrNil()
err := errors.Join(errs...)
if err != nil {
return "", fmt.Errorf("could not read any of files %q: %w", filenames, err)
}
@ -270,40 +270,40 @@ func readFirstFile(groupDir string, filenames []string) (string, error) {
// SetBlkioParameters writes BlockIO parameters to files in cgroups blkio contoller directory.
func SetBlkioParameters(group string, blockIO BlockIOParameters) error {
var errors *multierror.Error
errs := []error{}
if blockIO.Weight >= 0 {
errors = multierror.Append(errors, writeFirstFile(group, blkioWeightFiles, "%d", blockIO.Weight))
errs = append(errs, writeFirstFile(group, blkioWeightFiles, "%d", blockIO.Weight))
}
for _, wd := range blockIO.WeightDevice {
errors = multierror.Append(errors, writeFirstFile(group, blkioWeightDeviceFiles, "%d:%d %d", wd.Major, wd.Minor, wd.Weight))
errs = append(errs, writeFirstFile(group, blkioWeightDeviceFiles, "%d:%d %d", wd.Major, wd.Minor, wd.Weight))
}
for _, rd := range blockIO.ThrottleReadBpsDevice {
errors = multierror.Append(errors, writeFirstFile(group, blkioThrottleReadBpsFiles, "%d:%d %d", rd.Major, rd.Minor, rd.Rate))
errs = append(errs, writeFirstFile(group, blkioThrottleReadBpsFiles, "%d:%d %d", rd.Major, rd.Minor, rd.Rate))
}
for _, rd := range blockIO.ThrottleWriteBpsDevice {
errors = multierror.Append(errors, writeFirstFile(group, blkioThrottleWriteBpsFiles, "%d:%d %d", rd.Major, rd.Minor, rd.Rate))
errs = append(errs, writeFirstFile(group, blkioThrottleWriteBpsFiles, "%d:%d %d", rd.Major, rd.Minor, rd.Rate))
}
for _, rd := range blockIO.ThrottleReadIOPSDevice {
errors = multierror.Append(errors, writeFirstFile(group, blkioThrottleReadIOPSFiles, "%d:%d %d", rd.Major, rd.Minor, rd.Rate))
errs = append(errs, writeFirstFile(group, blkioThrottleReadIOPSFiles, "%d:%d %d", rd.Major, rd.Minor, rd.Rate))
}
for _, rd := range blockIO.ThrottleWriteIOPSDevice {
errors = multierror.Append(errors, writeFirstFile(group, blkioThrottleWriteIOPSFiles, "%d:%d %d", rd.Major, rd.Minor, rd.Rate))
errs = append(errs, writeFirstFile(group, blkioThrottleWriteIOPSFiles, "%d:%d %d", rd.Major, rd.Minor, rd.Rate))
}
return errors.ErrorOrNil()
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 {
var errors *multierror.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 {
errors = multierror.Append(errors, err)
errs = append(errs, err)
continue
}
return nil
}
err := errors.ErrorOrNil()
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)

View File

@ -31,7 +31,7 @@ type Controller int
// Group represents a control group.
type Group string
//nolint
// nolint
const (
// UnkownController represents a controller of unknown type.
UnknownController Controller = iota
@ -105,7 +105,7 @@ func (c Controller) String() string {
// Path returns the absolute path of the given controller.
func (c Controller) Path() string {
return path.Join(mountDir, c.String())
return cgroupPath(c.String())
}
// RelPath returns the relative path of the given controller.
@ -115,7 +115,7 @@ func (c Controller) RelPath() string {
// Group returns the given group for the controller.
func (c Controller) Group(group string) Group {
return Group(path.Join(mountDir, c.String(), group))
return Group(cgroupPath(c.String(), group))
}
// AsGroup returns the group for the given absolute directory path.
@ -125,7 +125,7 @@ func AsGroup(absDir string) Group {
// Controller returns the controller for the group.
func (g Group) Controller() Controller {
relPath := strings.TrimPrefix(string(g), mountDir+"/")
relPath := strings.TrimPrefix(string(g), cgroupPath()+"/")
split := strings.SplitN(relPath, "/", 2)
if len(split) > 0 {
return controllerDirs[split[0]]
@ -232,6 +232,6 @@ func (g Group) writePids(entry string, pids ...string) error {
// error returns a formatted group-specific error.
func (g Group) errorf(format string, args ...interface{}) error {
name := strings.TrimPrefix(string(g), mountDir+"/")
name := strings.TrimPrefix(string(g), cgroupPath()+"/")
return fmt.Errorf("cgroup "+name+": "+format, args...)
}

View File

@ -15,11 +15,10 @@
package cgroups
import (
"path"
"path/filepath"
goresctrlpath "github.com/intel/goresctrl/pkg/path"
)
//nolint
// nolint
const (
// Tasks is a cgroup's "tasks" entry.
Tasks = "tasks"
@ -37,39 +36,18 @@ const (
CpusetMems = "cpuset.mems"
)
var (
// mount is the parent directory for per-controller cgroupfs mounts.
mountDir = "/sys/fs/cgroup"
// v2Dir is the parent directory for per-controller cgroupfs mounts.
v2Dir = path.Join(mountDir, "unified")
// KubeletRoot is the --cgroup-root option the kubelet is running with.
KubeletRoot = ""
)
const cgroupBasePath = "sys/fs/cgroup"
// GetMountDir returns the common mount point for cgroup v1 controllers.
func GetMountDir() string {
return mountDir
}
// SetMountDir sets the common mount point for the cgroup v1 controllers.
func SetMountDir(dir string) {
v2, _ := filepath.Rel(mountDir, v2Dir)
mountDir = dir
if v2 != "" {
v2Dir = path.Join(mountDir, v2)
}
return cgroupPath()
}
// GetV2Dir returns the cgroup v2 unified mount directory.
func GetV2Dir() string {
return v2Dir
return cgroupPath("unified")
}
// SetV2Dir sets the unified cgroup v2 mount directory.
func SetV2Dir(dir string) {
if dir[0] == '/' {
v2Dir = dir
} else {
v2Dir = path.Join(mountDir, v2Dir)
}
func cgroupPath(elems ...string) string {
return goresctrlpath.Path(append([]string{cgroupBasePath}, elems...)...)
}

35
vendor/github.com/intel/goresctrl/pkg/path/path.go generated vendored Normal file
View File

@ -0,0 +1,35 @@
/*
Copyright 2023 Intel Corporation
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 path
import "path/filepath"
// RootDir is a helper for handling system directory paths
type RootDir string
var prefix RootDir = "/"
// Path returns a full path to a file under RootDir
func (d RootDir) Path(elems ...string) string {
return filepath.Join(append([]string{string(d)}, elems...)...)
}
// SetPrefix sets the global path prefix to use for all system files.
func SetPrefix(p string) { prefix = RootDir(p) }
// Path returns a path to a file, prefixed with the global prefix.
func Path(elems ...string) string { return prefix.Path(elems...) }

View File

@ -19,7 +19,6 @@ package rdt
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
@ -336,6 +335,6 @@ func readFileBitmask(path string) (bitmask, error) {
}
func readFileString(path string) (string, error) {
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
return strings.TrimSpace(string(data)), err
}

View File

@ -25,28 +25,28 @@ limitations under the License.
// Monitoring (MBM).
//
// Basic usage example:
// rdt.SetLogger(logrus.New())
//
// if err := rdt.Initialize(""); err != nil {
// return fmt.Errorf("RDT not supported: %v", err)
// }
// rdt.SetLogger(logrus.New())
//
// if err := rdt.SetConfigFromFile("/path/to/rdt.conf.yaml", false); err != nil {
// return fmt.Errorf("RDT configuration failed: %v", err)
// }
// if err := rdt.Initialize(""); err != nil {
// return fmt.Errorf("RDT not supported: %v", err)
// }
//
// if cls, ok := rdt.GetClass("my-class"); ok {
// // Set PIDs 12345 and 12346 to class "my-class"
// if err := cls.AddPids("12345", "12346"); err != nil {
// return fmt.Errorf("failed to add PIDs to RDT class: %v", err)
// }
// }
// if err := rdt.SetConfigFromFile("/path/to/rdt.conf.yaml", false); err != nil {
// return fmt.Errorf("RDT configuration failed: %v", err)
// }
//
// if cls, ok := rdt.GetClass("my-class"); ok {
// // Set PIDs 12345 and 12346 to class "my-class"
// if err := cls.AddPids("12345", "12346"); err != nil {
// return fmt.Errorf("failed to add PIDs to RDT class: %v", err)
// }
// }
package rdt
import (
"errors"
"fmt"
"io/ioutil"
stdlog "log"
"os"
"path/filepath"
@ -244,7 +244,7 @@ func SetConfigFromData(data []byte, force bool) error {
// SetConfigFromFile reads configuration from the filesystem and reconfigures
// the resctrl filesystem.
func SetConfigFromFile(path string, force bool) error {
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("failed to read config file: %v", err)
}
@ -490,11 +490,11 @@ func (c *control) pruneMonGroups() error {
}
func (c *control) readRdtFile(rdtPath string) ([]byte, error) {
return ioutil.ReadFile(filepath.Join(info.resctrlPath, rdtPath))
return os.ReadFile(filepath.Join(info.resctrlPath, rdtPath))
}
func (c *control) writeRdtFile(rdtPath string, data []byte) error {
if err := ioutil.WriteFile(filepath.Join(info.resctrlPath, rdtPath), data, 0644); err != nil {
if err := os.WriteFile(filepath.Join(info.resctrlPath, rdtPath), data, 0644); err != nil {
return c.cmdError(err)
}
return nil
@ -728,7 +728,7 @@ func (r *resctrlGroup) GetMonData() MonData {
}
func (r *resctrlGroup) getMonL3Data() (MonL3Data, error) {
files, err := ioutil.ReadDir(r.path("mon_data"))
files, err := os.ReadDir(r.path("mon_data"))
if err != nil {
return nil, err
}
@ -759,7 +759,7 @@ func (r *resctrlGroup) getMonL3Data() (MonL3Data, error) {
}
func (r *resctrlGroup) getMonLeafData(path string) (MonLeafData, error) {
files, err := ioutil.ReadDir(r.path(path))
files, err := os.ReadDir(r.path(path))
if err != nil {
return nil, err
}
@ -826,7 +826,7 @@ func (m *monGroup) GetAnnotations() map[string]string {
}
func resctrlGroupsFromFs(prefix string, path string) ([]string, error) {
files, err := ioutil.ReadDir(path)
files, err := os.ReadDir(path)
if err != nil {
return nil, err
}

View File

@ -20,12 +20,13 @@ import (
"encoding/binary"
"fmt"
"os"
goresctrlpath "github.com/intel/goresctrl/pkg/path"
)
func ReadMSR(cpu ID, msr int64) (uint64, error) {
str := fmt.Sprintf("/dev/cpu/%d/msr", cpu)
file, err := os.Open(str)
path := goresctrlpath.Path("dev/cpu", fmt.Sprintf("%d", cpu), "msr")
file, err := os.Open(path)
if err != nil {
return 0, err
}

View File

@ -18,26 +18,25 @@ package utils
import (
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
goresctrlpath "github.com/intel/goresctrl/pkg/path"
)
const (
SysfsUncoreBasepath = "/sys/devices/system/cpu/intel_uncore_frequency/"
SysfsUncoreBasepath = "sys/devices/system/cpu/intel_uncore_frequency"
SysfsCpuBasepath = "sys/devices/system/cpu"
)
func setCPUFreqValue(cpu ID, setting string, value int) error {
path := fmt.Sprintf("/sys/devices/system/cpu/cpu%d/cpufreq/%s", cpu, setting)
return writeFileInt(path, value)
return writeFileInt(cpuFreqPath(cpu, setting), value)
}
// GetCPUFreqValue returns information of the currently used CPU frequency
func GetCPUFreqValue(cpu ID, setting string) (int, error) {
str := fmt.Sprintf("/sys/devices/system/cpu/cpu%d/cpufreq/%s", cpu, setting)
raw, err := ioutil.ReadFile(str)
raw, err := os.ReadFile(cpuFreqPath(cpu, setting))
if err != nil {
return 0, err
}
@ -50,6 +49,10 @@ func GetCPUFreqValue(cpu ID, setting string) (int, error) {
return value, nil
}
func cpuFreqPath(cpu ID, setting string) string {
return goresctrlpath.Path(SysfsCpuBasepath, fmt.Sprintf("cpu%d", cpu), "cpufreq", setting)
}
// SetCPUScalingMinFreq sets the scaling_min_freq value of a given CPU
func SetCPUScalingMinFreq(cpu ID, freq int) error {
return setCPUFreqValue(cpu, "scaling_min_freq", freq)
@ -84,7 +87,7 @@ func SetCPUsScalingMaxFreq(cpus []ID, freq int) error {
// UncoreFreqAvailable returns true if the uncore frequency control functions are available.
func UncoreFreqAvailable() bool {
_, err := os.Stat(SysfsUncoreBasepath)
_, err := os.Stat(goresctrlpath.Path(SysfsUncoreBasepath))
return err == nil
}
@ -99,7 +102,7 @@ func SetUncoreMaxFreq(pkg, die ID, freqKhz int) error {
}
func uncoreFreqPath(pkg, die ID, attribute string) string {
return fmt.Sprintf(SysfsUncoreBasepath+"package_%02d_die_%02d/%s", pkg, die, attribute)
return goresctrlpath.Path(SysfsUncoreBasepath, fmt.Sprintf("package_%02d_die_%02d", pkg, die), attribute)
}
func getUncoreFreqValue(pkg, die ID, attribute string) (int, error) {
@ -123,11 +126,11 @@ func setUncoreFreqValue(pkg, die ID, attribute string, value int) error {
}
func writeFileInt(path string, value int) error {
return ioutil.WriteFile(path, []byte(strconv.Itoa(value)), 0644)
return os.WriteFile(path, []byte(strconv.Itoa(value)), 0644)
}
func readFileInt(path string) (int, error) {
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
if err != nil {
return 0, err
}

11
vendor/modules.txt vendored
View File

@ -252,18 +252,13 @@ 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/hashicorp/errwrap v1.1.0
## explicit
github.com/hashicorp/errwrap
# github.com/hashicorp/go-multierror v1.1.1
## explicit; go 1.13
github.com/hashicorp/go-multierror
# github.com/intel/goresctrl v0.3.0
## explicit; go 1.18
# github.com/intel/goresctrl v0.5.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
github.com/intel/goresctrl/pkg/rdt
github.com/intel/goresctrl/pkg/utils
# github.com/json-iterator/go v1.1.12