revendor containerd/cgroups

Note: now vndr >= v0.10 is required (https://github.com/containerd/cgroups/issues/139)

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
Akihiro Suda
2020-01-10 13:05:54 +09:00
parent 1c2606d05b
commit e1221e69a8
62 changed files with 3958 additions and 1444 deletions

View File

@@ -4,9 +4,9 @@ go 1.12
require (
github.com/cilium/ebpf v0.0.0-20191113100448-d9fb101ca1fb
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
github.com/coreos/go-systemd/v22 v22.0.0-20191111152658-2d78030078ef
github.com/docker/go-units v0.4.0
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e
github.com/godbus/dbus/v5 v5.0.3
github.com/gogo/protobuf v1.2.1
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700
github.com/pkg/errors v0.8.1

View File

@@ -22,8 +22,8 @@ import (
"strings"
"sync"
systemdDbus "github.com/coreos/go-systemd/dbus"
"github.com/godbus/dbus"
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
"github.com/godbus/dbus/v5"
specs "github.com/opencontainers/runtime-spec/specs-go"
)

View File

@@ -16,13 +16,44 @@
package v2
import (
"math"
"strconv"
"strings"
)
type CPUMax string
func NewCPUMax(quota *int64, period *uint64) CPUMax {
max := "max"
if quota != nil {
max = strconv.FormatInt(*quota, 10)
}
return CPUMax(strings.Join([]string{max, strconv.FormatUint(*period, 10)}, " "))
}
type CPU struct {
Weight *uint64
Max *uint64
Max CPUMax
Cpus string
Mems string
}
func (c CPUMax) extractQuotaAndPeriod() (int64, uint64) {
var (
quota int64
period uint64
)
values := strings.Split(string(c), " ")
if values[0] == "max" {
quota = math.MaxInt64
} else {
quota, _ = strconv.ParseInt(values[0], 10, 64)
}
period, _ = strconv.ParseUint(values[1], 10, 64)
return quota, period
}
func (r *CPU) Values() (o []Value) {
if r.Weight != nil {
o = append(o, Value{
@@ -30,10 +61,10 @@ func (r *CPU) Values() (o []Value) {
value: *r.Weight,
})
}
if r.Max != nil {
if r.Max != "" {
o = append(o, Value{
filename: "cpu.max",
value: *r.Max,
value: r.Max,
})
}
if r.Cpus != "" {

View File

@@ -19,25 +19,37 @@ package v2
import (
"bufio"
"fmt"
"github.com/opencontainers/runtime-spec/specs-go"
"io/ioutil"
"math"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"syscall"
"time"
"golang.org/x/sys/unix"
"github.com/containerd/cgroups/v2/stats"
"github.com/godbus/dbus/v5"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
)
const (
subtreeControl = "cgroup.subtree_control"
controllersFile = "cgroup.controllers"
subtreeControl = "cgroup.subtree_control"
controllersFile = "cgroup.controllers"
defaultCgroup2Path = "/sys/fs/cgroup"
defaultSlice = "system.slice"
)
var (
canDelegate bool
once sync.Once
)
type cgValuer interface {
@@ -66,22 +78,45 @@ type Resources struct {
// Values returns the raw filenames and values that
// can be written to the unified hierarchy
func (r *Resources) Values() (o []Value) {
values := []cgValuer{
r.CPU,
r.Memory,
r.Pids,
r.IO,
r.RDMA,
if r.CPU != nil {
o = append(o, r.CPU.Values()...)
}
for _, v := range values {
if v == nil {
continue
}
o = append(o, v.Values()...)
if r.Memory != nil {
o = append(o, r.Memory.Values()...)
}
if r.Pids != nil {
o = append(o, r.Pids.Values()...)
}
if r.IO != nil {
o = append(o, r.IO.Values()...)
}
if r.RDMA != nil {
o = append(o, r.RDMA.Values()...)
}
return o
}
// EnabledControllers returns the list of all not nil resource controllers
func (r *Resources) EnabledControllers() (c []string) {
if r.CPU != nil {
c = append(c, "cpu")
c = append(c, "cpuset")
}
if r.Memory != nil {
c = append(c, "memory")
}
if r.Pids != nil {
c = append(c, "pids")
}
if r.IO != nil {
c = append(c, "io")
}
if r.RDMA != nil {
c = append(c, "rdma")
}
return
}
// Value of a cgroup setting
type Value struct {
filename string
@@ -102,6 +137,8 @@ func (c *Value) write(path string, perm os.FileMode) error {
data = t
case string:
data = []byte(t)
case CPUMax:
data = []byte(t)
default:
return ErrInvalidFormat
}
@@ -129,15 +166,20 @@ func NewManager(mountpoint string, group string, resources *Resources) (*Manager
if err := os.MkdirAll(path, defaultDirPerm); err != nil {
return nil, err
}
if err := setResources(path, resources); err != nil {
m := Manager{
unifiedMountpoint: mountpoint,
path: path,
}
if err := m.ToggleControllers(resources.EnabledControllers(), Enable); err != nil {
// clean up cgroup dir on failure
os.Remove(path)
return nil, err
}
return &Manager{
unifiedMountpoint: mountpoint,
path: path,
}, nil
if err := setResources(path, resources); err != nil {
os.Remove(path)
return nil, err
}
return &m, nil
}
func LoadManager(mountpoint string, group string) (*Manager, error) {
@@ -308,12 +350,15 @@ func (c *Manager) Stat() (*stats.Metrics, error) {
}
out := make(map[string]interface{})
for _, controller := range controllers {
filename := fmt.Sprintf("%s.stat", controller)
if err := readStatsFile(c.path, filename, out); err != nil {
if os.IsNotExist(err) {
continue
switch controller {
case "cpu", "memory":
filename := fmt.Sprintf("%s.stat", controller)
if err := readKVStatsFile(c.path, filename, out); err != nil {
if os.IsNotExist(err) {
continue
}
return nil, err
}
return nil, err
}
}
for _, name := range singleValueFiles {
@@ -376,6 +421,8 @@ func (c *Manager) Stat() (*stats.Metrics, error) {
SwapLimit: getStatFileContentUint64(filepath.Join(c.path, "memory.swap.max")),
}
metrics.Io = &stats.IOStat{Usage: readIoStats(c.path)}
metrics.Rdma = &stats.RdmaStat{
Current: rdmaStats(filepath.Join(c.path, "rdma.current")),
Limit: rdmaStats(filepath.Join(c.path, "rdma.max")),
@@ -433,7 +480,7 @@ func readSingleFile(path string, file string, out map[string]interface{}) error
return nil
}
func readStatsFile(path string, file string, out map[string]interface{}) error {
func readKVStatsFile(path string, file string, out map[string]interface{}) error {
f, err := os.Open(filepath.Join(path, file))
if err != nil {
return err
@@ -447,7 +494,7 @@ func readStatsFile(path string, file string, out map[string]interface{}) error {
}
name, value, err := parseKV(s.Text())
if err != nil {
return err
return errors.Wrapf(err, "error while parsing %s (line=%q)", filepath.Join(path, file), s.Text())
}
out[name] = value
}
@@ -516,7 +563,7 @@ func (c *Manager) waitForEvents(ec chan<- Event, errCh chan<- error) {
}
var out map[string]interface{}
if bytesRead >= syscall.SizeofInotifyEvent {
if err := readStatsFile(c.path, "memory.events", out); err != nil {
if err := readKVStatsFile(c.path, "memory.events", out); err != nil {
e := Event{
High: out["high"].(uint64),
Low: out["low"].(uint64),
@@ -550,3 +597,126 @@ func setDevices(path string, devices []specs.LinuxDeviceCgroup) error {
}
return nil
}
func NewSystemd(slice, group string, pid int, resources *Resources) (*Manager, error) {
if slice == "" {
slice = defaultSlice
}
path := filepath.Join(defaultCgroup2Path, slice, group)
conn, err := systemdDbus.New()
if err != nil {
return &Manager{}, err
}
defer conn.Close()
properties := []systemdDbus.Property{
systemdDbus.PropDescription(fmt.Sprintf("cgroup %s", group)),
newSystemdProperty("DefaultDependencies", false),
newSystemdProperty("MemoryAccounting", true),
newSystemdProperty("CPUAccounting", true),
newSystemdProperty("IOAccounting", true),
}
// if we create a slice, the parent is defined via a Wants=
if strings.HasSuffix(group, ".slice") {
properties = append(properties, systemdDbus.PropWants(defaultSlice))
} else {
// otherwise, we use Slice=
properties = append(properties, systemdDbus.PropSlice(defaultSlice))
}
// only add pid if its valid, -1 is used w/ general slice creation.
if pid != -1 {
properties = append(properties, newSystemdProperty("PIDs", []uint32{uint32(pid)}))
}
if resources.Memory != nil && *resources.Memory.Max != 0 {
properties = append(properties,
newSystemdProperty("MemoryMax", uint64(*resources.Memory.Max)))
}
if resources.CPU != nil && *resources.CPU.Weight != 0 {
properties = append(properties,
newSystemdProperty("CPUWeight", *resources.CPU.Weight))
}
if resources.CPU != nil && resources.CPU.Max != "" {
quota, period := resources.CPU.Max.extractQuotaAndPeriod()
// cpu.cfs_quota_us and cpu.cfs_period_us are controlled by systemd.
// corresponds to USEC_INFINITY in systemd
// if USEC_INFINITY is provided, CPUQuota is left unbound by systemd
// always setting a property value ensures we can apply a quota and remove it later
cpuQuotaPerSecUSec := uint64(math.MaxUint64)
if quota > 0 {
// systemd converts CPUQuotaPerSecUSec (microseconds per CPU second) to CPUQuota
// (integer percentage of CPU) internally. This means that if a fractional percent of
// CPU is indicated by Resources.CpuQuota, we need to round up to the nearest
// 10ms (1% of a second) such that child cgroups can set the cpu.cfs_quota_us they expect.
cpuQuotaPerSecUSec = uint64(quota*1000000) / period
if cpuQuotaPerSecUSec%10000 != 0 {
cpuQuotaPerSecUSec = ((cpuQuotaPerSecUSec / 10000) + 1) * 10000
}
}
properties = append(properties,
newSystemdProperty("CPUQuotaPerSecUSec", cpuQuotaPerSecUSec))
}
// If we can delegate, we add the property back in
if canDelegate {
properties = append(properties, newSystemdProperty("Delegate", true))
}
if resources.Pids != nil && resources.Pids.Max > 0 {
properties = append(properties,
newSystemdProperty("TasksAccounting", true),
newSystemdProperty("TasksMax", uint64(resources.Pids.Max)))
}
statusChan := make(chan string, 1)
if _, err := conn.StartTransientUnit(group, "replace", properties, statusChan); err == nil {
select {
case <-statusChan:
case <-time.After(time.Second):
logrus.Warnf("Timed out while waiting for StartTransientUnit(%s) completion signal from dbus. Continuing...", group)
}
} else if !isUnitExists(err) {
return &Manager{}, err
}
return &Manager{
path: path,
}, nil
}
func LoadSystemd(slice, group string) (*Manager, error) {
if slice == "" {
slice = defaultSlice
}
group = filepath.Join(defaultCgroup2Path, slice, group)
return &Manager{
path: group,
}, nil
}
func (c *Manager) DeleteSystemd() error {
conn, err := systemdDbus.New()
if err != nil {
return err
}
defer conn.Close()
group := systemdUnitFromPath(c.path)
ch := make(chan string)
_, err = conn.StopUnit(group, "replace", ch)
if err != nil {
return err
}
<-ch
return nil
}
func newSystemdProperty(name string, units interface{}) systemdDbus.Property {
return systemdDbus.Property{
Name: name,
Value: dbus.MakeVariant(units),
}
}

View File

@@ -29,6 +29,7 @@ type Metrics struct {
CPU *CPUStat `protobuf:"bytes,2,opt,name=cpu,proto3" json:"cpu,omitempty"`
Memory *MemoryStat `protobuf:"bytes,4,opt,name=memory,proto3" json:"memory,omitempty"`
Rdma *RdmaStat `protobuf:"bytes,5,opt,name=rdma,proto3" json:"rdma,omitempty"`
Io *IOStat `protobuf:"bytes,6,opt,name=io,proto3" json:"io,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -304,6 +305,89 @@ func (m *RdmaEntry) XXX_DiscardUnknown() {
var xxx_messageInfo_RdmaEntry proto.InternalMessageInfo
type IOStat struct {
Usage []*IOEntry `protobuf:"bytes,1,rep,name=usage,proto3" json:"usage,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *IOStat) Reset() { *m = IOStat{} }
func (*IOStat) ProtoMessage() {}
func (*IOStat) Descriptor() ([]byte, []int) {
return fileDescriptor_2fc6005842049e6b, []int{6}
}
func (m *IOStat) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *IOStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_IOStat.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalTo(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *IOStat) XXX_Merge(src proto.Message) {
xxx_messageInfo_IOStat.Merge(m, src)
}
func (m *IOStat) XXX_Size() int {
return m.Size()
}
func (m *IOStat) XXX_DiscardUnknown() {
xxx_messageInfo_IOStat.DiscardUnknown(m)
}
var xxx_messageInfo_IOStat proto.InternalMessageInfo
type IOEntry struct {
Major uint64 `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"`
Minor uint64 `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"`
Rbytes uint64 `protobuf:"varint,3,opt,name=rbytes,proto3" json:"rbytes,omitempty"`
Wbytes uint64 `protobuf:"varint,4,opt,name=wbytes,proto3" json:"wbytes,omitempty"`
Rios uint64 `protobuf:"varint,5,opt,name=rios,proto3" json:"rios,omitempty"`
Wios uint64 `protobuf:"varint,6,opt,name=wios,proto3" json:"wios,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *IOEntry) Reset() { *m = IOEntry{} }
func (*IOEntry) ProtoMessage() {}
func (*IOEntry) Descriptor() ([]byte, []int) {
return fileDescriptor_2fc6005842049e6b, []int{7}
}
func (m *IOEntry) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *IOEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_IOEntry.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalTo(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *IOEntry) XXX_Merge(src proto.Message) {
xxx_messageInfo_IOEntry.Merge(m, src)
}
func (m *IOEntry) XXX_Size() int {
return m.Size()
}
func (m *IOEntry) XXX_DiscardUnknown() {
xxx_messageInfo_IOEntry.DiscardUnknown(m)
}
var xxx_messageInfo_IOEntry proto.InternalMessageInfo
func init() {
proto.RegisterType((*Metrics)(nil), "io.containerd.cgroups.v2.Metrics")
proto.RegisterType((*PidsStat)(nil), "io.containerd.cgroups.v2.PidsStat")
@@ -311,6 +395,8 @@ func init() {
proto.RegisterType((*MemoryStat)(nil), "io.containerd.cgroups.v2.MemoryStat")
proto.RegisterType((*RdmaStat)(nil), "io.containerd.cgroups.v2.RdmaStat")
proto.RegisterType((*RdmaEntry)(nil), "io.containerd.cgroups.v2.RdmaEntry")
proto.RegisterType((*IOStat)(nil), "io.containerd.cgroups.v2.IOStat")
proto.RegisterType((*IOEntry)(nil), "io.containerd.cgroups.v2.IOEntry")
}
func init() {
@@ -318,68 +404,74 @@ func init() {
}
var fileDescriptor_2fc6005842049e6b = []byte{
// 965 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x4d, 0x6f, 0x1c, 0x45,
0x10, 0xcd, 0xe2, 0x8d, 0xbd, 0x5b, 0x6b, 0xc7, 0x4e, 0xc7, 0x31, 0x1d, 0x07, 0xaf, 0xed, 0x35,
0xa0, 0x20, 0xc1, 0xae, 0x64, 0x3e, 0x24, 0x50, 0x38, 0x38, 0x86, 0x88, 0x03, 0x06, 0x6b, 0x12,
0x8b, 0xe3, 0xa8, 0x77, 0xa6, 0x3d, 0x33, 0xf1, 0x7c, 0xa9, 0xbb, 0xc7, 0x96, 0x39, 0x71, 0xe0,
0xce, 0xdf, 0xca, 0x0d, 0x8e, 0x9c, 0x10, 0xf1, 0x7f, 0xe0, 0x8e, 0xaa, 0x6a, 0x66, 0x67, 0x38,
0x18, 0xb8, 0x75, 0xbd, 0xf7, 0xaa, 0xba, 0xea, 0xed, 0x74, 0x2d, 0x7c, 0x12, 0x25, 0x2e, 0xae,
0xe6, 0xd3, 0xa0, 0xc8, 0x66, 0x41, 0x91, 0x3b, 0x95, 0xe4, 0xda, 0x84, 0xb3, 0x20, 0x32, 0x45,
0x55, 0xda, 0xd9, 0xe5, 0xe1, 0xcc, 0x3a, 0xe5, 0xec, 0x2c, 0xd3, 0xce, 0x24, 0x81, 0x9d, 0x96,
0xa6, 0x70, 0x85, 0x90, 0x49, 0x31, 0x6d, 0xd5, 0xd3, 0x5a, 0x3d, 0xbd, 0x3c, 0xdc, 0xde, 0x8c,
0x8a, 0xa8, 0x20, 0xd1, 0x0c, 0x4f, 0xac, 0x9f, 0xfc, 0xd5, 0x83, 0x95, 0x13, 0xae, 0x20, 0x3e,
0x83, 0x7e, 0x99, 0x84, 0x56, 0xf6, 0xf6, 0x7a, 0x4f, 0x46, 0x87, 0x93, 0xe9, 0x6d, 0xa5, 0xa6,
0xa7, 0x49, 0x68, 0x5f, 0x38, 0xe5, 0x3c, 0xd2, 0x8b, 0xa7, 0xb0, 0x14, 0x94, 0x95, 0x7c, 0x8b,
0xd2, 0xf6, 0x6f, 0x4f, 0x3b, 0x3e, 0x3d, 0xc3, 0xac, 0x67, 0x2b, 0x37, 0x7f, 0xec, 0x2e, 0x1d,
0x9f, 0x9e, 0x79, 0x98, 0x26, 0x9e, 0xc2, 0x72, 0xa6, 0xb3, 0xc2, 0x5c, 0xcb, 0x3e, 0x15, 0x78,
0xf7, 0xf6, 0x02, 0x27, 0xa4, 0xa3, 0x9b, 0xeb, 0x1c, 0xec, 0xd9, 0x84, 0x99, 0x92, 0x77, 0xff,
0xab, 0x67, 0x2f, 0xcc, 0x14, 0xf7, 0x8c, 0xfa, 0xc9, 0x17, 0x30, 0x68, 0xa6, 0x10, 0x12, 0x56,
0x82, 0xca, 0x18, 0x9d, 0x3b, 0x1a, 0xbd, 0xef, 0x35, 0xa1, 0xd8, 0x84, 0xbb, 0x69, 0x92, 0x25,
0x8e, 0x66, 0xeb, 0x7b, 0x1c, 0x4c, 0x7e, 0xed, 0xc1, 0x4a, 0x3d, 0x8b, 0xd8, 0x01, 0xa8, 0xac,
0x8a, 0xb4, 0x5f, 0x59, 0x1d, 0xd4, 0xe9, 0x43, 0x42, 0xce, 0xac, 0x0e, 0xc4, 0x63, 0x18, 0x56,
0x56, 0x1b, 0x66, 0xb9, 0xc8, 0x00, 0x01, 0x22, 0x77, 0x61, 0x64, 0xaf, 0xad, 0xd3, 0x19, 0xd3,
0x4b, 0x44, 0x03, 0x43, 0x24, 0xd8, 0x01, 0xc8, 0x8d, 0x5f, 0x6a, 0x93, 0x14, 0xa1, 0x25, 0x7b,
0xfa, 0xde, 0x30, 0x37, 0xa7, 0x0c, 0x88, 0x7d, 0x58, 0xcd, 0x8d, 0xef, 0x62, 0x53, 0x38, 0x97,
0xea, 0x90, 0x3c, 0xe8, 0x7b, 0xa3, 0xdc, 0xbc, 0x6c, 0x20, 0xf1, 0x1e, 0xdc, 0x5b, 0xf0, 0x7c,
0xcb, 0x32, 0x89, 0xd6, 0x16, 0x28, 0x5e, 0x34, 0xf9, 0x65, 0x08, 0xd0, 0x9a, 0x2b, 0x04, 0xf4,
0x55, 0x5e, 0xe4, 0xf5, 0x38, 0x74, 0x46, 0xec, 0x3c, 0x49, 0x75, 0x3d, 0x04, 0x9d, 0xb1, 0x81,
0x0b, 0x6d, 0x72, 0x9d, 0xfa, 0xd6, 0xa9, 0xe0, 0xa2, 0x9e, 0x60, 0xc4, 0xd8, 0x0b, 0x84, 0x30,
0xcd, 0xa6, 0x6a, 0x5e, 0x37, 0x4f, 0x67, 0xc2, 0x8a, 0xe0, 0xa2, 0xee, 0x97, 0xce, 0xe8, 0xb4,
0x8d, 0x33, 0x9d, 0xd5, 0xfd, 0x71, 0x80, 0x0e, 0xe1, 0x45, 0x7e, 0xa6, 0xca, 0x52, 0x87, 0x72,
0x85, 0x1d, 0x42, 0xe8, 0x84, 0x10, 0x74, 0x88, 0x04, 0x61, 0x62, 0xdc, 0xb5, 0x1c, 0xb0, 0x43,
0x88, 0x7c, 0x85, 0x00, 0x8e, 0x4f, 0xf4, 0x95, 0x49, 0x9c, 0x9e, 0x63, 0x8b, 0x43, 0x1e, 0x1f,
0xd1, 0x1f, 0x1a, 0x50, 0x3c, 0x82, 0x01, 0xce, 0xe8, 0xbb, 0xb8, 0x94, 0xc0, 0x5f, 0x00, 0xc6,
0x2f, 0xe3, 0x52, 0x1c, 0xc0, 0x5a, 0x92, 0xab, 0xc0, 0x25, 0x97, 0xda, 0x27, 0x4f, 0x46, 0xc4,
0xaf, 0x36, 0xe0, 0x11, 0x7a, 0xb3, 0x0b, 0xa3, 0xae, 0x64, 0x95, 0xdb, 0xec, 0x08, 0xba, 0x55,
0xc8, 0xc5, 0xb5, 0x7f, 0x56, 0x79, 0x8e, 0x6e, 0xb6, 0x55, 0x48, 0x72, 0xaf, 0x5b, 0x85, 0x04,
0x7b, 0x30, 0xaa, 0x72, 0x7d, 0x99, 0x04, 0x4e, 0xcd, 0x53, 0x2d, 0xd7, 0xd9, 0xed, 0x0e, 0x24,
0x3e, 0x80, 0x0d, 0x74, 0xd8, 0x37, 0x3a, 0x48, 0x55, 0x92, 0x91, 0x6c, 0x83, 0x64, 0xeb, 0x88,
0x7b, 0x2d, 0x2c, 0x3e, 0x02, 0x41, 0xd2, 0x2a, 0xef, 0x8a, 0xef, 0x93, 0xf8, 0x3e, 0x32, 0x67,
0x5d, 0x02, 0xdf, 0x48, 0x19, 0x9d, 0xab, 0x2a, 0x75, 0x52, 0xb0, 0x43, 0x75, 0x28, 0xc6, 0x00,
0x65, 0x94, 0xa9, 0x57, 0x4c, 0x3e, 0xe0, 0xae, 0x5b, 0x04, 0x2f, 0xba, 0x2a, 0xcc, 0x45, 0x92,
0x47, 0x56, 0x3b, 0xdf, 0x68, 0xd6, 0x6d, 0xf2, 0x45, 0x2d, 0xe3, 0x31, 0x21, 0x66, 0xf0, 0xa0,
0x23, 0xa7, 0xe9, 0x95, 0xd3, 0xf2, 0x21, 0xe9, 0x3b, 0x95, 0x8e, 0x6a, 0x46, 0x7c, 0x0a, 0x5b,
0x9d, 0x84, 0xbc, 0x08, 0x75, 0xdd, 0xb7, 0xdc, 0xa2, 0x9c, 0x87, 0x2d, 0xfb, 0x5d, 0x4b, 0x8a,
0x6d, 0x18, 0x94, 0x91, 0xd1, 0xe7, 0x49, 0x9a, 0xca, 0xb7, 0xf9, 0x61, 0x36, 0xb1, 0xd8, 0x82,
0xe5, 0x32, 0xb2, 0x81, 0xca, 0xa5, 0x24, 0xa6, 0x8e, 0xd8, 0x04, 0xeb, 0xb4, 0x4a, 0xe5, 0xa3,
0xc6, 0x04, 0x0a, 0xd9, 0x84, 0x45, 0xb3, 0xdb, 0x8d, 0x09, 0x0d, 0x22, 0x26, 0xb0, 0x5a, 0x46,
0xa1, 0x5e, 0x28, 0x1e, 0xf3, 0xef, 0xdf, 0xc5, 0xb8, 0x46, 0xaa, 0x7e, 0xbc, 0x3e, 0x37, 0x5a,
0xcb, 0x77, 0x9a, 0x1a, 0x0d, 0x82, 0x3f, 0x7f, 0x1b, 0x85, 0x72, 0x87, 0x7f, 0xfe, 0x0e, 0x24,
0xde, 0x87, 0x75, 0x17, 0x97, 0x3e, 0x19, 0xe9, 0xab, 0x34, 0x2d, 0x02, 0x39, 0x6e, 0x9e, 0x7b,
0xf9, 0x1c, 0xd1, 0x23, 0x04, 0xc5, 0x87, 0x20, 0x50, 0x17, 0x14, 0x69, 0xaa, 0x4a, 0xab, 0x6b,
0xe9, 0x2e, 0x49, 0x37, 0x5c, 0x5c, 0x1e, 0xd7, 0x04, 0xab, 0x37, 0xe1, 0x2e, 0x2d, 0x34, 0xb9,
0xc7, 0x4f, 0x93, 0x02, 0xfc, 0x5a, 0x79, 0xf1, 0xf1, 0x82, 0xdc, 0xe7, 0x76, 0x09, 0xfa, 0x16,
0x11, 0x7c, 0x9a, 0xf6, 0x4a, 0x95, 0x3e, 0xe7, 0x4e, 0xf8, 0x69, 0x22, 0x72, 0x46, 0xf9, 0x0d,
0xcd, 0xe9, 0x07, 0x2d, 0x4d, 0xd9, 0x93, 0x9f, 0x7b, 0x30, 0x68, 0x56, 0xb6, 0xf8, 0xb2, 0xbb,
0xa0, 0x97, 0x9e, 0x8c, 0x0e, 0x0f, 0xfe, 0x7d, 0xcf, 0x7f, 0x9d, 0x3b, 0x73, 0xdd, 0x6e, 0xf1,
0xcf, 0xdb, 0x2d, 0xfe, 0xbf, 0x93, 0xeb, 0x55, 0xaf, 0x61, 0xb8, 0xc0, 0xf0, 0xb3, 0x08, 0xf1,
0xad, 0x69, 0x5a, 0x8c, 0x43, 0xaf, 0x8e, 0xd0, 0x8a, 0x38, 0x50, 0x7e, 0xac, 0xf2, 0x30, 0xd5,
0x96, 0x36, 0xe4, 0x9a, 0x07, 0x71, 0xa0, 0xbe, 0x61, 0xa4, 0x11, 0x14, 0xf3, 0x57, 0x3a, 0x70,
0x96, 0xd6, 0x24, 0x0b, 0xbe, 0x67, 0xe4, 0x99, 0x7c, 0xfd, 0x66, 0x7c, 0xe7, 0xf7, 0x37, 0xe3,
0x3b, 0x3f, 0xdd, 0x8c, 0x7b, 0xaf, 0x6f, 0xc6, 0xbd, 0xdf, 0x6e, 0xc6, 0xbd, 0x3f, 0x6f, 0xc6,
0xbd, 0xf9, 0x32, 0xfd, 0x4d, 0x7f, 0xfc, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2e, 0xcc, 0xc8,
0x5a, 0x0e, 0x08, 0x00, 0x00,
// 1064 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0x4f, 0x6f, 0x1c, 0xc5,
0x13, 0xcd, 0xda, 0x9b, 0xfd, 0xd3, 0x6b, 0x27, 0x4e, 0xc7, 0xf1, 0xaf, 0xe3, 0xfc, 0xbc, 0xb6,
0xd7, 0x80, 0x82, 0x04, 0xbb, 0xc8, 0xfc, 0x13, 0x28, 0x1c, 0x1c, 0x43, 0x04, 0x12, 0x26, 0xd6,
0x26, 0x16, 0xc7, 0x51, 0xef, 0x4c, 0x7b, 0xb7, 0xed, 0x99, 0xe9, 0x51, 0x77, 0xaf, 0xad, 0xe5,
0xc4, 0x81, 0x2b, 0xe2, 0x63, 0xf0, 0x55, 0x72, 0x83, 0x23, 0x27, 0x44, 0xfc, 0x49, 0x50, 0x55,
0xf5, 0x78, 0x86, 0x83, 0x03, 0xb7, 0xae, 0xf7, 0x5e, 0xd5, 0x54, 0xbd, 0xd9, 0xae, 0x59, 0xf6,
0xd1, 0x54, 0xfb, 0xd9, 0x7c, 0x32, 0x8c, 0x4d, 0x36, 0x8a, 0x4d, 0xee, 0xa5, 0xce, 0x95, 0x4d,
0x46, 0xf1, 0xd4, 0x9a, 0x79, 0xe1, 0x46, 0x17, 0xfb, 0x23, 0xe7, 0xa5, 0x77, 0xa3, 0x4c, 0x79,
0xab, 0x63, 0x37, 0x2c, 0xac, 0xf1, 0x86, 0x0b, 0x6d, 0x86, 0x95, 0x7a, 0x18, 0xd4, 0xc3, 0x8b,
0xfd, 0xcd, 0xf5, 0xa9, 0x99, 0x1a, 0x14, 0x8d, 0xe0, 0x44, 0xfa, 0xc1, 0xaf, 0x4b, 0xac, 0x7d,
0x44, 0x15, 0xf8, 0x27, 0xac, 0x59, 0xe8, 0xc4, 0x89, 0xc6, 0x4e, 0xe3, 0x71, 0x6f, 0x7f, 0x30,
0xbc, 0xa9, 0xd4, 0xf0, 0x58, 0x27, 0xee, 0x85, 0x97, 0x7e, 0x8c, 0x7a, 0xfe, 0x84, 0x2d, 0xc7,
0xc5, 0x5c, 0x2c, 0x61, 0xda, 0xee, 0xcd, 0x69, 0x87, 0xc7, 0x27, 0x90, 0xf5, 0xb4, 0x7d, 0xf5,
0xe7, 0xf6, 0xf2, 0xe1, 0xf1, 0xc9, 0x18, 0xd2, 0xf8, 0x13, 0xd6, 0xca, 0x54, 0x66, 0xec, 0x42,
0x34, 0xb1, 0xc0, 0x5b, 0x37, 0x17, 0x38, 0x42, 0x1d, 0x3e, 0x39, 0xe4, 0x40, 0xcf, 0x36, 0xc9,
0xa4, 0xb8, 0xfd, 0x6f, 0x3d, 0x8f, 0x93, 0x4c, 0x52, 0xcf, 0xa0, 0xe7, 0x1f, 0xb0, 0x25, 0x6d,
0x44, 0x0b, 0xb3, 0x76, 0x6e, 0xce, 0xfa, 0xe6, 0x39, 0xe6, 0x2c, 0x69, 0x33, 0xf8, 0x9c, 0x75,
0xca, 0xb9, 0xb9, 0x60, 0xed, 0x78, 0x6e, 0xad, 0xca, 0x3d, 0x9a, 0xd5, 0x1c, 0x97, 0x21, 0x5f,
0x67, 0xb7, 0x53, 0x9d, 0x69, 0x8f, 0x6e, 0x34, 0xc7, 0x14, 0x0c, 0x7e, 0x6b, 0xb0, 0x76, 0x98,
0x9e, 0x6f, 0x31, 0x36, 0x77, 0x72, 0xaa, 0xa2, 0xb9, 0x53, 0x71, 0x48, 0xef, 0x22, 0x72, 0xe2,
0x54, 0xcc, 0x1f, 0xb1, 0xee, 0xdc, 0x29, 0x4b, 0x2c, 0x15, 0xe9, 0x00, 0x80, 0xe4, 0x36, 0xeb,
0xb9, 0x85, 0xf3, 0x2a, 0x23, 0x7a, 0x19, 0x69, 0x46, 0x10, 0x0a, 0xb6, 0x18, 0xcb, 0x6d, 0x54,
0x28, 0xab, 0x4d, 0xe2, 0xd0, 0xd0, 0xe6, 0xb8, 0x9b, 0xdb, 0x63, 0x02, 0xf8, 0x2e, 0x5b, 0xc9,
0x6d, 0xe4, 0x67, 0xd6, 0x78, 0x9f, 0xaa, 0x04, 0x5d, 0x6b, 0x8e, 0x7b, 0xb9, 0x7d, 0x59, 0x42,
0xfc, 0x6d, 0x76, 0xe7, 0x9a, 0xa7, 0xa7, 0xb4, 0x50, 0xb4, 0x7a, 0x8d, 0xc2, 0x83, 0x06, 0xbf,
0x74, 0x19, 0xab, 0x5e, 0x07, 0xe7, 0xac, 0x29, 0x73, 0x93, 0x87, 0x71, 0xf0, 0x0c, 0xd8, 0xa9,
0x4e, 0x55, 0x18, 0x02, 0xcf, 0xd0, 0xc0, 0xb9, 0xb2, 0xb9, 0x4a, 0x23, 0xe7, 0x65, 0x7c, 0x1e,
0x26, 0xe8, 0x11, 0xf6, 0x02, 0x20, 0x48, 0x73, 0xa9, 0x9c, 0x84, 0xe6, 0xf1, 0x8c, 0x98, 0x89,
0xcf, 0x43, 0xbf, 0x78, 0x06, 0xa7, 0xdd, 0x2c, 0x53, 0x59, 0xe8, 0x8f, 0x02, 0x70, 0x08, 0x1e,
0x14, 0x65, 0xb2, 0x28, 0x54, 0x22, 0xda, 0xe4, 0x10, 0x40, 0x47, 0x88, 0x80, 0x43, 0x28, 0x48,
0xb4, 0xf5, 0x0b, 0xd1, 0x21, 0x87, 0x00, 0xf9, 0x12, 0x00, 0x18, 0x1f, 0xe9, 0x4b, 0xab, 0xbd,
0x9a, 0x40, 0x8b, 0x5d, 0x1a, 0x1f, 0xd0, 0xef, 0x4b, 0x90, 0x3f, 0x64, 0x1d, 0x98, 0x31, 0xf2,
0xb3, 0x42, 0x30, 0xfa, 0x05, 0x40, 0xfc, 0x72, 0x56, 0xf0, 0x3d, 0xb6, 0xaa, 0x73, 0x19, 0x7b,
0x7d, 0xa1, 0x22, 0xf4, 0xa4, 0x87, 0xfc, 0x4a, 0x09, 0x1e, 0x80, 0x37, 0xdb, 0xac, 0x57, 0x97,
0xac, 0x50, 0x9b, 0x35, 0x41, 0xbd, 0x0a, 0xba, 0xb8, 0xfa, 0xcf, 0x2a, 0xcf, 0xc0, 0xcd, 0xaa,
0x0a, 0x4a, 0xee, 0xd4, 0xab, 0xa0, 0x60, 0x87, 0xf5, 0xe6, 0xb9, 0xba, 0xd0, 0xb1, 0x97, 0x93,
0x54, 0x89, 0xbb, 0xe4, 0x76, 0x0d, 0xe2, 0xef, 0xb2, 0x35, 0x70, 0x38, 0xb2, 0x2a, 0x4e, 0xa5,
0xce, 0x50, 0xb6, 0x86, 0xb2, 0xbb, 0x80, 0x8f, 0x2b, 0x98, 0xbf, 0xcf, 0x38, 0x4a, 0xe7, 0x79,
0x5d, 0x7c, 0x0f, 0xc5, 0xf7, 0x80, 0x39, 0xa9, 0x13, 0x70, 0x47, 0x8a, 0xe9, 0xa9, 0x9c, 0xa7,
0x5e, 0x70, 0x72, 0x28, 0x84, 0xbc, 0xcf, 0x58, 0x31, 0xcd, 0xe4, 0x19, 0x91, 0xf7, 0xa9, 0xeb,
0x0a, 0x81, 0x07, 0x5d, 0x1a, 0x7b, 0xae, 0xf3, 0xa9, 0x53, 0x3e, 0xb2, 0x8a, 0x74, 0xeb, 0xf4,
0xa0, 0x8a, 0x19, 0x13, 0xc1, 0x47, 0xec, 0x7e, 0x4d, 0x8e, 0xd3, 0x4b, 0xaf, 0xc4, 0x03, 0xd4,
0xd7, 0x2a, 0x1d, 0x04, 0x86, 0x7f, 0xcc, 0x36, 0x6a, 0x09, 0xb9, 0x49, 0x54, 0xe8, 0x5b, 0x6c,
0x60, 0xce, 0x83, 0x8a, 0xfd, 0xae, 0x22, 0xf9, 0x26, 0xeb, 0x14, 0x53, 0xab, 0x4e, 0x75, 0x9a,
0x8a, 0xff, 0xd1, 0xc5, 0x2c, 0x63, 0xbe, 0xc1, 0x5a, 0xc5, 0xd4, 0xc5, 0x32, 0x17, 0x02, 0x99,
0x10, 0x91, 0x09, 0xce, 0x2b, 0x99, 0x8a, 0x87, 0xa5, 0x09, 0x18, 0x92, 0x09, 0xd7, 0xcd, 0x6e,
0x96, 0x26, 0x94, 0x08, 0x1f, 0xb0, 0x95, 0x62, 0x9a, 0xa8, 0x6b, 0xc5, 0x23, 0x7a, 0xff, 0x75,
0x8c, 0x6a, 0xa4, 0xf2, 0x87, 0xc5, 0xa9, 0x55, 0x4a, 0xfc, 0xbf, 0xac, 0x51, 0x22, 0xf0, 0xfa,
0xab, 0x28, 0x11, 0x5b, 0xf4, 0xfa, 0x6b, 0x10, 0x7f, 0x87, 0xdd, 0xf5, 0xb3, 0x22, 0x42, 0x23,
0x23, 0x99, 0xa6, 0x26, 0x16, 0xfd, 0xf2, 0xba, 0x17, 0xcf, 0x00, 0x3d, 0x00, 0x90, 0xbf, 0xc7,
0x38, 0xe8, 0x62, 0x93, 0xa6, 0xb2, 0x70, 0x2a, 0x48, 0xb7, 0x51, 0xba, 0xe6, 0x67, 0xc5, 0x61,
0x20, 0x48, 0xbd, 0xce, 0x6e, 0xe3, 0x42, 0x13, 0x3b, 0x74, 0x35, 0x31, 0x80, 0x5f, 0x2b, 0x2d,
0x3e, 0x5a, 0x90, 0xbb, 0xd4, 0x2e, 0x42, 0xdf, 0x02, 0x02, 0x57, 0xd3, 0x5d, 0xca, 0x22, 0xa2,
0xdc, 0x01, 0x5d, 0x4d, 0x40, 0x4e, 0x30, 0xbf, 0xa4, 0x29, 0x7d, 0xaf, 0xa2, 0x31, 0x7b, 0xf0,
0x53, 0x83, 0x75, 0xca, 0x25, 0xcf, 0xbf, 0xa8, 0x2f, 0xe8, 0xe5, 0xc7, 0xbd, 0xfd, 0xbd, 0x37,
0x7f, 0x19, 0xbe, 0xca, 0xbd, 0x5d, 0x54, 0x5b, 0xfc, 0xb3, 0x6a, 0x8b, 0xff, 0xe7, 0xe4, 0xb0,
0xea, 0x15, 0xeb, 0x5e, 0x63, 0xf0, 0xb3, 0x48, 0xe0, 0xae, 0x29, 0x5c, 0x8c, 0xdd, 0x71, 0x88,
0xc0, 0x8a, 0x59, 0x2c, 0xa3, 0x99, 0xcc, 0x93, 0x54, 0x39, 0xdc, 0x90, 0xab, 0x63, 0x36, 0x8b,
0xe5, 0xd7, 0x84, 0x94, 0x02, 0x33, 0x39, 0x53, 0xb1, 0x77, 0xb8, 0x26, 0x49, 0xf0, 0x9c, 0x90,
0xc1, 0x01, 0x6b, 0xd1, 0xb7, 0x89, 0x7f, 0x5a, 0x9a, 0x4d, 0x83, 0xee, 0xbe, 0xe9, 0x63, 0x16,
0x3a, 0x45, 0xfd, 0xe0, 0xe7, 0x06, 0x6b, 0x07, 0x08, 0xde, 0x58, 0x26, 0xcf, 0x8c, 0x0d, 0x0b,
0x9c, 0x02, 0x44, 0x75, 0x6e, 0x6c, 0xf9, 0x31, 0xc3, 0x00, 0x86, 0xb2, 0x93, 0x85, 0x57, 0x2e,
0x6c, 0xef, 0x10, 0x01, 0x7e, 0x49, 0x38, 0xad, 0xee, 0x10, 0xc1, 0xf2, 0xb6, 0xda, 0xb8, 0x72,
0x79, 0xc3, 0x19, 0xb0, 0x4b, 0xc0, 0x68, 0x77, 0xe3, 0xf9, 0xa9, 0x78, 0xf5, 0xba, 0x7f, 0xeb,
0x8f, 0xd7, 0xfd, 0x5b, 0x3f, 0x5e, 0xf5, 0x1b, 0xaf, 0xae, 0xfa, 0x8d, 0xdf, 0xaf, 0xfa, 0x8d,
0xbf, 0xae, 0xfa, 0x8d, 0x49, 0x0b, 0xff, 0xab, 0x7c, 0xf8, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff,
0xf0, 0xd3, 0x07, 0x15, 0x13, 0x09, 0x00, 0x00,
}
func (m *Metrics) Marshal() (dAtA []byte, err error) {
@@ -437,6 +529,16 @@ func (m *Metrics) MarshalTo(dAtA []byte) (int, error) {
}
i += n4
}
if m.Io != nil {
dAtA[i] = 0x32
i++
i = encodeVarintMetrics(dAtA, i, uint64(m.Io.Size()))
n5, err := m.Io.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n5
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
}
@@ -843,6 +945,90 @@ func (m *RdmaEntry) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *IOStat) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *IOStat) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Usage) > 0 {
for _, msg := range m.Usage {
dAtA[i] = 0xa
i++
i = encodeVarintMetrics(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n
}
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
}
return i, nil
}
func (m *IOEntry) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *IOEntry) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Major != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintMetrics(dAtA, i, uint64(m.Major))
}
if m.Minor != 0 {
dAtA[i] = 0x10
i++
i = encodeVarintMetrics(dAtA, i, uint64(m.Minor))
}
if m.Rbytes != 0 {
dAtA[i] = 0x18
i++
i = encodeVarintMetrics(dAtA, i, uint64(m.Rbytes))
}
if m.Wbytes != 0 {
dAtA[i] = 0x20
i++
i = encodeVarintMetrics(dAtA, i, uint64(m.Wbytes))
}
if m.Rios != 0 {
dAtA[i] = 0x28
i++
i = encodeVarintMetrics(dAtA, i, uint64(m.Rios))
}
if m.Wios != 0 {
dAtA[i] = 0x30
i++
i = encodeVarintMetrics(dAtA, i, uint64(m.Wios))
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeVarintMetrics(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
@@ -874,6 +1060,10 @@ func (m *Metrics) Size() (n int) {
l = m.Rdma.Size()
n += 1 + l + sovMetrics(uint64(l))
}
if m.Io != nil {
l = m.Io.Size()
n += 1 + l + sovMetrics(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -1091,6 +1281,54 @@ func (m *RdmaEntry) Size() (n int) {
return n
}
func (m *IOStat) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Usage) > 0 {
for _, e := range m.Usage {
l = e.Size()
n += 1 + l + sovMetrics(uint64(l))
}
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *IOEntry) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Major != 0 {
n += 1 + sovMetrics(uint64(m.Major))
}
if m.Minor != 0 {
n += 1 + sovMetrics(uint64(m.Minor))
}
if m.Rbytes != 0 {
n += 1 + sovMetrics(uint64(m.Rbytes))
}
if m.Wbytes != 0 {
n += 1 + sovMetrics(uint64(m.Wbytes))
}
if m.Rios != 0 {
n += 1 + sovMetrics(uint64(m.Rios))
}
if m.Wios != 0 {
n += 1 + sovMetrics(uint64(m.Wios))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovMetrics(x uint64) (n int) {
for {
n++
@@ -1113,6 +1351,7 @@ func (this *Metrics) String() string {
`CPU:` + strings.Replace(fmt.Sprintf("%v", this.CPU), "CPUStat", "CPUStat", 1) + `,`,
`Memory:` + strings.Replace(fmt.Sprintf("%v", this.Memory), "MemoryStat", "MemoryStat", 1) + `,`,
`Rdma:` + strings.Replace(fmt.Sprintf("%v", this.Rdma), "RdmaStat", "RdmaStat", 1) + `,`,
`Io:` + strings.Replace(fmt.Sprintf("%v", this.Io), "IOStat", "IOStat", 1) + `,`,
`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
@@ -1216,6 +1455,33 @@ func (this *RdmaEntry) String() string {
}, "")
return s
}
func (this *IOStat) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&IOStat{`,
`Usage:` + strings.Replace(fmt.Sprintf("%v", this.Usage), "IOEntry", "IOEntry", 1) + `,`,
`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func (this *IOEntry) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&IOEntry{`,
`Major:` + fmt.Sprintf("%v", this.Major) + `,`,
`Minor:` + fmt.Sprintf("%v", this.Minor) + `,`,
`Rbytes:` + fmt.Sprintf("%v", this.Rbytes) + `,`,
`Wbytes:` + fmt.Sprintf("%v", this.Wbytes) + `,`,
`Rios:` + fmt.Sprintf("%v", this.Rios) + `,`,
`Wios:` + fmt.Sprintf("%v", this.Wios) + `,`,
`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func valueToStringMetrics(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
@@ -1397,6 +1663,42 @@ func (m *Metrics) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Io", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthMetrics
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthMetrics
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Io == nil {
m.Io = &IOStat{}
}
if err := m.Io.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipMetrics(dAtA[iNdEx:])
@@ -2647,6 +2949,262 @@ func (m *RdmaEntry) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *IOStat) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: IOStat: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: IOStat: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Usage", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthMetrics
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthMetrics
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Usage = append(m.Usage, &IOEntry{})
if err := m.Usage[len(m.Usage)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipMetrics(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthMetrics
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthMetrics
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *IOEntry) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: IOEntry: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: IOEntry: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Major", wireType)
}
m.Major = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Major |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Minor", wireType)
}
m.Minor = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Minor |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Rbytes", wireType)
}
m.Rbytes = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Rbytes |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Wbytes", wireType)
}
m.Wbytes = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Wbytes |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 5:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Rios", wireType)
}
m.Rios = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Rios |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Wios", wireType)
}
m.Wios = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Wios |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipMetrics(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthMetrics
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthMetrics
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipMetrics(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0

View File

@@ -9,6 +9,7 @@ message Metrics {
CPUStat cpu = 2 [(gogoproto.customname) = "CPU"];
MemoryStat memory = 4;
RdmaStat rdma = 5;
IOStat io = 6;
}
message PidsStat {
@@ -74,5 +75,15 @@ message RdmaEntry {
uint32 hca_objects = 3;
}
// iostat
// fmt: 230:0 rbytes=394211328 wbytes=65044480 rios=16313 wios=2006 dbytes=0 dios=0
message IOStat {
repeated IOEntry usage = 1;
}
message IOEntry {
uint64 major = 1;
uint64 minor = 2;
uint64 rbytes = 3;
uint64 wbytes = 4;
uint64 rios = 5;
uint64 wios = 6;
}

View File

@@ -23,10 +23,13 @@ import (
"io/ioutil"
"math"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/godbus/dbus/v5"
"github.com/containerd/cgroups/v2/stats"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
@@ -176,7 +179,7 @@ func ToResources(spec *specs.LinuxResources) *Resources {
resources.CPU.Weight = &convertedWeight
}
if period := cpu.Period; period != nil {
resources.CPU.Max = period
resources.CPU.Max = NewCPUMax(cpu.Quota, period)
}
}
if mem := spec.Memory; mem != nil {
@@ -237,7 +240,6 @@ func ToResources(spec *specs.LinuxResources) *Resources {
func getStatFileContentUint64(filePath string) uint64 {
contents, err := ioutil.ReadFile(filePath)
if err != nil {
logrus.Error(err)
return 0
}
trimmed := strings.TrimSpace(string(contents))
@@ -253,6 +255,64 @@ func getStatFileContentUint64(filePath string) uint64 {
return res
}
func readIoStats(path string) []*stats.IOEntry {
// more details on the io.stat file format: https://www.kernel.org/doc/Documentation/cgroup-v2.txt
var usage []*stats.IOEntry
fpath := filepath.Join(path, "io.stat")
currentData, err := ioutil.ReadFile(fpath)
if err != nil {
return usage
}
entries := strings.Split(string(currentData), "\n")
for _, entry := range entries {
parts := strings.Split(entry, " ")
if len(parts) < 2 {
continue
}
majmin := strings.Split(parts[0], ":")
if len(majmin) != 2 {
continue
}
major, err := strconv.ParseUint(majmin[0], 10, 0)
if err != nil {
return usage
}
minor, err := strconv.ParseUint(majmin[1], 10, 0)
if err != nil {
return usage
}
parts = parts[1:]
ioEntry := stats.IOEntry{
Major: major,
Minor: minor,
}
for _, stats := range parts {
keyPairValue := strings.Split(stats, "=")
if len(keyPairValue) != 2 {
continue
}
v, err := strconv.ParseUint(keyPairValue[1], 10, 0)
if err != nil {
continue
}
switch keyPairValue[0] {
case "rbytes":
ioEntry.Rbytes = v
case "wbytes":
ioEntry.Wbytes = v
case "rios":
ioEntry.Rios = v
case "wios":
ioEntry.Wios = v
}
}
usage = append(usage, &ioEntry)
}
return usage
}
func rdmaStats(filepath string) []*stats.RdmaEntry {
currentData, err := ioutil.ReadFile(filepath)
if err != nil {
@@ -302,3 +362,18 @@ func toRdmaEntry(strEntries []string) []*stats.RdmaEntry {
}
return rdmaEntries
}
// isUnitExists returns true if the error is that a systemd unit already exists.
func isUnitExists(err error) bool {
if err != nil {
if dbusError, ok := err.(dbus.Error); ok {
return strings.Contains(dbusError.Name, "org.freedesktop.systemd1.UnitExists")
}
}
return false
}
func systemdUnitFromPath(path string) string {
_, unit := filepath.Split(path)
return unit
}