diff options
Diffstat (limited to 'vendor/github.com/containerd/cgroups')
53 files changed, 17916 insertions, 0 deletions
diff --git a/vendor/github.com/containerd/cgroups/.gitignore b/vendor/github.com/containerd/cgroups/.gitignore new file mode 100644 index 000000000..3465c14cf --- /dev/null +++ b/vendor/github.com/containerd/cgroups/.gitignore @@ -0,0 +1,2 @@ +example/example +cmd/cgctl/cgctl diff --git a/vendor/github.com/containerd/cgroups/LICENSE b/vendor/github.com/containerd/cgroups/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/LICENSE @@ -0,0 +1,201 @@ +                                 Apache License +                           Version 2.0, January 2004 +                        http://www.apache.org/licenses/ + +   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +   1. Definitions. + +      "License" shall mean the terms and conditions for use, reproduction, +      and distribution as defined by Sections 1 through 9 of this document. + +      "Licensor" shall mean the copyright owner or entity authorized by +      the copyright owner that is granting the License. + +      "Legal Entity" shall mean the union of the acting entity and all +      other entities that control, are controlled by, or are under common +      control with that entity. For the purposes of this definition, +      "control" means (i) the power, direct or indirect, to cause the +      direction or management of such entity, whether by contract or +      otherwise, or (ii) ownership of fifty percent (50%) or more of the +      outstanding shares, or (iii) beneficial ownership of such entity. + +      "You" (or "Your") shall mean an individual or Legal Entity +      exercising permissions granted by this License. + +      "Source" form shall mean the preferred form for making modifications, +      including but not limited to software source code, documentation +      source, and configuration files. + +      "Object" form shall mean any form resulting from mechanical +      transformation or translation of a Source form, including but +      not limited to compiled object code, generated documentation, +      and conversions to other media types. + +      "Work" shall mean the work of authorship, whether in Source or +      Object form, made available under the License, as indicated by a +      copyright notice that is included in or attached to the work +      (an example is provided in the Appendix below). + +      "Derivative Works" shall mean any work, whether in Source or Object +      form, that is based on (or derived from) the Work and for which the +      editorial revisions, annotations, elaborations, or other modifications +      represent, as a whole, an original work of authorship. For the purposes +      of this License, Derivative Works shall not include works that remain +      separable from, or merely link (or bind by name) to the interfaces of, +      the Work and Derivative Works thereof. + +      "Contribution" shall mean any work of authorship, including +      the original version of the Work and any modifications or additions +      to that Work or Derivative Works thereof, that is intentionally +      submitted to Licensor for inclusion in the Work by the copyright owner +      or by an individual or Legal Entity authorized to submit on behalf of +      the copyright owner. For the purposes of this definition, "submitted" +      means any form of electronic, verbal, or written communication sent +      to the Licensor or its representatives, including but not limited to +      communication on electronic mailing lists, source code control systems, +      and issue tracking systems that are managed by, or on behalf of, the +      Licensor for the purpose of discussing and improving the Work, but +      excluding communication that is conspicuously marked or otherwise +      designated in writing by the copyright owner as "Not a Contribution." + +      "Contributor" shall mean Licensor and any individual or Legal Entity +      on behalf of whom a Contribution has been received by Licensor and +      subsequently incorporated within the Work. + +   2. Grant of Copyright License. Subject to the terms and conditions of +      this License, each Contributor hereby grants to You a perpetual, +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable +      copyright license to reproduce, prepare Derivative Works of, +      publicly display, publicly perform, sublicense, and distribute the +      Work and such Derivative Works in Source or Object form. + +   3. Grant of Patent License. Subject to the terms and conditions of +      this License, each Contributor hereby grants to You a perpetual, +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable +      (except as stated in this section) patent license to make, have made, +      use, offer to sell, sell, import, and otherwise transfer the Work, +      where such license applies only to those patent claims licensable +      by such Contributor that are necessarily infringed by their +      Contribution(s) alone or by combination of their Contribution(s) +      with the Work to which such Contribution(s) was submitted. If You +      institute patent litigation against any entity (including a +      cross-claim or counterclaim in a lawsuit) alleging that the Work +      or a Contribution incorporated within the Work constitutes direct +      or contributory patent infringement, then any patent licenses +      granted to You under this License for that Work shall terminate +      as of the date such litigation is filed. + +   4. Redistribution. You may reproduce and distribute copies of the +      Work or Derivative Works thereof in any medium, with or without +      modifications, and in Source or Object form, provided that You +      meet the following conditions: + +      (a) You must give any other recipients of the Work or +          Derivative Works a copy of this License; and + +      (b) You must cause any modified files to carry prominent notices +          stating that You changed the files; and + +      (c) You must retain, in the Source form of any Derivative Works +          that You distribute, all copyright, patent, trademark, and +          attribution notices from the Source form of the Work, +          excluding those notices that do not pertain to any part of +          the Derivative Works; and + +      (d) If the Work includes a "NOTICE" text file as part of its +          distribution, then any Derivative Works that You distribute must +          include a readable copy of the attribution notices contained +          within such NOTICE file, excluding those notices that do not +          pertain to any part of the Derivative Works, in at least one +          of the following places: within a NOTICE text file distributed +          as part of the Derivative Works; within the Source form or +          documentation, if provided along with the Derivative Works; or, +          within a display generated by the Derivative Works, if and +          wherever such third-party notices normally appear. The contents +          of the NOTICE file are for informational purposes only and +          do not modify the License. You may add Your own attribution +          notices within Derivative Works that You distribute, alongside +          or as an addendum to the NOTICE text from the Work, provided +          that such additional attribution notices cannot be construed +          as modifying the License. + +      You may add Your own copyright statement to Your modifications and +      may provide additional or different license terms and conditions +      for use, reproduction, or distribution of Your modifications, or +      for any such Derivative Works as a whole, provided Your use, +      reproduction, and distribution of the Work otherwise complies with +      the conditions stated in this License. + +   5. Submission of Contributions. Unless You explicitly state otherwise, +      any Contribution intentionally submitted for inclusion in the Work +      by You to the Licensor shall be under the terms and conditions of +      this License, without any additional terms or conditions. +      Notwithstanding the above, nothing herein shall supersede or modify +      the terms of any separate license agreement you may have executed +      with Licensor regarding such Contributions. + +   6. Trademarks. This License does not grant permission to use the trade +      names, trademarks, service marks, or product names of the Licensor, +      except as required for reasonable and customary use in describing the +      origin of the Work and reproducing the content of the NOTICE file. + +   7. Disclaimer of Warranty. Unless required by applicable law or +      agreed to in writing, Licensor provides the Work (and each +      Contributor provides its Contributions) on an "AS IS" BASIS, +      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +      implied, including, without limitation, any warranties or conditions +      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +      PARTICULAR PURPOSE. You are solely responsible for determining the +      appropriateness of using or redistributing the Work and assume any +      risks associated with Your exercise of permissions under this License. + +   8. Limitation of Liability. In no event and under no legal theory, +      whether in tort (including negligence), contract, or otherwise, +      unless required by applicable law (such as deliberate and grossly +      negligent acts) or agreed to in writing, shall any Contributor be +      liable to You for damages, including any direct, indirect, special, +      incidental, or consequential damages of any character arising as a +      result of this License or out of the use or inability to use the +      Work (including but not limited to damages for loss of goodwill, +      work stoppage, computer failure or malfunction, or any and all +      other commercial damages or losses), even if such Contributor +      has been advised of the possibility of such damages. + +   9. Accepting Warranty or Additional Liability. While redistributing +      the Work or Derivative Works thereof, You may choose to offer, +      and charge a fee for, acceptance of support, warranty, indemnity, +      or other liability obligations and/or rights consistent with this +      License. However, in accepting such obligations, You may act only +      on Your own behalf and on Your sole responsibility, not on behalf +      of any other Contributor, and only if You agree to indemnify, +      defend, and hold each Contributor harmless for any liability +      incurred by, or claims asserted against, such Contributor by reason +      of your accepting any such warranty or additional liability. + +   END OF TERMS AND CONDITIONS + +   APPENDIX: How to apply the Apache License to your work. + +      To apply the Apache License to your work, attach the following +      boilerplate notice, with the fields enclosed by brackets "[]" +      replaced with your own identifying information. (Don't include +      the brackets!)  The text should be enclosed in the appropriate +      comment syntax for the file format. We also recommend that a +      file or class name and description of purpose be included on the +      same "printed page" as the copyright notice for easier +      identification within third-party archives. + +   Copyright [yyyy] [name of copyright owner] + +   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. diff --git a/vendor/github.com/containerd/cgroups/Makefile b/vendor/github.com/containerd/cgroups/Makefile new file mode 100644 index 000000000..19e660756 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/Makefile @@ -0,0 +1,24 @@ +#   Copyright The containerd Authors. + +#   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. + +PACKAGES=$(shell go list ./... | grep -v /vendor/) + +all: cgutil +	go build -v + +cgutil: +	cd cmd/cgctl && go build -v + +proto: +	protobuild --quiet ${PACKAGES} diff --git a/vendor/github.com/containerd/cgroups/Protobuild.toml b/vendor/github.com/containerd/cgroups/Protobuild.toml new file mode 100644 index 000000000..1c4c802fe --- /dev/null +++ b/vendor/github.com/containerd/cgroups/Protobuild.toml @@ -0,0 +1,46 @@ +version = "unstable" +generator = "gogoctrd" +plugins = ["grpc"] + +# Control protoc include paths. Below are usually some good defaults, but feel +# free to try it without them if it works for your project. +[includes] +  # Include paths that will be added before all others. Typically, you want to +  # treat the root of the project as an include, but this may not be necessary. +  # before = ["."] + +  # Paths that should be treated as include roots in relation to the vendor +  # directory. These will be calculated with the vendor directory nearest the +  # target package. +  # vendored = ["github.com/gogo/protobuf"] +  packages = ["github.com/gogo/protobuf"] + +  # Paths that will be added untouched to the end of the includes. We use +  # `/usr/local/include` to pickup the common install location of protobuf. +  # This is the default. +  after = ["/usr/local/include", "/usr/include"] + +# This section maps protobuf imports to Go packages. These will become +# `-M` directives in the call to the go protobuf generator. +[packages] +  "gogoproto/gogo.proto" = "github.com/gogo/protobuf/gogoproto" +  "google/protobuf/any.proto" = "github.com/gogo/protobuf/types" +  "google/protobuf/descriptor.proto" = "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" +  "google/protobuf/field_mask.proto" = "github.com/gogo/protobuf/types" +  "google/protobuf/timestamp.proto" = "github.com/gogo/protobuf/types" + +# Aggregrate the API descriptors to lock down API changes. +[[descriptors]] +prefix = "github.com/containerd/cgroups/stats/v1" +target = "stats/v1/metrics.pb.txt" +ignore_files = [ +	"google/protobuf/descriptor.proto", +	"gogoproto/gogo.proto" +] +[[descriptors]] +prefix = "github.com/containerd/cgroups/v2/stats" +target = "v2/stats/metrics.pb.txt" +ignore_files = [ +	"google/protobuf/descriptor.proto", +	"gogoproto/gogo.proto" +] diff --git a/vendor/github.com/containerd/cgroups/README.md b/vendor/github.com/containerd/cgroups/README.md new file mode 100644 index 000000000..eccb9d984 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/README.md @@ -0,0 +1,149 @@ +# cgroups + +[](https://github.com/containerd/cgroups/actions?query=workflow%3ACI) +[](https://codecov.io/gh/containerd/cgroups) +[](https://godoc.org/github.com/containerd/cgroups) +[](https://goreportcard.com/report/github.com/containerd/cgroups) + +Go package for creating, managing, inspecting, and destroying cgroups. +The resources format for settings on the cgroup uses the OCI runtime-spec found +[here](https://github.com/opencontainers/runtime-spec). + +## Examples + +### Create a new cgroup + +This creates a new cgroup using a static path for all subsystems under `/test`. + +* /sys/fs/cgroup/cpu/test +* /sys/fs/cgroup/memory/test +* etc.... + +It uses a single hierarchy and specifies cpu shares as a resource constraint and +uses the v1 implementation of cgroups. + + +```go +shares := uint64(100) +control, err := cgroups.New(cgroups.V1, cgroups.StaticPath("/test"), &specs.LinuxResources{ +    CPU: &specs.LinuxCPU{ +        Shares: &shares, +    }, +}) +defer control.Delete() +``` + +### Create with systemd slice support + + +```go +control, err := cgroups.New(cgroups.Systemd, cgroups.Slice("system.slice", "runc-test"), &specs.LinuxResources{ +    CPU: &specs.CPU{ +        Shares: &shares, +    }, +}) + +``` + +### Load an existing cgroup + +```go +control, err = cgroups.Load(cgroups.V1, cgroups.StaticPath("/test")) +``` + +### Add a process to the cgroup + +```go +if err := control.Add(cgroups.Process{Pid:1234}); err != nil { +} +``` + +###  Update the cgroup  + +To update the resources applied in the cgroup + +```go +shares = uint64(200) +if err := control.Update(&specs.LinuxResources{ +    CPU: &specs.LinuxCPU{ +        Shares: &shares, +    }, +}); err != nil { +} +``` + +### Freeze and Thaw the cgroup + +```go +if err := control.Freeze(); err != nil { +} +if err := control.Thaw(); err != nil { +} +``` + +### List all processes in the cgroup or recursively + +```go +processes, err := control.Processes(cgroups.Devices, recursive) +``` + +### Get Stats on the cgroup + +```go +stats, err := control.Stat() +``` + +By adding `cgroups.IgnoreNotExist` all non-existent files will be ignored, e.g. swap memory stats without swap enabled +```go +stats, err := control.Stat(cgroups.IgnoreNotExist) +``` + +### Move process across cgroups + +This allows you to take processes from one cgroup and move them to another. + +```go +err := control.MoveTo(destination) +``` + +### Create subcgroup + +```go +subCgroup, err := control.New("child", resources) +``` + +### Registering for memory events + +This allows you to get notified by an eventfd for v1 memory cgroups events. + +```go +event := cgroups.MemoryThresholdEvent(50 * 1024 * 1024, false) +efd, err := control.RegisterMemoryEvent(event) +``` + +```go +event := cgroups.MemoryPressureEvent(cgroups.MediumPressure, cgroups.DefaultMode) +efd, err := control.RegisterMemoryEvent(event) +``` + +```go +efd, err := control.OOMEventFD() +// or by using RegisterMemoryEvent +event := cgroups.OOMEvent() +efd, err := control.RegisterMemoryEvent(event) +``` + +### Attention + +All static path should not include `/sys/fs/cgroup/` prefix, it should start with your own cgroups name + +## Project details + +Cgroups is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). +As a containerd sub-project, you will find the: + + * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), + * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS), + * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) + +information in our [`containerd/project`](https://github.com/containerd/project) repository. diff --git a/vendor/github.com/containerd/cgroups/Vagrantfile b/vendor/github.com/containerd/cgroups/Vagrantfile new file mode 100644 index 000000000..9a4aac8cb --- /dev/null +++ b/vendor/github.com/containerd/cgroups/Vagrantfile @@ -0,0 +1,46 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure("2") do |config| +# Fedora box is used for testing cgroup v2 support +  config.vm.box = "fedora/35-cloud-base" +  config.vm.provider :virtualbox do |v| +    v.memory = 4096 +    v.cpus = 2 +  end +  config.vm.provider :libvirt do |v| +    v.memory = 4096 +    v.cpus = 2 +  end +  config.vm.provision "shell", inline: <<-SHELL +    set -eux -o pipefail +    # configuration +    GO_VERSION="1.17.7" + +    # install gcc and Golang +    dnf -y install gcc +    curl -fsSL "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz" | tar Cxz /usr/local + +    # setup env vars +    cat >> /etc/profile.d/sh.local <<EOF +PATH=/usr/local/go/bin:$PATH +GO111MODULE=on +export PATH GO111MODULE +EOF +    source /etc/profile.d/sh.local + +    # enter /root/go/src/github.com/containerd/cgroups +    mkdir -p /root/go/src/github.com/containerd +    ln -s /vagrant /root/go/src/github.com/containerd/cgroups +    cd /root/go/src/github.com/containerd/cgroups + +    # create /test.sh +    cat > /test.sh <<EOF +#!/bin/bash +set -eux -o pipefail +cd /root/go/src/github.com/containerd/cgroups +go test -v ./... +EOF +    chmod +x /test.sh +  SHELL +end diff --git a/vendor/github.com/containerd/cgroups/blkio.go b/vendor/github.com/containerd/cgroups/blkio.go new file mode 100644 index 000000000..f59c75bb5 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/blkio.go @@ -0,0 +1,361 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"bufio" +	"fmt" +	"io" +	"os" +	"path/filepath" +	"strconv" +	"strings" + +	v1 "github.com/containerd/cgroups/stats/v1" +	specs "github.com/opencontainers/runtime-spec/specs-go" +) + +// NewBlkio returns a Blkio controller given the root folder of cgroups. +// It may optionally accept other configuration options, such as ProcRoot(path) +func NewBlkio(root string, options ...func(controller *blkioController)) *blkioController { +	ctrl := &blkioController{ +		root:     filepath.Join(root, string(Blkio)), +		procRoot: "/proc", +	} +	for _, opt := range options { +		opt(ctrl) +	} +	return ctrl +} + +// ProcRoot overrides the default location of the "/proc" filesystem +func ProcRoot(path string) func(controller *blkioController) { +	return func(c *blkioController) { +		c.procRoot = path +	} +} + +type blkioController struct { +	root     string +	procRoot string +} + +func (b *blkioController) Name() Name { +	return Blkio +} + +func (b *blkioController) Path(path string) string { +	return filepath.Join(b.root, path) +} + +func (b *blkioController) Create(path string, resources *specs.LinuxResources) error { +	if err := os.MkdirAll(b.Path(path), defaultDirPerm); err != nil { +		return err +	} +	if resources.BlockIO == nil { +		return nil +	} +	for _, t := range createBlkioSettings(resources.BlockIO) { +		if t.value != nil { +			if err := retryingWriteFile( +				filepath.Join(b.Path(path), "blkio."+t.name), +				t.format(t.value), +				defaultFilePerm, +			); err != nil { +				return err +			} +		} +	} +	return nil +} + +func (b *blkioController) Update(path string, resources *specs.LinuxResources) error { +	return b.Create(path, resources) +} + +func (b *blkioController) Stat(path string, stats *v1.Metrics) error { +	stats.Blkio = &v1.BlkIOStat{} + +	var settings []blkioStatSettings + +	// Try to read CFQ stats available on all CFQ enabled kernels first +	if _, err := os.Lstat(filepath.Join(b.Path(path), "blkio.io_serviced_recursive")); err == nil { +		settings = []blkioStatSettings{ +			{ +				name:  "sectors_recursive", +				entry: &stats.Blkio.SectorsRecursive, +			}, +			{ +				name:  "io_service_bytes_recursive", +				entry: &stats.Blkio.IoServiceBytesRecursive, +			}, +			{ +				name:  "io_serviced_recursive", +				entry: &stats.Blkio.IoServicedRecursive, +			}, +			{ +				name:  "io_queued_recursive", +				entry: &stats.Blkio.IoQueuedRecursive, +			}, +			{ +				name:  "io_service_time_recursive", +				entry: &stats.Blkio.IoServiceTimeRecursive, +			}, +			{ +				name:  "io_wait_time_recursive", +				entry: &stats.Blkio.IoWaitTimeRecursive, +			}, +			{ +				name:  "io_merged_recursive", +				entry: &stats.Blkio.IoMergedRecursive, +			}, +			{ +				name:  "time_recursive", +				entry: &stats.Blkio.IoTimeRecursive, +			}, +		} +	} + +	f, err := os.Open(filepath.Join(b.procRoot, "partitions")) +	if err != nil { +		return err +	} +	defer f.Close() + +	devices, err := getDevices(f) +	if err != nil { +		return err +	} + +	var size int +	for _, t := range settings { +		if err := b.readEntry(devices, path, t.name, t.entry); err != nil { +			return err +		} +		size += len(*t.entry) +	} +	if size > 0 { +		return nil +	} + +	// Even the kernel is compiled with the CFQ scheduler, the cgroup may not use +	// block devices with the CFQ scheduler. If so, we should fallback to throttle.* files. +	settings = []blkioStatSettings{ +		{ +			name:  "throttle.io_serviced", +			entry: &stats.Blkio.IoServicedRecursive, +		}, +		{ +			name:  "throttle.io_service_bytes", +			entry: &stats.Blkio.IoServiceBytesRecursive, +		}, +	} +	for _, t := range settings { +		if err := b.readEntry(devices, path, t.name, t.entry); err != nil { +			return err +		} +	} +	return nil +} + +func (b *blkioController) readEntry(devices map[deviceKey]string, path, name string, entry *[]*v1.BlkIOEntry) error { +	f, err := os.Open(filepath.Join(b.Path(path), "blkio."+name)) +	if err != nil { +		return err +	} +	defer f.Close() +	sc := bufio.NewScanner(f) +	for sc.Scan() { +		// format: dev type amount +		fields := strings.FieldsFunc(sc.Text(), splitBlkIOStatLine) +		if len(fields) < 3 { +			if len(fields) == 2 && fields[0] == "Total" { +				// skip total line +				continue +			} else { +				return fmt.Errorf("invalid line found while parsing %s: %s", path, sc.Text()) +			} +		} +		major, err := strconv.ParseUint(fields[0], 10, 64) +		if err != nil { +			return err +		} +		minor, err := strconv.ParseUint(fields[1], 10, 64) +		if err != nil { +			return err +		} +		op := "" +		valueField := 2 +		if len(fields) == 4 { +			op = fields[2] +			valueField = 3 +		} +		v, err := strconv.ParseUint(fields[valueField], 10, 64) +		if err != nil { +			return err +		} +		*entry = append(*entry, &v1.BlkIOEntry{ +			Device: devices[deviceKey{major, minor}], +			Major:  major, +			Minor:  minor, +			Op:     op, +			Value:  v, +		}) +	} +	return sc.Err() +} + +func createBlkioSettings(blkio *specs.LinuxBlockIO) []blkioSettings { +	settings := []blkioSettings{} + +	if blkio.Weight != nil { +		settings = append(settings, +			blkioSettings{ +				name:   "weight", +				value:  blkio.Weight, +				format: uintf, +			}) +	} +	if blkio.LeafWeight != nil { +		settings = append(settings, +			blkioSettings{ +				name:   "leaf_weight", +				value:  blkio.LeafWeight, +				format: uintf, +			}) +	} +	for _, wd := range blkio.WeightDevice { +		if wd.Weight != nil { +			settings = append(settings, +				blkioSettings{ +					name:   "weight_device", +					value:  wd, +					format: weightdev, +				}) +		} +		if wd.LeafWeight != nil { +			settings = append(settings, +				blkioSettings{ +					name:   "leaf_weight_device", +					value:  wd, +					format: weightleafdev, +				}) +		} +	} +	for _, t := range []struct { +		name string +		list []specs.LinuxThrottleDevice +	}{ +		{ +			name: "throttle.read_bps_device", +			list: blkio.ThrottleReadBpsDevice, +		}, +		{ +			name: "throttle.read_iops_device", +			list: blkio.ThrottleReadIOPSDevice, +		}, +		{ +			name: "throttle.write_bps_device", +			list: blkio.ThrottleWriteBpsDevice, +		}, +		{ +			name: "throttle.write_iops_device", +			list: blkio.ThrottleWriteIOPSDevice, +		}, +	} { +		for _, td := range t.list { +			settings = append(settings, blkioSettings{ +				name:   t.name, +				value:  td, +				format: throttleddev, +			}) +		} +	} +	return settings +} + +type blkioSettings struct { +	name   string +	value  interface{} +	format func(v interface{}) []byte +} + +type blkioStatSettings struct { +	name  string +	entry *[]*v1.BlkIOEntry +} + +func uintf(v interface{}) []byte { +	return []byte(strconv.FormatUint(uint64(*v.(*uint16)), 10)) +} + +func weightdev(v interface{}) []byte { +	wd := v.(specs.LinuxWeightDevice) +	return []byte(fmt.Sprintf("%d:%d %d", wd.Major, wd.Minor, *wd.Weight)) +} + +func weightleafdev(v interface{}) []byte { +	wd := v.(specs.LinuxWeightDevice) +	return []byte(fmt.Sprintf("%d:%d %d", wd.Major, wd.Minor, *wd.LeafWeight)) +} + +func throttleddev(v interface{}) []byte { +	td := v.(specs.LinuxThrottleDevice) +	return []byte(fmt.Sprintf("%d:%d %d", td.Major, td.Minor, td.Rate)) +} + +func splitBlkIOStatLine(r rune) bool { +	return r == ' ' || r == ':' +} + +type deviceKey struct { +	major, minor uint64 +} + +// getDevices makes a best effort attempt to read all the devices into a map +// keyed by major and minor number. Since devices may be mapped multiple times, +// we err on taking the first occurrence. +func getDevices(r io.Reader) (map[deviceKey]string, error) { + +	var ( +		s       = bufio.NewScanner(r) +		devices = make(map[deviceKey]string) +	) +	for i := 0; s.Scan(); i++ { +		if i < 2 { +			continue +		} +		fields := strings.Fields(s.Text()) +		major, err := strconv.Atoi(fields[0]) +		if err != nil { +			return nil, err +		} +		minor, err := strconv.Atoi(fields[1]) +		if err != nil { +			return nil, err +		} +		key := deviceKey{ +			major: uint64(major), +			minor: uint64(minor), +		} +		if _, ok := devices[key]; ok { +			continue +		} +		devices[key] = filepath.Join("/dev", fields[3]) +	} +	return devices, s.Err() +} diff --git a/vendor/github.com/containerd/cgroups/cgroup.go b/vendor/github.com/containerd/cgroups/cgroup.go new file mode 100644 index 000000000..0fab1cecf --- /dev/null +++ b/vendor/github.com/containerd/cgroups/cgroup.go @@ -0,0 +1,533 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"errors" +	"fmt" +	"os" +	"path/filepath" +	"strconv" +	"strings" +	"sync" + +	v1 "github.com/containerd/cgroups/stats/v1" + +	"github.com/opencontainers/runtime-spec/specs-go" +) + +// New returns a new control via the cgroup cgroups interface +func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources, opts ...InitOpts) (Cgroup, error) { +	config := newInitConfig() +	for _, o := range opts { +		if err := o(config); err != nil { +			return nil, err +		} +	} +	subsystems, err := hierarchy() +	if err != nil { +		return nil, err +	} +	var active []Subsystem +	for _, s := range subsystems { +		// check if subsystem exists +		if err := initializeSubsystem(s, path, resources); err != nil { +			if err == ErrControllerNotActive { +				if config.InitCheck != nil { +					if skerr := config.InitCheck(s, path, err); skerr != nil { +						if skerr != ErrIgnoreSubsystem { +							return nil, skerr +						} +					} +				} +				continue +			} +			return nil, err +		} +		active = append(active, s) +	} +	return &cgroup{ +		path:       path, +		subsystems: active, +	}, nil +} + +// Load will load an existing cgroup and allow it to be controlled +// All static path should not include `/sys/fs/cgroup/` prefix, it should start with your own cgroups name +func Load(hierarchy Hierarchy, path Path, opts ...InitOpts) (Cgroup, error) { +	config := newInitConfig() +	for _, o := range opts { +		if err := o(config); err != nil { +			return nil, err +		} +	} +	var activeSubsystems []Subsystem +	subsystems, err := hierarchy() +	if err != nil { +		return nil, err +	} +	// check that the subsystems still exist, and keep only those that actually exist +	for _, s := range pathers(subsystems) { +		p, err := path(s.Name()) +		if err != nil { +			if  errors.Is(err, os.ErrNotExist) { +				return nil, ErrCgroupDeleted +			} +			if err == ErrControllerNotActive { +				if config.InitCheck != nil { +					if skerr := config.InitCheck(s, path, err); skerr != nil { +						if skerr != ErrIgnoreSubsystem { +							return nil, skerr +						} +					} +				} +				continue +			} +			return nil, err +		} +		if _, err := os.Lstat(s.Path(p)); err != nil { +			if os.IsNotExist(err) { +				continue +			} +			return nil, err +		} +		activeSubsystems = append(activeSubsystems, s) +	} +	// if we do not have any active systems then the cgroup is deleted +	if len(activeSubsystems) == 0 { +		return nil, ErrCgroupDeleted +	} +	return &cgroup{ +		path:       path, +		subsystems: activeSubsystems, +	}, nil +} + +type cgroup struct { +	path Path + +	subsystems []Subsystem +	mu         sync.Mutex +	err        error +} + +// New returns a new sub cgroup +func (c *cgroup) New(name string, resources *specs.LinuxResources) (Cgroup, error) { +	c.mu.Lock() +	defer c.mu.Unlock() +	if c.err != nil { +		return nil, c.err +	} +	path := subPath(c.path, name) +	for _, s := range c.subsystems { +		if err := initializeSubsystem(s, path, resources); err != nil { +			return nil, err +		} +	} +	return &cgroup{ +		path:       path, +		subsystems: c.subsystems, +	}, nil +} + +// Subsystems returns all the subsystems that are currently being +// consumed by the group +func (c *cgroup) Subsystems() []Subsystem { +	return c.subsystems +} + +func (c *cgroup) subsystemsFilter(subsystems ...Name) []Subsystem { +	if len(subsystems) == 0 { +		return c.subsystems +	} + +	var filteredSubsystems = []Subsystem{} +	for _, s := range c.subsystems { +		for _, f := range subsystems { +			if s.Name() == f { +				filteredSubsystems = append(filteredSubsystems, s) +				break +			} +		} +	} + +	return filteredSubsystems +} + +// Add moves the provided process into the new cgroup. +// Without additional arguments, the process is added to all the cgroup subsystems. +// When giving Add a list of subsystem names, the process is only added to those +// subsystems, provided that they are active in the targeted cgroup. +func (c *cgroup) Add(process Process, subsystems ...Name) error { +	return c.add(process, cgroupProcs, subsystems...) +} + +// AddProc moves the provided process id into the new cgroup. +// Without additional arguments, the process with the given id is added to all +// the cgroup subsystems. When giving AddProc a list of subsystem names, the process +// id is only added to those subsystems, provided that they are active in the targeted +// cgroup. +func (c *cgroup) AddProc(pid uint64, subsystems ...Name) error { +	return c.add(Process{Pid: int(pid)}, cgroupProcs, subsystems...) +} + +// AddTask moves the provided tasks (threads) into the new cgroup. +// Without additional arguments, the task is added to all the cgroup subsystems. +// When giving AddTask a list of subsystem names, the task is only added to those +// subsystems, provided that they are active in the targeted cgroup. +func (c *cgroup) AddTask(process Process, subsystems ...Name) error { +	return c.add(process, cgroupTasks, subsystems...) +} + +func (c *cgroup) add(process Process, pType procType, subsystems ...Name) error { +	if process.Pid <= 0 { +		return ErrInvalidPid +	} +	c.mu.Lock() +	defer c.mu.Unlock() +	if c.err != nil { +		return c.err +	} +	for _, s := range pathers(c.subsystemsFilter(subsystems...)) { +		p, err := c.path(s.Name()) +		if err != nil { +			return err +		} +		err = retryingWriteFile( +			filepath.Join(s.Path(p), pType), +			[]byte(strconv.Itoa(process.Pid)), +			defaultFilePerm, +		) +		if err != nil { +			return err +		} +	} +	return nil +} + +// Delete will remove the control group from each of the subsystems registered +func (c *cgroup) Delete() error { +	c.mu.Lock() +	defer c.mu.Unlock() +	if c.err != nil { +		return c.err +	} +	var errs []string +	for _, s := range c.subsystems { +		if d, ok := s.(deleter); ok { +			sp, err := c.path(s.Name()) +			if err != nil { +				return err +			} +			if err := d.Delete(sp); err != nil { +				errs = append(errs, string(s.Name())) +			} +			continue +		} +		if p, ok := s.(pather); ok { +			sp, err := c.path(s.Name()) +			if err != nil { +				return err +			} +			path := p.Path(sp) +			if err := remove(path); err != nil { +				errs = append(errs, path) +			} +		} +	} +	if len(errs) > 0 { +		return fmt.Errorf("cgroups: unable to remove paths %s", strings.Join(errs, ", ")) +	} +	c.err = ErrCgroupDeleted +	return nil +} + +// Stat returns the current metrics for the cgroup +func (c *cgroup) Stat(handlers ...ErrorHandler) (*v1.Metrics, error) { +	c.mu.Lock() +	defer c.mu.Unlock() +	if c.err != nil { +		return nil, c.err +	} +	if len(handlers) == 0 { +		handlers = append(handlers, errPassthrough) +	} +	var ( +		stats = &v1.Metrics{ +			CPU: &v1.CPUStat{ +				Throttling: &v1.Throttle{}, +				Usage:      &v1.CPUUsage{}, +			}, +		} +		wg   = &sync.WaitGroup{} +		errs = make(chan error, len(c.subsystems)) +	) +	for _, s := range c.subsystems { +		if ss, ok := s.(stater); ok { +			sp, err := c.path(s.Name()) +			if err != nil { +				return nil, err +			} +			wg.Add(1) +			go func() { +				defer wg.Done() +				if err := ss.Stat(sp, stats); err != nil { +					for _, eh := range handlers { +						if herr := eh(err); herr != nil { +							errs <- herr +						} +					} +				} +			}() +		} +	} +	wg.Wait() +	close(errs) +	for err := range errs { +		return nil, err +	} +	return stats, nil +} + +// Update updates the cgroup with the new resource values provided +// +// Be prepared to handle EBUSY when trying to update a cgroup with +// live processes and other operations like Stats being performed at the +// same time +func (c *cgroup) Update(resources *specs.LinuxResources) error { +	c.mu.Lock() +	defer c.mu.Unlock() +	if c.err != nil { +		return c.err +	} +	for _, s := range c.subsystems { +		if u, ok := s.(updater); ok { +			sp, err := c.path(s.Name()) +			if err != nil { +				return err +			} +			if err := u.Update(sp, resources); err != nil { +				return err +			} +		} +	} +	return nil +} + +// Processes returns the processes running inside the cgroup along +// with the subsystem used, pid, and path +func (c *cgroup) Processes(subsystem Name, recursive bool) ([]Process, error) { +	c.mu.Lock() +	defer c.mu.Unlock() +	if c.err != nil { +		return nil, c.err +	} +	return c.processes(subsystem, recursive, cgroupProcs) +} + +// Tasks returns the tasks running inside the cgroup along +// with the subsystem used, pid, and path +func (c *cgroup) Tasks(subsystem Name, recursive bool) ([]Task, error) { +	c.mu.Lock() +	defer c.mu.Unlock() +	if c.err != nil { +		return nil, c.err +	} +	return c.processes(subsystem, recursive, cgroupTasks) +} + +func (c *cgroup) processes(subsystem Name, recursive bool, pType procType) ([]Process, error) { +	s := c.getSubsystem(subsystem) +	sp, err := c.path(subsystem) +	if err != nil { +		return nil, err +	} +	if s == nil { +		return nil, fmt.Errorf("cgroups: %s doesn't exist in %s subsystem", sp, subsystem) +	} +	path := s.(pather).Path(sp) +	var processes []Process +	err = filepath.Walk(path, func(p string, info os.FileInfo, err error) error { +		if err != nil { +			return err +		} +		if !recursive && info.IsDir() { +			if p == path { +				return nil +			} +			return filepath.SkipDir +		} +		dir, name := filepath.Split(p) +		if name != pType { +			return nil +		} +		procs, err := readPids(dir, subsystem, pType) +		if err != nil { +			return err +		} +		processes = append(processes, procs...) +		return nil +	}) +	return processes, err +} + +// Freeze freezes the entire cgroup and all the processes inside it +func (c *cgroup) Freeze() error { +	c.mu.Lock() +	defer c.mu.Unlock() +	if c.err != nil { +		return c.err +	} +	s := c.getSubsystem(Freezer) +	if s == nil { +		return ErrFreezerNotSupported +	} +	sp, err := c.path(Freezer) +	if err != nil { +		return err +	} +	return s.(*freezerController).Freeze(sp) +} + +// Thaw thaws out the cgroup and all the processes inside it +func (c *cgroup) Thaw() error { +	c.mu.Lock() +	defer c.mu.Unlock() +	if c.err != nil { +		return c.err +	} +	s := c.getSubsystem(Freezer) +	if s == nil { +		return ErrFreezerNotSupported +	} +	sp, err := c.path(Freezer) +	if err != nil { +		return err +	} +	return s.(*freezerController).Thaw(sp) +} + +// OOMEventFD returns the memory cgroup's out of memory event fd that triggers +// when processes inside the cgroup receive an oom event. Returns +// ErrMemoryNotSupported if memory cgroups is not supported. +func (c *cgroup) OOMEventFD() (uintptr, error) { +	c.mu.Lock() +	defer c.mu.Unlock() +	if c.err != nil { +		return 0, c.err +	} +	s := c.getSubsystem(Memory) +	if s == nil { +		return 0, ErrMemoryNotSupported +	} +	sp, err := c.path(Memory) +	if err != nil { +		return 0, err +	} +	return s.(*memoryController).memoryEvent(sp, OOMEvent()) +} + +// RegisterMemoryEvent allows the ability to register for all v1 memory cgroups +// notifications. +func (c *cgroup) RegisterMemoryEvent(event MemoryEvent) (uintptr, error) { +	c.mu.Lock() +	defer c.mu.Unlock() +	if c.err != nil { +		return 0, c.err +	} +	s := c.getSubsystem(Memory) +	if s == nil { +		return 0, ErrMemoryNotSupported +	} +	sp, err := c.path(Memory) +	if err != nil { +		return 0, err +	} +	return s.(*memoryController).memoryEvent(sp, event) +} + +// State returns the state of the cgroup and its processes +func (c *cgroup) State() State { +	c.mu.Lock() +	defer c.mu.Unlock() +	c.checkExists() +	if c.err != nil && c.err == ErrCgroupDeleted { +		return Deleted +	} +	s := c.getSubsystem(Freezer) +	if s == nil { +		return Thawed +	} +	sp, err := c.path(Freezer) +	if err != nil { +		return Unknown +	} +	state, err := s.(*freezerController).state(sp) +	if err != nil { +		return Unknown +	} +	return state +} + +// MoveTo does a recursive move subsystem by subsystem of all the processes +// inside the group +func (c *cgroup) MoveTo(destination Cgroup) error { +	c.mu.Lock() +	defer c.mu.Unlock() +	if c.err != nil { +		return c.err +	} +	for _, s := range c.subsystems { +		processes, err := c.processes(s.Name(), true, cgroupProcs) +		if err != nil { +			return err +		} +		for _, p := range processes { +			if err := destination.Add(p); err != nil { +				if strings.Contains(err.Error(), "no such process") { +					continue +				} +				return err +			} +		} +	} +	return nil +} + +func (c *cgroup) getSubsystem(n Name) Subsystem { +	for _, s := range c.subsystems { +		if s.Name() == n { +			return s +		} +	} +	return nil +} + +func (c *cgroup) checkExists() { +	for _, s := range pathers(c.subsystems) { +		p, err := c.path(s.Name()) +		if err != nil { +			return +		} +		if _, err := os.Lstat(s.Path(p)); err != nil { +			if os.IsNotExist(err) { +				c.err = ErrCgroupDeleted +				return +			} +		} +	} +} diff --git a/vendor/github.com/containerd/cgroups/control.go b/vendor/github.com/containerd/cgroups/control.go new file mode 100644 index 000000000..5fcaac6d0 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/control.go @@ -0,0 +1,99 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"os" + +	v1 "github.com/containerd/cgroups/stats/v1" +	specs "github.com/opencontainers/runtime-spec/specs-go" +) + +type procType = string + +const ( +	cgroupProcs    procType = "cgroup.procs" +	cgroupTasks    procType = "tasks" +	defaultDirPerm          = 0755 +) + +// defaultFilePerm is a var so that the test framework can change the filemode +// of all files created when the tests are running.  The difference between the +// tests and real world use is that files like "cgroup.procs" will exist when writing +// to a read cgroup filesystem and do not exist prior when running in the tests. +// this is set to a non 0 value in the test code +var defaultFilePerm = os.FileMode(0) + +type Process struct { +	// Subsystem is the name of the subsystem that the process / task is in. +	Subsystem Name +	// Pid is the process id of the process / task. +	Pid int +	// Path is the full path of the subsystem and location that the process / task is in. +	Path string +} + +type Task = Process + +// Cgroup handles interactions with the individual groups to perform +// actions on them as them main interface to this cgroup package +type Cgroup interface { +	// New creates a new cgroup under the calling cgroup +	New(string, *specs.LinuxResources) (Cgroup, error) +	// Add adds a process to the cgroup (cgroup.procs). Without additional arguments, +	// the process is added to all the cgroup subsystems. When giving Add a list of +	// subsystem names, the process is only added to those subsystems, provided that +	// they are active in the targeted cgroup. +	Add(Process, ...Name) error +	// AddProc adds the process with the given id to the cgroup (cgroup.procs). +	// Without additional arguments, the process with the given id is added to all +	// the cgroup subsystems. When giving AddProc a list of subsystem names, the process +	// id is only added to those subsystems, provided that they are active in the targeted +	// cgroup. +	AddProc(uint64, ...Name) error +	// AddTask adds a process to the cgroup (tasks). Without additional arguments, the +	// task is added to all the cgroup subsystems. When giving AddTask a list of subsystem +	// names, the task is only added to those subsystems, provided that they are active in +	// the targeted cgroup. +	AddTask(Process, ...Name) error +	// Delete removes the cgroup as a whole +	Delete() error +	// MoveTo moves all the processes under the calling cgroup to the provided one +	// subsystems are moved one at a time +	MoveTo(Cgroup) error +	// Stat returns the stats for all subsystems in the cgroup +	Stat(...ErrorHandler) (*v1.Metrics, error) +	// Update updates all the subsystems with the provided resource changes +	Update(resources *specs.LinuxResources) error +	// Processes returns all the processes in a select subsystem for the cgroup +	Processes(Name, bool) ([]Process, error) +	// Tasks returns all the tasks in a select subsystem for the cgroup +	Tasks(Name, bool) ([]Task, error) +	// Freeze freezes or pauses all processes inside the cgroup +	Freeze() error +	// Thaw thaw or resumes all processes inside the cgroup +	Thaw() error +	// OOMEventFD returns the memory subsystem's event fd for OOM events +	OOMEventFD() (uintptr, error) +	// RegisterMemoryEvent returns the memory subsystems event fd for whatever memory event was +	// registered for. Can alternatively register for the oom event with this method. +	RegisterMemoryEvent(MemoryEvent) (uintptr, error) +	// State returns the cgroups current state +	State() State +	// Subsystems returns all the subsystems in the cgroup +	Subsystems() []Subsystem +} diff --git a/vendor/github.com/containerd/cgroups/cpu.go b/vendor/github.com/containerd/cgroups/cpu.go new file mode 100644 index 000000000..27024f17b --- /dev/null +++ b/vendor/github.com/containerd/cgroups/cpu.go @@ -0,0 +1,125 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"bufio" +	"os" +	"path/filepath" +	"strconv" + +	v1 "github.com/containerd/cgroups/stats/v1" +	specs "github.com/opencontainers/runtime-spec/specs-go" +) + +func NewCpu(root string) *cpuController { +	return &cpuController{ +		root: filepath.Join(root, string(Cpu)), +	} +} + +type cpuController struct { +	root string +} + +func (c *cpuController) Name() Name { +	return Cpu +} + +func (c *cpuController) Path(path string) string { +	return filepath.Join(c.root, path) +} + +func (c *cpuController) Create(path string, resources *specs.LinuxResources) error { +	if err := os.MkdirAll(c.Path(path), defaultDirPerm); err != nil { +		return err +	} +	if cpu := resources.CPU; cpu != nil { +		for _, t := range []struct { +			name   string +			ivalue *int64 +			uvalue *uint64 +		}{ +			{ +				name:   "rt_period_us", +				uvalue: cpu.RealtimePeriod, +			}, +			{ +				name:   "rt_runtime_us", +				ivalue: cpu.RealtimeRuntime, +			}, +			{ +				name:   "shares", +				uvalue: cpu.Shares, +			}, +			{ +				name:   "cfs_period_us", +				uvalue: cpu.Period, +			}, +			{ +				name:   "cfs_quota_us", +				ivalue: cpu.Quota, +			}, +		} { +			var value []byte +			if t.uvalue != nil { +				value = []byte(strconv.FormatUint(*t.uvalue, 10)) +			} else if t.ivalue != nil { +				value = []byte(strconv.FormatInt(*t.ivalue, 10)) +			} +			if value != nil { +				if err := retryingWriteFile( +					filepath.Join(c.Path(path), "cpu."+t.name), +					value, +					defaultFilePerm, +				); err != nil { +					return err +				} +			} +		} +	} +	return nil +} + +func (c *cpuController) Update(path string, resources *specs.LinuxResources) error { +	return c.Create(path, resources) +} + +func (c *cpuController) Stat(path string, stats *v1.Metrics) error { +	f, err := os.Open(filepath.Join(c.Path(path), "cpu.stat")) +	if err != nil { +		return err +	} +	defer f.Close() +	// get or create the cpu field because cpuacct can also set values on this struct +	sc := bufio.NewScanner(f) +	for sc.Scan() { +		key, v, err := parseKV(sc.Text()) +		if err != nil { +			return err +		} +		switch key { +		case "nr_periods": +			stats.CPU.Throttling.Periods = v +		case "nr_throttled": +			stats.CPU.Throttling.ThrottledPeriods = v +		case "throttled_time": +			stats.CPU.Throttling.ThrottledTime = v +		} +	} +	return sc.Err() +} diff --git a/vendor/github.com/containerd/cgroups/cpuacct.go b/vendor/github.com/containerd/cgroups/cpuacct.go new file mode 100644 index 000000000..e5fc864bd --- /dev/null +++ b/vendor/github.com/containerd/cgroups/cpuacct.go @@ -0,0 +1,123 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"fmt" +	"io/ioutil" +	"path/filepath" +	"strconv" +	"strings" + +	v1 "github.com/containerd/cgroups/stats/v1" +) + +const nanosecondsInSecond = 1000000000 + +var clockTicks = getClockTicks() + +func NewCpuacct(root string) *cpuacctController { +	return &cpuacctController{ +		root: filepath.Join(root, string(Cpuacct)), +	} +} + +type cpuacctController struct { +	root string +} + +func (c *cpuacctController) Name() Name { +	return Cpuacct +} + +func (c *cpuacctController) Path(path string) string { +	return filepath.Join(c.root, path) +} + +func (c *cpuacctController) Stat(path string, stats *v1.Metrics) error { +	user, kernel, err := c.getUsage(path) +	if err != nil { +		return err +	} +	total, err := readUint(filepath.Join(c.Path(path), "cpuacct.usage")) +	if err != nil { +		return err +	} +	percpu, err := c.percpuUsage(path) +	if err != nil { +		return err +	} +	stats.CPU.Usage.Total = total +	stats.CPU.Usage.User = user +	stats.CPU.Usage.Kernel = kernel +	stats.CPU.Usage.PerCPU = percpu +	return nil +} + +func (c *cpuacctController) percpuUsage(path string) ([]uint64, error) { +	var usage []uint64 +	data, err := ioutil.ReadFile(filepath.Join(c.Path(path), "cpuacct.usage_percpu")) +	if err != nil { +		return nil, err +	} +	for _, v := range strings.Fields(string(data)) { +		u, err := strconv.ParseUint(v, 10, 64) +		if err != nil { +			return nil, err +		} +		usage = append(usage, u) +	} +	return usage, nil +} + +func (c *cpuacctController) getUsage(path string) (user uint64, kernel uint64, err error) { +	statPath := filepath.Join(c.Path(path), "cpuacct.stat") +	data, err := ioutil.ReadFile(statPath) +	if err != nil { +		return 0, 0, err +	} +	fields := strings.Fields(string(data)) +	if len(fields) != 4 { +		return 0, 0, fmt.Errorf("%q is expected to have 4 fields", statPath) +	} +	for _, t := range []struct { +		index int +		name  string +		value *uint64 +	}{ +		{ +			index: 0, +			name:  "user", +			value: &user, +		}, +		{ +			index: 2, +			name:  "system", +			value: &kernel, +		}, +	} { +		if fields[t.index] != t.name { +			return 0, 0, fmt.Errorf("expected field %q but found %q in %q", t.name, fields[t.index], statPath) +		} +		v, err := strconv.ParseUint(fields[t.index+1], 10, 64) +		if err != nil { +			return 0, 0, err +		} +		*t.value = v +	} +	return (user * nanosecondsInSecond) / clockTicks, (kernel * nanosecondsInSecond) / clockTicks, nil +} diff --git a/vendor/github.com/containerd/cgroups/cpuset.go b/vendor/github.com/containerd/cgroups/cpuset.go new file mode 100644 index 000000000..3cae173bd --- /dev/null +++ b/vendor/github.com/containerd/cgroups/cpuset.go @@ -0,0 +1,159 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"bytes" +	"fmt" +	"io/ioutil" +	"os" +	"path/filepath" + +	specs "github.com/opencontainers/runtime-spec/specs-go" +) + +func NewCpuset(root string) *cpusetController { +	return &cpusetController{ +		root: filepath.Join(root, string(Cpuset)), +	} +} + +type cpusetController struct { +	root string +} + +func (c *cpusetController) Name() Name { +	return Cpuset +} + +func (c *cpusetController) Path(path string) string { +	return filepath.Join(c.root, path) +} + +func (c *cpusetController) Create(path string, resources *specs.LinuxResources) error { +	if err := c.ensureParent(c.Path(path), c.root); err != nil { +		return err +	} +	if err := os.MkdirAll(c.Path(path), defaultDirPerm); err != nil { +		return err +	} +	if err := c.copyIfNeeded(c.Path(path), filepath.Dir(c.Path(path))); err != nil { +		return err +	} +	if resources.CPU != nil { +		for _, t := range []struct { +			name  string +			value string +		}{ +			{ +				name:  "cpus", +				value: resources.CPU.Cpus, +			}, +			{ +				name:  "mems", +				value: resources.CPU.Mems, +			}, +		} { +			if t.value != "" { +				if err := retryingWriteFile( +					filepath.Join(c.Path(path), "cpuset."+t.name), +					[]byte(t.value), +					defaultFilePerm, +				); err != nil { +					return err +				} +			} +		} +	} +	return nil +} + +func (c *cpusetController) Update(path string, resources *specs.LinuxResources) error { +	return c.Create(path, resources) +} + +func (c *cpusetController) getValues(path string) (cpus []byte, mems []byte, err error) { +	if cpus, err = ioutil.ReadFile(filepath.Join(path, "cpuset.cpus")); err != nil && !os.IsNotExist(err) { +		return +	} +	if mems, err = ioutil.ReadFile(filepath.Join(path, "cpuset.mems")); err != nil && !os.IsNotExist(err) { +		return +	} +	return cpus, mems, nil +} + +// ensureParent makes sure that the parent directory of current is created +// and populated with the proper cpus and mems files copied from +// it's parent. +func (c *cpusetController) ensureParent(current, root string) error { +	parent := filepath.Dir(current) +	if _, err := filepath.Rel(root, parent); err != nil { +		return nil +	} +	// Avoid infinite recursion. +	if parent == current { +		return fmt.Errorf("cpuset: cgroup parent path outside cgroup root") +	} +	if cleanPath(parent) != root { +		if err := c.ensureParent(parent, root); err != nil { +			return err +		} +	} +	if err := os.MkdirAll(current, defaultDirPerm); err != nil { +		return err +	} +	return c.copyIfNeeded(current, parent) +} + +// copyIfNeeded copies the cpuset.cpus and cpuset.mems from the parent +// directory to the current directory if the file's contents are 0 +func (c *cpusetController) copyIfNeeded(current, parent string) error { +	var ( +		err                      error +		currentCpus, currentMems []byte +		parentCpus, parentMems   []byte +	) +	if currentCpus, currentMems, err = c.getValues(current); err != nil { +		return err +	} +	if parentCpus, parentMems, err = c.getValues(parent); err != nil { +		return err +	} +	if isEmpty(currentCpus) { +		if err := retryingWriteFile( +			filepath.Join(current, "cpuset.cpus"), +			parentCpus, +			defaultFilePerm, +		); err != nil { +			return err +		} +	} +	if isEmpty(currentMems) { +		if err := retryingWriteFile( +			filepath.Join(current, "cpuset.mems"), +			parentMems, +			defaultFilePerm, +		); err != nil { +			return err +		} +	} +	return nil +} + +func isEmpty(b []byte) bool { +	return len(bytes.Trim(b, "\n")) == 0 +} diff --git a/vendor/github.com/containerd/cgroups/devices.go b/vendor/github.com/containerd/cgroups/devices.go new file mode 100644 index 000000000..7792566d5 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/devices.go @@ -0,0 +1,92 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"fmt" +	"os" +	"path/filepath" + +	specs "github.com/opencontainers/runtime-spec/specs-go" +) + +const ( +	allowDeviceFile = "devices.allow" +	denyDeviceFile  = "devices.deny" +	wildcard        = -1 +) + +func NewDevices(root string) *devicesController { +	return &devicesController{ +		root: filepath.Join(root, string(Devices)), +	} +} + +type devicesController struct { +	root string +} + +func (d *devicesController) Name() Name { +	return Devices +} + +func (d *devicesController) Path(path string) string { +	return filepath.Join(d.root, path) +} + +func (d *devicesController) Create(path string, resources *specs.LinuxResources) error { +	if err := os.MkdirAll(d.Path(path), defaultDirPerm); err != nil { +		return err +	} +	for _, device := range resources.Devices { +		file := denyDeviceFile +		if device.Allow { +			file = allowDeviceFile +		} +		if device.Type == "" { +			device.Type = "a" +		} +		if err := retryingWriteFile( +			filepath.Join(d.Path(path), file), +			[]byte(deviceString(device)), +			defaultFilePerm, +		); err != nil { +			return err +		} +	} +	return nil +} + +func (d *devicesController) Update(path string, resources *specs.LinuxResources) error { +	return d.Create(path, resources) +} + +func deviceString(device specs.LinuxDeviceCgroup) string { +	return fmt.Sprintf("%s %s:%s %s", +		device.Type, +		deviceNumber(device.Major), +		deviceNumber(device.Minor), +		device.Access, +	) +} + +func deviceNumber(number *int64) string { +	if number == nil || *number == wildcard { +		return "*" +	} +	return fmt.Sprint(*number) +} diff --git a/vendor/github.com/containerd/cgroups/errors.go b/vendor/github.com/containerd/cgroups/errors.go new file mode 100644 index 000000000..f1ad8315c --- /dev/null +++ b/vendor/github.com/containerd/cgroups/errors.go @@ -0,0 +1,47 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"errors" +	"os" +) + +var ( +	ErrInvalidPid               = errors.New("cgroups: pid must be greater than 0") +	ErrMountPointNotExist       = errors.New("cgroups: cgroup mountpoint does not exist") +	ErrInvalidFormat            = errors.New("cgroups: parsing file with invalid format failed") +	ErrFreezerNotSupported      = errors.New("cgroups: freezer cgroup not supported on this system") +	ErrMemoryNotSupported       = errors.New("cgroups: memory cgroup not supported on this system") +	ErrCgroupDeleted            = errors.New("cgroups: cgroup deleted") +	ErrNoCgroupMountDestination = errors.New("cgroups: cannot find cgroup mount destination") +) + +// ErrorHandler is a function that handles and acts on errors +type ErrorHandler func(err error) error + +// IgnoreNotExist ignores any errors that are for not existing files +func IgnoreNotExist(err error) error { +	if os.IsNotExist(err) { +		return nil +	} +	return err +} + +func errPassthrough(err error) error { +	return err +} diff --git a/vendor/github.com/containerd/cgroups/freezer.go b/vendor/github.com/containerd/cgroups/freezer.go new file mode 100644 index 000000000..59a7e7128 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/freezer.go @@ -0,0 +1,82 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"io/ioutil" +	"path/filepath" +	"strings" +	"time" +) + +func NewFreezer(root string) *freezerController { +	return &freezerController{ +		root: filepath.Join(root, string(Freezer)), +	} +} + +type freezerController struct { +	root string +} + +func (f *freezerController) Name() Name { +	return Freezer +} + +func (f *freezerController) Path(path string) string { +	return filepath.Join(f.root, path) +} + +func (f *freezerController) Freeze(path string) error { +	return f.waitState(path, Frozen) +} + +func (f *freezerController) Thaw(path string) error { +	return f.waitState(path, Thawed) +} + +func (f *freezerController) changeState(path string, state State) error { +	return retryingWriteFile( +		filepath.Join(f.root, path, "freezer.state"), +		[]byte(strings.ToUpper(string(state))), +		defaultFilePerm, +	) +} + +func (f *freezerController) state(path string) (State, error) { +	current, err := ioutil.ReadFile(filepath.Join(f.root, path, "freezer.state")) +	if err != nil { +		return "", err +	} +	return State(strings.ToLower(strings.TrimSpace(string(current)))), nil +} + +func (f *freezerController) waitState(path string, state State) error { +	for { +		if err := f.changeState(path, state); err != nil { +			return err +		} +		current, err := f.state(path) +		if err != nil { +			return err +		} +		if current == state { +			return nil +		} +		time.Sleep(1 * time.Millisecond) +	} +} diff --git a/vendor/github.com/containerd/cgroups/hierarchy.go b/vendor/github.com/containerd/cgroups/hierarchy.go new file mode 100644 index 000000000..ca3f1b938 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/hierarchy.go @@ -0,0 +1,20 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +// Hierarchy enables both unified and split hierarchy for cgroups +type Hierarchy func() ([]Subsystem, error) diff --git a/vendor/github.com/containerd/cgroups/hugetlb.go b/vendor/github.com/containerd/cgroups/hugetlb.go new file mode 100644 index 000000000..c0eb03b24 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/hugetlb.go @@ -0,0 +1,109 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"os" +	"path/filepath" +	"strconv" +	"strings" + +	v1 "github.com/containerd/cgroups/stats/v1" +	specs "github.com/opencontainers/runtime-spec/specs-go" +) + +func NewHugetlb(root string) (*hugetlbController, error) { +	sizes, err := hugePageSizes() +	if err != nil { +		return nil, err +	} + +	return &hugetlbController{ +		root:  filepath.Join(root, string(Hugetlb)), +		sizes: sizes, +	}, nil +} + +type hugetlbController struct { +	root  string +	sizes []string +} + +func (h *hugetlbController) Name() Name { +	return Hugetlb +} + +func (h *hugetlbController) Path(path string) string { +	return filepath.Join(h.root, path) +} + +func (h *hugetlbController) Create(path string, resources *specs.LinuxResources) error { +	if err := os.MkdirAll(h.Path(path), defaultDirPerm); err != nil { +		return err +	} +	for _, limit := range resources.HugepageLimits { +		if err := retryingWriteFile( +			filepath.Join(h.Path(path), strings.Join([]string{"hugetlb", limit.Pagesize, "limit_in_bytes"}, ".")), +			[]byte(strconv.FormatUint(limit.Limit, 10)), +			defaultFilePerm, +		); err != nil { +			return err +		} +	} +	return nil +} + +func (h *hugetlbController) Stat(path string, stats *v1.Metrics) error { +	for _, size := range h.sizes { +		s, err := h.readSizeStat(path, size) +		if err != nil { +			return err +		} +		stats.Hugetlb = append(stats.Hugetlb, s) +	} +	return nil +} + +func (h *hugetlbController) readSizeStat(path, size string) (*v1.HugetlbStat, error) { +	s := v1.HugetlbStat{ +		Pagesize: size, +	} +	for _, t := range []struct { +		name  string +		value *uint64 +	}{ +		{ +			name:  "usage_in_bytes", +			value: &s.Usage, +		}, +		{ +			name:  "max_usage_in_bytes", +			value: &s.Max, +		}, +		{ +			name:  "failcnt", +			value: &s.Failcnt, +		}, +	} { +		v, err := readUint(filepath.Join(h.Path(path), strings.Join([]string{"hugetlb", size, t.name}, "."))) +		if err != nil { +			return nil, err +		} +		*t.value = v +	} +	return &s, nil +} diff --git a/vendor/github.com/containerd/cgroups/memory.go b/vendor/github.com/containerd/cgroups/memory.go new file mode 100644 index 000000000..e271866ef --- /dev/null +++ b/vendor/github.com/containerd/cgroups/memory.go @@ -0,0 +1,480 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"bufio" +	"fmt" +	"io" +	"os" +	"path/filepath" +	"strconv" +	"strings" + +	v1 "github.com/containerd/cgroups/stats/v1" +	specs "github.com/opencontainers/runtime-spec/specs-go" +	"golang.org/x/sys/unix" +) + +// MemoryEvent is an interface that V1 memory Cgroup notifications implement. Arg returns the +// file name whose fd should be written to "cgroups.event_control". EventFile returns the name of +// the file that supports the notification api e.g. "memory.usage_in_bytes". +type MemoryEvent interface { +	Arg() string +	EventFile() string +} + +type memoryThresholdEvent struct { +	threshold uint64 +	swap      bool +} + +// MemoryThresholdEvent returns a new memory threshold event to be used with RegisterMemoryEvent. +// If swap is true, the event will be registered using memory.memsw.usage_in_bytes +func MemoryThresholdEvent(threshold uint64, swap bool) MemoryEvent { +	return &memoryThresholdEvent{ +		threshold, +		swap, +	} +} + +func (m *memoryThresholdEvent) Arg() string { +	return strconv.FormatUint(m.threshold, 10) +} + +func (m *memoryThresholdEvent) EventFile() string { +	if m.swap { +		return "memory.memsw.usage_in_bytes" +	} +	return "memory.usage_in_bytes" +} + +type oomEvent struct{} + +// OOMEvent returns a new oom event to be used with RegisterMemoryEvent. +func OOMEvent() MemoryEvent { +	return &oomEvent{} +} + +func (oom *oomEvent) Arg() string { +	return "" +} + +func (oom *oomEvent) EventFile() string { +	return "memory.oom_control" +} + +type memoryPressureEvent struct { +	pressureLevel MemoryPressureLevel +	hierarchy     EventNotificationMode +} + +// MemoryPressureEvent returns a new memory pressure event to be used with RegisterMemoryEvent. +func MemoryPressureEvent(pressureLevel MemoryPressureLevel, hierarchy EventNotificationMode) MemoryEvent { +	return &memoryPressureEvent{ +		pressureLevel, +		hierarchy, +	} +} + +func (m *memoryPressureEvent) Arg() string { +	return string(m.pressureLevel) + "," + string(m.hierarchy) +} + +func (m *memoryPressureEvent) EventFile() string { +	return "memory.pressure_level" +} + +// MemoryPressureLevel corresponds to the memory pressure levels defined +// for memory cgroups. +type MemoryPressureLevel string + +// The three memory pressure levels are as follows. +//  - The "low" level means that the system is reclaiming memory for new +//    allocations. Monitoring this reclaiming activity might be useful for +//    maintaining cache level. Upon notification, the program (typically +//    "Activity Manager") might analyze vmstat and act in advance (i.e. +//    prematurely shutdown unimportant services). +//  - The "medium" level means that the system is experiencing medium memory +//    pressure, the system might be making swap, paging out active file caches, +//    etc. Upon this event applications may decide to further analyze +//    vmstat/zoneinfo/memcg or internal memory usage statistics and free any +//    resources that can be easily reconstructed or re-read from a disk. +//  - The "critical" level means that the system is actively thrashing, it is +//    about to out of memory (OOM) or even the in-kernel OOM killer is on its +//    way to trigger. Applications should do whatever they can to help the +//    system. It might be too late to consult with vmstat or any other +//    statistics, so it is advisable to take an immediate action. +//    "https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt" Section 11 +const ( +	LowPressure      MemoryPressureLevel = "low" +	MediumPressure   MemoryPressureLevel = "medium" +	CriticalPressure MemoryPressureLevel = "critical" +) + +// EventNotificationMode corresponds to the notification modes +// for the memory cgroups pressure level notifications. +type EventNotificationMode string + +// There are three optional modes that specify different propagation behavior: +//  - "default": this is the default behavior specified above. This mode is the +//    same as omitting the optional mode parameter, preserved by backwards +//    compatibility. +//  - "hierarchy": events always propagate up to the root, similar to the default +//    behavior, except that propagation continues regardless of whether there are +//    event listeners at each level, with the "hierarchy" mode. In the above +//    example, groups A, B, and C will receive notification of memory pressure. +//  - "local": events are pass-through, i.e. they only receive notifications when +//    memory pressure is experienced in the memcg for which the notification is +//    registered. In the above example, group C will receive notification if +//    registered for "local" notification and the group experiences memory +//    pressure. However, group B will never receive notification, regardless if +//    there is an event listener for group C or not, if group B is registered for +//    local notification. +//    "https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt" Section 11 +const ( +	DefaultMode   EventNotificationMode = "default" +	LocalMode     EventNotificationMode = "local" +	HierarchyMode EventNotificationMode = "hierarchy" +) + +// NewMemory returns a Memory controller given the root folder of cgroups. +// It may optionally accept other configuration options, such as IgnoreModules(...) +func NewMemory(root string, options ...func(*memoryController)) *memoryController { +	mc := &memoryController{ +		root:    filepath.Join(root, string(Memory)), +		ignored: map[string]struct{}{}, +	} +	for _, opt := range options { +		opt(mc) +	} +	return mc +} + +// IgnoreModules configure the memory controller to not read memory metrics for some +// module names (e.g. passing "memsw" would avoid all the memory.memsw.* entries) +func IgnoreModules(names ...string) func(*memoryController) { +	return func(mc *memoryController) { +		for _, name := range names { +			mc.ignored[name] = struct{}{} +		} +	} +} + +// OptionalSwap allows the memory controller to not fail if cgroups is not accounting +// Swap memory (there are no memory.memsw.* entries) +func OptionalSwap() func(*memoryController) { +	return func(mc *memoryController) { +		_, err := os.Stat(filepath.Join(mc.root, "memory.memsw.usage_in_bytes")) +		if os.IsNotExist(err) { +			mc.ignored["memsw"] = struct{}{} +		} +	} +} + +type memoryController struct { +	root    string +	ignored map[string]struct{} +} + +func (m *memoryController) Name() Name { +	return Memory +} + +func (m *memoryController) Path(path string) string { +	return filepath.Join(m.root, path) +} + +func (m *memoryController) Create(path string, resources *specs.LinuxResources) error { +	if err := os.MkdirAll(m.Path(path), defaultDirPerm); err != nil { +		return err +	} +	if resources.Memory == nil { +		return nil +	} +	return m.set(path, getMemorySettings(resources)) +} + +func (m *memoryController) Update(path string, resources *specs.LinuxResources) error { +	if resources.Memory == nil { +		return nil +	} +	g := func(v *int64) bool { +		return v != nil && *v > 0 +	} +	settings := getMemorySettings(resources) +	if g(resources.Memory.Limit) && g(resources.Memory.Swap) { +		// if the updated swap value is larger than the current memory limit set the swap changes first +		// then set the memory limit as swap must always be larger than the current limit +		current, err := readUint(filepath.Join(m.Path(path), "memory.limit_in_bytes")) +		if err != nil { +			return err +		} +		if current < uint64(*resources.Memory.Swap) { +			settings[0], settings[1] = settings[1], settings[0] +		} +	} +	return m.set(path, settings) +} + +func (m *memoryController) Stat(path string, stats *v1.Metrics) error { +	fMemStat, err := os.Open(filepath.Join(m.Path(path), "memory.stat")) +	if err != nil { +		return err +	} +	defer fMemStat.Close() +	stats.Memory = &v1.MemoryStat{ +		Usage:     &v1.MemoryEntry{}, +		Swap:      &v1.MemoryEntry{}, +		Kernel:    &v1.MemoryEntry{}, +		KernelTCP: &v1.MemoryEntry{}, +	} +	if err := m.parseStats(fMemStat, stats.Memory); err != nil { +		return err +	} + +	fMemOomControl, err := os.Open(filepath.Join(m.Path(path), "memory.oom_control")) +	if err != nil { +		return err +	} +	defer fMemOomControl.Close() +	stats.MemoryOomControl = &v1.MemoryOomControl{} +	if err := m.parseOomControlStats(fMemOomControl, stats.MemoryOomControl); err != nil { +		return err +	} +	for _, t := range []struct { +		module string +		entry  *v1.MemoryEntry +	}{ +		{ +			module: "", +			entry:  stats.Memory.Usage, +		}, +		{ +			module: "memsw", +			entry:  stats.Memory.Swap, +		}, +		{ +			module: "kmem", +			entry:  stats.Memory.Kernel, +		}, +		{ +			module: "kmem.tcp", +			entry:  stats.Memory.KernelTCP, +		}, +	} { +		if _, ok := m.ignored[t.module]; ok { +			continue +		} +		for _, tt := range []struct { +			name  string +			value *uint64 +		}{ +			{ +				name:  "usage_in_bytes", +				value: &t.entry.Usage, +			}, +			{ +				name:  "max_usage_in_bytes", +				value: &t.entry.Max, +			}, +			{ +				name:  "failcnt", +				value: &t.entry.Failcnt, +			}, +			{ +				name:  "limit_in_bytes", +				value: &t.entry.Limit, +			}, +		} { +			parts := []string{"memory"} +			if t.module != "" { +				parts = append(parts, t.module) +			} +			parts = append(parts, tt.name) +			v, err := readUint(filepath.Join(m.Path(path), strings.Join(parts, "."))) +			if err != nil { +				return err +			} +			*tt.value = v +		} +	} +	return nil +} + +func (m *memoryController) parseStats(r io.Reader, stat *v1.MemoryStat) error { +	var ( +		raw  = make(map[string]uint64) +		sc   = bufio.NewScanner(r) +		line int +	) +	for sc.Scan() { +		key, v, err := parseKV(sc.Text()) +		if err != nil { +			return fmt.Errorf("%d: %v", line, err) +		} +		raw[key] = v +		line++ +	} +	if err := sc.Err(); err != nil { +		return err +	} +	stat.Cache = raw["cache"] +	stat.RSS = raw["rss"] +	stat.RSSHuge = raw["rss_huge"] +	stat.MappedFile = raw["mapped_file"] +	stat.Dirty = raw["dirty"] +	stat.Writeback = raw["writeback"] +	stat.PgPgIn = raw["pgpgin"] +	stat.PgPgOut = raw["pgpgout"] +	stat.PgFault = raw["pgfault"] +	stat.PgMajFault = raw["pgmajfault"] +	stat.InactiveAnon = raw["inactive_anon"] +	stat.ActiveAnon = raw["active_anon"] +	stat.InactiveFile = raw["inactive_file"] +	stat.ActiveFile = raw["active_file"] +	stat.Unevictable = raw["unevictable"] +	stat.HierarchicalMemoryLimit = raw["hierarchical_memory_limit"] +	stat.HierarchicalSwapLimit = raw["hierarchical_memsw_limit"] +	stat.TotalCache = raw["total_cache"] +	stat.TotalRSS = raw["total_rss"] +	stat.TotalRSSHuge = raw["total_rss_huge"] +	stat.TotalMappedFile = raw["total_mapped_file"] +	stat.TotalDirty = raw["total_dirty"] +	stat.TotalWriteback = raw["total_writeback"] +	stat.TotalPgPgIn = raw["total_pgpgin"] +	stat.TotalPgPgOut = raw["total_pgpgout"] +	stat.TotalPgFault = raw["total_pgfault"] +	stat.TotalPgMajFault = raw["total_pgmajfault"] +	stat.TotalInactiveAnon = raw["total_inactive_anon"] +	stat.TotalActiveAnon = raw["total_active_anon"] +	stat.TotalInactiveFile = raw["total_inactive_file"] +	stat.TotalActiveFile = raw["total_active_file"] +	stat.TotalUnevictable = raw["total_unevictable"] +	return nil +} + +func (m *memoryController) parseOomControlStats(r io.Reader, stat *v1.MemoryOomControl) error { +	var ( +		raw  = make(map[string]uint64) +		sc   = bufio.NewScanner(r) +		line int +	) +	for sc.Scan() { +		key, v, err := parseKV(sc.Text()) +		if err != nil { +			return fmt.Errorf("%d: %v", line, err) +		} +		raw[key] = v +		line++ +	} +	if err := sc.Err(); err != nil { +		return err +	} +	stat.OomKillDisable = raw["oom_kill_disable"] +	stat.UnderOom = raw["under_oom"] +	stat.OomKill = raw["oom_kill"] +	return nil +} + +func (m *memoryController) set(path string, settings []memorySettings) error { +	for _, t := range settings { +		if t.value != nil { +			if err := retryingWriteFile( +				filepath.Join(m.Path(path), "memory."+t.name), +				[]byte(strconv.FormatInt(*t.value, 10)), +				defaultFilePerm, +			); err != nil { +				return err +			} +		} +	} +	return nil +} + +type memorySettings struct { +	name  string +	value *int64 +} + +func getMemorySettings(resources *specs.LinuxResources) []memorySettings { +	mem := resources.Memory +	var swappiness *int64 +	if mem.Swappiness != nil { +		v := int64(*mem.Swappiness) +		swappiness = &v +	} +	return []memorySettings{ +		{ +			name:  "limit_in_bytes", +			value: mem.Limit, +		}, +		{ +			name:  "soft_limit_in_bytes", +			value: mem.Reservation, +		}, +		{ +			name:  "memsw.limit_in_bytes", +			value: mem.Swap, +		}, +		{ +			name:  "kmem.limit_in_bytes", +			value: mem.Kernel, +		}, +		{ +			name:  "kmem.tcp.limit_in_bytes", +			value: mem.KernelTCP, +		}, +		{ +			name:  "oom_control", +			value: getOomControlValue(mem), +		}, +		{ +			name:  "swappiness", +			value: swappiness, +		}, +	} +} + +func getOomControlValue(mem *specs.LinuxMemory) *int64 { +	if mem.DisableOOMKiller != nil && *mem.DisableOOMKiller { +		i := int64(1) +		return &i +	} +	return nil +} + +func (m *memoryController) memoryEvent(path string, event MemoryEvent) (uintptr, error) { +	root := m.Path(path) +	efd, err := unix.Eventfd(0, unix.EFD_CLOEXEC) +	if err != nil { +		return 0, err +	} +	evtFile, err := os.Open(filepath.Join(root, event.EventFile())) +	if err != nil { +		unix.Close(efd) +		return 0, err +	} +	defer evtFile.Close() +	data := fmt.Sprintf("%d %d %s", efd, evtFile.Fd(), event.Arg()) +	evctlPath := filepath.Join(root, "cgroup.event_control") +	if err := retryingWriteFile(evctlPath, []byte(data), 0700); err != nil { +		unix.Close(efd) +		return 0, err +	} +	return uintptr(efd), nil +} diff --git a/vendor/github.com/containerd/cgroups/named.go b/vendor/github.com/containerd/cgroups/named.go new file mode 100644 index 000000000..06b16c3b1 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/named.go @@ -0,0 +1,39 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import "path/filepath" + +func NewNamed(root string, name Name) *namedController { +	return &namedController{ +		root: root, +		name: name, +	} +} + +type namedController struct { +	root string +	name Name +} + +func (n *namedController) Name() Name { +	return n.name +} + +func (n *namedController) Path(path string) string { +	return filepath.Join(n.root, string(n.name), path) +} diff --git a/vendor/github.com/containerd/cgroups/net_cls.go b/vendor/github.com/containerd/cgroups/net_cls.go new file mode 100644 index 000000000..839b06de0 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/net_cls.go @@ -0,0 +1,61 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"os" +	"path/filepath" +	"strconv" + +	specs "github.com/opencontainers/runtime-spec/specs-go" +) + +func NewNetCls(root string) *netclsController { +	return &netclsController{ +		root: filepath.Join(root, string(NetCLS)), +	} +} + +type netclsController struct { +	root string +} + +func (n *netclsController) Name() Name { +	return NetCLS +} + +func (n *netclsController) Path(path string) string { +	return filepath.Join(n.root, path) +} + +func (n *netclsController) Create(path string, resources *specs.LinuxResources) error { +	if err := os.MkdirAll(n.Path(path), defaultDirPerm); err != nil { +		return err +	} +	if resources.Network != nil && resources.Network.ClassID != nil && *resources.Network.ClassID > 0 { +		return retryingWriteFile( +			filepath.Join(n.Path(path), "net_cls.classid"), +			[]byte(strconv.FormatUint(uint64(*resources.Network.ClassID), 10)), +			defaultFilePerm, +		) +	} +	return nil +} + +func (n *netclsController) Update(path string, resources *specs.LinuxResources) error { +	return n.Create(path, resources) +} diff --git a/vendor/github.com/containerd/cgroups/net_prio.go b/vendor/github.com/containerd/cgroups/net_prio.go new file mode 100644 index 000000000..6362fd084 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/net_prio.go @@ -0,0 +1,65 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"fmt" +	"os" +	"path/filepath" + +	specs "github.com/opencontainers/runtime-spec/specs-go" +) + +func NewNetPrio(root string) *netprioController { +	return &netprioController{ +		root: filepath.Join(root, string(NetPrio)), +	} +} + +type netprioController struct { +	root string +} + +func (n *netprioController) Name() Name { +	return NetPrio +} + +func (n *netprioController) Path(path string) string { +	return filepath.Join(n.root, path) +} + +func (n *netprioController) Create(path string, resources *specs.LinuxResources) error { +	if err := os.MkdirAll(n.Path(path), defaultDirPerm); err != nil { +		return err +	} +	if resources.Network != nil { +		for _, prio := range resources.Network.Priorities { +			if err := retryingWriteFile( +				filepath.Join(n.Path(path), "net_prio.ifpriomap"), +				formatPrio(prio.Name, prio.Priority), +				defaultFilePerm, +			); err != nil { +				return err +			} +		} +	} +	return nil +} + +func formatPrio(name string, prio uint32) []byte { +	return []byte(fmt.Sprintf("%s %d", name, prio)) +} diff --git a/vendor/github.com/containerd/cgroups/opts.go b/vendor/github.com/containerd/cgroups/opts.go new file mode 100644 index 000000000..1e428d048 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/opts.go @@ -0,0 +1,61 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"errors" +) + +var ( +	// ErrIgnoreSubsystem allows the specific subsystem to be skipped +	ErrIgnoreSubsystem = errors.New("skip subsystem") +	// ErrDevicesRequired is returned when the devices subsystem is required but +	// does not exist or is not active +	ErrDevicesRequired = errors.New("devices subsystem is required") +) + +// InitOpts allows configuration for the creation or loading of a cgroup +type InitOpts func(*InitConfig) error + +// InitConfig provides configuration options for the creation +// or loading of a cgroup and its subsystems +type InitConfig struct { +	// InitCheck can be used to check initialization errors from the subsystem +	InitCheck InitCheck +} + +func newInitConfig() *InitConfig { +	return &InitConfig{ +		InitCheck: RequireDevices, +	} +} + +// InitCheck allows subsystems errors to be checked when initialized or loaded +type InitCheck func(Subsystem, Path, error) error + +// AllowAny allows any subsystem errors to be skipped +func AllowAny(_ Subsystem, _ Path, _ error) error { +	return ErrIgnoreSubsystem +} + +// RequireDevices requires the device subsystem but no others +func RequireDevices(s Subsystem, _ Path, _ error) error { +	if s.Name() == Devices { +		return ErrDevicesRequired +	} +	return ErrIgnoreSubsystem +} diff --git a/vendor/github.com/containerd/cgroups/paths.go b/vendor/github.com/containerd/cgroups/paths.go new file mode 100644 index 000000000..bddc4e9cd --- /dev/null +++ b/vendor/github.com/containerd/cgroups/paths.go @@ -0,0 +1,106 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"errors" +	"fmt" +	"path/filepath" +) + +type Path func(subsystem Name) (string, error) + +func RootPath(subsystem Name) (string, error) { +	return "/", nil +} + +// StaticPath returns a static path to use for all cgroups +func StaticPath(path string) Path { +	return func(_ Name) (string, error) { +		return path, nil +	} +} + +// NestedPath will nest the cgroups based on the calling processes cgroup +// placing its child processes inside its own path +func NestedPath(suffix string) Path { +	paths, err := ParseCgroupFile("/proc/self/cgroup") +	if err != nil { +		return errorPath(err) +	} +	return existingPath(paths, suffix) +} + +// PidPath will return the correct cgroup paths for an existing process running inside a cgroup +// This is commonly used for the Load function to restore an existing container +func PidPath(pid int) Path { +	p := fmt.Sprintf("/proc/%d/cgroup", pid) +	paths, err := ParseCgroupFile(p) +	if err != nil { +		return errorPath(fmt.Errorf("parse cgroup file %s: %w", p, err)) +	} +	return existingPath(paths, "") +} + +// ErrControllerNotActive is returned when a controller is not supported or enabled +var ErrControllerNotActive = errors.New("controller is not supported") + +func existingPath(paths map[string]string, suffix string) Path { +	// localize the paths based on the root mount dest for nested cgroups +	for n, p := range paths { +		dest, err := getCgroupDestination(n) +		if err != nil { +			return errorPath(err) +		} +		rel, err := filepath.Rel(dest, p) +		if err != nil { +			return errorPath(err) +		} +		if rel == "." { +			rel = dest +		} +		paths[n] = filepath.Join("/", rel) +	} +	return func(name Name) (string, error) { +		root, ok := paths[string(name)] +		if !ok { +			if root, ok = paths["name="+string(name)]; !ok { +				return "", ErrControllerNotActive +			} +		} +		if suffix != "" { +			return filepath.Join(root, suffix), nil +		} +		return root, nil +	} +} + +func subPath(path Path, subName string) Path { +	return func(name Name) (string, error) { +		p, err := path(name) +		if err != nil { +			return "", err +		} +		return filepath.Join(p, subName), nil +	} +} + +func errorPath(err error) Path { +	return func(_ Name) (string, error) { +		return "", err +	} +} diff --git a/vendor/github.com/containerd/cgroups/perf_event.go b/vendor/github.com/containerd/cgroups/perf_event.go new file mode 100644 index 000000000..648786db6 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/perf_event.go @@ -0,0 +1,37 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import "path/filepath" + +func NewPerfEvent(root string) *PerfEventController { +	return &PerfEventController{ +		root: filepath.Join(root, string(PerfEvent)), +	} +} + +type PerfEventController struct { +	root string +} + +func (p *PerfEventController) Name() Name { +	return PerfEvent +} + +func (p *PerfEventController) Path(path string) string { +	return filepath.Join(p.root, path) +} diff --git a/vendor/github.com/containerd/cgroups/pids.go b/vendor/github.com/containerd/cgroups/pids.go new file mode 100644 index 000000000..ce78e44c1 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/pids.go @@ -0,0 +1,86 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"io/ioutil" +	"os" +	"path/filepath" +	"strconv" +	"strings" + +	v1 "github.com/containerd/cgroups/stats/v1" +	specs "github.com/opencontainers/runtime-spec/specs-go" +) + +func NewPids(root string) *pidsController { +	return &pidsController{ +		root: filepath.Join(root, string(Pids)), +	} +} + +type pidsController struct { +	root string +} + +func (p *pidsController) Name() Name { +	return Pids +} + +func (p *pidsController) Path(path string) string { +	return filepath.Join(p.root, path) +} + +func (p *pidsController) Create(path string, resources *specs.LinuxResources) error { +	if err := os.MkdirAll(p.Path(path), defaultDirPerm); err != nil { +		return err +	} +	if resources.Pids != nil && resources.Pids.Limit > 0 { +		return retryingWriteFile( +			filepath.Join(p.Path(path), "pids.max"), +			[]byte(strconv.FormatInt(resources.Pids.Limit, 10)), +			defaultFilePerm, +		) +	} +	return nil +} + +func (p *pidsController) Update(path string, resources *specs.LinuxResources) error { +	return p.Create(path, resources) +} + +func (p *pidsController) Stat(path string, stats *v1.Metrics) error { +	current, err := readUint(filepath.Join(p.Path(path), "pids.current")) +	if err != nil { +		return err +	} +	var max uint64 +	maxData, err := ioutil.ReadFile(filepath.Join(p.Path(path), "pids.max")) +	if err != nil { +		return err +	} +	if maxS := strings.TrimSpace(string(maxData)); maxS != "max" { +		if max, err = parseUint(maxS, 10, 64); err != nil { +			return err +		} +	} +	stats.Pids = &v1.PidsStat{ +		Current: current, +		Limit:   max, +	} +	return nil +} diff --git a/vendor/github.com/containerd/cgroups/rdma.go b/vendor/github.com/containerd/cgroups/rdma.go new file mode 100644 index 000000000..3b59b1071 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/rdma.go @@ -0,0 +1,155 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"io/ioutil" +	"math" +	"os" +	"path/filepath" +	"strconv" +	"strings" + +	v1 "github.com/containerd/cgroups/stats/v1" +	specs "github.com/opencontainers/runtime-spec/specs-go" +) + +type rdmaController struct { +	root string +} + +func (p *rdmaController) Name() Name { +	return Rdma +} + +func (p *rdmaController) Path(path string) string { +	return filepath.Join(p.root, path) +} + +func NewRdma(root string) *rdmaController { +	return &rdmaController{ +		root: filepath.Join(root, string(Rdma)), +	} +} + +func createCmdString(device string, limits *specs.LinuxRdma) string { +	var cmdString string + +	cmdString = device +	if limits.HcaHandles != nil { +		cmdString = cmdString + " " + "hca_handle=" + strconv.FormatUint(uint64(*limits.HcaHandles), 10) +	} + +	if limits.HcaObjects != nil { +		cmdString = cmdString + " " + "hca_object=" + strconv.FormatUint(uint64(*limits.HcaObjects), 10) +	} +	return cmdString +} + +func (p *rdmaController) Create(path string, resources *specs.LinuxResources) error { +	if err := os.MkdirAll(p.Path(path), defaultDirPerm); err != nil { +		return err +	} + +	for device, limit := range resources.Rdma { +		if device != "" && (limit.HcaHandles != nil || limit.HcaObjects != nil) { +			limit := limit +			return retryingWriteFile( +				filepath.Join(p.Path(path), "rdma.max"), +				[]byte(createCmdString(device, &limit)), +				defaultFilePerm, +			) +		} +	} +	return nil +} + +func (p *rdmaController) Update(path string, resources *specs.LinuxResources) error { +	return p.Create(path, resources) +} + +func parseRdmaKV(raw string, entry *v1.RdmaEntry) { +	var value uint64 +	var err error + +	parts := strings.Split(raw, "=") +	switch len(parts) { +	case 2: +		if parts[1] == "max" { +			value = math.MaxUint32 +		} else { +			value, err = parseUint(parts[1], 10, 32) +			if err != nil { +				return +			} +		} +		if parts[0] == "hca_handle" { +			entry.HcaHandles = uint32(value) +		} else if parts[0] == "hca_object" { +			entry.HcaObjects = uint32(value) +		} +	} +} + +func toRdmaEntry(strEntries []string) []*v1.RdmaEntry { +	var rdmaEntries []*v1.RdmaEntry +	for i := range strEntries { +		parts := strings.Fields(strEntries[i]) +		switch len(parts) { +		case 3: +			entry := new(v1.RdmaEntry) +			entry.Device = parts[0] +			parseRdmaKV(parts[1], entry) +			parseRdmaKV(parts[2], entry) + +			rdmaEntries = append(rdmaEntries, entry) +		default: +			continue +		} +	} +	return rdmaEntries +} + +func (p *rdmaController) Stat(path string, stats *v1.Metrics) error { + +	currentData, err := ioutil.ReadFile(filepath.Join(p.Path(path), "rdma.current")) +	if err != nil { +		return err +	} +	currentPerDevices := strings.Split(string(currentData), "\n") + +	maxData, err := ioutil.ReadFile(filepath.Join(p.Path(path), "rdma.max")) +	if err != nil { +		return err +	} +	maxPerDevices := strings.Split(string(maxData), "\n") + +	// If device got removed between reading two files, ignore returning +	// stats. +	if len(currentPerDevices) != len(maxPerDevices) { +		return nil +	} + +	currentEntries := toRdmaEntry(currentPerDevices) +	maxEntries := toRdmaEntry(maxPerDevices) + +	stats.Rdma = &v1.RdmaStat{ +		Current: currentEntries, +		Limit:   maxEntries, +	} +	return nil +} diff --git a/vendor/github.com/containerd/cgroups/state.go b/vendor/github.com/containerd/cgroups/state.go new file mode 100644 index 000000000..cfeabbbc6 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/state.go @@ -0,0 +1,28 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +// State is a type that represents the state of the current cgroup +type State string + +const ( +	Unknown  State = "" +	Thawed   State = "thawed" +	Frozen   State = "frozen" +	Freezing State = "freezing" +	Deleted  State = "deleted" +) diff --git a/vendor/github.com/containerd/cgroups/stats/v1/doc.go b/vendor/github.com/containerd/cgroups/stats/v1/doc.go new file mode 100644 index 000000000..23f3cdd4b --- /dev/null +++ b/vendor/github.com/containerd/cgroups/stats/v1/doc.go @@ -0,0 +1,17 @@ +/* +   Copyright The containerd Authors. + +   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 v1 diff --git a/vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.go b/vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.go new file mode 100644 index 000000000..6d2d41770 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.go @@ -0,0 +1,6125 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: github.com/containerd/cgroups/stats/v1/metrics.proto + +package v1 + +import ( +	fmt "fmt" +	_ "github.com/gogo/protobuf/gogoproto" +	proto "github.com/gogo/protobuf/proto" +	io "io" +	math "math" +	math_bits "math/bits" +	reflect "reflect" +	strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type Metrics struct { +	Hugetlb              []*HugetlbStat    `protobuf:"bytes,1,rep,name=hugetlb,proto3" json:"hugetlb,omitempty"` +	Pids                 *PidsStat         `protobuf:"bytes,2,opt,name=pids,proto3" json:"pids,omitempty"` +	CPU                  *CPUStat          `protobuf:"bytes,3,opt,name=cpu,proto3" json:"cpu,omitempty"` +	Memory               *MemoryStat       `protobuf:"bytes,4,opt,name=memory,proto3" json:"memory,omitempty"` +	Blkio                *BlkIOStat        `protobuf:"bytes,5,opt,name=blkio,proto3" json:"blkio,omitempty"` +	Rdma                 *RdmaStat         `protobuf:"bytes,6,opt,name=rdma,proto3" json:"rdma,omitempty"` +	Network              []*NetworkStat    `protobuf:"bytes,7,rep,name=network,proto3" json:"network,omitempty"` +	CgroupStats          *CgroupStats      `protobuf:"bytes,8,opt,name=cgroup_stats,json=cgroupStats,proto3" json:"cgroup_stats,omitempty"` +	MemoryOomControl     *MemoryOomControl `protobuf:"bytes,9,opt,name=memory_oom_control,json=memoryOomControl,proto3" json:"memory_oom_control,omitempty"` +	XXX_NoUnkeyedLiteral struct{}          `json:"-"` +	XXX_unrecognized     []byte            `json:"-"` +	XXX_sizecache        int32             `json:"-"` +} + +func (m *Metrics) Reset()      { *m = Metrics{} } +func (*Metrics) ProtoMessage() {} +func (*Metrics) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{0} +} +func (m *Metrics) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *Metrics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_Metrics.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *Metrics) XXX_Merge(src proto.Message) { +	xxx_messageInfo_Metrics.Merge(m, src) +} +func (m *Metrics) XXX_Size() int { +	return m.Size() +} +func (m *Metrics) XXX_DiscardUnknown() { +	xxx_messageInfo_Metrics.DiscardUnknown(m) +} + +var xxx_messageInfo_Metrics proto.InternalMessageInfo + +type HugetlbStat struct { +	Usage                uint64   `protobuf:"varint,1,opt,name=usage,proto3" json:"usage,omitempty"` +	Max                  uint64   `protobuf:"varint,2,opt,name=max,proto3" json:"max,omitempty"` +	Failcnt              uint64   `protobuf:"varint,3,opt,name=failcnt,proto3" json:"failcnt,omitempty"` +	Pagesize             string   `protobuf:"bytes,4,opt,name=pagesize,proto3" json:"pagesize,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *HugetlbStat) Reset()      { *m = HugetlbStat{} } +func (*HugetlbStat) ProtoMessage() {} +func (*HugetlbStat) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{1} +} +func (m *HugetlbStat) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *HugetlbStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_HugetlbStat.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *HugetlbStat) XXX_Merge(src proto.Message) { +	xxx_messageInfo_HugetlbStat.Merge(m, src) +} +func (m *HugetlbStat) XXX_Size() int { +	return m.Size() +} +func (m *HugetlbStat) XXX_DiscardUnknown() { +	xxx_messageInfo_HugetlbStat.DiscardUnknown(m) +} + +var xxx_messageInfo_HugetlbStat proto.InternalMessageInfo + +type PidsStat struct { +	Current              uint64   `protobuf:"varint,1,opt,name=current,proto3" json:"current,omitempty"` +	Limit                uint64   `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *PidsStat) Reset()      { *m = PidsStat{} } +func (*PidsStat) ProtoMessage() {} +func (*PidsStat) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{2} +} +func (m *PidsStat) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *PidsStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_PidsStat.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *PidsStat) XXX_Merge(src proto.Message) { +	xxx_messageInfo_PidsStat.Merge(m, src) +} +func (m *PidsStat) XXX_Size() int { +	return m.Size() +} +func (m *PidsStat) XXX_DiscardUnknown() { +	xxx_messageInfo_PidsStat.DiscardUnknown(m) +} + +var xxx_messageInfo_PidsStat proto.InternalMessageInfo + +type CPUStat struct { +	Usage                *CPUUsage `protobuf:"bytes,1,opt,name=usage,proto3" json:"usage,omitempty"` +	Throttling           *Throttle `protobuf:"bytes,2,opt,name=throttling,proto3" json:"throttling,omitempty"` +	XXX_NoUnkeyedLiteral struct{}  `json:"-"` +	XXX_unrecognized     []byte    `json:"-"` +	XXX_sizecache        int32     `json:"-"` +} + +func (m *CPUStat) Reset()      { *m = CPUStat{} } +func (*CPUStat) ProtoMessage() {} +func (*CPUStat) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{3} +} +func (m *CPUStat) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *CPUStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_CPUStat.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *CPUStat) XXX_Merge(src proto.Message) { +	xxx_messageInfo_CPUStat.Merge(m, src) +} +func (m *CPUStat) XXX_Size() int { +	return m.Size() +} +func (m *CPUStat) XXX_DiscardUnknown() { +	xxx_messageInfo_CPUStat.DiscardUnknown(m) +} + +var xxx_messageInfo_CPUStat proto.InternalMessageInfo + +type CPUUsage struct { +	// values in nanoseconds +	Total                uint64   `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` +	Kernel               uint64   `protobuf:"varint,2,opt,name=kernel,proto3" json:"kernel,omitempty"` +	User                 uint64   `protobuf:"varint,3,opt,name=user,proto3" json:"user,omitempty"` +	PerCPU               []uint64 `protobuf:"varint,4,rep,packed,name=per_cpu,json=perCpu,proto3" json:"per_cpu,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *CPUUsage) Reset()      { *m = CPUUsage{} } +func (*CPUUsage) ProtoMessage() {} +func (*CPUUsage) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{4} +} +func (m *CPUUsage) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *CPUUsage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_CPUUsage.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *CPUUsage) XXX_Merge(src proto.Message) { +	xxx_messageInfo_CPUUsage.Merge(m, src) +} +func (m *CPUUsage) XXX_Size() int { +	return m.Size() +} +func (m *CPUUsage) XXX_DiscardUnknown() { +	xxx_messageInfo_CPUUsage.DiscardUnknown(m) +} + +var xxx_messageInfo_CPUUsage proto.InternalMessageInfo + +type Throttle struct { +	Periods              uint64   `protobuf:"varint,1,opt,name=periods,proto3" json:"periods,omitempty"` +	ThrottledPeriods     uint64   `protobuf:"varint,2,opt,name=throttled_periods,json=throttledPeriods,proto3" json:"throttled_periods,omitempty"` +	ThrottledTime        uint64   `protobuf:"varint,3,opt,name=throttled_time,json=throttledTime,proto3" json:"throttled_time,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *Throttle) Reset()      { *m = Throttle{} } +func (*Throttle) ProtoMessage() {} +func (*Throttle) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{5} +} +func (m *Throttle) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *Throttle) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_Throttle.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *Throttle) XXX_Merge(src proto.Message) { +	xxx_messageInfo_Throttle.Merge(m, src) +} +func (m *Throttle) XXX_Size() int { +	return m.Size() +} +func (m *Throttle) XXX_DiscardUnknown() { +	xxx_messageInfo_Throttle.DiscardUnknown(m) +} + +var xxx_messageInfo_Throttle proto.InternalMessageInfo + +type MemoryStat struct { +	Cache                   uint64       `protobuf:"varint,1,opt,name=cache,proto3" json:"cache,omitempty"` +	RSS                     uint64       `protobuf:"varint,2,opt,name=rss,proto3" json:"rss,omitempty"` +	RSSHuge                 uint64       `protobuf:"varint,3,opt,name=rss_huge,json=rssHuge,proto3" json:"rss_huge,omitempty"` +	MappedFile              uint64       `protobuf:"varint,4,opt,name=mapped_file,json=mappedFile,proto3" json:"mapped_file,omitempty"` +	Dirty                   uint64       `protobuf:"varint,5,opt,name=dirty,proto3" json:"dirty,omitempty"` +	Writeback               uint64       `protobuf:"varint,6,opt,name=writeback,proto3" json:"writeback,omitempty"` +	PgPgIn                  uint64       `protobuf:"varint,7,opt,name=pg_pg_in,json=pgPgIn,proto3" json:"pg_pg_in,omitempty"` +	PgPgOut                 uint64       `protobuf:"varint,8,opt,name=pg_pg_out,json=pgPgOut,proto3" json:"pg_pg_out,omitempty"` +	PgFault                 uint64       `protobuf:"varint,9,opt,name=pg_fault,json=pgFault,proto3" json:"pg_fault,omitempty"` +	PgMajFault              uint64       `protobuf:"varint,10,opt,name=pg_maj_fault,json=pgMajFault,proto3" json:"pg_maj_fault,omitempty"` +	InactiveAnon            uint64       `protobuf:"varint,11,opt,name=inactive_anon,json=inactiveAnon,proto3" json:"inactive_anon,omitempty"` +	ActiveAnon              uint64       `protobuf:"varint,12,opt,name=active_anon,json=activeAnon,proto3" json:"active_anon,omitempty"` +	InactiveFile            uint64       `protobuf:"varint,13,opt,name=inactive_file,json=inactiveFile,proto3" json:"inactive_file,omitempty"` +	ActiveFile              uint64       `protobuf:"varint,14,opt,name=active_file,json=activeFile,proto3" json:"active_file,omitempty"` +	Unevictable             uint64       `protobuf:"varint,15,opt,name=unevictable,proto3" json:"unevictable,omitempty"` +	HierarchicalMemoryLimit uint64       `protobuf:"varint,16,opt,name=hierarchical_memory_limit,json=hierarchicalMemoryLimit,proto3" json:"hierarchical_memory_limit,omitempty"` +	HierarchicalSwapLimit   uint64       `protobuf:"varint,17,opt,name=hierarchical_swap_limit,json=hierarchicalSwapLimit,proto3" json:"hierarchical_swap_limit,omitempty"` +	TotalCache              uint64       `protobuf:"varint,18,opt,name=total_cache,json=totalCache,proto3" json:"total_cache,omitempty"` +	TotalRSS                uint64       `protobuf:"varint,19,opt,name=total_rss,json=totalRss,proto3" json:"total_rss,omitempty"` +	TotalRSSHuge            uint64       `protobuf:"varint,20,opt,name=total_rss_huge,json=totalRssHuge,proto3" json:"total_rss_huge,omitempty"` +	TotalMappedFile         uint64       `protobuf:"varint,21,opt,name=total_mapped_file,json=totalMappedFile,proto3" json:"total_mapped_file,omitempty"` +	TotalDirty              uint64       `protobuf:"varint,22,opt,name=total_dirty,json=totalDirty,proto3" json:"total_dirty,omitempty"` +	TotalWriteback          uint64       `protobuf:"varint,23,opt,name=total_writeback,json=totalWriteback,proto3" json:"total_writeback,omitempty"` +	TotalPgPgIn             uint64       `protobuf:"varint,24,opt,name=total_pg_pg_in,json=totalPgPgIn,proto3" json:"total_pg_pg_in,omitempty"` +	TotalPgPgOut            uint64       `protobuf:"varint,25,opt,name=total_pg_pg_out,json=totalPgPgOut,proto3" json:"total_pg_pg_out,omitempty"` +	TotalPgFault            uint64       `protobuf:"varint,26,opt,name=total_pg_fault,json=totalPgFault,proto3" json:"total_pg_fault,omitempty"` +	TotalPgMajFault         uint64       `protobuf:"varint,27,opt,name=total_pg_maj_fault,json=totalPgMajFault,proto3" json:"total_pg_maj_fault,omitempty"` +	TotalInactiveAnon       uint64       `protobuf:"varint,28,opt,name=total_inactive_anon,json=totalInactiveAnon,proto3" json:"total_inactive_anon,omitempty"` +	TotalActiveAnon         uint64       `protobuf:"varint,29,opt,name=total_active_anon,json=totalActiveAnon,proto3" json:"total_active_anon,omitempty"` +	TotalInactiveFile       uint64       `protobuf:"varint,30,opt,name=total_inactive_file,json=totalInactiveFile,proto3" json:"total_inactive_file,omitempty"` +	TotalActiveFile         uint64       `protobuf:"varint,31,opt,name=total_active_file,json=totalActiveFile,proto3" json:"total_active_file,omitempty"` +	TotalUnevictable        uint64       `protobuf:"varint,32,opt,name=total_unevictable,json=totalUnevictable,proto3" json:"total_unevictable,omitempty"` +	Usage                   *MemoryEntry `protobuf:"bytes,33,opt,name=usage,proto3" json:"usage,omitempty"` +	Swap                    *MemoryEntry `protobuf:"bytes,34,opt,name=swap,proto3" json:"swap,omitempty"` +	Kernel                  *MemoryEntry `protobuf:"bytes,35,opt,name=kernel,proto3" json:"kernel,omitempty"` +	KernelTCP               *MemoryEntry `protobuf:"bytes,36,opt,name=kernel_tcp,json=kernelTcp,proto3" json:"kernel_tcp,omitempty"` +	XXX_NoUnkeyedLiteral    struct{}     `json:"-"` +	XXX_unrecognized        []byte       `json:"-"` +	XXX_sizecache           int32        `json:"-"` +} + +func (m *MemoryStat) Reset()      { *m = MemoryStat{} } +func (*MemoryStat) ProtoMessage() {} +func (*MemoryStat) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{6} +} +func (m *MemoryStat) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *MemoryStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_MemoryStat.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *MemoryStat) XXX_Merge(src proto.Message) { +	xxx_messageInfo_MemoryStat.Merge(m, src) +} +func (m *MemoryStat) XXX_Size() int { +	return m.Size() +} +func (m *MemoryStat) XXX_DiscardUnknown() { +	xxx_messageInfo_MemoryStat.DiscardUnknown(m) +} + +var xxx_messageInfo_MemoryStat proto.InternalMessageInfo + +type MemoryEntry struct { +	Limit                uint64   `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"` +	Usage                uint64   `protobuf:"varint,2,opt,name=usage,proto3" json:"usage,omitempty"` +	Max                  uint64   `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty"` +	Failcnt              uint64   `protobuf:"varint,4,opt,name=failcnt,proto3" json:"failcnt,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *MemoryEntry) Reset()      { *m = MemoryEntry{} } +func (*MemoryEntry) ProtoMessage() {} +func (*MemoryEntry) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{7} +} +func (m *MemoryEntry) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *MemoryEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_MemoryEntry.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *MemoryEntry) XXX_Merge(src proto.Message) { +	xxx_messageInfo_MemoryEntry.Merge(m, src) +} +func (m *MemoryEntry) XXX_Size() int { +	return m.Size() +} +func (m *MemoryEntry) XXX_DiscardUnknown() { +	xxx_messageInfo_MemoryEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_MemoryEntry proto.InternalMessageInfo + +type MemoryOomControl struct { +	OomKillDisable       uint64   `protobuf:"varint,1,opt,name=oom_kill_disable,json=oomKillDisable,proto3" json:"oom_kill_disable,omitempty"` +	UnderOom             uint64   `protobuf:"varint,2,opt,name=under_oom,json=underOom,proto3" json:"under_oom,omitempty"` +	OomKill              uint64   `protobuf:"varint,3,opt,name=oom_kill,json=oomKill,proto3" json:"oom_kill,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *MemoryOomControl) Reset()      { *m = MemoryOomControl{} } +func (*MemoryOomControl) ProtoMessage() {} +func (*MemoryOomControl) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{8} +} +func (m *MemoryOomControl) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *MemoryOomControl) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_MemoryOomControl.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *MemoryOomControl) XXX_Merge(src proto.Message) { +	xxx_messageInfo_MemoryOomControl.Merge(m, src) +} +func (m *MemoryOomControl) XXX_Size() int { +	return m.Size() +} +func (m *MemoryOomControl) XXX_DiscardUnknown() { +	xxx_messageInfo_MemoryOomControl.DiscardUnknown(m) +} + +var xxx_messageInfo_MemoryOomControl proto.InternalMessageInfo + +type BlkIOStat struct { +	IoServiceBytesRecursive []*BlkIOEntry `protobuf:"bytes,1,rep,name=io_service_bytes_recursive,json=ioServiceBytesRecursive,proto3" json:"io_service_bytes_recursive,omitempty"` +	IoServicedRecursive     []*BlkIOEntry `protobuf:"bytes,2,rep,name=io_serviced_recursive,json=ioServicedRecursive,proto3" json:"io_serviced_recursive,omitempty"` +	IoQueuedRecursive       []*BlkIOEntry `protobuf:"bytes,3,rep,name=io_queued_recursive,json=ioQueuedRecursive,proto3" json:"io_queued_recursive,omitempty"` +	IoServiceTimeRecursive  []*BlkIOEntry `protobuf:"bytes,4,rep,name=io_service_time_recursive,json=ioServiceTimeRecursive,proto3" json:"io_service_time_recursive,omitempty"` +	IoWaitTimeRecursive     []*BlkIOEntry `protobuf:"bytes,5,rep,name=io_wait_time_recursive,json=ioWaitTimeRecursive,proto3" json:"io_wait_time_recursive,omitempty"` +	IoMergedRecursive       []*BlkIOEntry `protobuf:"bytes,6,rep,name=io_merged_recursive,json=ioMergedRecursive,proto3" json:"io_merged_recursive,omitempty"` +	IoTimeRecursive         []*BlkIOEntry `protobuf:"bytes,7,rep,name=io_time_recursive,json=ioTimeRecursive,proto3" json:"io_time_recursive,omitempty"` +	SectorsRecursive        []*BlkIOEntry `protobuf:"bytes,8,rep,name=sectors_recursive,json=sectorsRecursive,proto3" json:"sectors_recursive,omitempty"` +	XXX_NoUnkeyedLiteral    struct{}      `json:"-"` +	XXX_unrecognized        []byte        `json:"-"` +	XXX_sizecache           int32         `json:"-"` +} + +func (m *BlkIOStat) Reset()      { *m = BlkIOStat{} } +func (*BlkIOStat) ProtoMessage() {} +func (*BlkIOStat) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{9} +} +func (m *BlkIOStat) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *BlkIOStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_BlkIOStat.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *BlkIOStat) XXX_Merge(src proto.Message) { +	xxx_messageInfo_BlkIOStat.Merge(m, src) +} +func (m *BlkIOStat) XXX_Size() int { +	return m.Size() +} +func (m *BlkIOStat) XXX_DiscardUnknown() { +	xxx_messageInfo_BlkIOStat.DiscardUnknown(m) +} + +var xxx_messageInfo_BlkIOStat proto.InternalMessageInfo + +type BlkIOEntry struct { +	Op                   string   `protobuf:"bytes,1,opt,name=op,proto3" json:"op,omitempty"` +	Device               string   `protobuf:"bytes,2,opt,name=device,proto3" json:"device,omitempty"` +	Major                uint64   `protobuf:"varint,3,opt,name=major,proto3" json:"major,omitempty"` +	Minor                uint64   `protobuf:"varint,4,opt,name=minor,proto3" json:"minor,omitempty"` +	Value                uint64   `protobuf:"varint,5,opt,name=value,proto3" json:"value,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *BlkIOEntry) Reset()      { *m = BlkIOEntry{} } +func (*BlkIOEntry) ProtoMessage() {} +func (*BlkIOEntry) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{10} +} +func (m *BlkIOEntry) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *BlkIOEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_BlkIOEntry.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *BlkIOEntry) XXX_Merge(src proto.Message) { +	xxx_messageInfo_BlkIOEntry.Merge(m, src) +} +func (m *BlkIOEntry) XXX_Size() int { +	return m.Size() +} +func (m *BlkIOEntry) XXX_DiscardUnknown() { +	xxx_messageInfo_BlkIOEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_BlkIOEntry proto.InternalMessageInfo + +type RdmaStat struct { +	Current              []*RdmaEntry `protobuf:"bytes,1,rep,name=current,proto3" json:"current,omitempty"` +	Limit                []*RdmaEntry `protobuf:"bytes,2,rep,name=limit,proto3" json:"limit,omitempty"` +	XXX_NoUnkeyedLiteral struct{}     `json:"-"` +	XXX_unrecognized     []byte       `json:"-"` +	XXX_sizecache        int32        `json:"-"` +} + +func (m *RdmaStat) Reset()      { *m = RdmaStat{} } +func (*RdmaStat) ProtoMessage() {} +func (*RdmaStat) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{11} +} +func (m *RdmaStat) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *RdmaStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_RdmaStat.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *RdmaStat) XXX_Merge(src proto.Message) { +	xxx_messageInfo_RdmaStat.Merge(m, src) +} +func (m *RdmaStat) XXX_Size() int { +	return m.Size() +} +func (m *RdmaStat) XXX_DiscardUnknown() { +	xxx_messageInfo_RdmaStat.DiscardUnknown(m) +} + +var xxx_messageInfo_RdmaStat proto.InternalMessageInfo + +type RdmaEntry struct { +	Device               string   `protobuf:"bytes,1,opt,name=device,proto3" json:"device,omitempty"` +	HcaHandles           uint32   `protobuf:"varint,2,opt,name=hca_handles,json=hcaHandles,proto3" json:"hca_handles,omitempty"` +	HcaObjects           uint32   `protobuf:"varint,3,opt,name=hca_objects,json=hcaObjects,proto3" json:"hca_objects,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *RdmaEntry) Reset()      { *m = RdmaEntry{} } +func (*RdmaEntry) ProtoMessage() {} +func (*RdmaEntry) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{12} +} +func (m *RdmaEntry) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *RdmaEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_RdmaEntry.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *RdmaEntry) XXX_Merge(src proto.Message) { +	xxx_messageInfo_RdmaEntry.Merge(m, src) +} +func (m *RdmaEntry) XXX_Size() int { +	return m.Size() +} +func (m *RdmaEntry) XXX_DiscardUnknown() { +	xxx_messageInfo_RdmaEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_RdmaEntry proto.InternalMessageInfo + +type NetworkStat struct { +	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +	RxBytes              uint64   `protobuf:"varint,2,opt,name=rx_bytes,json=rxBytes,proto3" json:"rx_bytes,omitempty"` +	RxPackets            uint64   `protobuf:"varint,3,opt,name=rx_packets,json=rxPackets,proto3" json:"rx_packets,omitempty"` +	RxErrors             uint64   `protobuf:"varint,4,opt,name=rx_errors,json=rxErrors,proto3" json:"rx_errors,omitempty"` +	RxDropped            uint64   `protobuf:"varint,5,opt,name=rx_dropped,json=rxDropped,proto3" json:"rx_dropped,omitempty"` +	TxBytes              uint64   `protobuf:"varint,6,opt,name=tx_bytes,json=txBytes,proto3" json:"tx_bytes,omitempty"` +	TxPackets            uint64   `protobuf:"varint,7,opt,name=tx_packets,json=txPackets,proto3" json:"tx_packets,omitempty"` +	TxErrors             uint64   `protobuf:"varint,8,opt,name=tx_errors,json=txErrors,proto3" json:"tx_errors,omitempty"` +	TxDropped            uint64   `protobuf:"varint,9,opt,name=tx_dropped,json=txDropped,proto3" json:"tx_dropped,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *NetworkStat) Reset()      { *m = NetworkStat{} } +func (*NetworkStat) ProtoMessage() {} +func (*NetworkStat) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{13} +} +func (m *NetworkStat) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *NetworkStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_NetworkStat.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *NetworkStat) XXX_Merge(src proto.Message) { +	xxx_messageInfo_NetworkStat.Merge(m, src) +} +func (m *NetworkStat) XXX_Size() int { +	return m.Size() +} +func (m *NetworkStat) XXX_DiscardUnknown() { +	xxx_messageInfo_NetworkStat.DiscardUnknown(m) +} + +var xxx_messageInfo_NetworkStat proto.InternalMessageInfo + +// CgroupStats exports per-cgroup statistics. +type CgroupStats struct { +	// number of tasks sleeping +	NrSleeping uint64 `protobuf:"varint,1,opt,name=nr_sleeping,json=nrSleeping,proto3" json:"nr_sleeping,omitempty"` +	// number of tasks running +	NrRunning uint64 `protobuf:"varint,2,opt,name=nr_running,json=nrRunning,proto3" json:"nr_running,omitempty"` +	// number of tasks in stopped state +	NrStopped uint64 `protobuf:"varint,3,opt,name=nr_stopped,json=nrStopped,proto3" json:"nr_stopped,omitempty"` +	// number of tasks in uninterruptible state +	NrUninterruptible uint64 `protobuf:"varint,4,opt,name=nr_uninterruptible,json=nrUninterruptible,proto3" json:"nr_uninterruptible,omitempty"` +	// number of tasks waiting on IO +	NrIoWait             uint64   `protobuf:"varint,5,opt,name=nr_io_wait,json=nrIoWait,proto3" json:"nr_io_wait,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *CgroupStats) Reset()      { *m = CgroupStats{} } +func (*CgroupStats) ProtoMessage() {} +func (*CgroupStats) Descriptor() ([]byte, []int) { +	return fileDescriptor_a17b2d87c332bfaa, []int{14} +} +func (m *CgroupStats) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *CgroupStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_CgroupStats.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *CgroupStats) XXX_Merge(src proto.Message) { +	xxx_messageInfo_CgroupStats.Merge(m, src) +} +func (m *CgroupStats) XXX_Size() int { +	return m.Size() +} +func (m *CgroupStats) XXX_DiscardUnknown() { +	xxx_messageInfo_CgroupStats.DiscardUnknown(m) +} + +var xxx_messageInfo_CgroupStats proto.InternalMessageInfo + +func init() { +	proto.RegisterType((*Metrics)(nil), "io.containerd.cgroups.v1.Metrics") +	proto.RegisterType((*HugetlbStat)(nil), "io.containerd.cgroups.v1.HugetlbStat") +	proto.RegisterType((*PidsStat)(nil), "io.containerd.cgroups.v1.PidsStat") +	proto.RegisterType((*CPUStat)(nil), "io.containerd.cgroups.v1.CPUStat") +	proto.RegisterType((*CPUUsage)(nil), "io.containerd.cgroups.v1.CPUUsage") +	proto.RegisterType((*Throttle)(nil), "io.containerd.cgroups.v1.Throttle") +	proto.RegisterType((*MemoryStat)(nil), "io.containerd.cgroups.v1.MemoryStat") +	proto.RegisterType((*MemoryEntry)(nil), "io.containerd.cgroups.v1.MemoryEntry") +	proto.RegisterType((*MemoryOomControl)(nil), "io.containerd.cgroups.v1.MemoryOomControl") +	proto.RegisterType((*BlkIOStat)(nil), "io.containerd.cgroups.v1.BlkIOStat") +	proto.RegisterType((*BlkIOEntry)(nil), "io.containerd.cgroups.v1.BlkIOEntry") +	proto.RegisterType((*RdmaStat)(nil), "io.containerd.cgroups.v1.RdmaStat") +	proto.RegisterType((*RdmaEntry)(nil), "io.containerd.cgroups.v1.RdmaEntry") +	proto.RegisterType((*NetworkStat)(nil), "io.containerd.cgroups.v1.NetworkStat") +	proto.RegisterType((*CgroupStats)(nil), "io.containerd.cgroups.v1.CgroupStats") +} + +func init() { +	proto.RegisterFile("github.com/containerd/cgroups/stats/v1/metrics.proto", fileDescriptor_a17b2d87c332bfaa) +} + +var fileDescriptor_a17b2d87c332bfaa = []byte{ +	// 1749 bytes of a gzipped FileDescriptorProto +	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x58, 0xcd, 0x72, 0xe3, 0xc6, +	0x11, 0x36, 0x45, 0x48, 0x24, 0x9a, 0x92, 0x56, 0x9a, 0xfd, 0x83, 0xe4, 0xb5, 0x28, 0x53, 0xbb, +	0x89, 0xe2, 0xad, 0x48, 0x65, 0x27, 0xb5, 0x95, 0x75, 0xec, 0x4a, 0x59, 0x5a, 0xbb, 0x76, 0xcb, +	0x51, 0x44, 0x83, 0x52, 0xd9, 0x39, 0xa1, 0x40, 0x70, 0x16, 0x9c, 0x15, 0x80, 0x81, 0x07, 0x03, +	0x89, 0xca, 0x29, 0x87, 0x54, 0xe5, 0x94, 0x07, 0xca, 0x1b, 0xf8, 0x98, 0x4b, 0x52, 0xc9, 0x45, +	0x15, 0xf3, 0x49, 0x52, 0x33, 0x3d, 0xf8, 0xa1, 0xbc, 0x5a, 0x85, 0x37, 0x76, 0xcf, 0xd7, 0x5f, +	0xf7, 0x34, 0xbe, 0x19, 0x34, 0x08, 0xbf, 0x0e, 0x99, 0x1c, 0xe7, 0xc3, 0xbd, 0x80, 0xc7, 0xfb, +	0x01, 0x4f, 0xa4, 0xcf, 0x12, 0x2a, 0x46, 0xfb, 0x41, 0x28, 0x78, 0x9e, 0x66, 0xfb, 0x99, 0xf4, +	0x65, 0xb6, 0x7f, 0xfe, 0xf1, 0x7e, 0x4c, 0xa5, 0x60, 0x41, 0xb6, 0x97, 0x0a, 0x2e, 0x39, 0x71, +	0x18, 0xdf, 0xab, 0xd0, 0x7b, 0x06, 0xbd, 0x77, 0xfe, 0xf1, 0xe6, 0xbd, 0x90, 0x87, 0x5c, 0x83, +	0xf6, 0xd5, 0x2f, 0xc4, 0xf7, 0xfe, 0x65, 0x41, 0xeb, 0x08, 0x19, 0xc8, 0xef, 0xa0, 0x35, 0xce, +	0x43, 0x2a, 0xa3, 0xa1, 0xd3, 0xd8, 0x6e, 0xee, 0x76, 0x3e, 0x79, 0xb2, 0x77, 0x13, 0xdb, 0xde, +	0x4b, 0x04, 0x0e, 0xa4, 0x2f, 0xdd, 0x22, 0x8a, 0x3c, 0x03, 0x2b, 0x65, 0xa3, 0xcc, 0x59, 0xd8, +	0x6e, 0xec, 0x76, 0x3e, 0xe9, 0xdd, 0x1c, 0xdd, 0x67, 0xa3, 0x4c, 0x87, 0x6a, 0x3c, 0xf9, 0x0c, +	0x9a, 0x41, 0x9a, 0x3b, 0x4d, 0x1d, 0xf6, 0xe1, 0xcd, 0x61, 0x87, 0xfd, 0x53, 0x15, 0x75, 0xd0, +	0x9a, 0x5e, 0x75, 0x9b, 0x87, 0xfd, 0x53, 0x57, 0x85, 0x91, 0xcf, 0x60, 0x29, 0xa6, 0x31, 0x17, +	0x97, 0x8e, 0xa5, 0x09, 0x1e, 0xdf, 0x4c, 0x70, 0xa4, 0x71, 0x3a, 0xb3, 0x89, 0x21, 0xcf, 0x61, +	0x71, 0x18, 0x9d, 0x31, 0xee, 0x2c, 0xea, 0xe0, 0x9d, 0x9b, 0x83, 0x0f, 0xa2, 0xb3, 0x57, 0xc7, +	0x3a, 0x16, 0x23, 0xd4, 0x76, 0xc5, 0x28, 0xf6, 0x9d, 0xa5, 0xdb, 0xb6, 0xeb, 0x8e, 0x62, 0x1f, +	0xb7, 0xab, 0xf0, 0xaa, 0xcf, 0x09, 0x95, 0x17, 0x5c, 0x9c, 0x39, 0xad, 0xdb, 0xfa, 0xfc, 0x07, +	0x04, 0x62, 0x9f, 0x4d, 0x14, 0x79, 0x09, 0xcb, 0x08, 0xf1, 0xb4, 0x0a, 0x9c, 0xb6, 0x2e, 0xe0, +	0x1d, 0x2c, 0x87, 0xfa, 0xa7, 0x22, 0xc9, 0xdc, 0x4e, 0x50, 0x19, 0xe4, 0x3b, 0x20, 0xd8, 0x07, +	0x8f, 0xf3, 0xd8, 0x53, 0xc1, 0x82, 0x47, 0x8e, 0xad, 0xf9, 0x3e, 0xba, 0xad, 0x8f, 0xc7, 0x3c, +	0x3e, 0xc4, 0x08, 0x77, 0x2d, 0xbe, 0xe6, 0xe9, 0x9d, 0x41, 0xa7, 0xa6, 0x11, 0x72, 0x0f, 0x16, +	0xf3, 0xcc, 0x0f, 0xa9, 0xd3, 0xd8, 0x6e, 0xec, 0x5a, 0x2e, 0x1a, 0x64, 0x0d, 0x9a, 0xb1, 0x3f, +	0xd1, 0x7a, 0xb1, 0x5c, 0xf5, 0x93, 0x38, 0xd0, 0x7a, 0xed, 0xb3, 0x28, 0x48, 0xa4, 0x96, 0x83, +	0xe5, 0x16, 0x26, 0xd9, 0x84, 0x76, 0xea, 0x87, 0x34, 0x63, 0x7f, 0xa2, 0xfa, 0x41, 0xdb, 0x6e, +	0x69, 0xf7, 0x3e, 0x85, 0x76, 0x21, 0x29, 0xc5, 0x10, 0xe4, 0x42, 0xd0, 0x44, 0x9a, 0x5c, 0x85, +	0xa9, 0x6a, 0x88, 0x58, 0xcc, 0xa4, 0xc9, 0x87, 0x46, 0xef, 0xaf, 0x0d, 0x68, 0x19, 0x61, 0x91, +	0xdf, 0xd4, 0xab, 0x7c, 0xe7, 0x23, 0x3d, 0xec, 0x9f, 0x9e, 0x2a, 0x64, 0xb1, 0x93, 0x03, 0x00, +	0x39, 0x16, 0x5c, 0xca, 0x88, 0x25, 0xe1, 0xed, 0x07, 0xe0, 0x04, 0xb1, 0xd4, 0xad, 0x45, 0xf5, +	0xbe, 0x87, 0x76, 0x41, 0xab, 0x6a, 0x95, 0x5c, 0xfa, 0x51, 0xd1, 0x2f, 0x6d, 0x90, 0x07, 0xb0, +	0x74, 0x46, 0x45, 0x42, 0x23, 0xb3, 0x05, 0x63, 0x11, 0x02, 0x56, 0x9e, 0x51, 0x61, 0x5a, 0xa6, +	0x7f, 0x93, 0x1d, 0x68, 0xa5, 0x54, 0x78, 0xea, 0x60, 0x59, 0xdb, 0xcd, 0x5d, 0xeb, 0x00, 0xa6, +	0x57, 0xdd, 0xa5, 0x3e, 0x15, 0xea, 0xe0, 0x2c, 0xa5, 0x54, 0x1c, 0xa6, 0x79, 0x6f, 0x02, 0xed, +	0xa2, 0x14, 0xd5, 0xb8, 0x94, 0x0a, 0xc6, 0x47, 0x59, 0xd1, 0x38, 0x63, 0x92, 0xa7, 0xb0, 0x6e, +	0xca, 0xa4, 0x23, 0xaf, 0xc0, 0x60, 0x05, 0x6b, 0xe5, 0x42, 0xdf, 0x80, 0x9f, 0xc0, 0x6a, 0x05, +	0x96, 0x2c, 0xa6, 0xa6, 0xaa, 0x95, 0xd2, 0x7b, 0xc2, 0x62, 0xda, 0xfb, 0x4f, 0x07, 0xa0, 0x3a, +	0x8e, 0x6a, 0xbf, 0x81, 0x1f, 0x8c, 0x4b, 0x7d, 0x68, 0x83, 0x6c, 0x40, 0x53, 0x64, 0x26, 0x15, +	0x9e, 0x7a, 0x77, 0x30, 0x70, 0x95, 0x8f, 0xfc, 0x0c, 0xda, 0x22, 0xcb, 0x3c, 0x75, 0xf5, 0x60, +	0x82, 0x83, 0xce, 0xf4, 0xaa, 0xdb, 0x72, 0x07, 0x03, 0x25, 0x3b, 0xb7, 0x25, 0xb2, 0x4c, 0xfd, +	0x20, 0x5d, 0xe8, 0xc4, 0x7e, 0x9a, 0xd2, 0x91, 0xf7, 0x9a, 0x45, 0xa8, 0x1c, 0xcb, 0x05, 0x74, +	0x7d, 0xc5, 0x22, 0xdd, 0xe9, 0x11, 0x13, 0xf2, 0x52, 0x5f, 0x00, 0x96, 0x8b, 0x06, 0x79, 0x04, +	0xf6, 0x85, 0x60, 0x92, 0x0e, 0xfd, 0xe0, 0x4c, 0x1f, 0x70, 0xcb, 0xad, 0x1c, 0xc4, 0x81, 0x76, +	0x1a, 0x7a, 0x69, 0xe8, 0xb1, 0xc4, 0x69, 0xe1, 0x93, 0x48, 0xc3, 0x7e, 0xf8, 0x2a, 0x21, 0x9b, +	0x60, 0xe3, 0x0a, 0xcf, 0xa5, 0x3e, 0x97, 0xaa, 0x8d, 0x61, 0x3f, 0x3c, 0xce, 0x25, 0xd9, 0xd0, +	0x51, 0xaf, 0xfd, 0x3c, 0x92, 0xfa, 0x88, 0xe9, 0xa5, 0xaf, 0x94, 0x49, 0xb6, 0x61, 0x39, 0x0d, +	0xbd, 0xd8, 0x7f, 0x63, 0x96, 0x01, 0xcb, 0x4c, 0xc3, 0x23, 0xff, 0x0d, 0x22, 0x76, 0x60, 0x85, +	0x25, 0x7e, 0x20, 0xd9, 0x39, 0xf5, 0xfc, 0x84, 0x27, 0x4e, 0x47, 0x43, 0x96, 0x0b, 0xe7, 0x17, +	0x09, 0x4f, 0xd4, 0x66, 0xeb, 0x90, 0x65, 0x64, 0xa9, 0x01, 0xea, 0x2c, 0xba, 0x1f, 0x2b, 0xb3, +	0x2c, 0xba, 0x23, 0x15, 0x8b, 0x86, 0xac, 0xd6, 0x59, 0x34, 0x60, 0x1b, 0x3a, 0x79, 0x42, 0xcf, +	0x59, 0x20, 0xfd, 0x61, 0x44, 0x9d, 0x3b, 0x1a, 0x50, 0x77, 0x91, 0x4f, 0x61, 0x63, 0xcc, 0xa8, +	0xf0, 0x45, 0x30, 0x66, 0x81, 0x1f, 0x79, 0xe6, 0x92, 0xc1, 0xe3, 0xb7, 0xa6, 0xf1, 0x0f, 0xeb, +	0x00, 0x54, 0xc2, 0xef, 0xd5, 0x32, 0x79, 0x06, 0x33, 0x4b, 0x5e, 0x76, 0xe1, 0xa7, 0x26, 0x72, +	0x5d, 0x47, 0xde, 0xaf, 0x2f, 0x0f, 0x2e, 0xfc, 0x14, 0xe3, 0xba, 0xd0, 0xd1, 0xa7, 0xc4, 0x43, +	0x21, 0x11, 0x2c, 0x5b, 0xbb, 0x0e, 0xb5, 0x9a, 0x7e, 0x01, 0x36, 0x02, 0x94, 0xa6, 0xee, 0x6a, +	0xcd, 0x2c, 0x4f, 0xaf, 0xba, 0xed, 0x13, 0xe5, 0x54, 0xc2, 0x6a, 0xeb, 0x65, 0x37, 0xcb, 0xc8, +	0x33, 0x58, 0x2d, 0xa1, 0xa8, 0xb1, 0x7b, 0x1a, 0xbf, 0x36, 0xbd, 0xea, 0x2e, 0x17, 0x78, 0x2d, +	0xb4, 0xe5, 0x22, 0x46, 0xab, 0xed, 0x23, 0x58, 0xc7, 0xb8, 0xba, 0xe6, 0xee, 0xeb, 0x4a, 0xee, +	0xe8, 0x85, 0xa3, 0x4a, 0x78, 0x65, 0xbd, 0x28, 0xbf, 0x07, 0xb5, 0x7a, 0x5f, 0x68, 0x0d, 0xfe, +	0x1c, 0x30, 0xc6, 0xab, 0x94, 0xf8, 0x50, 0x83, 0xb0, 0xb6, 0x6f, 0x4b, 0x39, 0xee, 0x14, 0xd5, +	0x96, 0xa2, 0x74, 0xf0, 0x91, 0x68, 0x6f, 0x1f, 0x95, 0xf9, 0xa4, 0x60, 0xab, 0xf4, 0xb9, 0x81, +	0x0f, 0xbf, 0x44, 0x29, 0x91, 0x3e, 0xae, 0x71, 0xa1, 0x16, 0x37, 0x67, 0x50, 0xa8, 0xc6, 0xa7, +	0x40, 0x4a, 0x54, 0xa5, 0xda, 0xf7, 0x6b, 0x1b, 0xed, 0x57, 0xd2, 0xdd, 0x83, 0xbb, 0x08, 0x9e, +	0x15, 0xf0, 0x23, 0x8d, 0xc6, 0x7e, 0xbd, 0xaa, 0xab, 0xb8, 0x6c, 0x62, 0x1d, 0xfd, 0x41, 0x8d, +	0xfb, 0x8b, 0x0a, 0xfb, 0x53, 0x6e, 0xdd, 0xf2, 0xad, 0xb7, 0x70, 0xeb, 0xa6, 0x5f, 0xe7, 0xd6, +	0xe8, 0xee, 0x4f, 0xb8, 0x35, 0xf6, 0x69, 0x81, 0xad, 0x8b, 0x7d, 0xdb, 0x5c, 0x7b, 0x6a, 0xe1, +	0xb4, 0xa6, 0xf8, 0xdf, 0x16, 0xaf, 0x8e, 0x0f, 0x6f, 0x7b, 0x19, 0xa3, 0xd6, 0xbf, 0x4c, 0xa4, +	0xb8, 0x2c, 0xde, 0x1e, 0xcf, 0xc1, 0x52, 0x2a, 0x77, 0x7a, 0xf3, 0xc4, 0xea, 0x10, 0xf2, 0x79, +	0xf9, 0x4a, 0xd8, 0x99, 0x27, 0xb8, 0x78, 0x73, 0x0c, 0x00, 0xf0, 0x97, 0x27, 0x83, 0xd4, 0x79, +	0x3c, 0x07, 0xc5, 0xc1, 0xca, 0xf4, 0xaa, 0x6b, 0x7f, 0xad, 0x83, 0x4f, 0x0e, 0xfb, 0xae, 0x8d, +	0x3c, 0x27, 0x41, 0xda, 0xa3, 0xd0, 0xa9, 0x01, 0xab, 0xf7, 0x6e, 0xa3, 0xf6, 0xde, 0xad, 0x26, +	0x82, 0x85, 0xb7, 0x4c, 0x04, 0xcd, 0xb7, 0x4e, 0x04, 0xd6, 0xcc, 0x44, 0xd0, 0x93, 0xb0, 0x76, +	0x7d, 0x10, 0x21, 0xbb, 0xb0, 0xa6, 0x26, 0x99, 0x33, 0x16, 0xa9, 0x73, 0x95, 0xe9, 0x47, 0x86, +	0x69, 0x57, 0x39, 0x8f, 0xbf, 0x66, 0x51, 0xf4, 0x02, 0xbd, 0xe4, 0x7d, 0xb0, 0xf3, 0x64, 0x44, +	0x85, 0x9a, 0x7c, 0x4c, 0x0d, 0x6d, 0xed, 0x38, 0xe6, 0xb1, 0xba, 0xaa, 0x0b, 0x9a, 0x62, 0x0e, +	0x31, 0xe1, 0xbd, 0x7f, 0x2e, 0x82, 0x5d, 0x8e, 0x82, 0xc4, 0x87, 0x4d, 0xc6, 0xbd, 0x8c, 0x8a, +	0x73, 0x16, 0x50, 0x6f, 0x78, 0x29, 0x69, 0xe6, 0x09, 0x1a, 0xe4, 0x22, 0x63, 0xe7, 0xd4, 0x8c, +	0xd1, 0x8f, 0x6f, 0x99, 0x29, 0xf1, 0x89, 0x3c, 0x64, 0x7c, 0x80, 0x34, 0x07, 0x8a, 0xc5, 0x2d, +	0x48, 0xc8, 0x77, 0x70, 0xbf, 0x4a, 0x31, 0xaa, 0xb1, 0x2f, 0xcc, 0xc1, 0x7e, 0xb7, 0x64, 0x1f, +	0x55, 0xcc, 0x27, 0x70, 0x97, 0x71, 0xef, 0xfb, 0x9c, 0xe6, 0x33, 0xbc, 0xcd, 0x39, 0x78, 0xd7, +	0x19, 0xff, 0x46, 0xc7, 0x57, 0xac, 0x1e, 0x6c, 0xd4, 0x5a, 0xa2, 0x26, 0x80, 0x1a, 0xb7, 0x35, +	0x07, 0xf7, 0x83, 0xb2, 0x66, 0x35, 0x31, 0x54, 0x09, 0xfe, 0x08, 0x0f, 0x18, 0xf7, 0x2e, 0x7c, +	0x26, 0xaf, 0xb3, 0x2f, 0xce, 0xd7, 0x91, 0x6f, 0x7d, 0x26, 0x67, 0xa9, 0xb1, 0x23, 0x31, 0x15, +	0xe1, 0x4c, 0x47, 0x96, 0xe6, 0xeb, 0xc8, 0x91, 0x8e, 0xaf, 0x58, 0xfb, 0xb0, 0xce, 0xf8, 0xf5, +	0x5a, 0x5b, 0x73, 0x70, 0xde, 0x61, 0x7c, 0xb6, 0xce, 0x6f, 0x60, 0x3d, 0xa3, 0x81, 0xe4, 0xa2, +	0xae, 0xb6, 0xf6, 0x1c, 0x8c, 0x6b, 0x26, 0xbc, 0xa4, 0xec, 0x9d, 0x03, 0x54, 0xeb, 0x64, 0x15, +	0x16, 0x78, 0xaa, 0x4f, 0x8e, 0xed, 0x2e, 0xf0, 0x54, 0x4d, 0x9e, 0x23, 0x75, 0xd9, 0xe1, 0x71, +	0xb5, 0x5d, 0x63, 0xa9, 0x53, 0x1c, 0xfb, 0x6f, 0x78, 0x31, 0x7a, 0xa2, 0xa1, 0xbd, 0x2c, 0xe1, +	0xc2, 0x9c, 0x58, 0x34, 0x94, 0xf7, 0xdc, 0x8f, 0x72, 0x5a, 0x4c, 0x5a, 0xda, 0xe8, 0xfd, 0xa5, +	0x01, 0xed, 0xe2, 0x03, 0x89, 0x7c, 0x5e, 0x1f, 0xde, 0x9b, 0xef, 0xfe, 0x1e, 0x53, 0x41, 0xb8, +	0x99, 0x72, 0xc2, 0x7f, 0x5e, 0x4d, 0xf8, 0xff, 0x77, 0xb0, 0xf9, 0x0c, 0xa0, 0x60, 0x97, 0xbe, +	0xda, 0x6e, 0x1b, 0x33, 0xbb, 0xed, 0x42, 0x67, 0x1c, 0xf8, 0xde, 0xd8, 0x4f, 0x46, 0x11, 0xc5, +	0xb9, 0x74, 0xc5, 0x85, 0x71, 0xe0, 0xbf, 0x44, 0x4f, 0x01, 0xe0, 0xc3, 0x37, 0x34, 0x90, 0x99, +	0x6e, 0x0a, 0x02, 0x8e, 0xd1, 0xd3, 0xfb, 0xdb, 0x02, 0x74, 0x6a, 0xdf, 0x74, 0x6a, 0x72, 0x4f, +	0xfc, 0xb8, 0xc8, 0xa3, 0x7f, 0xab, 0xcb, 0x47, 0x4c, 0xf0, 0x2e, 0x31, 0x17, 0x53, 0x4b, 0x4c, +	0xf4, 0xa5, 0x40, 0x3e, 0x00, 0x10, 0x13, 0x2f, 0xf5, 0x83, 0x33, 0x6a, 0xe8, 0x2d, 0xd7, 0x16, +	0x93, 0x3e, 0x3a, 0xd4, 0x9d, 0x26, 0x26, 0x1e, 0x15, 0x82, 0x8b, 0xcc, 0xf4, 0xbe, 0x2d, 0x26, +	0x5f, 0x6a, 0xdb, 0xc4, 0x8e, 0x04, 0x57, 0x13, 0x88, 0x79, 0x06, 0xb6, 0x98, 0xbc, 0x40, 0x87, +	0xca, 0x2a, 0x8b, 0xac, 0x38, 0xf0, 0xb6, 0x64, 0x95, 0x55, 0x56, 0x59, 0x71, 0xe0, 0xb5, 0x65, +	0x3d, 0xab, 0x2c, 0xb3, 0xe2, 0xcc, 0xdb, 0x96, 0xb5, 0xac, 0xb2, 0xca, 0x6a, 0x17, 0xb1, 0x26, +	0x6b, 0xef, 0xef, 0x0d, 0xe8, 0xd4, 0xbe, 0x4e, 0x55, 0x03, 0x13, 0xe1, 0x65, 0x11, 0xa5, 0xa9, +	0xfa, 0x90, 0xc2, 0xab, 0x1b, 0x12, 0x31, 0x30, 0x1e, 0xc5, 0x97, 0x08, 0x4f, 0xe4, 0x49, 0x52, +	0x7c, 0x68, 0x59, 0xae, 0x9d, 0x08, 0x17, 0x1d, 0x66, 0x39, 0x93, 0x98, 0xae, 0x59, 0x2c, 0x0f, +	0xd0, 0x41, 0x7e, 0x09, 0x24, 0x11, 0x5e, 0x9e, 0xb0, 0x44, 0x52, 0x21, 0xf2, 0x54, 0xb2, 0x61, +	0xf9, 0x51, 0xb0, 0x9e, 0x88, 0xd3, 0xd9, 0x05, 0xf2, 0x48, 0xb3, 0x99, 0xcb, 0xc6, 0xb4, 0xac, +	0x9d, 0x88, 0x57, 0xfa, 0xe6, 0x38, 0x70, 0x7e, 0xf8, 0x71, 0xeb, 0xbd, 0x7f, 0xff, 0xb8, 0xf5, +	0xde, 0x9f, 0xa7, 0x5b, 0x8d, 0x1f, 0xa6, 0x5b, 0x8d, 0x7f, 0x4c, 0xb7, 0x1a, 0xff, 0x9d, 0x6e, +	0x35, 0x86, 0x4b, 0xfa, 0xcf, 0x95, 0x5f, 0xfd, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xc4, 0x4e, 0x24, +	0x22, 0xc4, 0x11, 0x00, 0x00, +} + +func (m *Metrics) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *Metrics) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Metrics) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.MemoryOomControl != nil { +		{ +			size, err := m.MemoryOomControl.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x4a +	} +	if m.CgroupStats != nil { +		{ +			size, err := m.CgroupStats.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x42 +	} +	if len(m.Network) > 0 { +		for iNdEx := len(m.Network) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.Network[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0x3a +		} +	} +	if m.Rdma != nil { +		{ +			size, err := m.Rdma.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x32 +	} +	if m.Blkio != nil { +		{ +			size, err := m.Blkio.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x2a +	} +	if m.Memory != nil { +		{ +			size, err := m.Memory.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x22 +	} +	if m.CPU != nil { +		{ +			size, err := m.CPU.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x1a +	} +	if m.Pids != nil { +		{ +			size, err := m.Pids.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x12 +	} +	if len(m.Hugetlb) > 0 { +		for iNdEx := len(m.Hugetlb) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.Hugetlb[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0xa +		} +	} +	return len(dAtA) - i, nil +} + +func (m *HugetlbStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *HugetlbStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HugetlbStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if len(m.Pagesize) > 0 { +		i -= len(m.Pagesize) +		copy(dAtA[i:], m.Pagesize) +		i = encodeVarintMetrics(dAtA, i, uint64(len(m.Pagesize))) +		i-- +		dAtA[i] = 0x22 +	} +	if m.Failcnt != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Failcnt)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.Max != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Max)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.Usage != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Usage)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func (m *PidsStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *PidsStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PidsStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.Limit != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Limit)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.Current != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Current)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func (m *CPUStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *CPUStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CPUStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.Throttling != nil { +		{ +			size, err := m.Throttling.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x12 +	} +	if m.Usage != nil { +		{ +			size, err := m.Usage.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0xa +	} +	return len(dAtA) - i, nil +} + +func (m *CPUUsage) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *CPUUsage) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CPUUsage) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if len(m.PerCPU) > 0 { +		dAtA11 := make([]byte, len(m.PerCPU)*10) +		var j10 int +		for _, num := range m.PerCPU { +			for num >= 1<<7 { +				dAtA11[j10] = uint8(uint64(num)&0x7f | 0x80) +				num >>= 7 +				j10++ +			} +			dAtA11[j10] = uint8(num) +			j10++ +		} +		i -= j10 +		copy(dAtA[i:], dAtA11[:j10]) +		i = encodeVarintMetrics(dAtA, i, uint64(j10)) +		i-- +		dAtA[i] = 0x22 +	} +	if m.User != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.User)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.Kernel != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Kernel)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.Total != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Total)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func (m *Throttle) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *Throttle) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Throttle) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.ThrottledTime != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.ThrottledTime)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.ThrottledPeriods != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.ThrottledPeriods)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.Periods != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Periods)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func (m *MemoryStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *MemoryStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MemoryStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.KernelTCP != nil { +		{ +			size, err := m.KernelTCP.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x2 +		i-- +		dAtA[i] = 0xa2 +	} +	if m.Kernel != nil { +		{ +			size, err := m.Kernel.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x2 +		i-- +		dAtA[i] = 0x9a +	} +	if m.Swap != nil { +		{ +			size, err := m.Swap.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x2 +		i-- +		dAtA[i] = 0x92 +	} +	if m.Usage != nil { +		{ +			size, err := m.Usage.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x2 +		i-- +		dAtA[i] = 0x8a +	} +	if m.TotalUnevictable != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalUnevictable)) +		i-- +		dAtA[i] = 0x2 +		i-- +		dAtA[i] = 0x80 +	} +	if m.TotalActiveFile != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalActiveFile)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xf8 +	} +	if m.TotalInactiveFile != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalInactiveFile)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xf0 +	} +	if m.TotalActiveAnon != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalActiveAnon)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xe8 +	} +	if m.TotalInactiveAnon != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalInactiveAnon)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xe0 +	} +	if m.TotalPgMajFault != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalPgMajFault)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xd8 +	} +	if m.TotalPgFault != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalPgFault)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xd0 +	} +	if m.TotalPgPgOut != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalPgPgOut)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xc8 +	} +	if m.TotalPgPgIn != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalPgPgIn)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xc0 +	} +	if m.TotalWriteback != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalWriteback)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xb8 +	} +	if m.TotalDirty != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalDirty)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xb0 +	} +	if m.TotalMappedFile != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalMappedFile)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xa8 +	} +	if m.TotalRSSHuge != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalRSSHuge)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xa0 +	} +	if m.TotalRSS != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalRSS)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0x98 +	} +	if m.TotalCache != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TotalCache)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0x90 +	} +	if m.HierarchicalSwapLimit != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.HierarchicalSwapLimit)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0x88 +	} +	if m.HierarchicalMemoryLimit != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.HierarchicalMemoryLimit)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0x80 +	} +	if m.Unevictable != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Unevictable)) +		i-- +		dAtA[i] = 0x78 +	} +	if m.ActiveFile != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.ActiveFile)) +		i-- +		dAtA[i] = 0x70 +	} +	if m.InactiveFile != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.InactiveFile)) +		i-- +		dAtA[i] = 0x68 +	} +	if m.ActiveAnon != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.ActiveAnon)) +		i-- +		dAtA[i] = 0x60 +	} +	if m.InactiveAnon != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.InactiveAnon)) +		i-- +		dAtA[i] = 0x58 +	} +	if m.PgMajFault != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.PgMajFault)) +		i-- +		dAtA[i] = 0x50 +	} +	if m.PgFault != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.PgFault)) +		i-- +		dAtA[i] = 0x48 +	} +	if m.PgPgOut != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.PgPgOut)) +		i-- +		dAtA[i] = 0x40 +	} +	if m.PgPgIn != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.PgPgIn)) +		i-- +		dAtA[i] = 0x38 +	} +	if m.Writeback != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Writeback)) +		i-- +		dAtA[i] = 0x30 +	} +	if m.Dirty != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Dirty)) +		i-- +		dAtA[i] = 0x28 +	} +	if m.MappedFile != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.MappedFile)) +		i-- +		dAtA[i] = 0x20 +	} +	if m.RSSHuge != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.RSSHuge)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.RSS != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.RSS)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.Cache != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Cache)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func (m *MemoryEntry) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *MemoryEntry) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MemoryEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.Failcnt != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Failcnt)) +		i-- +		dAtA[i] = 0x20 +	} +	if m.Max != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Max)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.Usage != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Usage)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.Limit != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Limit)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func (m *MemoryOomControl) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *MemoryOomControl) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MemoryOomControl) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.OomKill != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.OomKill)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.UnderOom != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.UnderOom)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.OomKillDisable != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.OomKillDisable)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func (m *BlkIOStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *BlkIOStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BlkIOStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if len(m.SectorsRecursive) > 0 { +		for iNdEx := len(m.SectorsRecursive) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.SectorsRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0x42 +		} +	} +	if len(m.IoTimeRecursive) > 0 { +		for iNdEx := len(m.IoTimeRecursive) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.IoTimeRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0x3a +		} +	} +	if len(m.IoMergedRecursive) > 0 { +		for iNdEx := len(m.IoMergedRecursive) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.IoMergedRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0x32 +		} +	} +	if len(m.IoWaitTimeRecursive) > 0 { +		for iNdEx := len(m.IoWaitTimeRecursive) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.IoWaitTimeRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0x2a +		} +	} +	if len(m.IoServiceTimeRecursive) > 0 { +		for iNdEx := len(m.IoServiceTimeRecursive) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.IoServiceTimeRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0x22 +		} +	} +	if len(m.IoQueuedRecursive) > 0 { +		for iNdEx := len(m.IoQueuedRecursive) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.IoQueuedRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0x1a +		} +	} +	if len(m.IoServicedRecursive) > 0 { +		for iNdEx := len(m.IoServicedRecursive) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.IoServicedRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0x12 +		} +	} +	if len(m.IoServiceBytesRecursive) > 0 { +		for iNdEx := len(m.IoServiceBytesRecursive) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.IoServiceBytesRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0xa +		} +	} +	return len(dAtA) - i, nil +} + +func (m *BlkIOEntry) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *BlkIOEntry) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BlkIOEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.Value != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Value)) +		i-- +		dAtA[i] = 0x28 +	} +	if m.Minor != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Minor)) +		i-- +		dAtA[i] = 0x20 +	} +	if m.Major != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Major)) +		i-- +		dAtA[i] = 0x18 +	} +	if len(m.Device) > 0 { +		i -= len(m.Device) +		copy(dAtA[i:], m.Device) +		i = encodeVarintMetrics(dAtA, i, uint64(len(m.Device))) +		i-- +		dAtA[i] = 0x12 +	} +	if len(m.Op) > 0 { +		i -= len(m.Op) +		copy(dAtA[i:], m.Op) +		i = encodeVarintMetrics(dAtA, i, uint64(len(m.Op))) +		i-- +		dAtA[i] = 0xa +	} +	return len(dAtA) - i, nil +} + +func (m *RdmaStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *RdmaStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RdmaStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if len(m.Limit) > 0 { +		for iNdEx := len(m.Limit) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.Limit[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0x12 +		} +	} +	if len(m.Current) > 0 { +		for iNdEx := len(m.Current) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.Current[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0xa +		} +	} +	return len(dAtA) - i, nil +} + +func (m *RdmaEntry) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *RdmaEntry) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RdmaEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.HcaObjects != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.HcaObjects)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.HcaHandles != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.HcaHandles)) +		i-- +		dAtA[i] = 0x10 +	} +	if len(m.Device) > 0 { +		i -= len(m.Device) +		copy(dAtA[i:], m.Device) +		i = encodeVarintMetrics(dAtA, i, uint64(len(m.Device))) +		i-- +		dAtA[i] = 0xa +	} +	return len(dAtA) - i, nil +} + +func (m *NetworkStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *NetworkStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NetworkStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.TxDropped != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TxDropped)) +		i-- +		dAtA[i] = 0x48 +	} +	if m.TxErrors != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TxErrors)) +		i-- +		dAtA[i] = 0x40 +	} +	if m.TxPackets != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TxPackets)) +		i-- +		dAtA[i] = 0x38 +	} +	if m.TxBytes != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.TxBytes)) +		i-- +		dAtA[i] = 0x30 +	} +	if m.RxDropped != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.RxDropped)) +		i-- +		dAtA[i] = 0x28 +	} +	if m.RxErrors != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.RxErrors)) +		i-- +		dAtA[i] = 0x20 +	} +	if m.RxPackets != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.RxPackets)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.RxBytes != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.RxBytes)) +		i-- +		dAtA[i] = 0x10 +	} +	if len(m.Name) > 0 { +		i -= len(m.Name) +		copy(dAtA[i:], m.Name) +		i = encodeVarintMetrics(dAtA, i, uint64(len(m.Name))) +		i-- +		dAtA[i] = 0xa +	} +	return len(dAtA) - i, nil +} + +func (m *CgroupStats) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *CgroupStats) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CgroupStats) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.NrIoWait != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.NrIoWait)) +		i-- +		dAtA[i] = 0x28 +	} +	if m.NrUninterruptible != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.NrUninterruptible)) +		i-- +		dAtA[i] = 0x20 +	} +	if m.NrStopped != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.NrStopped)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.NrRunning != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.NrRunning)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.NrSleeping != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.NrSleeping)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func encodeVarintMetrics(dAtA []byte, offset int, v uint64) int { +	offset -= sovMetrics(v) +	base := offset +	for v >= 1<<7 { +		dAtA[offset] = uint8(v&0x7f | 0x80) +		v >>= 7 +		offset++ +	} +	dAtA[offset] = uint8(v) +	return base +} +func (m *Metrics) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if len(m.Hugetlb) > 0 { +		for _, e := range m.Hugetlb { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if m.Pids != nil { +		l = m.Pids.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.CPU != nil { +		l = m.CPU.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.Memory != nil { +		l = m.Memory.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.Blkio != nil { +		l = m.Blkio.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.Rdma != nil { +		l = m.Rdma.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if len(m.Network) > 0 { +		for _, e := range m.Network { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if m.CgroupStats != nil { +		l = m.CgroupStats.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.MemoryOomControl != nil { +		l = m.MemoryOomControl.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *HugetlbStat) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.Usage != 0 { +		n += 1 + sovMetrics(uint64(m.Usage)) +	} +	if m.Max != 0 { +		n += 1 + sovMetrics(uint64(m.Max)) +	} +	if m.Failcnt != 0 { +		n += 1 + sovMetrics(uint64(m.Failcnt)) +	} +	l = len(m.Pagesize) +	if l > 0 { +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *PidsStat) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.Current != 0 { +		n += 1 + sovMetrics(uint64(m.Current)) +	} +	if m.Limit != 0 { +		n += 1 + sovMetrics(uint64(m.Limit)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *CPUStat) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.Usage != nil { +		l = m.Usage.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.Throttling != nil { +		l = m.Throttling.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *CPUUsage) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.Total != 0 { +		n += 1 + sovMetrics(uint64(m.Total)) +	} +	if m.Kernel != 0 { +		n += 1 + sovMetrics(uint64(m.Kernel)) +	} +	if m.User != 0 { +		n += 1 + sovMetrics(uint64(m.User)) +	} +	if len(m.PerCPU) > 0 { +		l = 0 +		for _, e := range m.PerCPU { +			l += sovMetrics(uint64(e)) +		} +		n += 1 + sovMetrics(uint64(l)) + l +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *Throttle) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.Periods != 0 { +		n += 1 + sovMetrics(uint64(m.Periods)) +	} +	if m.ThrottledPeriods != 0 { +		n += 1 + sovMetrics(uint64(m.ThrottledPeriods)) +	} +	if m.ThrottledTime != 0 { +		n += 1 + sovMetrics(uint64(m.ThrottledTime)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *MemoryStat) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.Cache != 0 { +		n += 1 + sovMetrics(uint64(m.Cache)) +	} +	if m.RSS != 0 { +		n += 1 + sovMetrics(uint64(m.RSS)) +	} +	if m.RSSHuge != 0 { +		n += 1 + sovMetrics(uint64(m.RSSHuge)) +	} +	if m.MappedFile != 0 { +		n += 1 + sovMetrics(uint64(m.MappedFile)) +	} +	if m.Dirty != 0 { +		n += 1 + sovMetrics(uint64(m.Dirty)) +	} +	if m.Writeback != 0 { +		n += 1 + sovMetrics(uint64(m.Writeback)) +	} +	if m.PgPgIn != 0 { +		n += 1 + sovMetrics(uint64(m.PgPgIn)) +	} +	if m.PgPgOut != 0 { +		n += 1 + sovMetrics(uint64(m.PgPgOut)) +	} +	if m.PgFault != 0 { +		n += 1 + sovMetrics(uint64(m.PgFault)) +	} +	if m.PgMajFault != 0 { +		n += 1 + sovMetrics(uint64(m.PgMajFault)) +	} +	if m.InactiveAnon != 0 { +		n += 1 + sovMetrics(uint64(m.InactiveAnon)) +	} +	if m.ActiveAnon != 0 { +		n += 1 + sovMetrics(uint64(m.ActiveAnon)) +	} +	if m.InactiveFile != 0 { +		n += 1 + sovMetrics(uint64(m.InactiveFile)) +	} +	if m.ActiveFile != 0 { +		n += 1 + sovMetrics(uint64(m.ActiveFile)) +	} +	if m.Unevictable != 0 { +		n += 1 + sovMetrics(uint64(m.Unevictable)) +	} +	if m.HierarchicalMemoryLimit != 0 { +		n += 2 + sovMetrics(uint64(m.HierarchicalMemoryLimit)) +	} +	if m.HierarchicalSwapLimit != 0 { +		n += 2 + sovMetrics(uint64(m.HierarchicalSwapLimit)) +	} +	if m.TotalCache != 0 { +		n += 2 + sovMetrics(uint64(m.TotalCache)) +	} +	if m.TotalRSS != 0 { +		n += 2 + sovMetrics(uint64(m.TotalRSS)) +	} +	if m.TotalRSSHuge != 0 { +		n += 2 + sovMetrics(uint64(m.TotalRSSHuge)) +	} +	if m.TotalMappedFile != 0 { +		n += 2 + sovMetrics(uint64(m.TotalMappedFile)) +	} +	if m.TotalDirty != 0 { +		n += 2 + sovMetrics(uint64(m.TotalDirty)) +	} +	if m.TotalWriteback != 0 { +		n += 2 + sovMetrics(uint64(m.TotalWriteback)) +	} +	if m.TotalPgPgIn != 0 { +		n += 2 + sovMetrics(uint64(m.TotalPgPgIn)) +	} +	if m.TotalPgPgOut != 0 { +		n += 2 + sovMetrics(uint64(m.TotalPgPgOut)) +	} +	if m.TotalPgFault != 0 { +		n += 2 + sovMetrics(uint64(m.TotalPgFault)) +	} +	if m.TotalPgMajFault != 0 { +		n += 2 + sovMetrics(uint64(m.TotalPgMajFault)) +	} +	if m.TotalInactiveAnon != 0 { +		n += 2 + sovMetrics(uint64(m.TotalInactiveAnon)) +	} +	if m.TotalActiveAnon != 0 { +		n += 2 + sovMetrics(uint64(m.TotalActiveAnon)) +	} +	if m.TotalInactiveFile != 0 { +		n += 2 + sovMetrics(uint64(m.TotalInactiveFile)) +	} +	if m.TotalActiveFile != 0 { +		n += 2 + sovMetrics(uint64(m.TotalActiveFile)) +	} +	if m.TotalUnevictable != 0 { +		n += 2 + sovMetrics(uint64(m.TotalUnevictable)) +	} +	if m.Usage != nil { +		l = m.Usage.Size() +		n += 2 + l + sovMetrics(uint64(l)) +	} +	if m.Swap != nil { +		l = m.Swap.Size() +		n += 2 + l + sovMetrics(uint64(l)) +	} +	if m.Kernel != nil { +		l = m.Kernel.Size() +		n += 2 + l + sovMetrics(uint64(l)) +	} +	if m.KernelTCP != nil { +		l = m.KernelTCP.Size() +		n += 2 + l + sovMetrics(uint64(l)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *MemoryEntry) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.Limit != 0 { +		n += 1 + sovMetrics(uint64(m.Limit)) +	} +	if m.Usage != 0 { +		n += 1 + sovMetrics(uint64(m.Usage)) +	} +	if m.Max != 0 { +		n += 1 + sovMetrics(uint64(m.Max)) +	} +	if m.Failcnt != 0 { +		n += 1 + sovMetrics(uint64(m.Failcnt)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *MemoryOomControl) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.OomKillDisable != 0 { +		n += 1 + sovMetrics(uint64(m.OomKillDisable)) +	} +	if m.UnderOom != 0 { +		n += 1 + sovMetrics(uint64(m.UnderOom)) +	} +	if m.OomKill != 0 { +		n += 1 + sovMetrics(uint64(m.OomKill)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *BlkIOStat) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if len(m.IoServiceBytesRecursive) > 0 { +		for _, e := range m.IoServiceBytesRecursive { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if len(m.IoServicedRecursive) > 0 { +		for _, e := range m.IoServicedRecursive { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if len(m.IoQueuedRecursive) > 0 { +		for _, e := range m.IoQueuedRecursive { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if len(m.IoServiceTimeRecursive) > 0 { +		for _, e := range m.IoServiceTimeRecursive { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if len(m.IoWaitTimeRecursive) > 0 { +		for _, e := range m.IoWaitTimeRecursive { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if len(m.IoMergedRecursive) > 0 { +		for _, e := range m.IoMergedRecursive { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if len(m.IoTimeRecursive) > 0 { +		for _, e := range m.IoTimeRecursive { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if len(m.SectorsRecursive) > 0 { +		for _, e := range m.SectorsRecursive { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *BlkIOEntry) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	l = len(m.Op) +	if l > 0 { +		n += 1 + l + sovMetrics(uint64(l)) +	} +	l = len(m.Device) +	if l > 0 { +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.Major != 0 { +		n += 1 + sovMetrics(uint64(m.Major)) +	} +	if m.Minor != 0 { +		n += 1 + sovMetrics(uint64(m.Minor)) +	} +	if m.Value != 0 { +		n += 1 + sovMetrics(uint64(m.Value)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *RdmaStat) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if len(m.Current) > 0 { +		for _, e := range m.Current { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if len(m.Limit) > 0 { +		for _, e := range m.Limit { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *RdmaEntry) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	l = len(m.Device) +	if l > 0 { +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.HcaHandles != 0 { +		n += 1 + sovMetrics(uint64(m.HcaHandles)) +	} +	if m.HcaObjects != 0 { +		n += 1 + sovMetrics(uint64(m.HcaObjects)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *NetworkStat) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	l = len(m.Name) +	if l > 0 { +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.RxBytes != 0 { +		n += 1 + sovMetrics(uint64(m.RxBytes)) +	} +	if m.RxPackets != 0 { +		n += 1 + sovMetrics(uint64(m.RxPackets)) +	} +	if m.RxErrors != 0 { +		n += 1 + sovMetrics(uint64(m.RxErrors)) +	} +	if m.RxDropped != 0 { +		n += 1 + sovMetrics(uint64(m.RxDropped)) +	} +	if m.TxBytes != 0 { +		n += 1 + sovMetrics(uint64(m.TxBytes)) +	} +	if m.TxPackets != 0 { +		n += 1 + sovMetrics(uint64(m.TxPackets)) +	} +	if m.TxErrors != 0 { +		n += 1 + sovMetrics(uint64(m.TxErrors)) +	} +	if m.TxDropped != 0 { +		n += 1 + sovMetrics(uint64(m.TxDropped)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *CgroupStats) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.NrSleeping != 0 { +		n += 1 + sovMetrics(uint64(m.NrSleeping)) +	} +	if m.NrRunning != 0 { +		n += 1 + sovMetrics(uint64(m.NrRunning)) +	} +	if m.NrStopped != 0 { +		n += 1 + sovMetrics(uint64(m.NrStopped)) +	} +	if m.NrUninterruptible != 0 { +		n += 1 + sovMetrics(uint64(m.NrUninterruptible)) +	} +	if m.NrIoWait != 0 { +		n += 1 + sovMetrics(uint64(m.NrIoWait)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func sovMetrics(x uint64) (n int) { +	return (math_bits.Len64(x|1) + 6) / 7 +} +func sozMetrics(x uint64) (n int) { +	return sovMetrics(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *Metrics) String() string { +	if this == nil { +		return "nil" +	} +	repeatedStringForHugetlb := "[]*HugetlbStat{" +	for _, f := range this.Hugetlb { +		repeatedStringForHugetlb += strings.Replace(f.String(), "HugetlbStat", "HugetlbStat", 1) + "," +	} +	repeatedStringForHugetlb += "}" +	repeatedStringForNetwork := "[]*NetworkStat{" +	for _, f := range this.Network { +		repeatedStringForNetwork += strings.Replace(f.String(), "NetworkStat", "NetworkStat", 1) + "," +	} +	repeatedStringForNetwork += "}" +	s := strings.Join([]string{`&Metrics{`, +		`Hugetlb:` + repeatedStringForHugetlb + `,`, +		`Pids:` + strings.Replace(this.Pids.String(), "PidsStat", "PidsStat", 1) + `,`, +		`CPU:` + strings.Replace(this.CPU.String(), "CPUStat", "CPUStat", 1) + `,`, +		`Memory:` + strings.Replace(this.Memory.String(), "MemoryStat", "MemoryStat", 1) + `,`, +		`Blkio:` + strings.Replace(this.Blkio.String(), "BlkIOStat", "BlkIOStat", 1) + `,`, +		`Rdma:` + strings.Replace(this.Rdma.String(), "RdmaStat", "RdmaStat", 1) + `,`, +		`Network:` + repeatedStringForNetwork + `,`, +		`CgroupStats:` + strings.Replace(this.CgroupStats.String(), "CgroupStats", "CgroupStats", 1) + `,`, +		`MemoryOomControl:` + strings.Replace(this.MemoryOomControl.String(), "MemoryOomControl", "MemoryOomControl", 1) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *HugetlbStat) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&HugetlbStat{`, +		`Usage:` + fmt.Sprintf("%v", this.Usage) + `,`, +		`Max:` + fmt.Sprintf("%v", this.Max) + `,`, +		`Failcnt:` + fmt.Sprintf("%v", this.Failcnt) + `,`, +		`Pagesize:` + fmt.Sprintf("%v", this.Pagesize) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *PidsStat) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&PidsStat{`, +		`Current:` + fmt.Sprintf("%v", this.Current) + `,`, +		`Limit:` + fmt.Sprintf("%v", this.Limit) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *CPUStat) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&CPUStat{`, +		`Usage:` + strings.Replace(this.Usage.String(), "CPUUsage", "CPUUsage", 1) + `,`, +		`Throttling:` + strings.Replace(this.Throttling.String(), "Throttle", "Throttle", 1) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *CPUUsage) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&CPUUsage{`, +		`Total:` + fmt.Sprintf("%v", this.Total) + `,`, +		`Kernel:` + fmt.Sprintf("%v", this.Kernel) + `,`, +		`User:` + fmt.Sprintf("%v", this.User) + `,`, +		`PerCPU:` + fmt.Sprintf("%v", this.PerCPU) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *Throttle) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&Throttle{`, +		`Periods:` + fmt.Sprintf("%v", this.Periods) + `,`, +		`ThrottledPeriods:` + fmt.Sprintf("%v", this.ThrottledPeriods) + `,`, +		`ThrottledTime:` + fmt.Sprintf("%v", this.ThrottledTime) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *MemoryStat) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&MemoryStat{`, +		`Cache:` + fmt.Sprintf("%v", this.Cache) + `,`, +		`RSS:` + fmt.Sprintf("%v", this.RSS) + `,`, +		`RSSHuge:` + fmt.Sprintf("%v", this.RSSHuge) + `,`, +		`MappedFile:` + fmt.Sprintf("%v", this.MappedFile) + `,`, +		`Dirty:` + fmt.Sprintf("%v", this.Dirty) + `,`, +		`Writeback:` + fmt.Sprintf("%v", this.Writeback) + `,`, +		`PgPgIn:` + fmt.Sprintf("%v", this.PgPgIn) + `,`, +		`PgPgOut:` + fmt.Sprintf("%v", this.PgPgOut) + `,`, +		`PgFault:` + fmt.Sprintf("%v", this.PgFault) + `,`, +		`PgMajFault:` + fmt.Sprintf("%v", this.PgMajFault) + `,`, +		`InactiveAnon:` + fmt.Sprintf("%v", this.InactiveAnon) + `,`, +		`ActiveAnon:` + fmt.Sprintf("%v", this.ActiveAnon) + `,`, +		`InactiveFile:` + fmt.Sprintf("%v", this.InactiveFile) + `,`, +		`ActiveFile:` + fmt.Sprintf("%v", this.ActiveFile) + `,`, +		`Unevictable:` + fmt.Sprintf("%v", this.Unevictable) + `,`, +		`HierarchicalMemoryLimit:` + fmt.Sprintf("%v", this.HierarchicalMemoryLimit) + `,`, +		`HierarchicalSwapLimit:` + fmt.Sprintf("%v", this.HierarchicalSwapLimit) + `,`, +		`TotalCache:` + fmt.Sprintf("%v", this.TotalCache) + `,`, +		`TotalRSS:` + fmt.Sprintf("%v", this.TotalRSS) + `,`, +		`TotalRSSHuge:` + fmt.Sprintf("%v", this.TotalRSSHuge) + `,`, +		`TotalMappedFile:` + fmt.Sprintf("%v", this.TotalMappedFile) + `,`, +		`TotalDirty:` + fmt.Sprintf("%v", this.TotalDirty) + `,`, +		`TotalWriteback:` + fmt.Sprintf("%v", this.TotalWriteback) + `,`, +		`TotalPgPgIn:` + fmt.Sprintf("%v", this.TotalPgPgIn) + `,`, +		`TotalPgPgOut:` + fmt.Sprintf("%v", this.TotalPgPgOut) + `,`, +		`TotalPgFault:` + fmt.Sprintf("%v", this.TotalPgFault) + `,`, +		`TotalPgMajFault:` + fmt.Sprintf("%v", this.TotalPgMajFault) + `,`, +		`TotalInactiveAnon:` + fmt.Sprintf("%v", this.TotalInactiveAnon) + `,`, +		`TotalActiveAnon:` + fmt.Sprintf("%v", this.TotalActiveAnon) + `,`, +		`TotalInactiveFile:` + fmt.Sprintf("%v", this.TotalInactiveFile) + `,`, +		`TotalActiveFile:` + fmt.Sprintf("%v", this.TotalActiveFile) + `,`, +		`TotalUnevictable:` + fmt.Sprintf("%v", this.TotalUnevictable) + `,`, +		`Usage:` + strings.Replace(this.Usage.String(), "MemoryEntry", "MemoryEntry", 1) + `,`, +		`Swap:` + strings.Replace(this.Swap.String(), "MemoryEntry", "MemoryEntry", 1) + `,`, +		`Kernel:` + strings.Replace(this.Kernel.String(), "MemoryEntry", "MemoryEntry", 1) + `,`, +		`KernelTCP:` + strings.Replace(this.KernelTCP.String(), "MemoryEntry", "MemoryEntry", 1) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *MemoryEntry) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&MemoryEntry{`, +		`Limit:` + fmt.Sprintf("%v", this.Limit) + `,`, +		`Usage:` + fmt.Sprintf("%v", this.Usage) + `,`, +		`Max:` + fmt.Sprintf("%v", this.Max) + `,`, +		`Failcnt:` + fmt.Sprintf("%v", this.Failcnt) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *MemoryOomControl) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&MemoryOomControl{`, +		`OomKillDisable:` + fmt.Sprintf("%v", this.OomKillDisable) + `,`, +		`UnderOom:` + fmt.Sprintf("%v", this.UnderOom) + `,`, +		`OomKill:` + fmt.Sprintf("%v", this.OomKill) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *BlkIOStat) String() string { +	if this == nil { +		return "nil" +	} +	repeatedStringForIoServiceBytesRecursive := "[]*BlkIOEntry{" +	for _, f := range this.IoServiceBytesRecursive { +		repeatedStringForIoServiceBytesRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," +	} +	repeatedStringForIoServiceBytesRecursive += "}" +	repeatedStringForIoServicedRecursive := "[]*BlkIOEntry{" +	for _, f := range this.IoServicedRecursive { +		repeatedStringForIoServicedRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," +	} +	repeatedStringForIoServicedRecursive += "}" +	repeatedStringForIoQueuedRecursive := "[]*BlkIOEntry{" +	for _, f := range this.IoQueuedRecursive { +		repeatedStringForIoQueuedRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," +	} +	repeatedStringForIoQueuedRecursive += "}" +	repeatedStringForIoServiceTimeRecursive := "[]*BlkIOEntry{" +	for _, f := range this.IoServiceTimeRecursive { +		repeatedStringForIoServiceTimeRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," +	} +	repeatedStringForIoServiceTimeRecursive += "}" +	repeatedStringForIoWaitTimeRecursive := "[]*BlkIOEntry{" +	for _, f := range this.IoWaitTimeRecursive { +		repeatedStringForIoWaitTimeRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," +	} +	repeatedStringForIoWaitTimeRecursive += "}" +	repeatedStringForIoMergedRecursive := "[]*BlkIOEntry{" +	for _, f := range this.IoMergedRecursive { +		repeatedStringForIoMergedRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," +	} +	repeatedStringForIoMergedRecursive += "}" +	repeatedStringForIoTimeRecursive := "[]*BlkIOEntry{" +	for _, f := range this.IoTimeRecursive { +		repeatedStringForIoTimeRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," +	} +	repeatedStringForIoTimeRecursive += "}" +	repeatedStringForSectorsRecursive := "[]*BlkIOEntry{" +	for _, f := range this.SectorsRecursive { +		repeatedStringForSectorsRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," +	} +	repeatedStringForSectorsRecursive += "}" +	s := strings.Join([]string{`&BlkIOStat{`, +		`IoServiceBytesRecursive:` + repeatedStringForIoServiceBytesRecursive + `,`, +		`IoServicedRecursive:` + repeatedStringForIoServicedRecursive + `,`, +		`IoQueuedRecursive:` + repeatedStringForIoQueuedRecursive + `,`, +		`IoServiceTimeRecursive:` + repeatedStringForIoServiceTimeRecursive + `,`, +		`IoWaitTimeRecursive:` + repeatedStringForIoWaitTimeRecursive + `,`, +		`IoMergedRecursive:` + repeatedStringForIoMergedRecursive + `,`, +		`IoTimeRecursive:` + repeatedStringForIoTimeRecursive + `,`, +		`SectorsRecursive:` + repeatedStringForSectorsRecursive + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *BlkIOEntry) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&BlkIOEntry{`, +		`Op:` + fmt.Sprintf("%v", this.Op) + `,`, +		`Device:` + fmt.Sprintf("%v", this.Device) + `,`, +		`Major:` + fmt.Sprintf("%v", this.Major) + `,`, +		`Minor:` + fmt.Sprintf("%v", this.Minor) + `,`, +		`Value:` + fmt.Sprintf("%v", this.Value) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *RdmaStat) String() string { +	if this == nil { +		return "nil" +	} +	repeatedStringForCurrent := "[]*RdmaEntry{" +	for _, f := range this.Current { +		repeatedStringForCurrent += strings.Replace(f.String(), "RdmaEntry", "RdmaEntry", 1) + "," +	} +	repeatedStringForCurrent += "}" +	repeatedStringForLimit := "[]*RdmaEntry{" +	for _, f := range this.Limit { +		repeatedStringForLimit += strings.Replace(f.String(), "RdmaEntry", "RdmaEntry", 1) + "," +	} +	repeatedStringForLimit += "}" +	s := strings.Join([]string{`&RdmaStat{`, +		`Current:` + repeatedStringForCurrent + `,`, +		`Limit:` + repeatedStringForLimit + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *RdmaEntry) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&RdmaEntry{`, +		`Device:` + fmt.Sprintf("%v", this.Device) + `,`, +		`HcaHandles:` + fmt.Sprintf("%v", this.HcaHandles) + `,`, +		`HcaObjects:` + fmt.Sprintf("%v", this.HcaObjects) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *NetworkStat) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&NetworkStat{`, +		`Name:` + fmt.Sprintf("%v", this.Name) + `,`, +		`RxBytes:` + fmt.Sprintf("%v", this.RxBytes) + `,`, +		`RxPackets:` + fmt.Sprintf("%v", this.RxPackets) + `,`, +		`RxErrors:` + fmt.Sprintf("%v", this.RxErrors) + `,`, +		`RxDropped:` + fmt.Sprintf("%v", this.RxDropped) + `,`, +		`TxBytes:` + fmt.Sprintf("%v", this.TxBytes) + `,`, +		`TxPackets:` + fmt.Sprintf("%v", this.TxPackets) + `,`, +		`TxErrors:` + fmt.Sprintf("%v", this.TxErrors) + `,`, +		`TxDropped:` + fmt.Sprintf("%v", this.TxDropped) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *CgroupStats) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&CgroupStats{`, +		`NrSleeping:` + fmt.Sprintf("%v", this.NrSleeping) + `,`, +		`NrRunning:` + fmt.Sprintf("%v", this.NrRunning) + `,`, +		`NrStopped:` + fmt.Sprintf("%v", this.NrStopped) + `,`, +		`NrUninterruptible:` + fmt.Sprintf("%v", this.NrUninterruptible) + `,`, +		`NrIoWait:` + fmt.Sprintf("%v", this.NrIoWait) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func valueToStringMetrics(v interface{}) string { +	rv := reflect.ValueOf(v) +	if rv.IsNil() { +		return "nil" +	} +	pv := reflect.Indirect(rv).Interface() +	return fmt.Sprintf("*%v", pv) +} +func (m *Metrics) 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: Metrics: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: Metrics: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Hugetlb", 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.Hugetlb = append(m.Hugetlb, &HugetlbStat{}) +			if err := m.Hugetlb[len(m.Hugetlb)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 2: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pids", 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.Pids == nil { +				m.Pids = &PidsStat{} +			} +			if err := m.Pids.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 3: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field CPU", 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.CPU == nil { +				m.CPU = &CPUStat{} +			} +			if err := m.CPU.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 4: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Memory", 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.Memory == nil { +				m.Memory = &MemoryStat{} +			} +			if err := m.Memory.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 5: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Blkio", 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.Blkio == nil { +				m.Blkio = &BlkIOStat{} +			} +			if err := m.Blkio.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 6: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Rdma", 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.Rdma == nil { +				m.Rdma = &RdmaStat{} +			} +			if err := m.Rdma.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 7: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Network", 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.Network = append(m.Network, &NetworkStat{}) +			if err := m.Network[len(m.Network)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 8: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field CgroupStats", 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.CgroupStats == nil { +				m.CgroupStats = &CgroupStats{} +			} +			if err := m.CgroupStats.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 9: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field MemoryOomControl", 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.MemoryOomControl == nil { +				m.MemoryOomControl = &MemoryOomControl{} +			} +			if err := m.MemoryOomControl.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) || (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 *HugetlbStat) 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: HugetlbStat: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: HugetlbStat: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Usage", wireType) +			} +			m.Usage = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Usage |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Max", wireType) +			} +			m.Max = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Max |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Failcnt", wireType) +			} +			m.Failcnt = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Failcnt |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 4: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pagesize", wireType) +			} +			var stringLen uint64 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				stringLen |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +			intStringLen := int(stringLen) +			if intStringLen < 0 { +				return ErrInvalidLengthMetrics +			} +			postIndex := iNdEx + intStringLen +			if postIndex < 0 { +				return ErrInvalidLengthMetrics +			} +			if postIndex > l { +				return io.ErrUnexpectedEOF +			} +			m.Pagesize = string(dAtA[iNdEx:postIndex]) +			iNdEx = postIndex +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *PidsStat) 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: PidsStat: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: PidsStat: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Current", wireType) +			} +			m.Current = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Current |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) +			} +			m.Limit = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Limit |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *CPUStat) 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: CPUStat: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: CPUStat: 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 +			} +			if m.Usage == nil { +				m.Usage = &CPUUsage{} +			} +			if err := m.Usage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 2: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Throttling", 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.Throttling == nil { +				m.Throttling = &Throttle{} +			} +			if err := m.Throttling.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) || (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 *CPUUsage) 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: CPUUsage: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: CPUUsage: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Total", wireType) +			} +			m.Total = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Total |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Kernel", wireType) +			} +			m.Kernel = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Kernel |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) +			} +			m.User = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.User |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 4: +			if wireType == 0 { +				var v uint64 +				for shift := uint(0); ; shift += 7 { +					if shift >= 64 { +						return ErrIntOverflowMetrics +					} +					if iNdEx >= l { +						return io.ErrUnexpectedEOF +					} +					b := dAtA[iNdEx] +					iNdEx++ +					v |= uint64(b&0x7F) << shift +					if b < 0x80 { +						break +					} +				} +				m.PerCPU = append(m.PerCPU, v) +			} else if wireType == 2 { +				var packedLen int +				for shift := uint(0); ; shift += 7 { +					if shift >= 64 { +						return ErrIntOverflowMetrics +					} +					if iNdEx >= l { +						return io.ErrUnexpectedEOF +					} +					b := dAtA[iNdEx] +					iNdEx++ +					packedLen |= int(b&0x7F) << shift +					if b < 0x80 { +						break +					} +				} +				if packedLen < 0 { +					return ErrInvalidLengthMetrics +				} +				postIndex := iNdEx + packedLen +				if postIndex < 0 { +					return ErrInvalidLengthMetrics +				} +				if postIndex > l { +					return io.ErrUnexpectedEOF +				} +				var elementCount int +				var count int +				for _, integer := range dAtA[iNdEx:postIndex] { +					if integer < 128 { +						count++ +					} +				} +				elementCount = count +				if elementCount != 0 && len(m.PerCPU) == 0 { +					m.PerCPU = make([]uint64, 0, elementCount) +				} +				for iNdEx < postIndex { +					var v uint64 +					for shift := uint(0); ; shift += 7 { +						if shift >= 64 { +							return ErrIntOverflowMetrics +						} +						if iNdEx >= l { +							return io.ErrUnexpectedEOF +						} +						b := dAtA[iNdEx] +						iNdEx++ +						v |= uint64(b&0x7F) << shift +						if b < 0x80 { +							break +						} +					} +					m.PerCPU = append(m.PerCPU, v) +				} +			} else { +				return fmt.Errorf("proto: wrong wireType = %d for field PerCPU", wireType) +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *Throttle) 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: Throttle: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: Throttle: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Periods", wireType) +			} +			m.Periods = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Periods |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field ThrottledPeriods", wireType) +			} +			m.ThrottledPeriods = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.ThrottledPeriods |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field ThrottledTime", wireType) +			} +			m.ThrottledTime = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.ThrottledTime |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *MemoryStat) 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: MemoryStat: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: MemoryStat: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Cache", wireType) +			} +			m.Cache = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Cache |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field RSS", wireType) +			} +			m.RSS = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.RSS |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field RSSHuge", wireType) +			} +			m.RSSHuge = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.RSSHuge |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 4: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field MappedFile", wireType) +			} +			m.MappedFile = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.MappedFile |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 5: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Dirty", wireType) +			} +			m.Dirty = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Dirty |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 6: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Writeback", wireType) +			} +			m.Writeback = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Writeback |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 7: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field PgPgIn", wireType) +			} +			m.PgPgIn = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.PgPgIn |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 8: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field PgPgOut", wireType) +			} +			m.PgPgOut = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.PgPgOut |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 9: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field PgFault", wireType) +			} +			m.PgFault = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.PgFault |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 10: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field PgMajFault", wireType) +			} +			m.PgMajFault = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.PgMajFault |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 11: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field InactiveAnon", wireType) +			} +			m.InactiveAnon = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.InactiveAnon |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 12: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field ActiveAnon", wireType) +			} +			m.ActiveAnon = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.ActiveAnon |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 13: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field InactiveFile", wireType) +			} +			m.InactiveFile = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.InactiveFile |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 14: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field ActiveFile", wireType) +			} +			m.ActiveFile = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.ActiveFile |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 15: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Unevictable", wireType) +			} +			m.Unevictable = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Unevictable |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 16: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field HierarchicalMemoryLimit", wireType) +			} +			m.HierarchicalMemoryLimit = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.HierarchicalMemoryLimit |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 17: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field HierarchicalSwapLimit", wireType) +			} +			m.HierarchicalSwapLimit = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.HierarchicalSwapLimit |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 18: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalCache", wireType) +			} +			m.TotalCache = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalCache |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 19: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalRSS", wireType) +			} +			m.TotalRSS = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalRSS |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 20: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalRSSHuge", wireType) +			} +			m.TotalRSSHuge = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalRSSHuge |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 21: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalMappedFile", wireType) +			} +			m.TotalMappedFile = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalMappedFile |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 22: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalDirty", wireType) +			} +			m.TotalDirty = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalDirty |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 23: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalWriteback", wireType) +			} +			m.TotalWriteback = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalWriteback |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 24: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalPgPgIn", wireType) +			} +			m.TotalPgPgIn = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalPgPgIn |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 25: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalPgPgOut", wireType) +			} +			m.TotalPgPgOut = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalPgPgOut |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 26: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalPgFault", wireType) +			} +			m.TotalPgFault = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalPgFault |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 27: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalPgMajFault", wireType) +			} +			m.TotalPgMajFault = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalPgMajFault |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 28: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalInactiveAnon", wireType) +			} +			m.TotalInactiveAnon = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalInactiveAnon |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 29: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalActiveAnon", wireType) +			} +			m.TotalActiveAnon = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalActiveAnon |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 30: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalInactiveFile", wireType) +			} +			m.TotalInactiveFile = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalInactiveFile |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 31: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalActiveFile", wireType) +			} +			m.TotalActiveFile = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalActiveFile |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 32: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TotalUnevictable", wireType) +			} +			m.TotalUnevictable = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TotalUnevictable |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 33: +			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 +			} +			if m.Usage == nil { +				m.Usage = &MemoryEntry{} +			} +			if err := m.Usage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 34: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Swap", 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.Swap == nil { +				m.Swap = &MemoryEntry{} +			} +			if err := m.Swap.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 35: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Kernel", 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.Kernel == nil { +				m.Kernel = &MemoryEntry{} +			} +			if err := m.Kernel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 36: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field KernelTCP", 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.KernelTCP == nil { +				m.KernelTCP = &MemoryEntry{} +			} +			if err := m.KernelTCP.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) || (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 *MemoryEntry) 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: MemoryEntry: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: MemoryEntry: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) +			} +			m.Limit = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Limit |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Usage", wireType) +			} +			m.Usage = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Usage |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Max", wireType) +			} +			m.Max = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Max |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 4: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Failcnt", wireType) +			} +			m.Failcnt = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Failcnt |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *MemoryOomControl) 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: MemoryOomControl: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: MemoryOomControl: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field OomKillDisable", wireType) +			} +			m.OomKillDisable = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.OomKillDisable |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field UnderOom", wireType) +			} +			m.UnderOom = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.UnderOom |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field OomKill", wireType) +			} +			m.OomKill = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.OomKill |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *BlkIOStat) 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: BlkIOStat: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: BlkIOStat: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field IoServiceBytesRecursive", 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.IoServiceBytesRecursive = append(m.IoServiceBytesRecursive, &BlkIOEntry{}) +			if err := m.IoServiceBytesRecursive[len(m.IoServiceBytesRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 2: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field IoServicedRecursive", 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.IoServicedRecursive = append(m.IoServicedRecursive, &BlkIOEntry{}) +			if err := m.IoServicedRecursive[len(m.IoServicedRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 3: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field IoQueuedRecursive", 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.IoQueuedRecursive = append(m.IoQueuedRecursive, &BlkIOEntry{}) +			if err := m.IoQueuedRecursive[len(m.IoQueuedRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 4: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field IoServiceTimeRecursive", 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.IoServiceTimeRecursive = append(m.IoServiceTimeRecursive, &BlkIOEntry{}) +			if err := m.IoServiceTimeRecursive[len(m.IoServiceTimeRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 5: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field IoWaitTimeRecursive", 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.IoWaitTimeRecursive = append(m.IoWaitTimeRecursive, &BlkIOEntry{}) +			if err := m.IoWaitTimeRecursive[len(m.IoWaitTimeRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 6: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field IoMergedRecursive", 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.IoMergedRecursive = append(m.IoMergedRecursive, &BlkIOEntry{}) +			if err := m.IoMergedRecursive[len(m.IoMergedRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 7: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field IoTimeRecursive", 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.IoTimeRecursive = append(m.IoTimeRecursive, &BlkIOEntry{}) +			if err := m.IoTimeRecursive[len(m.IoTimeRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 8: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field SectorsRecursive", 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.SectorsRecursive = append(m.SectorsRecursive, &BlkIOEntry{}) +			if err := m.SectorsRecursive[len(m.SectorsRecursive)-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) || (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 *BlkIOEntry) 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: BlkIOEntry: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: BlkIOEntry: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Op", wireType) +			} +			var stringLen uint64 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				stringLen |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +			intStringLen := int(stringLen) +			if intStringLen < 0 { +				return ErrInvalidLengthMetrics +			} +			postIndex := iNdEx + intStringLen +			if postIndex < 0 { +				return ErrInvalidLengthMetrics +			} +			if postIndex > l { +				return io.ErrUnexpectedEOF +			} +			m.Op = string(dAtA[iNdEx:postIndex]) +			iNdEx = postIndex +		case 2: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) +			} +			var stringLen uint64 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				stringLen |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +			intStringLen := int(stringLen) +			if intStringLen < 0 { +				return ErrInvalidLengthMetrics +			} +			postIndex := iNdEx + intStringLen +			if postIndex < 0 { +				return ErrInvalidLengthMetrics +			} +			if postIndex > l { +				return io.ErrUnexpectedEOF +			} +			m.Device = string(dAtA[iNdEx:postIndex]) +			iNdEx = postIndex +		case 3: +			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 4: +			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 5: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) +			} +			m.Value = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Value |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *RdmaStat) 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: RdmaStat: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: RdmaStat: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Current", 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.Current = append(m.Current, &RdmaEntry{}) +			if err := m.Current[len(m.Current)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 2: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Limit", 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.Limit = append(m.Limit, &RdmaEntry{}) +			if err := m.Limit[len(m.Limit)-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) || (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 *RdmaEntry) 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: RdmaEntry: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: RdmaEntry: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) +			} +			var stringLen uint64 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				stringLen |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +			intStringLen := int(stringLen) +			if intStringLen < 0 { +				return ErrInvalidLengthMetrics +			} +			postIndex := iNdEx + intStringLen +			if postIndex < 0 { +				return ErrInvalidLengthMetrics +			} +			if postIndex > l { +				return io.ErrUnexpectedEOF +			} +			m.Device = string(dAtA[iNdEx:postIndex]) +			iNdEx = postIndex +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field HcaHandles", wireType) +			} +			m.HcaHandles = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.HcaHandles |= uint32(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field HcaObjects", wireType) +			} +			m.HcaObjects = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.HcaObjects |= uint32(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *NetworkStat) 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: NetworkStat: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: NetworkStat: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) +			} +			var stringLen uint64 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				stringLen |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +			intStringLen := int(stringLen) +			if intStringLen < 0 { +				return ErrInvalidLengthMetrics +			} +			postIndex := iNdEx + intStringLen +			if postIndex < 0 { +				return ErrInvalidLengthMetrics +			} +			if postIndex > l { +				return io.ErrUnexpectedEOF +			} +			m.Name = string(dAtA[iNdEx:postIndex]) +			iNdEx = postIndex +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field RxBytes", wireType) +			} +			m.RxBytes = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.RxBytes |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field RxPackets", wireType) +			} +			m.RxPackets = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.RxPackets |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 4: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field RxErrors", wireType) +			} +			m.RxErrors = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.RxErrors |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 5: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field RxDropped", wireType) +			} +			m.RxDropped = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.RxDropped |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 6: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TxBytes", wireType) +			} +			m.TxBytes = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TxBytes |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 7: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TxPackets", wireType) +			} +			m.TxPackets = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TxPackets |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 8: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TxErrors", wireType) +			} +			m.TxErrors = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TxErrors |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 9: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field TxDropped", wireType) +			} +			m.TxDropped = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.TxDropped |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *CgroupStats) 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: CgroupStats: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: CgroupStats: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field NrSleeping", wireType) +			} +			m.NrSleeping = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.NrSleeping |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field NrRunning", wireType) +			} +			m.NrRunning = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.NrRunning |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field NrStopped", wireType) +			} +			m.NrStopped = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.NrStopped |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 4: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field NrUninterruptible", wireType) +			} +			m.NrUninterruptible = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.NrUninterruptible |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 5: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field NrIoWait", wireType) +			} +			m.NrIoWait = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.NrIoWait |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 +	depth := 0 +	for iNdEx < l { +		var wire uint64 +		for shift := uint(0); ; shift += 7 { +			if shift >= 64 { +				return 0, ErrIntOverflowMetrics +			} +			if iNdEx >= l { +				return 0, io.ErrUnexpectedEOF +			} +			b := dAtA[iNdEx] +			iNdEx++ +			wire |= (uint64(b) & 0x7F) << shift +			if b < 0x80 { +				break +			} +		} +		wireType := int(wire & 0x7) +		switch wireType { +		case 0: +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return 0, ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return 0, io.ErrUnexpectedEOF +				} +				iNdEx++ +				if dAtA[iNdEx-1] < 0x80 { +					break +				} +			} +		case 1: +			iNdEx += 8 +		case 2: +			var length int +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return 0, ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return 0, io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				length |= (int(b) & 0x7F) << shift +				if b < 0x80 { +					break +				} +			} +			if length < 0 { +				return 0, ErrInvalidLengthMetrics +			} +			iNdEx += length +		case 3: +			depth++ +		case 4: +			if depth == 0 { +				return 0, ErrUnexpectedEndOfGroupMetrics +			} +			depth-- +		case 5: +			iNdEx += 4 +		default: +			return 0, fmt.Errorf("proto: illegal wireType %d", wireType) +		} +		if iNdEx < 0 { +			return 0, ErrInvalidLengthMetrics +		} +		if depth == 0 { +			return iNdEx, nil +		} +	} +	return 0, io.ErrUnexpectedEOF +} + +var ( +	ErrInvalidLengthMetrics        = fmt.Errorf("proto: negative length found during unmarshaling") +	ErrIntOverflowMetrics          = fmt.Errorf("proto: integer overflow") +	ErrUnexpectedEndOfGroupMetrics = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.txt b/vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.txt new file mode 100644 index 000000000..e476cea64 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.txt @@ -0,0 +1,790 @@ +file { +  name: "github.com/containerd/cgroups/stats/v1/metrics.proto" +  package: "io.containerd.cgroups.v1" +  dependency: "gogoproto/gogo.proto" +  message_type { +    name: "Metrics" +    field { +      name: "hugetlb" +      number: 1 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.HugetlbStat" +      json_name: "hugetlb" +    } +    field { +      name: "pids" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.PidsStat" +      json_name: "pids" +    } +    field { +      name: "cpu" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.CPUStat" +      options { +        65004: "CPU" +      } +      json_name: "cpu" +    } +    field { +      name: "memory" +      number: 4 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.MemoryStat" +      json_name: "memory" +    } +    field { +      name: "blkio" +      number: 5 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.BlkIOStat" +      json_name: "blkio" +    } +    field { +      name: "rdma" +      number: 6 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.RdmaStat" +      json_name: "rdma" +    } +    field { +      name: "network" +      number: 7 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.NetworkStat" +      json_name: "network" +    } +    field { +      name: "cgroup_stats" +      number: 8 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.CgroupStats" +      json_name: "cgroupStats" +    } +    field { +      name: "memory_oom_control" +      number: 9 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.MemoryOomControl" +      json_name: "memoryOomControl" +    } +  } +  message_type { +    name: "HugetlbStat" +    field { +      name: "usage" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "usage" +    } +    field { +      name: "max" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "max" +    } +    field { +      name: "failcnt" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "failcnt" +    } +    field { +      name: "pagesize" +      number: 4 +      label: LABEL_OPTIONAL +      type: TYPE_STRING +      json_name: "pagesize" +    } +  } +  message_type { +    name: "PidsStat" +    field { +      name: "current" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "current" +    } +    field { +      name: "limit" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "limit" +    } +  } +  message_type { +    name: "CPUStat" +    field { +      name: "usage" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.CPUUsage" +      json_name: "usage" +    } +    field { +      name: "throttling" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.Throttle" +      json_name: "throttling" +    } +  } +  message_type { +    name: "CPUUsage" +    field { +      name: "total" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "total" +    } +    field { +      name: "kernel" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "kernel" +    } +    field { +      name: "user" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "user" +    } +    field { +      name: "per_cpu" +      number: 4 +      label: LABEL_REPEATED +      type: TYPE_UINT64 +      options { +        65004: "PerCPU" +      } +      json_name: "perCpu" +    } +  } +  message_type { +    name: "Throttle" +    field { +      name: "periods" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "periods" +    } +    field { +      name: "throttled_periods" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "throttledPeriods" +    } +    field { +      name: "throttled_time" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "throttledTime" +    } +  } +  message_type { +    name: "MemoryStat" +    field { +      name: "cache" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "cache" +    } +    field { +      name: "rss" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      options { +        65004: "RSS" +      } +      json_name: "rss" +    } +    field { +      name: "rss_huge" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      options { +        65004: "RSSHuge" +      } +      json_name: "rssHuge" +    } +    field { +      name: "mapped_file" +      number: 4 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "mappedFile" +    } +    field { +      name: "dirty" +      number: 5 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "dirty" +    } +    field { +      name: "writeback" +      number: 6 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "writeback" +    } +    field { +      name: "pg_pg_in" +      number: 7 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pgPgIn" +    } +    field { +      name: "pg_pg_out" +      number: 8 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pgPgOut" +    } +    field { +      name: "pg_fault" +      number: 9 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pgFault" +    } +    field { +      name: "pg_maj_fault" +      number: 10 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pgMajFault" +    } +    field { +      name: "inactive_anon" +      number: 11 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "inactiveAnon" +    } +    field { +      name: "active_anon" +      number: 12 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "activeAnon" +    } +    field { +      name: "inactive_file" +      number: 13 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "inactiveFile" +    } +    field { +      name: "active_file" +      number: 14 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "activeFile" +    } +    field { +      name: "unevictable" +      number: 15 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "unevictable" +    } +    field { +      name: "hierarchical_memory_limit" +      number: 16 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "hierarchicalMemoryLimit" +    } +    field { +      name: "hierarchical_swap_limit" +      number: 17 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "hierarchicalSwapLimit" +    } +    field { +      name: "total_cache" +      number: 18 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalCache" +    } +    field { +      name: "total_rss" +      number: 19 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      options { +        65004: "TotalRSS" +      } +      json_name: "totalRss" +    } +    field { +      name: "total_rss_huge" +      number: 20 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      options { +        65004: "TotalRSSHuge" +      } +      json_name: "totalRssHuge" +    } +    field { +      name: "total_mapped_file" +      number: 21 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalMappedFile" +    } +    field { +      name: "total_dirty" +      number: 22 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalDirty" +    } +    field { +      name: "total_writeback" +      number: 23 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalWriteback" +    } +    field { +      name: "total_pg_pg_in" +      number: 24 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalPgPgIn" +    } +    field { +      name: "total_pg_pg_out" +      number: 25 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalPgPgOut" +    } +    field { +      name: "total_pg_fault" +      number: 26 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalPgFault" +    } +    field { +      name: "total_pg_maj_fault" +      number: 27 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalPgMajFault" +    } +    field { +      name: "total_inactive_anon" +      number: 28 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalInactiveAnon" +    } +    field { +      name: "total_active_anon" +      number: 29 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalActiveAnon" +    } +    field { +      name: "total_inactive_file" +      number: 30 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalInactiveFile" +    } +    field { +      name: "total_active_file" +      number: 31 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalActiveFile" +    } +    field { +      name: "total_unevictable" +      number: 32 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "totalUnevictable" +    } +    field { +      name: "usage" +      number: 33 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.MemoryEntry" +      json_name: "usage" +    } +    field { +      name: "swap" +      number: 34 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.MemoryEntry" +      json_name: "swap" +    } +    field { +      name: "kernel" +      number: 35 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.MemoryEntry" +      json_name: "kernel" +    } +    field { +      name: "kernel_tcp" +      number: 36 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.MemoryEntry" +      options { +        65004: "KernelTCP" +      } +      json_name: "kernelTcp" +    } +  } +  message_type { +    name: "MemoryEntry" +    field { +      name: "limit" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "limit" +    } +    field { +      name: "usage" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "usage" +    } +    field { +      name: "max" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "max" +    } +    field { +      name: "failcnt" +      number: 4 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "failcnt" +    } +  } +  message_type { +    name: "MemoryOomControl" +    field { +      name: "oom_kill_disable" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "oomKillDisable" +    } +    field { +      name: "under_oom" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "underOom" +    } +    field { +      name: "oom_kill" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "oomKill" +    } +  } +  message_type { +    name: "BlkIOStat" +    field { +      name: "io_service_bytes_recursive" +      number: 1 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.BlkIOEntry" +      json_name: "ioServiceBytesRecursive" +    } +    field { +      name: "io_serviced_recursive" +      number: 2 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.BlkIOEntry" +      json_name: "ioServicedRecursive" +    } +    field { +      name: "io_queued_recursive" +      number: 3 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.BlkIOEntry" +      json_name: "ioQueuedRecursive" +    } +    field { +      name: "io_service_time_recursive" +      number: 4 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.BlkIOEntry" +      json_name: "ioServiceTimeRecursive" +    } +    field { +      name: "io_wait_time_recursive" +      number: 5 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.BlkIOEntry" +      json_name: "ioWaitTimeRecursive" +    } +    field { +      name: "io_merged_recursive" +      number: 6 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.BlkIOEntry" +      json_name: "ioMergedRecursive" +    } +    field { +      name: "io_time_recursive" +      number: 7 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.BlkIOEntry" +      json_name: "ioTimeRecursive" +    } +    field { +      name: "sectors_recursive" +      number: 8 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.BlkIOEntry" +      json_name: "sectorsRecursive" +    } +  } +  message_type { +    name: "BlkIOEntry" +    field { +      name: "op" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_STRING +      json_name: "op" +    } +    field { +      name: "device" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_STRING +      json_name: "device" +    } +    field { +      name: "major" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "major" +    } +    field { +      name: "minor" +      number: 4 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "minor" +    } +    field { +      name: "value" +      number: 5 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "value" +    } +  } +  message_type { +    name: "RdmaStat" +    field { +      name: "current" +      number: 1 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.RdmaEntry" +      json_name: "current" +    } +    field { +      name: "limit" +      number: 2 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v1.RdmaEntry" +      json_name: "limit" +    } +  } +  message_type { +    name: "RdmaEntry" +    field { +      name: "device" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_STRING +      json_name: "device" +    } +    field { +      name: "hca_handles" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT32 +      json_name: "hcaHandles" +    } +    field { +      name: "hca_objects" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT32 +      json_name: "hcaObjects" +    } +  } +  message_type { +    name: "NetworkStat" +    field { +      name: "name" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_STRING +      json_name: "name" +    } +    field { +      name: "rx_bytes" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "rxBytes" +    } +    field { +      name: "rx_packets" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "rxPackets" +    } +    field { +      name: "rx_errors" +      number: 4 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "rxErrors" +    } +    field { +      name: "rx_dropped" +      number: 5 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "rxDropped" +    } +    field { +      name: "tx_bytes" +      number: 6 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "txBytes" +    } +    field { +      name: "tx_packets" +      number: 7 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "txPackets" +    } +    field { +      name: "tx_errors" +      number: 8 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "txErrors" +    } +    field { +      name: "tx_dropped" +      number: 9 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "txDropped" +    } +  } +  message_type { +    name: "CgroupStats" +    field { +      name: "nr_sleeping" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "nrSleeping" +    } +    field { +      name: "nr_running" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "nrRunning" +    } +    field { +      name: "nr_stopped" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "nrStopped" +    } +    field { +      name: "nr_uninterruptible" +      number: 4 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "nrUninterruptible" +    } +    field { +      name: "nr_io_wait" +      number: 5 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "nrIoWait" +    } +  } +  syntax: "proto3" +} diff --git a/vendor/github.com/containerd/cgroups/stats/v1/metrics.proto b/vendor/github.com/containerd/cgroups/stats/v1/metrics.proto new file mode 100644 index 000000000..b3f6cc37d --- /dev/null +++ b/vendor/github.com/containerd/cgroups/stats/v1/metrics.proto @@ -0,0 +1,158 @@ +syntax = "proto3"; + +package io.containerd.cgroups.v1; + +import "gogoproto/gogo.proto"; + +message Metrics { +	repeated HugetlbStat hugetlb = 1; +	PidsStat pids = 2; +	CPUStat cpu = 3 [(gogoproto.customname) = "CPU"]; +	MemoryStat memory = 4; +	BlkIOStat blkio = 5; +	RdmaStat rdma = 6; +	repeated NetworkStat network = 7; +	CgroupStats cgroup_stats = 8; +	MemoryOomControl memory_oom_control = 9; +} + +message HugetlbStat { +	uint64 usage = 1; +	uint64 max = 2; +	uint64 failcnt = 3; +	string pagesize = 4; +} + +message PidsStat { +	uint64 current = 1; +	uint64 limit = 2; +} + +message CPUStat { +	CPUUsage usage = 1; +	Throttle throttling = 2; +} + +message CPUUsage { +	// values in nanoseconds +	uint64 total = 1; +	uint64 kernel = 2; +	uint64 user = 3; +	repeated uint64 per_cpu = 4 [(gogoproto.customname) = "PerCPU"]; + +} + +message Throttle { +	uint64 periods = 1; +	uint64 throttled_periods = 2; +	uint64 throttled_time = 3; +} + +message MemoryStat { +	uint64 cache = 1; +	uint64 rss = 2 [(gogoproto.customname) = "RSS"]; +	uint64 rss_huge = 3 [(gogoproto.customname) = "RSSHuge"]; +	uint64 mapped_file = 4; +	uint64 dirty = 5; +	uint64 writeback = 6; +	uint64 pg_pg_in = 7; +	uint64 pg_pg_out = 8; +	uint64 pg_fault = 9; +	uint64 pg_maj_fault = 10; +	uint64 inactive_anon = 11; +	uint64 active_anon = 12; +	uint64 inactive_file = 13; +	uint64 active_file = 14; +	uint64 unevictable = 15; +	uint64 hierarchical_memory_limit = 16; +	uint64 hierarchical_swap_limit = 17; +	uint64 total_cache = 18; +	uint64 total_rss = 19 [(gogoproto.customname) = "TotalRSS"]; +	uint64 total_rss_huge = 20 [(gogoproto.customname) = "TotalRSSHuge"]; +	uint64 total_mapped_file = 21; +	uint64 total_dirty = 22; +	uint64 total_writeback = 23; +	uint64 total_pg_pg_in = 24; +	uint64 total_pg_pg_out = 25; +	uint64 total_pg_fault = 26; +	uint64 total_pg_maj_fault = 27; +	uint64 total_inactive_anon = 28; +	uint64 total_active_anon = 29; +	uint64 total_inactive_file = 30; +	uint64 total_active_file = 31; +	uint64 total_unevictable = 32; +	MemoryEntry usage = 33; +	MemoryEntry swap = 34; +	MemoryEntry kernel = 35; +	MemoryEntry kernel_tcp = 36 [(gogoproto.customname) = "KernelTCP"]; + +} + +message MemoryEntry { +	uint64 limit = 1; +	uint64 usage = 2; +	uint64 max = 3; +	uint64 failcnt = 4; +} + +message MemoryOomControl { +	uint64 oom_kill_disable = 1; +	uint64 under_oom = 2; +	uint64 oom_kill = 3; +} + +message BlkIOStat { +	repeated BlkIOEntry io_service_bytes_recursive = 1; +	repeated BlkIOEntry io_serviced_recursive = 2; +	repeated BlkIOEntry io_queued_recursive = 3; +	repeated BlkIOEntry io_service_time_recursive = 4; +	repeated BlkIOEntry io_wait_time_recursive = 5; +	repeated BlkIOEntry io_merged_recursive = 6; +	repeated BlkIOEntry io_time_recursive = 7; +	repeated BlkIOEntry sectors_recursive = 8; +} + +message BlkIOEntry { +	string op = 1; +	string device = 2; +	uint64 major = 3; +	uint64 minor = 4; +	uint64 value = 5; +} + +message RdmaStat { +	repeated RdmaEntry current = 1; +	repeated RdmaEntry limit = 2; +} + +message RdmaEntry { +	string device = 1; +	uint32 hca_handles = 2; +	uint32 hca_objects = 3; +} + +message NetworkStat { +	string name = 1; +	uint64 rx_bytes = 2; +	uint64 rx_packets = 3; +	uint64 rx_errors  = 4; +	uint64 rx_dropped = 5; +	uint64 tx_bytes = 6; +	uint64 tx_packets = 7; +	uint64 tx_errors = 8; +	uint64 tx_dropped = 9; +} + +// CgroupStats exports per-cgroup statistics. +message CgroupStats { +	// number of tasks sleeping +	uint64 nr_sleeping = 1; +	// number of tasks running +	uint64 nr_running = 2; +	// number of tasks in stopped state +	uint64 nr_stopped = 3; +	// number of tasks in uninterruptible state +	uint64 nr_uninterruptible = 4; +	// number of tasks waiting on IO +	uint64 nr_io_wait = 5; +} diff --git a/vendor/github.com/containerd/cgroups/subsystem.go b/vendor/github.com/containerd/cgroups/subsystem.go new file mode 100644 index 000000000..b2f41854d --- /dev/null +++ b/vendor/github.com/containerd/cgroups/subsystem.go @@ -0,0 +1,116 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"fmt" +	"os" + +	v1 "github.com/containerd/cgroups/stats/v1" +	specs "github.com/opencontainers/runtime-spec/specs-go" +) + +// Name is a typed name for a cgroup subsystem +type Name string + +const ( +	Devices   Name = "devices" +	Hugetlb   Name = "hugetlb" +	Freezer   Name = "freezer" +	Pids      Name = "pids" +	NetCLS    Name = "net_cls" +	NetPrio   Name = "net_prio" +	PerfEvent Name = "perf_event" +	Cpuset    Name = "cpuset" +	Cpu       Name = "cpu" +	Cpuacct   Name = "cpuacct" +	Memory    Name = "memory" +	Blkio     Name = "blkio" +	Rdma      Name = "rdma" +) + +// Subsystems returns a complete list of the default cgroups +// available on most linux systems +func Subsystems() []Name { +	n := []Name{ +		Freezer, +		Pids, +		NetCLS, +		NetPrio, +		PerfEvent, +		Cpuset, +		Cpu, +		Cpuacct, +		Memory, +		Blkio, +		Rdma, +	} +	if !RunningInUserNS() { +		n = append(n, Devices) +	} +	if _, err := os.Stat("/sys/kernel/mm/hugepages"); err == nil { +		n = append(n, Hugetlb) +	} +	return n +} + +type Subsystem interface { +	Name() Name +} + +type pather interface { +	Subsystem +	Path(path string) string +} + +type creator interface { +	Subsystem +	Create(path string, resources *specs.LinuxResources) error +} + +type deleter interface { +	Subsystem +	Delete(path string) error +} + +type stater interface { +	Subsystem +	Stat(path string, stats *v1.Metrics) error +} + +type updater interface { +	Subsystem +	Update(path string, resources *specs.LinuxResources) error +} + +// SingleSubsystem returns a single cgroup subsystem within the base Hierarchy +func SingleSubsystem(baseHierarchy Hierarchy, subsystem Name) Hierarchy { +	return func() ([]Subsystem, error) { +		subsystems, err := baseHierarchy() +		if err != nil { +			return nil, err +		} +		for _, s := range subsystems { +			if s.Name() == subsystem { +				return []Subsystem{ +					s, +				}, nil +			} +		} +		return nil, fmt.Errorf("unable to find subsystem %s", subsystem) +	} +} diff --git a/vendor/github.com/containerd/cgroups/systemd.go b/vendor/github.com/containerd/cgroups/systemd.go new file mode 100644 index 000000000..4da57cb4b --- /dev/null +++ b/vendor/github.com/containerd/cgroups/systemd.go @@ -0,0 +1,158 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"context" +	"path/filepath" +	"strings" +	"sync" + +	systemdDbus "github.com/coreos/go-systemd/v22/dbus" +	"github.com/godbus/dbus/v5" +	specs "github.com/opencontainers/runtime-spec/specs-go" +) + +const ( +	SystemdDbus  Name = "systemd" +	defaultSlice      = "system.slice" +) + +var ( +	canDelegate bool +	once        sync.Once +) + +func Systemd() ([]Subsystem, error) { +	root, err := v1MountPoint() +	if err != nil { +		return nil, err +	} +	defaultSubsystems, err := defaults(root) +	if err != nil { +		return nil, err +	} +	s, err := NewSystemd(root) +	if err != nil { +		return nil, err +	} +	// make sure the systemd controller is added first +	return append([]Subsystem{s}, defaultSubsystems...), nil +} + +func Slice(slice, name string) Path { +	if slice == "" { +		slice = defaultSlice +	} +	return func(subsystem Name) (string, error) { +		return filepath.Join(slice, name), nil +	} +} + +func NewSystemd(root string) (*SystemdController, error) { +	return &SystemdController{ +		root: root, +	}, nil +} + +type SystemdController struct { +	mu   sync.Mutex +	root string +} + +func (s *SystemdController) Name() Name { +	return SystemdDbus +} + +func (s *SystemdController) Create(path string, _ *specs.LinuxResources) error { +	ctx := context.TODO() +	conn, err := systemdDbus.NewWithContext(ctx) +	if err != nil { +		return err +	} +	defer conn.Close() +	slice, name := splitName(path) +	// We need to see if systemd can handle the delegate property +	// Systemd will return an error if it cannot handle delegate regardless +	// of its bool setting. +	checkDelegate := func() { +		canDelegate = true +		dlSlice := newProperty("Delegate", true) +		if _, err := conn.StartTransientUnitContext(ctx, slice, "testdelegate", []systemdDbus.Property{dlSlice}, nil); err != nil { +			if dbusError, ok := err.(dbus.Error); ok { +				// Starting with systemd v237, Delegate is not even a property of slices anymore, +				// so the D-Bus call fails with "InvalidArgs" error. +				if strings.Contains(dbusError.Name, "org.freedesktop.DBus.Error.PropertyReadOnly") || strings.Contains(dbusError.Name, "org.freedesktop.DBus.Error.InvalidArgs") { +					canDelegate = false +				} +			} +		} + +		_, _ = conn.StopUnitContext(ctx, slice, "testDelegate", nil) +	} +	once.Do(checkDelegate) +	properties := []systemdDbus.Property{ +		systemdDbus.PropDescription("cgroup " + name), +		systemdDbus.PropWants(slice), +		newProperty("DefaultDependencies", false), +		newProperty("MemoryAccounting", true), +		newProperty("CPUAccounting", true), +		newProperty("BlockIOAccounting", true), +	} + +	// If we can delegate, we add the property back in +	if canDelegate { +		properties = append(properties, newProperty("Delegate", true)) +	} + +	ch := make(chan string) +	_, err = conn.StartTransientUnitContext(ctx, name, "replace", properties, ch) +	if err != nil { +		return err +	} +	<-ch +	return nil +} + +func (s *SystemdController) Delete(path string) error { +	ctx := context.TODO() +	conn, err := systemdDbus.NewWithContext(ctx) +	if err != nil { +		return err +	} +	defer conn.Close() +	_, name := splitName(path) +	ch := make(chan string) +	_, err = conn.StopUnitContext(ctx, name, "replace", ch) +	if err != nil { +		return err +	} +	<-ch +	return nil +} + +func newProperty(name string, units interface{}) systemdDbus.Property { +	return systemdDbus.Property{ +		Name:  name, +		Value: dbus.MakeVariant(units), +	} +} + +func splitName(path string) (slice string, unit string) { +	slice, unit = filepath.Split(path) +	return strings.TrimSuffix(slice, "/"), unit +} diff --git a/vendor/github.com/containerd/cgroups/ticks.go b/vendor/github.com/containerd/cgroups/ticks.go new file mode 100644 index 000000000..84dc38d0c --- /dev/null +++ b/vendor/github.com/containerd/cgroups/ticks.go @@ -0,0 +1,26 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +func getClockTicks() uint64 { +	// The value comes from `C.sysconf(C._SC_CLK_TCK)`, and +	// on Linux it's a constant which is safe to be hard coded, +	// so we can avoid using cgo here. +	// See https://github.com/containerd/cgroups/pull/12 for +	// more details. +	return 100 +} diff --git a/vendor/github.com/containerd/cgroups/utils.go b/vendor/github.com/containerd/cgroups/utils.go new file mode 100644 index 000000000..217138975 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/utils.go @@ -0,0 +1,392 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"bufio" +	"errors" +	"fmt" +	"io" +	"io/ioutil" +	"os" +	"path/filepath" +	"strconv" +	"strings" +	"sync" +	"syscall" +	"time" + +	units "github.com/docker/go-units" +	specs "github.com/opencontainers/runtime-spec/specs-go" +	"golang.org/x/sys/unix" +) + +var ( +	nsOnce    sync.Once +	inUserNS  bool +	checkMode sync.Once +	cgMode    CGMode +) + +const unifiedMountpoint = "/sys/fs/cgroup" + +// CGMode is the cgroups mode of the host system +type CGMode int + +const ( +	// Unavailable cgroup mountpoint +	Unavailable CGMode = iota +	// Legacy cgroups v1 +	Legacy +	// Hybrid with cgroups v1 and v2 controllers mounted +	Hybrid +	// Unified with only cgroups v2 mounted +	Unified +) + +// Mode returns the cgroups mode running on the host +func Mode() CGMode { +	checkMode.Do(func() { +		var st unix.Statfs_t +		if err := unix.Statfs(unifiedMountpoint, &st); err != nil { +			cgMode = Unavailable +			return +		} +		switch st.Type { +		case unix.CGROUP2_SUPER_MAGIC: +			cgMode = Unified +		default: +			cgMode = Legacy +			if err := unix.Statfs(filepath.Join(unifiedMountpoint, "unified"), &st); err != nil { +				return +			} +			if st.Type == unix.CGROUP2_SUPER_MAGIC { +				cgMode = Hybrid +			} +		} +	}) +	return cgMode +} + +// RunningInUserNS detects whether we are currently running in a user namespace. +// Copied from github.com/lxc/lxd/shared/util.go +func RunningInUserNS() bool { +	nsOnce.Do(func() { +		file, err := os.Open("/proc/self/uid_map") +		if err != nil { +			// This kernel-provided file only exists if user namespaces are supported +			return +		} +		defer file.Close() + +		buf := bufio.NewReader(file) +		l, _, err := buf.ReadLine() +		if err != nil { +			return +		} + +		line := string(l) +		var a, b, c int64 +		fmt.Sscanf(line, "%d %d %d", &a, &b, &c) + +		/* +		 * We assume we are in the initial user namespace if we have a full +		 * range - 4294967295 uids starting at uid 0. +		 */ +		if a == 0 && b == 0 && c == 4294967295 { +			return +		} +		inUserNS = true +	}) +	return inUserNS +} + +// defaults returns all known groups +func defaults(root string) ([]Subsystem, error) { +	h, err := NewHugetlb(root) +	if err != nil && !os.IsNotExist(err) { +		return nil, err +	} +	s := []Subsystem{ +		NewNamed(root, "systemd"), +		NewFreezer(root), +		NewPids(root), +		NewNetCls(root), +		NewNetPrio(root), +		NewPerfEvent(root), +		NewCpuset(root), +		NewCpu(root), +		NewCpuacct(root), +		NewMemory(root), +		NewBlkio(root), +		NewRdma(root), +	} +	// only add the devices cgroup if we are not in a user namespace +	// because modifications are not allowed +	if !RunningInUserNS() { +		s = append(s, NewDevices(root)) +	} +	// add the hugetlb cgroup if error wasn't due to missing hugetlb +	// cgroup support on the host +	if err == nil { +		s = append(s, h) +	} +	return s, nil +} + +// remove will remove a cgroup path handling EAGAIN and EBUSY errors and +// retrying the remove after a exp timeout +func remove(path string) error { +	delay := 10 * time.Millisecond +	for i := 0; i < 5; i++ { +		if i != 0 { +			time.Sleep(delay) +			delay *= 2 +		} +		if err := os.RemoveAll(path); err == nil { +			return nil +		} +	} +	return fmt.Errorf("cgroups: unable to remove path %q", path) +} + +// readPids will read all the pids of processes or tasks in a cgroup by the provided path +func readPids(path string, subsystem Name, pType procType) ([]Process, error) { +	f, err := os.Open(filepath.Join(path, pType)) +	if err != nil { +		return nil, err +	} +	defer f.Close() +	var ( +		out []Process +		s   = bufio.NewScanner(f) +	) +	for s.Scan() { +		if t := s.Text(); t != "" { +			pid, err := strconv.Atoi(t) +			if err != nil { +				return nil, err +			} +			out = append(out, Process{ +				Pid:       pid, +				Subsystem: subsystem, +				Path:      path, +			}) +		} +	} +	if err := s.Err(); err != nil { +		// failed to read all pids? +		return nil, err +	} +	return out, nil +} + +func hugePageSizes() ([]string, error) { +	var ( +		pageSizes []string +		sizeList  = []string{"B", "KB", "MB", "GB", "TB", "PB"} +	) +	files, err := ioutil.ReadDir("/sys/kernel/mm/hugepages") +	if err != nil { +		return nil, err +	} +	for _, st := range files { +		nameArray := strings.Split(st.Name(), "-") +		pageSize, err := units.RAMInBytes(nameArray[1]) +		if err != nil { +			return nil, err +		} +		pageSizes = append(pageSizes, units.CustomSize("%g%s", float64(pageSize), 1024.0, sizeList)) +	} +	return pageSizes, nil +} + +func readUint(path string) (uint64, error) { +	v, err := ioutil.ReadFile(path) +	if err != nil { +		return 0, err +	} +	return parseUint(strings.TrimSpace(string(v)), 10, 64) +} + +func parseUint(s string, base, bitSize int) (uint64, error) { +	v, err := strconv.ParseUint(s, base, bitSize) +	if err != nil { +		intValue, intErr := strconv.ParseInt(s, base, bitSize) +		// 1. Handle negative values greater than MinInt64 (and) +		// 2. Handle negative values lesser than MinInt64 +		if intErr == nil && intValue < 0 { +			return 0, nil +		} else if intErr != nil && +			intErr.(*strconv.NumError).Err == strconv.ErrRange && +			intValue < 0 { +			return 0, nil +		} +		return 0, err +	} +	return v, nil +} + +func parseKV(raw string) (string, uint64, error) { +	parts := strings.Fields(raw) +	switch len(parts) { +	case 2: +		v, err := parseUint(parts[1], 10, 64) +		if err != nil { +			return "", 0, err +		} +		return parts[0], v, nil +	default: +		return "", 0, ErrInvalidFormat +	} +} + +// ParseCgroupFile parses the given cgroup file, typically /proc/self/cgroup +// or /proc/<pid>/cgroup, into a map of subsystems to cgroup paths, e.g. +//   "cpu": "/user.slice/user-1000.slice" +//   "pids": "/user.slice/user-1000.slice" +// etc. +// +// The resulting map does not have an element for cgroup v2 unified hierarchy. +// Use ParseCgroupFileUnified to get the unified path. +func ParseCgroupFile(path string) (map[string]string, error) { +	x, _, err := ParseCgroupFileUnified(path) +	return x, err +} + +// ParseCgroupFileUnified returns legacy subsystem paths as the first value, +// and returns the unified path as the second value. +func ParseCgroupFileUnified(path string) (map[string]string, string, error) { +	f, err := os.Open(path) +	if err != nil { +		return nil, "", err +	} +	defer f.Close() +	return parseCgroupFromReaderUnified(f) +} + +func parseCgroupFromReaderUnified(r io.Reader) (map[string]string, string, error) { +	var ( +		cgroups = make(map[string]string) +		unified = "" +		s       = bufio.NewScanner(r) +	) +	for s.Scan() { +		var ( +			text  = s.Text() +			parts = strings.SplitN(text, ":", 3) +		) +		if len(parts) < 3 { +			return nil, unified, fmt.Errorf("invalid cgroup entry: %q", text) +		} +		for _, subs := range strings.Split(parts[1], ",") { +			if subs == "" { +				unified = parts[2] +			} else { +				cgroups[subs] = parts[2] +			} +		} +	} +	if err := s.Err(); err != nil { +		return nil, unified, err +	} +	return cgroups, unified, nil +} + +func getCgroupDestination(subsystem string) (string, error) { +	f, err := os.Open("/proc/self/mountinfo") +	if err != nil { +		return "", err +	} +	defer f.Close() +	s := bufio.NewScanner(f) +	for s.Scan() { +		fields := strings.Split(s.Text(), " ") +		if len(fields) < 10 { +			// broken mountinfo? +			continue +		} +		if fields[len(fields)-3] != "cgroup" { +			continue +		} +		for _, opt := range strings.Split(fields[len(fields)-1], ",") { +			if opt == subsystem { +				return fields[3], nil +			} +		} +	} +	if err := s.Err(); err != nil { +		return "", err +	} +	return "", ErrNoCgroupMountDestination +} + +func pathers(subystems []Subsystem) []pather { +	var out []pather +	for _, s := range subystems { +		if p, ok := s.(pather); ok { +			out = append(out, p) +		} +	} +	return out +} + +func initializeSubsystem(s Subsystem, path Path, resources *specs.LinuxResources) error { +	if c, ok := s.(creator); ok { +		p, err := path(s.Name()) +		if err != nil { +			return err +		} +		if err := c.Create(p, resources); err != nil { +			return err +		} +	} else if c, ok := s.(pather); ok { +		p, err := path(s.Name()) +		if err != nil { +			return err +		} +		// do the default create if the group does not have a custom one +		if err := os.MkdirAll(c.Path(p), defaultDirPerm); err != nil { +			return err +		} +	} +	return nil +} + +func cleanPath(path string) string { +	if path == "" { +		return "" +	} +	path = filepath.Clean(path) +	if !filepath.IsAbs(path) { +		path, _ = filepath.Rel(string(os.PathSeparator), filepath.Clean(string(os.PathSeparator)+path)) +	} +	return path +} + +func retryingWriteFile(path string, data []byte, mode os.FileMode) error { +	// Retry writes on EINTR; see: +	//    https://github.com/golang/go/issues/38033 +	for { +		err := ioutil.WriteFile(path, data, mode) +		if err == nil { +			return nil +		} else if !errors.Is(err, syscall.EINTR) { +			return err +		} +	} +} diff --git a/vendor/github.com/containerd/cgroups/v1.go b/vendor/github.com/containerd/cgroups/v1.go new file mode 100644 index 000000000..2ec215c06 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v1.go @@ -0,0 +1,73 @@ +/* +   Copyright The containerd Authors. + +   Licensed under the Apache License, Version 2.0 (the "License"); +   you may not use this file except in compliance with the License. +   You may obtain a copy of the License at + +       http://www.apache.org/licenses/LICENSE-2.0 + +   Unless required by applicable law or agreed to in writing, software +   distributed under the License is distributed on an "AS IS" BASIS, +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +   See the License for the specific language governing permissions and +   limitations under the License. +*/ + +package cgroups + +import ( +	"bufio" +	"fmt" +	"os" +	"path/filepath" +	"strings" +) + +// V1 returns all the groups in the default cgroups mountpoint in a single hierarchy +func V1() ([]Subsystem, error) { +	root, err := v1MountPoint() +	if err != nil { +		return nil, err +	} +	subsystems, err := defaults(root) +	if err != nil { +		return nil, err +	} +	var enabled []Subsystem +	for _, s := range pathers(subsystems) { +		// check and remove the default groups that do not exist +		if _, err := os.Lstat(s.Path("/")); err == nil { +			enabled = append(enabled, s) +		} +	} +	return enabled, nil +} + +// v1MountPoint returns the mount point where the cgroup +// mountpoints are mounted in a single hiearchy +func v1MountPoint() (string, error) { +	f, err := os.Open("/proc/self/mountinfo") +	if err != nil { +		return "", err +	} +	defer f.Close() +	scanner := bufio.NewScanner(f) +	for scanner.Scan() { +		var ( +			text      = scanner.Text() +			fields    = strings.Split(text, " ") +			numFields = len(fields) +		) +		if numFields < 10 { +			return "", fmt.Errorf("mountinfo: bad entry %q", text) +		} +		if fields[numFields-3] == "cgroup" { +			return filepath.Dir(fields[4]), nil +		} +	} +	if err := scanner.Err(); err != nil { +		return "", err +	} +	return "", ErrMountPointNotExist +} diff --git a/vendor/github.com/containerd/cgroups/v2/cpu.go b/vendor/github.com/containerd/cgroups/v2/cpu.go new file mode 100644 index 000000000..65282ff08 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/cpu.go @@ -0,0 +1,83 @@ +/* +   Copyright The containerd Authors. + +   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 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    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{ +			filename: "cpu.weight", +			value:    *r.Weight, +		}) +	} +	if r.Max != "" { +		o = append(o, Value{ +			filename: "cpu.max", +			value:    r.Max, +		}) +	} +	if r.Cpus != "" { +		o = append(o, Value{ +			filename: "cpuset.cpus", +			value:    r.Cpus, +		}) +	} +	if r.Mems != "" { +		o = append(o, Value{ +			filename: "cpuset.mems", +			value:    r.Mems, +		}) +	} +	return o +} diff --git a/vendor/github.com/containerd/cgroups/v2/devicefilter.go b/vendor/github.com/containerd/cgroups/v2/devicefilter.go new file mode 100644 index 000000000..0882036c2 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/devicefilter.go @@ -0,0 +1,200 @@ +/* +   Copyright The containerd Authors. + +   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. +*/ + +// Devicefilter containes eBPF device filter program +// +// The implementation is based on https://github.com/containers/crun/blob/0.10.2/src/libcrun/ebpf.c +// +// Although ebpf.c is originally licensed under LGPL-3.0-or-later, the author (Giuseppe Scrivano) +// agreed to relicense the file in Apache License 2.0: https://github.com/opencontainers/runc/issues/2144#issuecomment-543116397 +// +// This particular Go implementation based on runc version +// https://github.com/opencontainers/runc/blob/master/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go + +package v2 + +import ( +	"errors" +	"fmt" +	"math" + +	"github.com/cilium/ebpf/asm" +	"github.com/opencontainers/runtime-spec/specs-go" +	"golang.org/x/sys/unix" +) + +const ( +	// license string format is same as kernel MODULE_LICENSE macro +	license = "Apache" +) + +// DeviceFilter returns eBPF device filter program and its license string +func DeviceFilter(devices []specs.LinuxDeviceCgroup) (asm.Instructions, string, error) { +	p := &program{} +	p.init() +	for i := len(devices) - 1; i >= 0; i-- { +		if err := p.appendDevice(devices[i]); err != nil { +			return nil, "", err +		} +	} +	insts, err := p.finalize() +	return insts, license, err +} + +type program struct { +	insts       asm.Instructions +	hasWildCard bool +	blockID     int +} + +func (p *program) init() { +	// struct bpf_cgroup_dev_ctx: https://elixir.bootlin.com/linux/v5.3.6/source/include/uapi/linux/bpf.h#L3423 +	/* +		u32 access_type +		u32 major +		u32 minor +	*/ +	// R2 <- type (lower 16 bit of u32 access_type at R1[0]) +	p.insts = append(p.insts, +		asm.LoadMem(asm.R2, asm.R1, 0, asm.Half)) + +	// R3 <- access (upper 16 bit of u32 access_type at R1[0]) +	p.insts = append(p.insts, +		asm.LoadMem(asm.R3, asm.R1, 0, asm.Word), +		// RSh: bitwise shift right +		asm.RSh.Imm32(asm.R3, 16)) + +	// R4 <- major (u32 major at R1[4]) +	p.insts = append(p.insts, +		asm.LoadMem(asm.R4, asm.R1, 4, asm.Word)) + +	// R5 <- minor (u32 minor at R1[8]) +	p.insts = append(p.insts, +		asm.LoadMem(asm.R5, asm.R1, 8, asm.Word)) +} + +// appendDevice needs to be called from the last element of OCI linux.resources.devices to the head element. +func (p *program) appendDevice(dev specs.LinuxDeviceCgroup) error { +	if p.blockID < 0 { +		return errors.New("the program is finalized") +	} +	if p.hasWildCard { +		// All entries after wildcard entry are ignored +		return nil +	} + +	bpfType := int32(-1) +	hasType := true +	switch dev.Type { +	case string('c'): +		bpfType = int32(unix.BPF_DEVCG_DEV_CHAR) +	case string('b'): +		bpfType = int32(unix.BPF_DEVCG_DEV_BLOCK) +	case string('a'): +		hasType = false +	default: +		// if not specified in OCI json, typ is set to DeviceTypeAll +		return fmt.Errorf("invalid DeviceType %q", dev.Type) +	} +	if *dev.Major > math.MaxUint32 { +		return fmt.Errorf("invalid major %d", *dev.Major) +	} +	if *dev.Minor > math.MaxUint32 { +		return fmt.Errorf("invalid minor %d", *dev.Major) +	} +	hasMajor := *dev.Major >= 0 // if not specified in OCI json, major is set to -1 +	hasMinor := *dev.Minor >= 0 +	bpfAccess := int32(0) +	for _, r := range dev.Access { +		switch r { +		case 'r': +			bpfAccess |= unix.BPF_DEVCG_ACC_READ +		case 'w': +			bpfAccess |= unix.BPF_DEVCG_ACC_WRITE +		case 'm': +			bpfAccess |= unix.BPF_DEVCG_ACC_MKNOD +		default: +			return fmt.Errorf("unknown device access %v", r) +		} +	} +	// If the access is rwm, skip the check. +	hasAccess := bpfAccess != (unix.BPF_DEVCG_ACC_READ | unix.BPF_DEVCG_ACC_WRITE | unix.BPF_DEVCG_ACC_MKNOD) + +	blockSym := fmt.Sprintf("block-%d", p.blockID) +	nextBlockSym := fmt.Sprintf("block-%d", p.blockID+1) +	prevBlockLastIdx := len(p.insts) - 1 +	if hasType { +		p.insts = append(p.insts, +			// if (R2 != bpfType) goto next +			asm.JNE.Imm(asm.R2, bpfType, nextBlockSym), +		) +	} +	if hasAccess { +		p.insts = append(p.insts, +			// if (R3 & bpfAccess == 0 /* use R1 as a temp var */) goto next +			asm.Mov.Reg32(asm.R1, asm.R3), +			asm.And.Imm32(asm.R1, bpfAccess), +			asm.JEq.Imm(asm.R1, 0, nextBlockSym), +		) +	} +	if hasMajor { +		p.insts = append(p.insts, +			// if (R4 != major) goto next +			asm.JNE.Imm(asm.R4, int32(*dev.Major), nextBlockSym), +		) +	} +	if hasMinor { +		p.insts = append(p.insts, +			// if (R5 != minor) goto next +			asm.JNE.Imm(asm.R5, int32(*dev.Minor), nextBlockSym), +		) +	} +	if !hasType && !hasAccess && !hasMajor && !hasMinor { +		p.hasWildCard = true +	} +	p.insts = append(p.insts, acceptBlock(dev.Allow)...) +	// set blockSym to the first instruction we added in this iteration +	p.insts[prevBlockLastIdx+1] = p.insts[prevBlockLastIdx+1].Sym(blockSym) +	p.blockID++ +	return nil +} + +func (p *program) finalize() (asm.Instructions, error) { +	if p.hasWildCard { +		// acceptBlock with asm.Return() is already inserted +		return p.insts, nil +	} +	blockSym := fmt.Sprintf("block-%d", p.blockID) +	p.insts = append(p.insts, +		// R0 <- 0 +		asm.Mov.Imm32(asm.R0, 0).Sym(blockSym), +		asm.Return(), +	) +	p.blockID = -1 +	return p.insts, nil +} + +func acceptBlock(accept bool) asm.Instructions { +	v := int32(0) +	if accept { +		v = 1 +	} +	return []asm.Instruction{ +		// R0 <- v +		asm.Mov.Imm32(asm.R0, v), +		asm.Return(), +	} +} diff --git a/vendor/github.com/containerd/cgroups/v2/ebpf.go b/vendor/github.com/containerd/cgroups/v2/ebpf.go new file mode 100644 index 000000000..45bf5f99e --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/ebpf.go @@ -0,0 +1,96 @@ +/* +   Copyright The containerd Authors. + +   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 v2 + +import ( +	"fmt" + +	"github.com/cilium/ebpf" +	"github.com/cilium/ebpf/asm" +	"github.com/cilium/ebpf/link" +	"github.com/opencontainers/runtime-spec/specs-go" +	"golang.org/x/sys/unix" +) + +// LoadAttachCgroupDeviceFilter installs eBPF device filter program to /sys/fs/cgroup/<foo> directory. +// +// Requires the system to be running in cgroup2 unified-mode with kernel >= 4.15 . +// +// https://github.com/torvalds/linux/commit/ebc614f687369f9df99828572b1d85a7c2de3d92 +func LoadAttachCgroupDeviceFilter(insts asm.Instructions, license string, dirFD int) (func() error, error) { +	nilCloser := func() error { +		return nil +	} +	spec := &ebpf.ProgramSpec{ +		Type:         ebpf.CGroupDevice, +		Instructions: insts, +		License:      license, +	} +	prog, err := ebpf.NewProgram(spec) +	if err != nil { +		return nilCloser, err +	} +	err = link.RawAttachProgram(link.RawAttachProgramOptions{ +		Target:  dirFD, +		Program: prog, +		Attach:  ebpf.AttachCGroupDevice, +		Flags:   unix.BPF_F_ALLOW_MULTI, +	}) +	if err != nil { +		return nilCloser, fmt.Errorf("failed to call BPF_PROG_ATTACH (BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI): %w", err) +	} +	closer := func() error { +		err = link.RawDetachProgram(link.RawDetachProgramOptions{ +			Target:  dirFD, +			Program: prog, +			Attach:  ebpf.AttachCGroupDevice, +		}) +		if err != nil { +			return fmt.Errorf("failed to call BPF_PROG_DETACH (BPF_CGROUP_DEVICE): %w", err) +		} +		return nil +	} +	return closer, nil +} + +func isRWM(cgroupPermissions string) bool { +	r := false +	w := false +	m := false +	for _, rn := range cgroupPermissions { +		switch rn { +		case 'r': +			r = true +		case 'w': +			w = true +		case 'm': +			m = true +		} +	} +	return r && w && m +} + +// the logic is from runc +// https://github.com/opencontainers/runc/blob/master/libcontainer/cgroups/fs/devices_v2.go#L44 +func canSkipEBPFError(devices []specs.LinuxDeviceCgroup) bool { +	for _, dev := range devices { +		if dev.Allow || !isRWM(dev.Access) { +			return false +		} +	} +	return true +} diff --git a/vendor/github.com/containerd/cgroups/v2/errors.go b/vendor/github.com/containerd/cgroups/v2/errors.go new file mode 100644 index 000000000..eeae362b2 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/errors.go @@ -0,0 +1,26 @@ +/* +   Copyright The containerd Authors. + +   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 v2 + +import ( +	"errors" +) + +var ( +	ErrInvalidFormat    = errors.New("cgroups: parsing file with invalid format failed") +	ErrInvalidGroupPath = errors.New("cgroups: invalid group path") +) diff --git a/vendor/github.com/containerd/cgroups/v2/hugetlb.go b/vendor/github.com/containerd/cgroups/v2/hugetlb.go new file mode 100644 index 000000000..16b35bd78 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/hugetlb.go @@ -0,0 +1,37 @@ +/* +   Copyright The containerd Authors. + +   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 v2 + +import "strings" + +type HugeTlb []HugeTlbEntry + +type HugeTlbEntry struct { +	HugePageSize string +	Limit        uint64 +} + +func (r *HugeTlb) Values() (o []Value) { +	for _, e := range *r { +		o = append(o, Value{ +			filename: strings.Join([]string{"hugetlb", e.HugePageSize, "max"}, "."), +			value:    e.Limit, +		}) +	} + +	return o +} diff --git a/vendor/github.com/containerd/cgroups/v2/io.go b/vendor/github.com/containerd/cgroups/v2/io.go new file mode 100644 index 000000000..70078d576 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/io.go @@ -0,0 +1,64 @@ +/* +   Copyright The containerd Authors. + +   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 v2 + +import "fmt" + +type IOType string + +const ( +	ReadBPS   IOType = "rbps" +	WriteBPS  IOType = "wbps" +	ReadIOPS  IOType = "riops" +	WriteIOPS IOType = "wiops" +) + +type BFQ struct { +	Weight uint16 +} + +type Entry struct { +	Type  IOType +	Major int64 +	Minor int64 +	Rate  uint64 +} + +func (e Entry) String() string { +	return fmt.Sprintf("%d:%d %s=%d", e.Major, e.Minor, e.Type, e.Rate) +} + +type IO struct { +	BFQ BFQ +	Max []Entry +} + +func (i *IO) Values() (o []Value) { +	if i.BFQ.Weight != 0 { +		o = append(o, Value{ +			filename: "io.bfq.weight", +			value:    i.BFQ.Weight, +		}) +	} +	for _, e := range i.Max { +		o = append(o, Value{ +			filename: "io.max", +			value:    e.String(), +		}) +	} +	return o +} diff --git a/vendor/github.com/containerd/cgroups/v2/manager.go b/vendor/github.com/containerd/cgroups/v2/manager.go new file mode 100644 index 000000000..1f017509f --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/manager.go @@ -0,0 +1,863 @@ +/* +   Copyright The containerd Authors. + +   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 v2 + +import ( +	"bufio" +	"context" +	"errors" +	"fmt" +	"io/ioutil" +	"math" +	"os" +	"path/filepath" +	"strconv" +	"strings" +	"syscall" +	"time" + +	"github.com/containerd/cgroups/v2/stats" + +	systemdDbus "github.com/coreos/go-systemd/v22/dbus" +	"github.com/godbus/dbus/v5" +	"github.com/opencontainers/runtime-spec/specs-go" +	"github.com/sirupsen/logrus" +	"golang.org/x/sys/unix" +) + +const ( +	subtreeControl     = "cgroup.subtree_control" +	controllersFile    = "cgroup.controllers" +	defaultCgroup2Path = "/sys/fs/cgroup" +	defaultSlice       = "system.slice" +) + +var ( +	canDelegate bool +) + +type Event struct { +	Low     uint64 +	High    uint64 +	Max     uint64 +	OOM     uint64 +	OOMKill uint64 +} + +// Resources for a cgroups v2 unified hierarchy +type Resources struct { +	CPU     *CPU +	Memory  *Memory +	Pids    *Pids +	IO      *IO +	RDMA    *RDMA +	HugeTlb *HugeTlb +	// When len(Devices) is zero, devices are not controlled +	Devices []specs.LinuxDeviceCgroup +} + +// Values returns the raw filenames and values that +// can be written to the unified hierarchy +func (r *Resources) Values() (o []Value) { +	if r.CPU != nil { +		o = append(o, r.CPU.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()...) +	} +	if r.HugeTlb != nil { +		o = append(o, r.HugeTlb.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") +	} +	if r.HugeTlb != nil { +		c = append(c, "hugetlb") +	} +	return +} + +// Value of a cgroup setting +type Value struct { +	filename string +	value    interface{} +} + +// write the value to the full, absolute path, of a unified hierarchy +func (c *Value) write(path string, perm os.FileMode) error { +	var data []byte +	switch t := c.value.(type) { +	case uint64: +		data = []byte(strconv.FormatUint(t, 10)) +	case uint16: +		data = []byte(strconv.FormatUint(uint64(t), 10)) +	case int64: +		data = []byte(strconv.FormatInt(t, 10)) +	case []byte: +		data = t +	case string: +		data = []byte(t) +	case CPUMax: +		data = []byte(t) +	default: +		return ErrInvalidFormat +	} + +	// Retry writes on EINTR; see: +	//    https://github.com/golang/go/issues/38033 +	for { +		err := ioutil.WriteFile( +			filepath.Join(path, c.filename), +			data, +			perm, +		) +		if err == nil { +			return nil +		} else if !errors.Is(err, syscall.EINTR) { +			return err +		} +	} +} + +func writeValues(path string, values []Value) error { +	for _, o := range values { +		if err := o.write(path, defaultFilePerm); err != nil { +			return err +		} +	} +	return nil +} + +func NewManager(mountpoint string, group string, resources *Resources) (*Manager, error) { +	if resources == nil { +		return nil, errors.New("resources reference is nil") +	} +	if err := VerifyGroupPath(group); err != nil { +		return nil, err +	} +	path := filepath.Join(mountpoint, group) +	if err := os.MkdirAll(path, defaultDirPerm); err != nil { +		return nil, err +	} +	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 +	} +	if err := setResources(path, resources); err != nil { +		os.Remove(path) +		return nil, err +	} +	return &m, nil +} + +func LoadManager(mountpoint string, group string) (*Manager, error) { +	if err := VerifyGroupPath(group); err != nil { +		return nil, err +	} +	path := filepath.Join(mountpoint, group) +	return &Manager{ +		unifiedMountpoint: mountpoint, +		path:              path, +	}, nil +} + +type Manager struct { +	unifiedMountpoint string +	path              string +} + +func setResources(path string, resources *Resources) error { +	if resources != nil { +		if err := writeValues(path, resources.Values()); err != nil { +			return err +		} +		if err := setDevices(path, resources.Devices); err != nil { +			return err +		} +	} +	return nil +} + +func (c *Manager) RootControllers() ([]string, error) { +	b, err := ioutil.ReadFile(filepath.Join(c.unifiedMountpoint, controllersFile)) +	if err != nil { +		return nil, err +	} +	return strings.Fields(string(b)), nil +} + +func (c *Manager) Controllers() ([]string, error) { +	b, err := ioutil.ReadFile(filepath.Join(c.path, controllersFile)) +	if err != nil { +		return nil, err +	} +	return strings.Fields(string(b)), nil +} + +func (c *Manager) Update(resources *Resources) error { +	return setResources(c.path, resources) +} + +type ControllerToggle int + +const ( +	Enable ControllerToggle = iota + 1 +	Disable +) + +func toggleFunc(controllers []string, prefix string) []string { +	out := make([]string, len(controllers)) +	for i, c := range controllers { +		out[i] = prefix + c +	} +	return out +} + +func (c *Manager) ToggleControllers(controllers []string, t ControllerToggle) error { +	// when c.path is like /foo/bar/baz, the following files need to be written: +	// * /sys/fs/cgroup/cgroup.subtree_control +	// * /sys/fs/cgroup/foo/cgroup.subtree_control +	// * /sys/fs/cgroup/foo/bar/cgroup.subtree_control +	// Note that /sys/fs/cgroup/foo/bar/baz/cgroup.subtree_control does not need to be written. +	split := strings.Split(c.path, "/") +	var lastErr error +	for i := range split { +		f := strings.Join(split[:i], "/") +		if !strings.HasPrefix(f, c.unifiedMountpoint) || f == c.path { +			continue +		} +		filePath := filepath.Join(f, subtreeControl) +		if err := c.writeSubtreeControl(filePath, controllers, t); err != nil { +			// When running as rootless, the user may face EPERM on parent groups, but it is neglible when the +			// controller is already written. +			// So we only return the last error. +			lastErr = fmt.Errorf("failed to write subtree controllers %+v to %q: %w", controllers, filePath, err) +		} else { +			lastErr = nil +		} +	} +	return lastErr +} + +func (c *Manager) writeSubtreeControl(filePath string, controllers []string, t ControllerToggle) error { +	f, err := os.OpenFile(filePath, os.O_WRONLY, 0) +	if err != nil { +		return err +	} +	defer f.Close() +	switch t { +	case Enable: +		controllers = toggleFunc(controllers, "+") +	case Disable: +		controllers = toggleFunc(controllers, "-") +	} +	_, err = f.WriteString(strings.Join(controllers, " ")) +	return err +} + +func (c *Manager) NewChild(name string, resources *Resources) (*Manager, error) { +	if strings.HasPrefix(name, "/") { +		return nil, errors.New("name must be relative") +	} +	path := filepath.Join(c.path, name) +	if err := os.MkdirAll(path, defaultDirPerm); err != nil { +		return nil, err +	} +	m := Manager{ +		unifiedMountpoint: c.unifiedMountpoint, +		path:              path, +	} +	if resources != nil { +		if err := m.ToggleControllers(resources.EnabledControllers(), Enable); err != nil { +			// clean up cgroup dir on failure +			os.Remove(path) +			return nil, err +		} +	} +	if err := setResources(path, resources); err != nil { +		// clean up cgroup dir on failure +		os.Remove(path) +		return nil, err +	} +	return &m, nil +} + +func (c *Manager) AddProc(pid uint64) error { +	v := Value{ +		filename: cgroupProcs, +		value:    pid, +	} +	return writeValues(c.path, []Value{v}) +} + +func (c *Manager) Delete() error { +	return remove(c.path) +} + +func (c *Manager) Procs(recursive bool) ([]uint64, error) { +	var processes []uint64 +	err := filepath.Walk(c.path, func(p string, info os.FileInfo, err error) error { +		if err != nil { +			return err +		} +		if !recursive && info.IsDir() { +			if p == c.path { +				return nil +			} +			return filepath.SkipDir +		} +		_, name := filepath.Split(p) +		if name != cgroupProcs { +			return nil +		} +		procs, err := parseCgroupProcsFile(p) +		if err != nil { +			return err +		} +		processes = append(processes, procs...) +		return nil +	}) +	return processes, err +} + +var singleValueFiles = []string{ +	"pids.current", +	"pids.max", +} + +func (c *Manager) Stat() (*stats.Metrics, error) { +	controllers, err := c.Controllers() +	if err != nil { +		return nil, err +	} +	out := make(map[string]interface{}) +	for _, controller := range controllers { +		switch controller { +		case "cpu", "memory": +			if err := readKVStatsFile(c.path, controller+".stat", out); err != nil { +				if os.IsNotExist(err) { +					continue +				} +				return nil, err +			} +		} +	} +	for _, name := range singleValueFiles { +		if err := readSingleFile(c.path, name, out); err != nil { +			if os.IsNotExist(err) { +				continue +			} +			return nil, err +		} +	} +	memoryEvents := make(map[string]interface{}) +	if err := readKVStatsFile(c.path, "memory.events", memoryEvents); err != nil { +		if !os.IsNotExist(err) { +			return nil, err +		} +	} +	var metrics stats.Metrics + +	metrics.Pids = &stats.PidsStat{ +		Current: getPidValue("pids.current", out), +		Limit:   getPidValue("pids.max", out), +	} +	metrics.CPU = &stats.CPUStat{ +		UsageUsec:     getUint64Value("usage_usec", out), +		UserUsec:      getUint64Value("user_usec", out), +		SystemUsec:    getUint64Value("system_usec", out), +		NrPeriods:     getUint64Value("nr_periods", out), +		NrThrottled:   getUint64Value("nr_throttled", out), +		ThrottledUsec: getUint64Value("throttled_usec", out), +	} +	metrics.Memory = &stats.MemoryStat{ +		Anon:                  getUint64Value("anon", out), +		File:                  getUint64Value("file", out), +		KernelStack:           getUint64Value("kernel_stack", out), +		Slab:                  getUint64Value("slab", out), +		Sock:                  getUint64Value("sock", out), +		Shmem:                 getUint64Value("shmem", out), +		FileMapped:            getUint64Value("file_mapped", out), +		FileDirty:             getUint64Value("file_dirty", out), +		FileWriteback:         getUint64Value("file_writeback", out), +		AnonThp:               getUint64Value("anon_thp", out), +		InactiveAnon:          getUint64Value("inactive_anon", out), +		ActiveAnon:            getUint64Value("active_anon", out), +		InactiveFile:          getUint64Value("inactive_file", out), +		ActiveFile:            getUint64Value("active_file", out), +		Unevictable:           getUint64Value("unevictable", out), +		SlabReclaimable:       getUint64Value("slab_reclaimable", out), +		SlabUnreclaimable:     getUint64Value("slab_unreclaimable", out), +		Pgfault:               getUint64Value("pgfault", out), +		Pgmajfault:            getUint64Value("pgmajfault", out), +		WorkingsetRefault:     getUint64Value("workingset_refault", out), +		WorkingsetActivate:    getUint64Value("workingset_activate", out), +		WorkingsetNodereclaim: getUint64Value("workingset_nodereclaim", out), +		Pgrefill:              getUint64Value("pgrefill", out), +		Pgscan:                getUint64Value("pgscan", out), +		Pgsteal:               getUint64Value("pgsteal", out), +		Pgactivate:            getUint64Value("pgactivate", out), +		Pgdeactivate:          getUint64Value("pgdeactivate", out), +		Pglazyfree:            getUint64Value("pglazyfree", out), +		Pglazyfreed:           getUint64Value("pglazyfreed", out), +		ThpFaultAlloc:         getUint64Value("thp_fault_alloc", out), +		ThpCollapseAlloc:      getUint64Value("thp_collapse_alloc", out), +		Usage:                 getStatFileContentUint64(filepath.Join(c.path, "memory.current")), +		UsageLimit:            getStatFileContentUint64(filepath.Join(c.path, "memory.max")), +		SwapUsage:             getStatFileContentUint64(filepath.Join(c.path, "memory.swap.current")), +		SwapLimit:             getStatFileContentUint64(filepath.Join(c.path, "memory.swap.max")), +	} +	if len(memoryEvents) > 0 { +		metrics.MemoryEvents = &stats.MemoryEvents{ +			Low:     getUint64Value("low", memoryEvents), +			High:    getUint64Value("high", memoryEvents), +			Max:     getUint64Value("max", memoryEvents), +			Oom:     getUint64Value("oom", memoryEvents), +			OomKill: getUint64Value("oom_kill", memoryEvents), +		} +	} +	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")), +	} +	metrics.Hugetlb = readHugeTlbStats(c.path) + +	return &metrics, nil +} + +func getUint64Value(key string, out map[string]interface{}) uint64 { +	v, ok := out[key] +	if !ok { +		return 0 +	} +	switch t := v.(type) { +	case uint64: +		return t +	} +	return 0 +} + +func getPidValue(key string, out map[string]interface{}) uint64 { +	v, ok := out[key] +	if !ok { +		return 0 +	} +	switch t := v.(type) { +	case uint64: +		return t +	case string: +		if t == "max" { +			return math.MaxUint64 +		} +	} +	return 0 +} + +func readSingleFile(path string, file string, out map[string]interface{}) error { +	f, err := os.Open(filepath.Join(path, file)) +	if err != nil { +		return err +	} +	defer f.Close() +	data, err := ioutil.ReadAll(f) +	if err != nil { +		return err +	} +	s := strings.TrimSpace(string(data)) +	v, err := parseUint(s, 10, 64) +	if err != nil { +		// if we cannot parse as a uint, parse as a string +		out[file] = s +		return nil +	} +	out[file] = v +	return nil +} + +func readKVStatsFile(path string, file string, out map[string]interface{}) error { +	f, err := os.Open(filepath.Join(path, file)) +	if err != nil { +		return err +	} +	defer f.Close() + +	s := bufio.NewScanner(f) +	for s.Scan() { +		name, value, err := parseKV(s.Text()) +		if err != nil { +			return fmt.Errorf("error while parsing %s (line=%q): %w", filepath.Join(path, file), s.Text(), err) +		} +		out[name] = value +	} +	return s.Err() +} + +func (c *Manager) Freeze() error { +	return c.freeze(c.path, Frozen) +} + +func (c *Manager) Thaw() error { +	return c.freeze(c.path, Thawed) +} + +func (c *Manager) freeze(path string, state State) error { +	values := state.Values() +	for { +		if err := writeValues(path, values); err != nil { +			return err +		} +		current, err := fetchState(path) +		if err != nil { +			return err +		} +		if current == state { +			return nil +		} +		time.Sleep(1 * time.Millisecond) +	} +} + +func (c *Manager) isCgroupEmpty() bool { +	// In case of any error we return true so that we exit and don't leak resources +	out := make(map[string]interface{}) +	if err := readKVStatsFile(c.path, "cgroup.events", out); err != nil { +		return true +	} +	if v, ok := out["populated"]; ok { +		populated, ok := v.(uint64) +		if !ok { +			return true +		} +		return populated == 0 +	} +	return true +} + +// MemoryEventFD returns inotify file descriptor and 'memory.events' inotify watch descriptor +func (c *Manager) MemoryEventFD() (int, uint32, error) { +	fpath := filepath.Join(c.path, "memory.events") +	fd, err := syscall.InotifyInit() +	if err != nil { +		return 0, 0, errors.New("failed to create inotify fd") +	} +	wd, err := syscall.InotifyAddWatch(fd, fpath, unix.IN_MODIFY) +	if err != nil { +		syscall.Close(fd) +		return 0, 0, fmt.Errorf("failed to add inotify watch for %q: %w", fpath, err) +	} +	// monitor to detect process exit/cgroup deletion +	evpath := filepath.Join(c.path, "cgroup.events") +	if _, err = syscall.InotifyAddWatch(fd, evpath, unix.IN_MODIFY); err != nil { +		syscall.Close(fd) +		return 0, 0, fmt.Errorf("failed to add inotify watch for %q: %w", evpath, err) +	} + +	return fd, uint32(wd), nil +} + +func (c *Manager) EventChan() (<-chan Event, <-chan error) { +	ec := make(chan Event) +	errCh := make(chan error, 1) +	go c.waitForEvents(ec, errCh) + +	return ec, errCh +} + +func parseMemoryEvents(out map[string]interface{}) (Event, error) { +	e := Event{} +	if v, ok := out["high"]; ok { +		e.High, ok = v.(uint64) +		if !ok { +			return Event{}, fmt.Errorf("cannot convert high to uint64: %+v", v) +		} +	} +	if v, ok := out["low"]; ok { +		e.Low, ok = v.(uint64) +		if !ok { +			return Event{}, fmt.Errorf("cannot convert low to uint64: %+v", v) +		} +	} +	if v, ok := out["max"]; ok { +		e.Max, ok = v.(uint64) +		if !ok { +			return Event{}, fmt.Errorf("cannot convert max to uint64: %+v", v) +		} +	} +	if v, ok := out["oom"]; ok { +		e.OOM, ok = v.(uint64) +		if !ok { +			return Event{}, fmt.Errorf("cannot convert oom to uint64: %+v", v) +		} +	} +	if v, ok := out["oom_kill"]; ok { +		e.OOMKill, ok = v.(uint64) +		if !ok { +			return Event{}, fmt.Errorf("cannot convert oom_kill to uint64: %+v", v) +		} +	} +	return e, nil +} + +func (c *Manager) waitForEvents(ec chan<- Event, errCh chan<- error) { +	defer close(errCh) + +	fd, _, err := c.MemoryEventFD() +	if err != nil { +		errCh <- err +		return +	} +	defer syscall.Close(fd) + +	for { +		buffer := make([]byte, syscall.SizeofInotifyEvent*10) +		bytesRead, err := syscall.Read(fd, buffer) +		if err != nil { +			errCh <- err +			return +		} +		if bytesRead >= syscall.SizeofInotifyEvent { +			out := make(map[string]interface{}) +			if err := readKVStatsFile(c.path, "memory.events", out); err != nil { +				// When cgroup is deleted read may return -ENODEV instead of -ENOENT from open. +				if _, statErr := os.Lstat(filepath.Join(c.path, "memory.events")); !os.IsNotExist(statErr) { +					errCh <- err +				} +				return +			} +			e, err := parseMemoryEvents(out) +			if err != nil { +				errCh <- err +				return +			} +			ec <- e +			if c.isCgroupEmpty() { +				return +			} +		} +	} +} + +func setDevices(path string, devices []specs.LinuxDeviceCgroup) error { +	if len(devices) == 0 { +		return nil +	} +	insts, license, err := DeviceFilter(devices) +	if err != nil { +		return err +	} +	dirFD, err := unix.Open(path, unix.O_DIRECTORY|unix.O_RDONLY|unix.O_CLOEXEC, 0600) +	if err != nil { +		return fmt.Errorf("cannot get dir FD for %s", path) +	} +	defer unix.Close(dirFD) +	if _, err := LoadAttachCgroupDeviceFilter(insts, license, dirFD); err != nil { +		if !canSkipEBPFError(devices) { +			return err +		} +	} +	return nil +} + +// getSystemdFullPath returns the full systemd path when creating a systemd slice group. +// the reason this is necessary is because the "-" character has a special meaning in +// systemd slice. For example, when creating a slice called "my-group-112233.slice", +// systemd will create a hierarchy like this: +//      /sys/fs/cgroup/my.slice/my-group.slice/my-group-112233.slice +func getSystemdFullPath(slice, group string) string { +	return filepath.Join(defaultCgroup2Path, dashesToPath(slice), dashesToPath(group)) +} + +// dashesToPath converts a slice name with dashes to it's corresponding systemd filesystem path. +func dashesToPath(in string) string { +	path := "" +	if strings.HasSuffix(in, ".slice") && strings.Contains(in, "-") { +		parts := strings.Split(in, "-") +		for i := range parts { +			s := strings.Join(parts[0:i+1], "-") +			if !strings.HasSuffix(s, ".slice") { +				s += ".slice" +			} +			path = filepath.Join(path, s) +		} +	} else { +		path = filepath.Join(path, in) +	} +	return path +} + +func NewSystemd(slice, group string, pid int, resources *Resources) (*Manager, error) { +	if slice == "" { +		slice = defaultSlice +	} +	ctx := context.TODO() +	path := getSystemdFullPath(slice, group) +	conn, err := systemdDbus.NewWithContext(ctx) +	if err != nil { +		return &Manager{}, err +	} +	defer conn.Close() + +	properties := []systemdDbus.Property{ +		systemdDbus.PropDescription("cgroup " + 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.Min != nil && *resources.Memory.Min != 0 { +		properties = append(properties, +			newSystemdProperty("MemoryMin", uint64(*resources.Memory.Min))) +	} + +	if resources.Memory != nil && resources.Memory.Max != nil && *resources.Memory.Max != 0 { +		properties = append(properties, +			newSystemdProperty("MemoryMax", uint64(*resources.Memory.Max))) +	} + +	if resources.CPU != nil && resources.CPU.Weight != 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.StartTransientUnitContext(ctx, 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 +	} +	path := getSystemdFullPath(slice, group) +	return &Manager{ +		path: path, +	}, nil +} + +func (c *Manager) DeleteSystemd() error { +	ctx := context.TODO() +	conn, err := systemdDbus.NewWithContext(ctx) +	if err != nil { +		return err +	} +	defer conn.Close() +	group := systemdUnitFromPath(c.path) +	ch := make(chan string) +	_, err = conn.StopUnitContext(ctx, 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), +	} +} diff --git a/vendor/github.com/containerd/cgroups/v2/memory.go b/vendor/github.com/containerd/cgroups/v2/memory.go new file mode 100644 index 000000000..6f4733be6 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/memory.go @@ -0,0 +1,59 @@ +/* +   Copyright The containerd Authors. + +   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 v2 + +type Memory struct { +	Swap *int64 +	Min  *int64 +	Max  *int64 +	Low  *int64 +	High *int64 +} + +func (r *Memory) Values() (o []Value) { +	if r.Swap != nil { +		o = append(o, Value{ +			filename: "memory.swap.max", +			value:    *r.Swap, +		}) +	} +	if r.Min != nil { +		o = append(o, Value{ +			filename: "memory.min", +			value:    *r.Min, +		}) +	} +	if r.Max != nil { +		o = append(o, Value{ +			filename: "memory.max", +			value:    *r.Max, +		}) +	} +	if r.Low != nil { +		o = append(o, Value{ +			filename: "memory.low", +			value:    *r.Low, +		}) +	} +	if r.High != nil { +		o = append(o, Value{ +			filename: "memory.high", +			value:    *r.High, +		}) +	} +	return o +} diff --git a/vendor/github.com/containerd/cgroups/v2/paths.go b/vendor/github.com/containerd/cgroups/v2/paths.go new file mode 100644 index 000000000..c4778c142 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/paths.go @@ -0,0 +1,60 @@ +/* +   Copyright The containerd Authors. + +   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 v2 + +import ( +	"fmt" +	"path/filepath" +	"strings" +) + +// NestedGroupPath will nest the cgroups based on the calling processes cgroup +// placing its child processes inside its own path +func NestedGroupPath(suffix string) (string, error) { +	path, err := parseCgroupFile("/proc/self/cgroup") +	if err != nil { +		return "", err +	} +	return filepath.Join(path, suffix), nil +} + +// PidGroupPath will return the correct cgroup paths for an existing process running inside a cgroup +// This is commonly used for the Load function to restore an existing container +func PidGroupPath(pid int) (string, error) { +	p := fmt.Sprintf("/proc/%d/cgroup", pid) +	return parseCgroupFile(p) +} + +// VerifyGroupPath verifies the format of group path string g. +// The format is same as the third field in /proc/PID/cgroup. +// e.g. "/user.slice/user-1001.slice/session-1.scope" +// +// g must be a "clean" absolute path starts with "/", and must not contain "/sys/fs/cgroup" prefix. +// +// VerifyGroupPath doesn't verify whether g actually exists on the system. +func VerifyGroupPath(g string) error { +	if !strings.HasPrefix(g, "/") { +		return ErrInvalidGroupPath +	} +	if filepath.Clean(g) != g { +		return ErrInvalidGroupPath +	} +	if strings.HasPrefix(g, "/sys/fs/cgroup") { +		return ErrInvalidGroupPath +	} +	return nil +} diff --git a/vendor/github.com/containerd/cgroups/v2/pids.go b/vendor/github.com/containerd/cgroups/v2/pids.go new file mode 100644 index 000000000..0b5aa0c3b --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/pids.go @@ -0,0 +1,37 @@ +/* +   Copyright The containerd Authors. + +   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 v2 + +import "strconv" + +type Pids struct { +	Max int64 +} + +func (r *Pids) Values() (o []Value) { +	if r.Max != 0 { +		limit := "max" +		if r.Max > 0 { +			limit = strconv.FormatInt(r.Max, 10) +		} +		o = append(o, Value{ +			filename: "pids.max", +			value:    limit, +		}) +	} +	return o +} diff --git a/vendor/github.com/containerd/cgroups/v2/rdma.go b/vendor/github.com/containerd/cgroups/v2/rdma.go new file mode 100644 index 000000000..44caa4f57 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/rdma.go @@ -0,0 +1,46 @@ +/* +   Copyright The containerd Authors. + +   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 v2 + +import ( +	"fmt" +) + +type RDMA struct { +	Limit []RDMAEntry +} + +type RDMAEntry struct { +	Device     string +	HcaHandles uint32 +	HcaObjects uint32 +} + +func (r RDMAEntry) String() string { +	return fmt.Sprintf("%s hca_handle=%d hca_object=%d", r.Device, r.HcaHandles, r.HcaObjects) +} + +func (r *RDMA) Values() (o []Value) { +	for _, e := range r.Limit { +		o = append(o, Value{ +			filename: "rdma.max", +			value:    e.String(), +		}) +	} + +	return o +} diff --git a/vendor/github.com/containerd/cgroups/v2/state.go b/vendor/github.com/containerd/cgroups/v2/state.go new file mode 100644 index 000000000..09b75b6c3 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/state.go @@ -0,0 +1,65 @@ +/* +   Copyright The containerd Authors. + +   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 v2 + +import ( +	"io/ioutil" +	"path/filepath" +	"strings" +) + +// State is a type that represents the state of the current cgroup +type State string + +const ( +	Unknown State = "" +	Thawed  State = "thawed" +	Frozen  State = "frozen" +	Deleted State = "deleted" + +	cgroupFreeze = "cgroup.freeze" +) + +func (s State) Values() []Value { +	v := Value{ +		filename: cgroupFreeze, +	} +	switch s { +	case Frozen: +		v.value = "1" +	case Thawed: +		v.value = "0" +	} +	return []Value{ +		v, +	} +} + +func fetchState(path string) (State, error) { +	current, err := ioutil.ReadFile(filepath.Join(path, cgroupFreeze)) +	if err != nil { +		return Unknown, err +	} +	switch strings.TrimSpace(string(current)) { +	case "1": +		return Frozen, nil +	case "0": +		return Thawed, nil +	default: +		return Unknown, nil +	} +} diff --git a/vendor/github.com/containerd/cgroups/v2/stats/doc.go b/vendor/github.com/containerd/cgroups/v2/stats/doc.go new file mode 100644 index 000000000..e51e12f80 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/stats/doc.go @@ -0,0 +1,17 @@ +/* +   Copyright The containerd Authors. + +   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 stats diff --git a/vendor/github.com/containerd/cgroups/v2/stats/metrics.pb.go b/vendor/github.com/containerd/cgroups/v2/stats/metrics.pb.go new file mode 100644 index 000000000..0bd493998 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/stats/metrics.pb.go @@ -0,0 +1,3992 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: github.com/containerd/cgroups/v2/stats/metrics.proto + +package stats + +import ( +	fmt "fmt" +	_ "github.com/gogo/protobuf/gogoproto" +	proto "github.com/gogo/protobuf/proto" +	io "io" +	math "math" +	math_bits "math/bits" +	reflect "reflect" +	strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type Metrics struct { +	Pids                 *PidsStat      `protobuf:"bytes,1,opt,name=pids,proto3" json:"pids,omitempty"` +	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"` +	Hugetlb              []*HugeTlbStat `protobuf:"bytes,7,rep,name=hugetlb,proto3" json:"hugetlb,omitempty"` +	MemoryEvents         *MemoryEvents  `protobuf:"bytes,8,opt,name=memory_events,json=memoryEvents,proto3" json:"memory_events,omitempty"` +	XXX_NoUnkeyedLiteral struct{}       `json:"-"` +	XXX_unrecognized     []byte         `json:"-"` +	XXX_sizecache        int32          `json:"-"` +} + +func (m *Metrics) Reset()      { *m = Metrics{} } +func (*Metrics) ProtoMessage() {} +func (*Metrics) Descriptor() ([]byte, []int) { +	return fileDescriptor_2fc6005842049e6b, []int{0} +} +func (m *Metrics) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *Metrics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_Metrics.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *Metrics) XXX_Merge(src proto.Message) { +	xxx_messageInfo_Metrics.Merge(m, src) +} +func (m *Metrics) XXX_Size() int { +	return m.Size() +} +func (m *Metrics) XXX_DiscardUnknown() { +	xxx_messageInfo_Metrics.DiscardUnknown(m) +} + +var xxx_messageInfo_Metrics proto.InternalMessageInfo + +type PidsStat struct { +	Current              uint64   `protobuf:"varint,1,opt,name=current,proto3" json:"current,omitempty"` +	Limit                uint64   `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *PidsStat) Reset()      { *m = PidsStat{} } +func (*PidsStat) ProtoMessage() {} +func (*PidsStat) Descriptor() ([]byte, []int) { +	return fileDescriptor_2fc6005842049e6b, []int{1} +} +func (m *PidsStat) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *PidsStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_PidsStat.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *PidsStat) XXX_Merge(src proto.Message) { +	xxx_messageInfo_PidsStat.Merge(m, src) +} +func (m *PidsStat) XXX_Size() int { +	return m.Size() +} +func (m *PidsStat) XXX_DiscardUnknown() { +	xxx_messageInfo_PidsStat.DiscardUnknown(m) +} + +var xxx_messageInfo_PidsStat proto.InternalMessageInfo + +type CPUStat struct { +	UsageUsec            uint64   `protobuf:"varint,1,opt,name=usage_usec,json=usageUsec,proto3" json:"usage_usec,omitempty"` +	UserUsec             uint64   `protobuf:"varint,2,opt,name=user_usec,json=userUsec,proto3" json:"user_usec,omitempty"` +	SystemUsec           uint64   `protobuf:"varint,3,opt,name=system_usec,json=systemUsec,proto3" json:"system_usec,omitempty"` +	NrPeriods            uint64   `protobuf:"varint,4,opt,name=nr_periods,json=nrPeriods,proto3" json:"nr_periods,omitempty"` +	NrThrottled          uint64   `protobuf:"varint,5,opt,name=nr_throttled,json=nrThrottled,proto3" json:"nr_throttled,omitempty"` +	ThrottledUsec        uint64   `protobuf:"varint,6,opt,name=throttled_usec,json=throttledUsec,proto3" json:"throttled_usec,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *CPUStat) Reset()      { *m = CPUStat{} } +func (*CPUStat) ProtoMessage() {} +func (*CPUStat) Descriptor() ([]byte, []int) { +	return fileDescriptor_2fc6005842049e6b, []int{2} +} +func (m *CPUStat) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *CPUStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_CPUStat.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *CPUStat) XXX_Merge(src proto.Message) { +	xxx_messageInfo_CPUStat.Merge(m, src) +} +func (m *CPUStat) XXX_Size() int { +	return m.Size() +} +func (m *CPUStat) XXX_DiscardUnknown() { +	xxx_messageInfo_CPUStat.DiscardUnknown(m) +} + +var xxx_messageInfo_CPUStat proto.InternalMessageInfo + +type MemoryStat struct { +	Anon                  uint64   `protobuf:"varint,1,opt,name=anon,proto3" json:"anon,omitempty"` +	File                  uint64   `protobuf:"varint,2,opt,name=file,proto3" json:"file,omitempty"` +	KernelStack           uint64   `protobuf:"varint,3,opt,name=kernel_stack,json=kernelStack,proto3" json:"kernel_stack,omitempty"` +	Slab                  uint64   `protobuf:"varint,4,opt,name=slab,proto3" json:"slab,omitempty"` +	Sock                  uint64   `protobuf:"varint,5,opt,name=sock,proto3" json:"sock,omitempty"` +	Shmem                 uint64   `protobuf:"varint,6,opt,name=shmem,proto3" json:"shmem,omitempty"` +	FileMapped            uint64   `protobuf:"varint,7,opt,name=file_mapped,json=fileMapped,proto3" json:"file_mapped,omitempty"` +	FileDirty             uint64   `protobuf:"varint,8,opt,name=file_dirty,json=fileDirty,proto3" json:"file_dirty,omitempty"` +	FileWriteback         uint64   `protobuf:"varint,9,opt,name=file_writeback,json=fileWriteback,proto3" json:"file_writeback,omitempty"` +	AnonThp               uint64   `protobuf:"varint,10,opt,name=anon_thp,json=anonThp,proto3" json:"anon_thp,omitempty"` +	InactiveAnon          uint64   `protobuf:"varint,11,opt,name=inactive_anon,json=inactiveAnon,proto3" json:"inactive_anon,omitempty"` +	ActiveAnon            uint64   `protobuf:"varint,12,opt,name=active_anon,json=activeAnon,proto3" json:"active_anon,omitempty"` +	InactiveFile          uint64   `protobuf:"varint,13,opt,name=inactive_file,json=inactiveFile,proto3" json:"inactive_file,omitempty"` +	ActiveFile            uint64   `protobuf:"varint,14,opt,name=active_file,json=activeFile,proto3" json:"active_file,omitempty"` +	Unevictable           uint64   `protobuf:"varint,15,opt,name=unevictable,proto3" json:"unevictable,omitempty"` +	SlabReclaimable       uint64   `protobuf:"varint,16,opt,name=slab_reclaimable,json=slabReclaimable,proto3" json:"slab_reclaimable,omitempty"` +	SlabUnreclaimable     uint64   `protobuf:"varint,17,opt,name=slab_unreclaimable,json=slabUnreclaimable,proto3" json:"slab_unreclaimable,omitempty"` +	Pgfault               uint64   `protobuf:"varint,18,opt,name=pgfault,proto3" json:"pgfault,omitempty"` +	Pgmajfault            uint64   `protobuf:"varint,19,opt,name=pgmajfault,proto3" json:"pgmajfault,omitempty"` +	WorkingsetRefault     uint64   `protobuf:"varint,20,opt,name=workingset_refault,json=workingsetRefault,proto3" json:"workingset_refault,omitempty"` +	WorkingsetActivate    uint64   `protobuf:"varint,21,opt,name=workingset_activate,json=workingsetActivate,proto3" json:"workingset_activate,omitempty"` +	WorkingsetNodereclaim uint64   `protobuf:"varint,22,opt,name=workingset_nodereclaim,json=workingsetNodereclaim,proto3" json:"workingset_nodereclaim,omitempty"` +	Pgrefill              uint64   `protobuf:"varint,23,opt,name=pgrefill,proto3" json:"pgrefill,omitempty"` +	Pgscan                uint64   `protobuf:"varint,24,opt,name=pgscan,proto3" json:"pgscan,omitempty"` +	Pgsteal               uint64   `protobuf:"varint,25,opt,name=pgsteal,proto3" json:"pgsteal,omitempty"` +	Pgactivate            uint64   `protobuf:"varint,26,opt,name=pgactivate,proto3" json:"pgactivate,omitempty"` +	Pgdeactivate          uint64   `protobuf:"varint,27,opt,name=pgdeactivate,proto3" json:"pgdeactivate,omitempty"` +	Pglazyfree            uint64   `protobuf:"varint,28,opt,name=pglazyfree,proto3" json:"pglazyfree,omitempty"` +	Pglazyfreed           uint64   `protobuf:"varint,29,opt,name=pglazyfreed,proto3" json:"pglazyfreed,omitempty"` +	ThpFaultAlloc         uint64   `protobuf:"varint,30,opt,name=thp_fault_alloc,json=thpFaultAlloc,proto3" json:"thp_fault_alloc,omitempty"` +	ThpCollapseAlloc      uint64   `protobuf:"varint,31,opt,name=thp_collapse_alloc,json=thpCollapseAlloc,proto3" json:"thp_collapse_alloc,omitempty"` +	Usage                 uint64   `protobuf:"varint,32,opt,name=usage,proto3" json:"usage,omitempty"` +	UsageLimit            uint64   `protobuf:"varint,33,opt,name=usage_limit,json=usageLimit,proto3" json:"usage_limit,omitempty"` +	SwapUsage             uint64   `protobuf:"varint,34,opt,name=swap_usage,json=swapUsage,proto3" json:"swap_usage,omitempty"` +	SwapLimit             uint64   `protobuf:"varint,35,opt,name=swap_limit,json=swapLimit,proto3" json:"swap_limit,omitempty"` +	XXX_NoUnkeyedLiteral  struct{} `json:"-"` +	XXX_unrecognized      []byte   `json:"-"` +	XXX_sizecache         int32    `json:"-"` +} + +func (m *MemoryStat) Reset()      { *m = MemoryStat{} } +func (*MemoryStat) ProtoMessage() {} +func (*MemoryStat) Descriptor() ([]byte, []int) { +	return fileDescriptor_2fc6005842049e6b, []int{3} +} +func (m *MemoryStat) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *MemoryStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_MemoryStat.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *MemoryStat) XXX_Merge(src proto.Message) { +	xxx_messageInfo_MemoryStat.Merge(m, src) +} +func (m *MemoryStat) XXX_Size() int { +	return m.Size() +} +func (m *MemoryStat) XXX_DiscardUnknown() { +	xxx_messageInfo_MemoryStat.DiscardUnknown(m) +} + +var xxx_messageInfo_MemoryStat proto.InternalMessageInfo + +type MemoryEvents struct { +	Low                  uint64   `protobuf:"varint,1,opt,name=low,proto3" json:"low,omitempty"` +	High                 uint64   `protobuf:"varint,2,opt,name=high,proto3" json:"high,omitempty"` +	Max                  uint64   `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty"` +	Oom                  uint64   `protobuf:"varint,4,opt,name=oom,proto3" json:"oom,omitempty"` +	OomKill              uint64   `protobuf:"varint,5,opt,name=oom_kill,json=oomKill,proto3" json:"oom_kill,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *MemoryEvents) Reset()      { *m = MemoryEvents{} } +func (*MemoryEvents) ProtoMessage() {} +func (*MemoryEvents) Descriptor() ([]byte, []int) { +	return fileDescriptor_2fc6005842049e6b, []int{4} +} +func (m *MemoryEvents) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *MemoryEvents) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_MemoryEvents.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *MemoryEvents) XXX_Merge(src proto.Message) { +	xxx_messageInfo_MemoryEvents.Merge(m, src) +} +func (m *MemoryEvents) XXX_Size() int { +	return m.Size() +} +func (m *MemoryEvents) XXX_DiscardUnknown() { +	xxx_messageInfo_MemoryEvents.DiscardUnknown(m) +} + +var xxx_messageInfo_MemoryEvents proto.InternalMessageInfo + +type RdmaStat struct { +	Current              []*RdmaEntry `protobuf:"bytes,1,rep,name=current,proto3" json:"current,omitempty"` +	Limit                []*RdmaEntry `protobuf:"bytes,2,rep,name=limit,proto3" json:"limit,omitempty"` +	XXX_NoUnkeyedLiteral struct{}     `json:"-"` +	XXX_unrecognized     []byte       `json:"-"` +	XXX_sizecache        int32        `json:"-"` +} + +func (m *RdmaStat) Reset()      { *m = RdmaStat{} } +func (*RdmaStat) ProtoMessage() {} +func (*RdmaStat) Descriptor() ([]byte, []int) { +	return fileDescriptor_2fc6005842049e6b, []int{5} +} +func (m *RdmaStat) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *RdmaStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_RdmaStat.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *RdmaStat) XXX_Merge(src proto.Message) { +	xxx_messageInfo_RdmaStat.Merge(m, src) +} +func (m *RdmaStat) XXX_Size() int { +	return m.Size() +} +func (m *RdmaStat) XXX_DiscardUnknown() { +	xxx_messageInfo_RdmaStat.DiscardUnknown(m) +} + +var xxx_messageInfo_RdmaStat proto.InternalMessageInfo + +type RdmaEntry struct { +	Device               string   `protobuf:"bytes,1,opt,name=device,proto3" json:"device,omitempty"` +	HcaHandles           uint32   `protobuf:"varint,2,opt,name=hca_handles,json=hcaHandles,proto3" json:"hca_handles,omitempty"` +	HcaObjects           uint32   `protobuf:"varint,3,opt,name=hca_objects,json=hcaObjects,proto3" json:"hca_objects,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *RdmaEntry) Reset()      { *m = RdmaEntry{} } +func (*RdmaEntry) ProtoMessage() {} +func (*RdmaEntry) Descriptor() ([]byte, []int) { +	return fileDescriptor_2fc6005842049e6b, []int{6} +} +func (m *RdmaEntry) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *RdmaEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_RdmaEntry.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *RdmaEntry) XXX_Merge(src proto.Message) { +	xxx_messageInfo_RdmaEntry.Merge(m, src) +} +func (m *RdmaEntry) XXX_Size() int { +	return m.Size() +} +func (m *RdmaEntry) XXX_DiscardUnknown() { +	xxx_messageInfo_RdmaEntry.DiscardUnknown(m) +} + +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{7} +} +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.MarshalToSizedBuffer(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{8} +} +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.MarshalToSizedBuffer(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 + +type HugeTlbStat struct { +	Current              uint64   `protobuf:"varint,1,opt,name=current,proto3" json:"current,omitempty"` +	Max                  uint64   `protobuf:"varint,2,opt,name=max,proto3" json:"max,omitempty"` +	Pagesize             string   `protobuf:"bytes,3,opt,name=pagesize,proto3" json:"pagesize,omitempty"` +	XXX_NoUnkeyedLiteral struct{} `json:"-"` +	XXX_unrecognized     []byte   `json:"-"` +	XXX_sizecache        int32    `json:"-"` +} + +func (m *HugeTlbStat) Reset()      { *m = HugeTlbStat{} } +func (*HugeTlbStat) ProtoMessage() {} +func (*HugeTlbStat) Descriptor() ([]byte, []int) { +	return fileDescriptor_2fc6005842049e6b, []int{9} +} +func (m *HugeTlbStat) XXX_Unmarshal(b []byte) error { +	return m.Unmarshal(b) +} +func (m *HugeTlbStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +	if deterministic { +		return xxx_messageInfo_HugeTlbStat.Marshal(b, m, deterministic) +	} else { +		b = b[:cap(b)] +		n, err := m.MarshalToSizedBuffer(b) +		if err != nil { +			return nil, err +		} +		return b[:n], nil +	} +} +func (m *HugeTlbStat) XXX_Merge(src proto.Message) { +	xxx_messageInfo_HugeTlbStat.Merge(m, src) +} +func (m *HugeTlbStat) XXX_Size() int { +	return m.Size() +} +func (m *HugeTlbStat) XXX_DiscardUnknown() { +	xxx_messageInfo_HugeTlbStat.DiscardUnknown(m) +} + +var xxx_messageInfo_HugeTlbStat proto.InternalMessageInfo + +func init() { +	proto.RegisterType((*Metrics)(nil), "io.containerd.cgroups.v2.Metrics") +	proto.RegisterType((*PidsStat)(nil), "io.containerd.cgroups.v2.PidsStat") +	proto.RegisterType((*CPUStat)(nil), "io.containerd.cgroups.v2.CPUStat") +	proto.RegisterType((*MemoryStat)(nil), "io.containerd.cgroups.v2.MemoryStat") +	proto.RegisterType((*MemoryEvents)(nil), "io.containerd.cgroups.v2.MemoryEvents") +	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") +	proto.RegisterType((*HugeTlbStat)(nil), "io.containerd.cgroups.v2.HugeTlbStat") +} + +func init() { +	proto.RegisterFile("github.com/containerd/cgroups/v2/stats/metrics.proto", fileDescriptor_2fc6005842049e6b) +} + +var fileDescriptor_2fc6005842049e6b = []byte{ +	// 1198 bytes of a gzipped FileDescriptorProto +	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0x4d, 0x73, 0xd4, 0x46, +	0x13, 0x66, 0xed, 0xc5, 0xeb, 0xed, 0xb5, 0xc1, 0x0c, 0x86, 0x57, 0xc0, 0xcb, 0xda, 0x5e, 0x02, +	0x45, 0xaa, 0x92, 0xdd, 0x94, 0xf3, 0x55, 0x49, 0x91, 0x4a, 0x19, 0x02, 0x45, 0x8a, 0x10, 0x5c, +	0x02, 0x57, 0x8e, 0xaa, 0x59, 0x69, 0x2c, 0x0d, 0x96, 0x34, 0xaa, 0x99, 0x91, 0x1d, 0x73, 0xca, +	0x21, 0xd7, 0x54, 0x7e, 0x4d, 0xfe, 0x03, 0xb7, 0xe4, 0x98, 0x53, 0x2a, 0xf8, 0x97, 0xa4, 0xba, +	0x67, 0x64, 0x29, 0x07, 0x43, 0x6e, 0xd3, 0x4f, 0x3f, 0xdd, 0xea, 0x8f, 0x99, 0x6e, 0xc1, 0x27, +	0xa9, 0xb4, 0x59, 0x3d, 0x9f, 0xc6, 0xaa, 0x98, 0xc5, 0xaa, 0xb4, 0x5c, 0x96, 0x42, 0x27, 0xb3, +	0x38, 0xd5, 0xaa, 0xae, 0xcc, 0xec, 0x70, 0x7b, 0x66, 0x2c, 0xb7, 0x66, 0x56, 0x08, 0xab, 0x65, +	0x6c, 0xa6, 0x95, 0x56, 0x56, 0xb1, 0x40, 0xaa, 0x69, 0xcb, 0x9e, 0x7a, 0xf6, 0xf4, 0x70, 0xfb, +	0xfa, 0x7a, 0xaa, 0x52, 0x45, 0xa4, 0x19, 0x9e, 0x1c, 0x7f, 0xf2, 0xdb, 0x22, 0x0c, 0x9e, 0x3a, +	0x0f, 0xec, 0x33, 0xe8, 0x57, 0x32, 0x31, 0x41, 0x6f, 0xb3, 0x77, 0x77, 0xb4, 0x3d, 0x99, 0x9e, +	0xe5, 0x6a, 0xba, 0x2b, 0x13, 0xf3, 0xdc, 0x72, 0x1b, 0x12, 0x9f, 0xdd, 0x83, 0xc5, 0xb8, 0xaa, +	0x83, 0x05, 0x32, 0xdb, 0x3a, 0xdb, 0xec, 0xc1, 0xee, 0x1e, 0x5a, 0xdd, 0x1f, 0x9c, 0xfc, 0xb5, +	0xb1, 0xf8, 0x60, 0x77, 0x2f, 0x44, 0x33, 0x76, 0x0f, 0x96, 0x0a, 0x51, 0x28, 0x7d, 0x1c, 0xf4, +	0xc9, 0xc1, 0x7b, 0x67, 0x3b, 0x78, 0x4a, 0x3c, 0xfa, 0xb2, 0xb7, 0xc1, 0x98, 0x75, 0x52, 0xf0, +	0xe0, 0xfc, 0xbb, 0x62, 0x0e, 0x93, 0x82, 0xbb, 0x98, 0x91, 0xcf, 0x3e, 0x82, 0x05, 0xa9, 0x82, +	0x25, 0xb2, 0xda, 0x3c, 0xdb, 0xea, 0xdb, 0x67, 0x64, 0xb3, 0x20, 0x15, 0xfb, 0x1a, 0x06, 0x59, +	0x9d, 0x0a, 0x9b, 0xcf, 0x83, 0xc1, 0xe6, 0xe2, 0xdd, 0xd1, 0xf6, 0xed, 0xb3, 0xcd, 0x1e, 0xd7, +	0xa9, 0x78, 0x91, 0xcf, 0xc9, 0xb6, 0xb1, 0x62, 0x4f, 0x60, 0xd5, 0x05, 0x1d, 0x89, 0x43, 0x51, +	0x5a, 0x13, 0x2c, 0xd3, 0xd7, 0xef, 0xbc, 0x2b, 0xdf, 0x87, 0xc4, 0x0e, 0x57, 0x8a, 0x8e, 0x34, +	0xf9, 0x12, 0x96, 0x9b, 0x2e, 0xb0, 0x00, 0x06, 0x71, 0xad, 0xb5, 0x28, 0x2d, 0xb5, 0xae, 0x1f, +	0x36, 0x22, 0x5b, 0x87, 0xf3, 0xb9, 0x2c, 0xa4, 0xa5, 0xde, 0xf4, 0x43, 0x27, 0x4c, 0x7e, 0xef, +	0xc1, 0xc0, 0xf7, 0x82, 0xdd, 0x04, 0xa8, 0x0d, 0x4f, 0x45, 0x54, 0x1b, 0x11, 0x7b, 0xf3, 0x21, +	0x21, 0x7b, 0x46, 0xc4, 0xec, 0x06, 0x0c, 0x6b, 0x23, 0xb4, 0xd3, 0x3a, 0x27, 0xcb, 0x08, 0x90, +	0x72, 0x03, 0x46, 0xe6, 0xd8, 0x58, 0x51, 0x38, 0xf5, 0x22, 0xa9, 0xc1, 0x41, 0x44, 0xb8, 0x09, +	0x50, 0xea, 0xa8, 0x12, 0x5a, 0xaa, 0xc4, 0x50, 0x7b, 0xfb, 0xe1, 0xb0, 0xd4, 0xbb, 0x0e, 0x60, +	0x5b, 0xb0, 0x52, 0xea, 0xc8, 0x66, 0x5a, 0x59, 0x9b, 0x8b, 0x84, 0x7a, 0xd8, 0x0f, 0x47, 0xa5, +	0x7e, 0xd1, 0x40, 0xec, 0x36, 0x5c, 0x38, 0xd5, 0xbb, 0xaf, 0x2c, 0x11, 0x69, 0xf5, 0x14, 0xc5, +	0x0f, 0x4d, 0x7e, 0x1d, 0x02, 0xb4, 0x97, 0x83, 0x31, 0xe8, 0xf3, 0x52, 0x95, 0x3e, 0x1d, 0x3a, +	0x23, 0xb6, 0x2f, 0x73, 0xe1, 0x93, 0xa0, 0x33, 0x06, 0x70, 0x20, 0x74, 0x29, 0xf2, 0xc8, 0x58, +	0x1e, 0x1f, 0xf8, 0x0c, 0x46, 0x0e, 0x7b, 0x8e, 0x10, 0x9a, 0x99, 0x9c, 0xcf, 0x7d, 0xf0, 0x74, +	0x26, 0x4c, 0xc5, 0x07, 0x3e, 0x5e, 0x3a, 0x63, 0xa5, 0x4d, 0x56, 0x88, 0xc2, 0xc7, 0xe7, 0x04, +	0xac, 0x10, 0x7e, 0x28, 0x2a, 0x78, 0x55, 0x89, 0x24, 0x18, 0xb8, 0x0a, 0x21, 0xf4, 0x94, 0x10, +	0xac, 0x10, 0x11, 0x12, 0xa9, 0xed, 0x31, 0x5d, 0x88, 0x7e, 0x38, 0x44, 0xe4, 0x1b, 0x04, 0x30, +	0x7d, 0x52, 0x1f, 0x69, 0x69, 0xc5, 0x1c, 0x43, 0x1c, 0xba, 0xf4, 0x11, 0xfd, 0xa1, 0x01, 0xd9, +	0x35, 0x58, 0xc6, 0x1c, 0x23, 0x9b, 0x55, 0x01, 0xb8, 0x1b, 0x80, 0xf2, 0x8b, 0xac, 0x62, 0xb7, +	0x60, 0x55, 0x96, 0x3c, 0xb6, 0xf2, 0x50, 0x44, 0x54, 0x93, 0x11, 0xe9, 0x57, 0x1a, 0x70, 0x07, +	0x6b, 0xb3, 0x01, 0xa3, 0x2e, 0x65, 0xc5, 0x85, 0xd9, 0x21, 0x74, 0xbd, 0x50, 0x15, 0x57, 0xff, +	0xed, 0xe5, 0x11, 0x56, 0xb3, 0xf5, 0x42, 0x94, 0x0b, 0x5d, 0x2f, 0x44, 0xd8, 0x84, 0x51, 0x5d, +	0x8a, 0x43, 0x19, 0x5b, 0x3e, 0xcf, 0x45, 0x70, 0xd1, 0x55, 0xbb, 0x03, 0xb1, 0xf7, 0x61, 0x0d, +	0x2b, 0x1c, 0x69, 0x11, 0xe7, 0x5c, 0x16, 0x44, 0x5b, 0x23, 0xda, 0x45, 0xc4, 0xc3, 0x16, 0x66, +	0x1f, 0x02, 0x23, 0x6a, 0x5d, 0x76, 0xc9, 0x97, 0x88, 0x7c, 0x09, 0x35, 0x7b, 0x5d, 0x05, 0xbe, +	0x91, 0x2a, 0xdd, 0xe7, 0x75, 0x6e, 0x03, 0xe6, 0x2a, 0xe4, 0x45, 0x36, 0x06, 0xa8, 0xd2, 0x82, +	0xbf, 0x74, 0xca, 0xcb, 0x2e, 0xea, 0x16, 0xc1, 0x0f, 0x1d, 0x29, 0x7d, 0x20, 0xcb, 0xd4, 0x08, +	0x1b, 0x69, 0xe1, 0x78, 0xeb, 0xee, 0x43, 0xad, 0x26, 0x74, 0x0a, 0x36, 0x83, 0xcb, 0x1d, 0x3a, +	0x65, 0xcf, 0xad, 0x08, 0xae, 0x10, 0xbf, 0xe3, 0x69, 0xc7, 0x6b, 0xd8, 0xa7, 0x70, 0xb5, 0x63, +	0x50, 0xaa, 0x44, 0xf8, 0xb8, 0x83, 0xab, 0x64, 0x73, 0xa5, 0xd5, 0x7e, 0xdf, 0x2a, 0xd9, 0x75, +	0x58, 0xae, 0x52, 0x2d, 0xf6, 0x65, 0x9e, 0x07, 0xff, 0x73, 0x0f, 0xb3, 0x91, 0xd9, 0x55, 0x58, +	0xaa, 0x52, 0x13, 0xf3, 0x32, 0x08, 0x48, 0xe3, 0x25, 0x57, 0x04, 0x63, 0x05, 0xcf, 0x83, 0x6b, +	0x4d, 0x11, 0x48, 0x74, 0x45, 0x38, 0x0d, 0xf6, 0x7a, 0x53, 0x84, 0x06, 0x61, 0x13, 0x58, 0xa9, +	0xd2, 0x44, 0x9c, 0x32, 0x6e, 0xb8, 0xfe, 0x77, 0x31, 0xe7, 0x23, 0xe7, 0xaf, 0x8e, 0xf7, 0xb5, +	0x10, 0xc1, 0xff, 0x1b, 0x1f, 0x0d, 0x82, 0xed, 0x6f, 0xa5, 0x24, 0xb8, 0xe9, 0xda, 0xdf, 0x81, +	0xd8, 0x1d, 0xb8, 0x68, 0xb3, 0x2a, 0xa2, 0x42, 0x46, 0x3c, 0xcf, 0x55, 0x1c, 0x8c, 0x9b, 0xe7, +	0x5e, 0x3d, 0x42, 0x74, 0x07, 0x41, 0xf6, 0x01, 0x30, 0xe4, 0xc5, 0x2a, 0xcf, 0x79, 0x65, 0x84, +	0xa7, 0x6e, 0x10, 0x75, 0xcd, 0x66, 0xd5, 0x03, 0xaf, 0x70, 0xec, 0x75, 0x38, 0x4f, 0x03, 0x2d, +	0xd8, 0x74, 0x4f, 0x93, 0x04, 0xbc, 0xad, 0x6e, 0xf0, 0xb9, 0x01, 0xb9, 0xe5, 0xc2, 0x25, 0xe8, +	0x3b, 0x44, 0xf0, 0x69, 0x9a, 0x23, 0x5e, 0x45, 0xce, 0x76, 0xe2, 0x9e, 0x26, 0x22, 0x7b, 0x64, +	0xdf, 0xa8, 0x9d, 0xf9, 0xad, 0x56, 0x4d, 0xd6, 0x13, 0x03, 0x2b, 0xdd, 0xe9, 0xcd, 0xd6, 0x60, +	0x31, 0x57, 0x47, 0x7e, 0x22, 0xe1, 0x11, 0xa7, 0x48, 0x26, 0xd3, 0xac, 0x19, 0x48, 0x78, 0x46, +	0x56, 0xc1, 0x7f, 0xf4, 0x73, 0x08, 0x8f, 0x88, 0x28, 0x55, 0xf8, 0xf1, 0x83, 0x47, 0x7c, 0xec, +	0x4a, 0x15, 0xd1, 0x01, 0x36, 0xde, 0x4d, 0xa0, 0x81, 0x52, 0xc5, 0x13, 0x99, 0xe7, 0x93, 0x9f, +	0x7b, 0xb0, 0xdc, 0xec, 0x39, 0xf6, 0x55, 0x77, 0x2b, 0xe0, 0xbe, 0xba, 0xf5, 0xf6, 0xe5, 0xf8, +	0xb0, 0xb4, 0xfa, 0xb8, 0x5d, 0x1d, 0x5f, 0xb4, 0xab, 0xe3, 0x3f, 0x1b, 0xfb, 0xfd, 0x22, 0x60, +	0x78, 0x8a, 0xe1, 0x5d, 0x4c, 0xf0, 0x81, 0x0b, 0xca, 0x7d, 0x18, 0x7a, 0x09, 0xeb, 0x9f, 0xc5, +	0x3c, 0xca, 0x78, 0x99, 0xe4, 0xc2, 0x50, 0x15, 0x56, 0x43, 0xc8, 0x62, 0xfe, 0xd8, 0x21, 0x0d, +	0x41, 0xcd, 0x5f, 0x8a, 0xd8, 0x1a, 0xaa, 0x89, 0x23, 0x3c, 0x73, 0xc8, 0x64, 0x07, 0x96, 0xdc, +	0x7a, 0x66, 0x9f, 0x37, 0x1d, 0x76, 0x89, 0x6e, 0xbd, 0x6d, 0x9f, 0xfb, 0x48, 0x89, 0x3f, 0xf9, +	0xa5, 0x07, 0x03, 0x0f, 0xe1, 0x35, 0x29, 0xf8, 0x4b, 0xa5, 0x7d, 0x8f, 0x9c, 0x40, 0xa8, 0x2c, +	0x95, 0x6e, 0x36, 0x28, 0x09, 0x98, 0x94, 0x9e, 0x1f, 0x5b, 0x61, 0x7c, 0xab, 0xbc, 0x84, 0xf8, +	0x91, 0xc3, 0x5d, 0xc3, 0xbc, 0x84, 0xbd, 0xd6, 0x52, 0x99, 0x66, 0x63, 0xe0, 0x19, 0xb1, 0x23, +	0xc4, 0xdc, 0xc2, 0xa0, 0xf3, 0x64, 0x0f, 0x46, 0x9d, 0x5f, 0x87, 0xb7, 0x2c, 0x76, 0x7f, 0x51, +	0x16, 0xda, 0x8b, 0x82, 0xf3, 0x80, 0xa7, 0xc2, 0xc8, 0x57, 0x82, 0x82, 0x1a, 0x86, 0xa7, 0xf2, +	0xfd, 0xe0, 0xf5, 0x9b, 0xf1, 0xb9, 0x3f, 0xdf, 0x8c, 0xcf, 0xfd, 0x74, 0x32, 0xee, 0xbd, 0x3e, +	0x19, 0xf7, 0xfe, 0x38, 0x19, 0xf7, 0xfe, 0x3e, 0x19, 0xf7, 0xe6, 0x4b, 0xf4, 0x17, 0xf8, 0xf1, +	0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x4f, 0x2b, 0x30, 0xd6, 0x6d, 0x0a, 0x00, 0x00, +} + +func (m *Metrics) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *Metrics) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Metrics) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.MemoryEvents != nil { +		{ +			size, err := m.MemoryEvents.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x42 +	} +	if len(m.Hugetlb) > 0 { +		for iNdEx := len(m.Hugetlb) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.Hugetlb[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0x3a +		} +	} +	if m.Io != nil { +		{ +			size, err := m.Io.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x32 +	} +	if m.Rdma != nil { +		{ +			size, err := m.Rdma.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x2a +	} +	if m.Memory != nil { +		{ +			size, err := m.Memory.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x22 +	} +	if m.CPU != nil { +		{ +			size, err := m.CPU.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0x12 +	} +	if m.Pids != nil { +		{ +			size, err := m.Pids.MarshalToSizedBuffer(dAtA[:i]) +			if err != nil { +				return 0, err +			} +			i -= size +			i = encodeVarintMetrics(dAtA, i, uint64(size)) +		} +		i-- +		dAtA[i] = 0xa +	} +	return len(dAtA) - i, nil +} + +func (m *PidsStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *PidsStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PidsStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.Limit != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Limit)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.Current != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Current)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func (m *CPUStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *CPUStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CPUStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.ThrottledUsec != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.ThrottledUsec)) +		i-- +		dAtA[i] = 0x30 +	} +	if m.NrThrottled != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.NrThrottled)) +		i-- +		dAtA[i] = 0x28 +	} +	if m.NrPeriods != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.NrPeriods)) +		i-- +		dAtA[i] = 0x20 +	} +	if m.SystemUsec != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.SystemUsec)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.UserUsec != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.UserUsec)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.UsageUsec != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.UsageUsec)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func (m *MemoryStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *MemoryStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MemoryStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.SwapLimit != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.SwapLimit)) +		i-- +		dAtA[i] = 0x2 +		i-- +		dAtA[i] = 0x98 +	} +	if m.SwapUsage != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.SwapUsage)) +		i-- +		dAtA[i] = 0x2 +		i-- +		dAtA[i] = 0x90 +	} +	if m.UsageLimit != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.UsageLimit)) +		i-- +		dAtA[i] = 0x2 +		i-- +		dAtA[i] = 0x88 +	} +	if m.Usage != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Usage)) +		i-- +		dAtA[i] = 0x2 +		i-- +		dAtA[i] = 0x80 +	} +	if m.ThpCollapseAlloc != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.ThpCollapseAlloc)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xf8 +	} +	if m.ThpFaultAlloc != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.ThpFaultAlloc)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xf0 +	} +	if m.Pglazyfreed != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Pglazyfreed)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xe8 +	} +	if m.Pglazyfree != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Pglazyfree)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xe0 +	} +	if m.Pgdeactivate != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Pgdeactivate)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xd8 +	} +	if m.Pgactivate != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Pgactivate)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xd0 +	} +	if m.Pgsteal != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Pgsteal)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xc8 +	} +	if m.Pgscan != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Pgscan)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xc0 +	} +	if m.Pgrefill != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Pgrefill)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xb8 +	} +	if m.WorkingsetNodereclaim != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.WorkingsetNodereclaim)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xb0 +	} +	if m.WorkingsetActivate != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.WorkingsetActivate)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xa8 +	} +	if m.WorkingsetRefault != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.WorkingsetRefault)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0xa0 +	} +	if m.Pgmajfault != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Pgmajfault)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0x98 +	} +	if m.Pgfault != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Pgfault)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0x90 +	} +	if m.SlabUnreclaimable != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.SlabUnreclaimable)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0x88 +	} +	if m.SlabReclaimable != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.SlabReclaimable)) +		i-- +		dAtA[i] = 0x1 +		i-- +		dAtA[i] = 0x80 +	} +	if m.Unevictable != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Unevictable)) +		i-- +		dAtA[i] = 0x78 +	} +	if m.ActiveFile != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.ActiveFile)) +		i-- +		dAtA[i] = 0x70 +	} +	if m.InactiveFile != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.InactiveFile)) +		i-- +		dAtA[i] = 0x68 +	} +	if m.ActiveAnon != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.ActiveAnon)) +		i-- +		dAtA[i] = 0x60 +	} +	if m.InactiveAnon != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.InactiveAnon)) +		i-- +		dAtA[i] = 0x58 +	} +	if m.AnonThp != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.AnonThp)) +		i-- +		dAtA[i] = 0x50 +	} +	if m.FileWriteback != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.FileWriteback)) +		i-- +		dAtA[i] = 0x48 +	} +	if m.FileDirty != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.FileDirty)) +		i-- +		dAtA[i] = 0x40 +	} +	if m.FileMapped != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.FileMapped)) +		i-- +		dAtA[i] = 0x38 +	} +	if m.Shmem != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Shmem)) +		i-- +		dAtA[i] = 0x30 +	} +	if m.Sock != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Sock)) +		i-- +		dAtA[i] = 0x28 +	} +	if m.Slab != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Slab)) +		i-- +		dAtA[i] = 0x20 +	} +	if m.KernelStack != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.KernelStack)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.File != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.File)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.Anon != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Anon)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func (m *MemoryEvents) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *MemoryEvents) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MemoryEvents) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.OomKill != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.OomKill)) +		i-- +		dAtA[i] = 0x28 +	} +	if m.Oom != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Oom)) +		i-- +		dAtA[i] = 0x20 +	} +	if m.Max != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Max)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.High != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.High)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.Low != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Low)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func (m *RdmaStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *RdmaStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RdmaStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if len(m.Limit) > 0 { +		for iNdEx := len(m.Limit) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.Limit[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0x12 +		} +	} +	if len(m.Current) > 0 { +		for iNdEx := len(m.Current) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.Current[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0xa +		} +	} +	return len(dAtA) - i, nil +} + +func (m *RdmaEntry) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *RdmaEntry) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RdmaEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.HcaObjects != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.HcaObjects)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.HcaHandles != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.HcaHandles)) +		i-- +		dAtA[i] = 0x10 +	} +	if len(m.Device) > 0 { +		i -= len(m.Device) +		copy(dAtA[i:], m.Device) +		i = encodeVarintMetrics(dAtA, i, uint64(len(m.Device))) +		i-- +		dAtA[i] = 0xa +	} +	return len(dAtA) - i, nil +} + +func (m *IOStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *IOStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IOStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if len(m.Usage) > 0 { +		for iNdEx := len(m.Usage) - 1; iNdEx >= 0; iNdEx-- { +			{ +				size, err := m.Usage[iNdEx].MarshalToSizedBuffer(dAtA[:i]) +				if err != nil { +					return 0, err +				} +				i -= size +				i = encodeVarintMetrics(dAtA, i, uint64(size)) +			} +			i-- +			dAtA[i] = 0xa +		} +	} +	return len(dAtA) - i, nil +} + +func (m *IOEntry) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *IOEntry) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IOEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if m.Wios != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Wios)) +		i-- +		dAtA[i] = 0x30 +	} +	if m.Rios != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Rios)) +		i-- +		dAtA[i] = 0x28 +	} +	if m.Wbytes != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Wbytes)) +		i-- +		dAtA[i] = 0x20 +	} +	if m.Rbytes != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Rbytes)) +		i-- +		dAtA[i] = 0x18 +	} +	if m.Minor != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Minor)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.Major != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Major)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func (m *HugeTlbStat) Marshal() (dAtA []byte, err error) { +	size := m.Size() +	dAtA = make([]byte, size) +	n, err := m.MarshalToSizedBuffer(dAtA[:size]) +	if err != nil { +		return nil, err +	} +	return dAtA[:n], nil +} + +func (m *HugeTlbStat) MarshalTo(dAtA []byte) (int, error) { +	size := m.Size() +	return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HugeTlbStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { +	i := len(dAtA) +	_ = i +	var l int +	_ = l +	if m.XXX_unrecognized != nil { +		i -= len(m.XXX_unrecognized) +		copy(dAtA[i:], m.XXX_unrecognized) +	} +	if len(m.Pagesize) > 0 { +		i -= len(m.Pagesize) +		copy(dAtA[i:], m.Pagesize) +		i = encodeVarintMetrics(dAtA, i, uint64(len(m.Pagesize))) +		i-- +		dAtA[i] = 0x1a +	} +	if m.Max != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Max)) +		i-- +		dAtA[i] = 0x10 +	} +	if m.Current != 0 { +		i = encodeVarintMetrics(dAtA, i, uint64(m.Current)) +		i-- +		dAtA[i] = 0x8 +	} +	return len(dAtA) - i, nil +} + +func encodeVarintMetrics(dAtA []byte, offset int, v uint64) int { +	offset -= sovMetrics(v) +	base := offset +	for v >= 1<<7 { +		dAtA[offset] = uint8(v&0x7f | 0x80) +		v >>= 7 +		offset++ +	} +	dAtA[offset] = uint8(v) +	return base +} +func (m *Metrics) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.Pids != nil { +		l = m.Pids.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.CPU != nil { +		l = m.CPU.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.Memory != nil { +		l = m.Memory.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.Rdma != nil { +		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 len(m.Hugetlb) > 0 { +		for _, e := range m.Hugetlb { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if m.MemoryEvents != nil { +		l = m.MemoryEvents.Size() +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *PidsStat) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.Current != 0 { +		n += 1 + sovMetrics(uint64(m.Current)) +	} +	if m.Limit != 0 { +		n += 1 + sovMetrics(uint64(m.Limit)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *CPUStat) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.UsageUsec != 0 { +		n += 1 + sovMetrics(uint64(m.UsageUsec)) +	} +	if m.UserUsec != 0 { +		n += 1 + sovMetrics(uint64(m.UserUsec)) +	} +	if m.SystemUsec != 0 { +		n += 1 + sovMetrics(uint64(m.SystemUsec)) +	} +	if m.NrPeriods != 0 { +		n += 1 + sovMetrics(uint64(m.NrPeriods)) +	} +	if m.NrThrottled != 0 { +		n += 1 + sovMetrics(uint64(m.NrThrottled)) +	} +	if m.ThrottledUsec != 0 { +		n += 1 + sovMetrics(uint64(m.ThrottledUsec)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *MemoryStat) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.Anon != 0 { +		n += 1 + sovMetrics(uint64(m.Anon)) +	} +	if m.File != 0 { +		n += 1 + sovMetrics(uint64(m.File)) +	} +	if m.KernelStack != 0 { +		n += 1 + sovMetrics(uint64(m.KernelStack)) +	} +	if m.Slab != 0 { +		n += 1 + sovMetrics(uint64(m.Slab)) +	} +	if m.Sock != 0 { +		n += 1 + sovMetrics(uint64(m.Sock)) +	} +	if m.Shmem != 0 { +		n += 1 + sovMetrics(uint64(m.Shmem)) +	} +	if m.FileMapped != 0 { +		n += 1 + sovMetrics(uint64(m.FileMapped)) +	} +	if m.FileDirty != 0 { +		n += 1 + sovMetrics(uint64(m.FileDirty)) +	} +	if m.FileWriteback != 0 { +		n += 1 + sovMetrics(uint64(m.FileWriteback)) +	} +	if m.AnonThp != 0 { +		n += 1 + sovMetrics(uint64(m.AnonThp)) +	} +	if m.InactiveAnon != 0 { +		n += 1 + sovMetrics(uint64(m.InactiveAnon)) +	} +	if m.ActiveAnon != 0 { +		n += 1 + sovMetrics(uint64(m.ActiveAnon)) +	} +	if m.InactiveFile != 0 { +		n += 1 + sovMetrics(uint64(m.InactiveFile)) +	} +	if m.ActiveFile != 0 { +		n += 1 + sovMetrics(uint64(m.ActiveFile)) +	} +	if m.Unevictable != 0 { +		n += 1 + sovMetrics(uint64(m.Unevictable)) +	} +	if m.SlabReclaimable != 0 { +		n += 2 + sovMetrics(uint64(m.SlabReclaimable)) +	} +	if m.SlabUnreclaimable != 0 { +		n += 2 + sovMetrics(uint64(m.SlabUnreclaimable)) +	} +	if m.Pgfault != 0 { +		n += 2 + sovMetrics(uint64(m.Pgfault)) +	} +	if m.Pgmajfault != 0 { +		n += 2 + sovMetrics(uint64(m.Pgmajfault)) +	} +	if m.WorkingsetRefault != 0 { +		n += 2 + sovMetrics(uint64(m.WorkingsetRefault)) +	} +	if m.WorkingsetActivate != 0 { +		n += 2 + sovMetrics(uint64(m.WorkingsetActivate)) +	} +	if m.WorkingsetNodereclaim != 0 { +		n += 2 + sovMetrics(uint64(m.WorkingsetNodereclaim)) +	} +	if m.Pgrefill != 0 { +		n += 2 + sovMetrics(uint64(m.Pgrefill)) +	} +	if m.Pgscan != 0 { +		n += 2 + sovMetrics(uint64(m.Pgscan)) +	} +	if m.Pgsteal != 0 { +		n += 2 + sovMetrics(uint64(m.Pgsteal)) +	} +	if m.Pgactivate != 0 { +		n += 2 + sovMetrics(uint64(m.Pgactivate)) +	} +	if m.Pgdeactivate != 0 { +		n += 2 + sovMetrics(uint64(m.Pgdeactivate)) +	} +	if m.Pglazyfree != 0 { +		n += 2 + sovMetrics(uint64(m.Pglazyfree)) +	} +	if m.Pglazyfreed != 0 { +		n += 2 + sovMetrics(uint64(m.Pglazyfreed)) +	} +	if m.ThpFaultAlloc != 0 { +		n += 2 + sovMetrics(uint64(m.ThpFaultAlloc)) +	} +	if m.ThpCollapseAlloc != 0 { +		n += 2 + sovMetrics(uint64(m.ThpCollapseAlloc)) +	} +	if m.Usage != 0 { +		n += 2 + sovMetrics(uint64(m.Usage)) +	} +	if m.UsageLimit != 0 { +		n += 2 + sovMetrics(uint64(m.UsageLimit)) +	} +	if m.SwapUsage != 0 { +		n += 2 + sovMetrics(uint64(m.SwapUsage)) +	} +	if m.SwapLimit != 0 { +		n += 2 + sovMetrics(uint64(m.SwapLimit)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *MemoryEvents) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.Low != 0 { +		n += 1 + sovMetrics(uint64(m.Low)) +	} +	if m.High != 0 { +		n += 1 + sovMetrics(uint64(m.High)) +	} +	if m.Max != 0 { +		n += 1 + sovMetrics(uint64(m.Max)) +	} +	if m.Oom != 0 { +		n += 1 + sovMetrics(uint64(m.Oom)) +	} +	if m.OomKill != 0 { +		n += 1 + sovMetrics(uint64(m.OomKill)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *RdmaStat) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if len(m.Current) > 0 { +		for _, e := range m.Current { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if len(m.Limit) > 0 { +		for _, e := range m.Limit { +			l = e.Size() +			n += 1 + l + sovMetrics(uint64(l)) +		} +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func (m *RdmaEntry) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	l = len(m.Device) +	if l > 0 { +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.HcaHandles != 0 { +		n += 1 + sovMetrics(uint64(m.HcaHandles)) +	} +	if m.HcaObjects != 0 { +		n += 1 + sovMetrics(uint64(m.HcaObjects)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	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 (m *HugeTlbStat) Size() (n int) { +	if m == nil { +		return 0 +	} +	var l int +	_ = l +	if m.Current != 0 { +		n += 1 + sovMetrics(uint64(m.Current)) +	} +	if m.Max != 0 { +		n += 1 + sovMetrics(uint64(m.Max)) +	} +	l = len(m.Pagesize) +	if l > 0 { +		n += 1 + l + sovMetrics(uint64(l)) +	} +	if m.XXX_unrecognized != nil { +		n += len(m.XXX_unrecognized) +	} +	return n +} + +func sovMetrics(x uint64) (n int) { +	return (math_bits.Len64(x|1) + 6) / 7 +} +func sozMetrics(x uint64) (n int) { +	return sovMetrics(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *Metrics) String() string { +	if this == nil { +		return "nil" +	} +	repeatedStringForHugetlb := "[]*HugeTlbStat{" +	for _, f := range this.Hugetlb { +		repeatedStringForHugetlb += strings.Replace(f.String(), "HugeTlbStat", "HugeTlbStat", 1) + "," +	} +	repeatedStringForHugetlb += "}" +	s := strings.Join([]string{`&Metrics{`, +		`Pids:` + strings.Replace(this.Pids.String(), "PidsStat", "PidsStat", 1) + `,`, +		`CPU:` + strings.Replace(this.CPU.String(), "CPUStat", "CPUStat", 1) + `,`, +		`Memory:` + strings.Replace(this.Memory.String(), "MemoryStat", "MemoryStat", 1) + `,`, +		`Rdma:` + strings.Replace(this.Rdma.String(), "RdmaStat", "RdmaStat", 1) + `,`, +		`Io:` + strings.Replace(this.Io.String(), "IOStat", "IOStat", 1) + `,`, +		`Hugetlb:` + repeatedStringForHugetlb + `,`, +		`MemoryEvents:` + strings.Replace(this.MemoryEvents.String(), "MemoryEvents", "MemoryEvents", 1) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *PidsStat) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&PidsStat{`, +		`Current:` + fmt.Sprintf("%v", this.Current) + `,`, +		`Limit:` + fmt.Sprintf("%v", this.Limit) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *CPUStat) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&CPUStat{`, +		`UsageUsec:` + fmt.Sprintf("%v", this.UsageUsec) + `,`, +		`UserUsec:` + fmt.Sprintf("%v", this.UserUsec) + `,`, +		`SystemUsec:` + fmt.Sprintf("%v", this.SystemUsec) + `,`, +		`NrPeriods:` + fmt.Sprintf("%v", this.NrPeriods) + `,`, +		`NrThrottled:` + fmt.Sprintf("%v", this.NrThrottled) + `,`, +		`ThrottledUsec:` + fmt.Sprintf("%v", this.ThrottledUsec) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *MemoryStat) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&MemoryStat{`, +		`Anon:` + fmt.Sprintf("%v", this.Anon) + `,`, +		`File:` + fmt.Sprintf("%v", this.File) + `,`, +		`KernelStack:` + fmt.Sprintf("%v", this.KernelStack) + `,`, +		`Slab:` + fmt.Sprintf("%v", this.Slab) + `,`, +		`Sock:` + fmt.Sprintf("%v", this.Sock) + `,`, +		`Shmem:` + fmt.Sprintf("%v", this.Shmem) + `,`, +		`FileMapped:` + fmt.Sprintf("%v", this.FileMapped) + `,`, +		`FileDirty:` + fmt.Sprintf("%v", this.FileDirty) + `,`, +		`FileWriteback:` + fmt.Sprintf("%v", this.FileWriteback) + `,`, +		`AnonThp:` + fmt.Sprintf("%v", this.AnonThp) + `,`, +		`InactiveAnon:` + fmt.Sprintf("%v", this.InactiveAnon) + `,`, +		`ActiveAnon:` + fmt.Sprintf("%v", this.ActiveAnon) + `,`, +		`InactiveFile:` + fmt.Sprintf("%v", this.InactiveFile) + `,`, +		`ActiveFile:` + fmt.Sprintf("%v", this.ActiveFile) + `,`, +		`Unevictable:` + fmt.Sprintf("%v", this.Unevictable) + `,`, +		`SlabReclaimable:` + fmt.Sprintf("%v", this.SlabReclaimable) + `,`, +		`SlabUnreclaimable:` + fmt.Sprintf("%v", this.SlabUnreclaimable) + `,`, +		`Pgfault:` + fmt.Sprintf("%v", this.Pgfault) + `,`, +		`Pgmajfault:` + fmt.Sprintf("%v", this.Pgmajfault) + `,`, +		`WorkingsetRefault:` + fmt.Sprintf("%v", this.WorkingsetRefault) + `,`, +		`WorkingsetActivate:` + fmt.Sprintf("%v", this.WorkingsetActivate) + `,`, +		`WorkingsetNodereclaim:` + fmt.Sprintf("%v", this.WorkingsetNodereclaim) + `,`, +		`Pgrefill:` + fmt.Sprintf("%v", this.Pgrefill) + `,`, +		`Pgscan:` + fmt.Sprintf("%v", this.Pgscan) + `,`, +		`Pgsteal:` + fmt.Sprintf("%v", this.Pgsteal) + `,`, +		`Pgactivate:` + fmt.Sprintf("%v", this.Pgactivate) + `,`, +		`Pgdeactivate:` + fmt.Sprintf("%v", this.Pgdeactivate) + `,`, +		`Pglazyfree:` + fmt.Sprintf("%v", this.Pglazyfree) + `,`, +		`Pglazyfreed:` + fmt.Sprintf("%v", this.Pglazyfreed) + `,`, +		`ThpFaultAlloc:` + fmt.Sprintf("%v", this.ThpFaultAlloc) + `,`, +		`ThpCollapseAlloc:` + fmt.Sprintf("%v", this.ThpCollapseAlloc) + `,`, +		`Usage:` + fmt.Sprintf("%v", this.Usage) + `,`, +		`UsageLimit:` + fmt.Sprintf("%v", this.UsageLimit) + `,`, +		`SwapUsage:` + fmt.Sprintf("%v", this.SwapUsage) + `,`, +		`SwapLimit:` + fmt.Sprintf("%v", this.SwapLimit) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *MemoryEvents) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&MemoryEvents{`, +		`Low:` + fmt.Sprintf("%v", this.Low) + `,`, +		`High:` + fmt.Sprintf("%v", this.High) + `,`, +		`Max:` + fmt.Sprintf("%v", this.Max) + `,`, +		`Oom:` + fmt.Sprintf("%v", this.Oom) + `,`, +		`OomKill:` + fmt.Sprintf("%v", this.OomKill) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *RdmaStat) String() string { +	if this == nil { +		return "nil" +	} +	repeatedStringForCurrent := "[]*RdmaEntry{" +	for _, f := range this.Current { +		repeatedStringForCurrent += strings.Replace(f.String(), "RdmaEntry", "RdmaEntry", 1) + "," +	} +	repeatedStringForCurrent += "}" +	repeatedStringForLimit := "[]*RdmaEntry{" +	for _, f := range this.Limit { +		repeatedStringForLimit += strings.Replace(f.String(), "RdmaEntry", "RdmaEntry", 1) + "," +	} +	repeatedStringForLimit += "}" +	s := strings.Join([]string{`&RdmaStat{`, +		`Current:` + repeatedStringForCurrent + `,`, +		`Limit:` + repeatedStringForLimit + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *RdmaEntry) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&RdmaEntry{`, +		`Device:` + fmt.Sprintf("%v", this.Device) + `,`, +		`HcaHandles:` + fmt.Sprintf("%v", this.HcaHandles) + `,`, +		`HcaObjects:` + fmt.Sprintf("%v", this.HcaObjects) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func (this *IOStat) String() string { +	if this == nil { +		return "nil" +	} +	repeatedStringForUsage := "[]*IOEntry{" +	for _, f := range this.Usage { +		repeatedStringForUsage += strings.Replace(f.String(), "IOEntry", "IOEntry", 1) + "," +	} +	repeatedStringForUsage += "}" +	s := strings.Join([]string{`&IOStat{`, +		`Usage:` + repeatedStringForUsage + `,`, +		`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 (this *HugeTlbStat) String() string { +	if this == nil { +		return "nil" +	} +	s := strings.Join([]string{`&HugeTlbStat{`, +		`Current:` + fmt.Sprintf("%v", this.Current) + `,`, +		`Max:` + fmt.Sprintf("%v", this.Max) + `,`, +		`Pagesize:` + fmt.Sprintf("%v", this.Pagesize) + `,`, +		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, +		`}`, +	}, "") +	return s +} +func valueToStringMetrics(v interface{}) string { +	rv := reflect.ValueOf(v) +	if rv.IsNil() { +		return "nil" +	} +	pv := reflect.Indirect(rv).Interface() +	return fmt.Sprintf("*%v", pv) +} +func (m *Metrics) 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: Metrics: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: Metrics: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pids", 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.Pids == nil { +				m.Pids = &PidsStat{} +			} +			if err := m.Pids.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 2: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field CPU", 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.CPU == nil { +				m.CPU = &CPUStat{} +			} +			if err := m.CPU.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 4: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Memory", 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.Memory == nil { +				m.Memory = &MemoryStat{} +			} +			if err := m.Memory.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 5: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Rdma", 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.Rdma == nil { +				m.Rdma = &RdmaStat{} +			} +			if err := m.Rdma.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				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 +		case 7: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Hugetlb", 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.Hugetlb = append(m.Hugetlb, &HugeTlbStat{}) +			if err := m.Hugetlb[len(m.Hugetlb)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 8: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field MemoryEvents", 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.MemoryEvents == nil { +				m.MemoryEvents = &MemoryEvents{} +			} +			if err := m.MemoryEvents.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) || (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 *PidsStat) 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: PidsStat: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: PidsStat: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Current", wireType) +			} +			m.Current = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Current |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) +			} +			m.Limit = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Limit |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *CPUStat) 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: CPUStat: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: CPUStat: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field UsageUsec", wireType) +			} +			m.UsageUsec = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.UsageUsec |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field UserUsec", wireType) +			} +			m.UserUsec = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.UserUsec |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field SystemUsec", wireType) +			} +			m.SystemUsec = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.SystemUsec |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 4: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field NrPeriods", wireType) +			} +			m.NrPeriods = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.NrPeriods |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 5: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field NrThrottled", wireType) +			} +			m.NrThrottled = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.NrThrottled |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 6: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field ThrottledUsec", wireType) +			} +			m.ThrottledUsec = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.ThrottledUsec |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *MemoryStat) 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: MemoryStat: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: MemoryStat: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Anon", wireType) +			} +			m.Anon = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Anon |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field File", wireType) +			} +			m.File = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.File |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field KernelStack", wireType) +			} +			m.KernelStack = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.KernelStack |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 4: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Slab", wireType) +			} +			m.Slab = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Slab |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 5: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Sock", wireType) +			} +			m.Sock = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Sock |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 6: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Shmem", wireType) +			} +			m.Shmem = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Shmem |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 7: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field FileMapped", wireType) +			} +			m.FileMapped = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.FileMapped |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 8: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field FileDirty", wireType) +			} +			m.FileDirty = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.FileDirty |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 9: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field FileWriteback", wireType) +			} +			m.FileWriteback = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.FileWriteback |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 10: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field AnonThp", wireType) +			} +			m.AnonThp = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.AnonThp |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 11: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field InactiveAnon", wireType) +			} +			m.InactiveAnon = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.InactiveAnon |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 12: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field ActiveAnon", wireType) +			} +			m.ActiveAnon = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.ActiveAnon |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 13: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field InactiveFile", wireType) +			} +			m.InactiveFile = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.InactiveFile |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 14: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field ActiveFile", wireType) +			} +			m.ActiveFile = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.ActiveFile |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 15: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Unevictable", wireType) +			} +			m.Unevictable = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Unevictable |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 16: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field SlabReclaimable", wireType) +			} +			m.SlabReclaimable = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.SlabReclaimable |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 17: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field SlabUnreclaimable", wireType) +			} +			m.SlabUnreclaimable = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.SlabUnreclaimable |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 18: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pgfault", wireType) +			} +			m.Pgfault = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Pgfault |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 19: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pgmajfault", wireType) +			} +			m.Pgmajfault = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Pgmajfault |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 20: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field WorkingsetRefault", wireType) +			} +			m.WorkingsetRefault = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.WorkingsetRefault |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 21: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field WorkingsetActivate", wireType) +			} +			m.WorkingsetActivate = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.WorkingsetActivate |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 22: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field WorkingsetNodereclaim", wireType) +			} +			m.WorkingsetNodereclaim = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.WorkingsetNodereclaim |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 23: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pgrefill", wireType) +			} +			m.Pgrefill = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Pgrefill |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 24: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pgscan", wireType) +			} +			m.Pgscan = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Pgscan |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 25: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pgsteal", wireType) +			} +			m.Pgsteal = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Pgsteal |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 26: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pgactivate", wireType) +			} +			m.Pgactivate = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Pgactivate |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 27: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pgdeactivate", wireType) +			} +			m.Pgdeactivate = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Pgdeactivate |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 28: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pglazyfree", wireType) +			} +			m.Pglazyfree = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Pglazyfree |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 29: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pglazyfreed", wireType) +			} +			m.Pglazyfreed = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Pglazyfreed |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 30: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field ThpFaultAlloc", wireType) +			} +			m.ThpFaultAlloc = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.ThpFaultAlloc |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 31: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field ThpCollapseAlloc", wireType) +			} +			m.ThpCollapseAlloc = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.ThpCollapseAlloc |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 32: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Usage", wireType) +			} +			m.Usage = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Usage |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 33: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field UsageLimit", wireType) +			} +			m.UsageLimit = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.UsageLimit |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 34: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field SwapUsage", wireType) +			} +			m.SwapUsage = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.SwapUsage |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 35: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field SwapLimit", wireType) +			} +			m.SwapLimit = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.SwapLimit |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *MemoryEvents) 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: MemoryEvents: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: MemoryEvents: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Low", wireType) +			} +			m.Low = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Low |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field High", wireType) +			} +			m.High = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.High |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Max", wireType) +			} +			m.Max = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Max |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 4: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Oom", wireType) +			} +			m.Oom = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Oom |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 5: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field OomKill", wireType) +			} +			m.OomKill = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.OomKill |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *RdmaStat) 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: RdmaStat: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: RdmaStat: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Current", 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.Current = append(m.Current, &RdmaEntry{}) +			if err := m.Current[len(m.Current)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { +				return err +			} +			iNdEx = postIndex +		case 2: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Limit", 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.Limit = append(m.Limit, &RdmaEntry{}) +			if err := m.Limit[len(m.Limit)-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) || (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 *RdmaEntry) 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: RdmaEntry: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: RdmaEntry: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) +			} +			var stringLen uint64 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				stringLen |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +			intStringLen := int(stringLen) +			if intStringLen < 0 { +				return ErrInvalidLengthMetrics +			} +			postIndex := iNdEx + intStringLen +			if postIndex < 0 { +				return ErrInvalidLengthMetrics +			} +			if postIndex > l { +				return io.ErrUnexpectedEOF +			} +			m.Device = string(dAtA[iNdEx:postIndex]) +			iNdEx = postIndex +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field HcaHandles", wireType) +			} +			m.HcaHandles = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.HcaHandles |= uint32(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field HcaObjects", wireType) +			} +			m.HcaObjects = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.HcaObjects |= uint32(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 *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) || (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) || (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 *HugeTlbStat) 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: HugeTlbStat: wiretype end group for non-group") +		} +		if fieldNum <= 0 { +			return fmt.Errorf("proto: HugeTlbStat: illegal tag %d (wire type %d)", fieldNum, wire) +		} +		switch fieldNum { +		case 1: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Current", wireType) +			} +			m.Current = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Current |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 2: +			if wireType != 0 { +				return fmt.Errorf("proto: wrong wireType = %d for field Max", wireType) +			} +			m.Max = 0 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				m.Max |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +		case 3: +			if wireType != 2 { +				return fmt.Errorf("proto: wrong wireType = %d for field Pagesize", wireType) +			} +			var stringLen uint64 +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				stringLen |= uint64(b&0x7F) << shift +				if b < 0x80 { +					break +				} +			} +			intStringLen := int(stringLen) +			if intStringLen < 0 { +				return ErrInvalidLengthMetrics +			} +			postIndex := iNdEx + intStringLen +			if postIndex < 0 { +				return ErrInvalidLengthMetrics +			} +			if postIndex > l { +				return io.ErrUnexpectedEOF +			} +			m.Pagesize = string(dAtA[iNdEx:postIndex]) +			iNdEx = postIndex +		default: +			iNdEx = preIndex +			skippy, err := skipMetrics(dAtA[iNdEx:]) +			if err != nil { +				return err +			} +			if (skippy < 0) || (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 +	depth := 0 +	for iNdEx < l { +		var wire uint64 +		for shift := uint(0); ; shift += 7 { +			if shift >= 64 { +				return 0, ErrIntOverflowMetrics +			} +			if iNdEx >= l { +				return 0, io.ErrUnexpectedEOF +			} +			b := dAtA[iNdEx] +			iNdEx++ +			wire |= (uint64(b) & 0x7F) << shift +			if b < 0x80 { +				break +			} +		} +		wireType := int(wire & 0x7) +		switch wireType { +		case 0: +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return 0, ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return 0, io.ErrUnexpectedEOF +				} +				iNdEx++ +				if dAtA[iNdEx-1] < 0x80 { +					break +				} +			} +		case 1: +			iNdEx += 8 +		case 2: +			var length int +			for shift := uint(0); ; shift += 7 { +				if shift >= 64 { +					return 0, ErrIntOverflowMetrics +				} +				if iNdEx >= l { +					return 0, io.ErrUnexpectedEOF +				} +				b := dAtA[iNdEx] +				iNdEx++ +				length |= (int(b) & 0x7F) << shift +				if b < 0x80 { +					break +				} +			} +			if length < 0 { +				return 0, ErrInvalidLengthMetrics +			} +			iNdEx += length +		case 3: +			depth++ +		case 4: +			if depth == 0 { +				return 0, ErrUnexpectedEndOfGroupMetrics +			} +			depth-- +		case 5: +			iNdEx += 4 +		default: +			return 0, fmt.Errorf("proto: illegal wireType %d", wireType) +		} +		if iNdEx < 0 { +			return 0, ErrInvalidLengthMetrics +		} +		if depth == 0 { +			return iNdEx, nil +		} +	} +	return 0, io.ErrUnexpectedEOF +} + +var ( +	ErrInvalidLengthMetrics        = fmt.Errorf("proto: negative length found during unmarshaling") +	ErrIntOverflowMetrics          = fmt.Errorf("proto: integer overflow") +	ErrUnexpectedEndOfGroupMetrics = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vendor/github.com/containerd/cgroups/v2/stats/metrics.pb.txt b/vendor/github.com/containerd/cgroups/v2/stats/metrics.pb.txt new file mode 100644 index 000000000..59fe27cbf --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/stats/metrics.pb.txt @@ -0,0 +1,539 @@ +file { +  name: "github.com/containerd/cgroups/v2/stats/metrics.proto" +  package: "io.containerd.cgroups.v2" +  dependency: "gogoproto/gogo.proto" +  message_type { +    name: "Metrics" +    field { +      name: "pids" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v2.PidsStat" +      json_name: "pids" +    } +    field { +      name: "cpu" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v2.CPUStat" +      options { +        65004: "CPU" +      } +      json_name: "cpu" +    } +    field { +      name: "memory" +      number: 4 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v2.MemoryStat" +      json_name: "memory" +    } +    field { +      name: "rdma" +      number: 5 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v2.RdmaStat" +      json_name: "rdma" +    } +    field { +      name: "io" +      number: 6 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v2.IOStat" +      json_name: "io" +    } +    field { +      name: "hugetlb" +      number: 7 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v2.HugeTlbStat" +      json_name: "hugetlb" +    } +    field { +      name: "memory_events" +      number: 8 +      label: LABEL_OPTIONAL +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v2.MemoryEvents" +      json_name: "memoryEvents" +    } +  } +  message_type { +    name: "PidsStat" +    field { +      name: "current" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "current" +    } +    field { +      name: "limit" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "limit" +    } +  } +  message_type { +    name: "CPUStat" +    field { +      name: "usage_usec" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "usageUsec" +    } +    field { +      name: "user_usec" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "userUsec" +    } +    field { +      name: "system_usec" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "systemUsec" +    } +    field { +      name: "nr_periods" +      number: 4 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "nrPeriods" +    } +    field { +      name: "nr_throttled" +      number: 5 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "nrThrottled" +    } +    field { +      name: "throttled_usec" +      number: 6 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "throttledUsec" +    } +  } +  message_type { +    name: "MemoryStat" +    field { +      name: "anon" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "anon" +    } +    field { +      name: "file" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "file" +    } +    field { +      name: "kernel_stack" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "kernelStack" +    } +    field { +      name: "slab" +      number: 4 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "slab" +    } +    field { +      name: "sock" +      number: 5 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "sock" +    } +    field { +      name: "shmem" +      number: 6 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "shmem" +    } +    field { +      name: "file_mapped" +      number: 7 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "fileMapped" +    } +    field { +      name: "file_dirty" +      number: 8 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "fileDirty" +    } +    field { +      name: "file_writeback" +      number: 9 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "fileWriteback" +    } +    field { +      name: "anon_thp" +      number: 10 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "anonThp" +    } +    field { +      name: "inactive_anon" +      number: 11 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "inactiveAnon" +    } +    field { +      name: "active_anon" +      number: 12 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "activeAnon" +    } +    field { +      name: "inactive_file" +      number: 13 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "inactiveFile" +    } +    field { +      name: "active_file" +      number: 14 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "activeFile" +    } +    field { +      name: "unevictable" +      number: 15 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "unevictable" +    } +    field { +      name: "slab_reclaimable" +      number: 16 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "slabReclaimable" +    } +    field { +      name: "slab_unreclaimable" +      number: 17 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "slabUnreclaimable" +    } +    field { +      name: "pgfault" +      number: 18 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pgfault" +    } +    field { +      name: "pgmajfault" +      number: 19 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pgmajfault" +    } +    field { +      name: "workingset_refault" +      number: 20 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "workingsetRefault" +    } +    field { +      name: "workingset_activate" +      number: 21 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "workingsetActivate" +    } +    field { +      name: "workingset_nodereclaim" +      number: 22 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "workingsetNodereclaim" +    } +    field { +      name: "pgrefill" +      number: 23 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pgrefill" +    } +    field { +      name: "pgscan" +      number: 24 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pgscan" +    } +    field { +      name: "pgsteal" +      number: 25 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pgsteal" +    } +    field { +      name: "pgactivate" +      number: 26 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pgactivate" +    } +    field { +      name: "pgdeactivate" +      number: 27 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pgdeactivate" +    } +    field { +      name: "pglazyfree" +      number: 28 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pglazyfree" +    } +    field { +      name: "pglazyfreed" +      number: 29 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "pglazyfreed" +    } +    field { +      name: "thp_fault_alloc" +      number: 30 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "thpFaultAlloc" +    } +    field { +      name: "thp_collapse_alloc" +      number: 31 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "thpCollapseAlloc" +    } +    field { +      name: "usage" +      number: 32 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "usage" +    } +    field { +      name: "usage_limit" +      number: 33 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "usageLimit" +    } +    field { +      name: "swap_usage" +      number: 34 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "swapUsage" +    } +    field { +      name: "swap_limit" +      number: 35 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "swapLimit" +    } +  } +  message_type { +    name: "MemoryEvents" +    field { +      name: "low" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "low" +    } +    field { +      name: "high" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "high" +    } +    field { +      name: "max" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "max" +    } +    field { +      name: "oom" +      number: 4 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "oom" +    } +    field { +      name: "oom_kill" +      number: 5 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "oomKill" +    } +  } +  message_type { +    name: "RdmaStat" +    field { +      name: "current" +      number: 1 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v2.RdmaEntry" +      json_name: "current" +    } +    field { +      name: "limit" +      number: 2 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v2.RdmaEntry" +      json_name: "limit" +    } +  } +  message_type { +    name: "RdmaEntry" +    field { +      name: "device" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_STRING +      json_name: "device" +    } +    field { +      name: "hca_handles" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT32 +      json_name: "hcaHandles" +    } +    field { +      name: "hca_objects" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT32 +      json_name: "hcaObjects" +    } +  } +  message_type { +    name: "IOStat" +    field { +      name: "usage" +      number: 1 +      label: LABEL_REPEATED +      type: TYPE_MESSAGE +      type_name: ".io.containerd.cgroups.v2.IOEntry" +      json_name: "usage" +    } +  } +  message_type { +    name: "IOEntry" +    field { +      name: "major" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "major" +    } +    field { +      name: "minor" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "minor" +    } +    field { +      name: "rbytes" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "rbytes" +    } +    field { +      name: "wbytes" +      number: 4 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "wbytes" +    } +    field { +      name: "rios" +      number: 5 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "rios" +    } +    field { +      name: "wios" +      number: 6 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "wios" +    } +  } +  message_type { +    name: "HugeTlbStat" +    field { +      name: "current" +      number: 1 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "current" +    } +    field { +      name: "max" +      number: 2 +      label: LABEL_OPTIONAL +      type: TYPE_UINT64 +      json_name: "max" +    } +    field { +      name: "pagesize" +      number: 3 +      label: LABEL_OPTIONAL +      type: TYPE_STRING +      json_name: "pagesize" +    } +  } +  syntax: "proto3" +} diff --git a/vendor/github.com/containerd/cgroups/v2/stats/metrics.proto b/vendor/github.com/containerd/cgroups/v2/stats/metrics.proto new file mode 100644 index 000000000..8ac472e46 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/stats/metrics.proto @@ -0,0 +1,105 @@ +syntax = "proto3"; + +package io.containerd.cgroups.v2; + + import "gogoproto/gogo.proto"; + +message Metrics { +	PidsStat pids = 1; +	CPUStat cpu = 2 [(gogoproto.customname) = "CPU"]; +	MemoryStat memory = 4; +	RdmaStat rdma = 5; +	IOStat io = 6; +	repeated HugeTlbStat hugetlb = 7; +	MemoryEvents memory_events = 8; +} + +message PidsStat { +	uint64 current = 1; +	uint64 limit = 2; +} + +message CPUStat { +	uint64 usage_usec  = 1; +	uint64 user_usec = 2; +	uint64 system_usec = 3; +	uint64 nr_periods = 4; +	uint64 nr_throttled = 5; +	uint64 throttled_usec = 6; +} + +message MemoryStat { +	uint64 anon = 1; +	uint64 file = 2; +	uint64 kernel_stack = 3; +	uint64 slab = 4; +	uint64 sock = 5; +	uint64 shmem = 6; +	uint64 file_mapped = 7; +	uint64 file_dirty = 8; +	uint64 file_writeback = 9; +	uint64 anon_thp = 10; +	uint64 inactive_anon = 11; +	uint64 active_anon = 12; +	uint64 inactive_file = 13; +	uint64 active_file = 14; +	uint64 unevictable = 15; +	uint64 slab_reclaimable = 16; +	uint64 slab_unreclaimable = 17; +	uint64 pgfault = 18; +	uint64 pgmajfault = 19; +	uint64 workingset_refault = 20; +	uint64 workingset_activate = 21; +	uint64 workingset_nodereclaim = 22; +	uint64 pgrefill = 23; +	uint64 pgscan = 24; +	uint64 pgsteal = 25; +	uint64 pgactivate = 26; +	uint64 pgdeactivate = 27; +	uint64 pglazyfree = 28; +	uint64 pglazyfreed = 29; +	uint64 thp_fault_alloc = 30; +	uint64 thp_collapse_alloc = 31; +	uint64 usage = 32; +	uint64 usage_limit = 33; +	uint64 swap_usage = 34; +	uint64 swap_limit = 35; +} + +message MemoryEvents { +	uint64 low = 1; +	uint64 high = 2; +	uint64 max = 3; +	uint64 oom = 4; +	uint64 oom_kill = 5; +} + +message RdmaStat { +	repeated RdmaEntry current = 1; +	repeated RdmaEntry limit = 2; +} + +message RdmaEntry { +	string device = 1; +	uint32 hca_handles = 2; +	uint32 hca_objects = 3; +} + +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; +} + +message HugeTlbStat { +	uint64 current = 1; +	uint64 max = 2; +	string pagesize = 3; +} diff --git a/vendor/github.com/containerd/cgroups/v2/utils.go b/vendor/github.com/containerd/cgroups/v2/utils.go new file mode 100644 index 000000000..240c92677 --- /dev/null +++ b/vendor/github.com/containerd/cgroups/v2/utils.go @@ -0,0 +1,436 @@ +/* +   Copyright The containerd Authors. + +   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 v2 + +import ( +	"bufio" +	"fmt" +	"io" +	"io/ioutil" +	"math" +	"os" +	"path/filepath" +	"strconv" +	"strings" +	"time" + +	"github.com/containerd/cgroups/v2/stats" + +	"github.com/godbus/dbus/v5" +	"github.com/opencontainers/runtime-spec/specs-go" +	"github.com/sirupsen/logrus" +) + +const ( +	cgroupProcs    = "cgroup.procs" +	defaultDirPerm = 0755 +) + +// defaultFilePerm is a var so that the test framework can change the filemode +// of all files created when the tests are running.  The difference between the +// tests and real world use is that files like "cgroup.procs" will exist when writing +// to a read cgroup filesystem and do not exist prior when running in the tests. +// this is set to a non 0 value in the test code +var defaultFilePerm = os.FileMode(0) + +// remove will remove a cgroup path handling EAGAIN and EBUSY errors and +// retrying the remove after a exp timeout +func remove(path string) error { +	var err error +	delay := 10 * time.Millisecond +	for i := 0; i < 5; i++ { +		if i != 0 { +			time.Sleep(delay) +			delay *= 2 +		} +		if err = os.RemoveAll(path); err == nil { +			return nil +		} +	} +	return fmt.Errorf("cgroups: unable to remove path %q: %w", path, err) +} + +// parseCgroupProcsFile parses /sys/fs/cgroup/$GROUPPATH/cgroup.procs +func parseCgroupProcsFile(path string) ([]uint64, error) { +	f, err := os.Open(path) +	if err != nil { +		return nil, err +	} +	defer f.Close() +	var ( +		out []uint64 +		s   = bufio.NewScanner(f) +	) +	for s.Scan() { +		if t := s.Text(); t != "" { +			pid, err := strconv.ParseUint(t, 10, 0) +			if err != nil { +				return nil, err +			} +			out = append(out, pid) +		} +	} +	if err := s.Err(); err != nil { +		return nil, err +	} +	return out, nil +} + +func parseKV(raw string) (string, interface{}, error) { +	parts := strings.Fields(raw) +	switch len(parts) { +	case 2: +		v, err := parseUint(parts[1], 10, 64) +		if err != nil { +			// if we cannot parse as a uint, parse as a string +			return parts[0], parts[1], nil +		} +		return parts[0], v, nil +	default: +		return "", 0, ErrInvalidFormat +	} +} + +func parseUint(s string, base, bitSize int) (uint64, error) { +	v, err := strconv.ParseUint(s, base, bitSize) +	if err != nil { +		intValue, intErr := strconv.ParseInt(s, base, bitSize) +		// 1. Handle negative values greater than MinInt64 (and) +		// 2. Handle negative values lesser than MinInt64 +		if intErr == nil && intValue < 0 { +			return 0, nil +		} else if intErr != nil && +			intErr.(*strconv.NumError).Err == strconv.ErrRange && +			intValue < 0 { +			return 0, nil +		} +		return 0, err +	} +	return v, nil +} + +// parseCgroupFile parses /proc/PID/cgroup file and return string +func parseCgroupFile(path string) (string, error) { +	f, err := os.Open(path) +	if err != nil { +		return "", err +	} +	defer f.Close() +	return parseCgroupFromReader(f) +} + +func parseCgroupFromReader(r io.Reader) (string, error) { +	var ( +		s = bufio.NewScanner(r) +	) +	for s.Scan() { +		var ( +			text  = s.Text() +			parts = strings.SplitN(text, ":", 3) +		) +		if len(parts) < 3 { +			return "", fmt.Errorf("invalid cgroup entry: %q", text) +		} +		// text is like "0::/user.slice/user-1001.slice/session-1.scope" +		if parts[0] == "0" && parts[1] == "" { +			return parts[2], nil +		} +	} +	if err := s.Err(); err != nil { +		return "", err +	} +	return "", fmt.Errorf("cgroup path not found") +} + +// ToResources converts the oci LinuxResources struct into a +// v2 Resources type for use with this package. +// +// converting cgroups configuration from v1 to v2 +// ref: https://github.com/containers/crun/blob/master/crun.1.md#cgroup-v2 +func ToResources(spec *specs.LinuxResources) *Resources { +	var resources Resources +	if cpu := spec.CPU; cpu != nil { +		resources.CPU = &CPU{ +			Cpus: cpu.Cpus, +			Mems: cpu.Mems, +		} +		if shares := cpu.Shares; shares != nil { +			convertedWeight := 1 + ((*shares-2)*9999)/262142 +			resources.CPU.Weight = &convertedWeight +		} +		if period := cpu.Period; period != nil { +			resources.CPU.Max = NewCPUMax(cpu.Quota, period) +		} +	} +	if mem := spec.Memory; mem != nil { +		resources.Memory = &Memory{} +		if swap := mem.Swap; swap != nil { +			resources.Memory.Swap = swap +		} +		if l := mem.Limit; l != nil { +			resources.Memory.Max = l +		} +		if l := mem.Reservation; l != nil { +			resources.Memory.Low = l +		} +	} +	if hugetlbs := spec.HugepageLimits; hugetlbs != nil { +		hugeTlbUsage := HugeTlb{} +		for _, hugetlb := range hugetlbs { +			hugeTlbUsage = append(hugeTlbUsage, HugeTlbEntry{ +				HugePageSize: hugetlb.Pagesize, +				Limit:        hugetlb.Limit, +			}) +		} +		resources.HugeTlb = &hugeTlbUsage +	} +	if pids := spec.Pids; pids != nil { +		resources.Pids = &Pids{ +			Max: pids.Limit, +		} +	} +	if i := spec.BlockIO; i != nil { +		resources.IO = &IO{} +		if i.Weight != nil { +			resources.IO.BFQ.Weight = 1 + (*i.Weight-10)*9999/990 +		} +		for t, devices := range map[IOType][]specs.LinuxThrottleDevice{ +			ReadBPS:   i.ThrottleReadBpsDevice, +			WriteBPS:  i.ThrottleWriteBpsDevice, +			ReadIOPS:  i.ThrottleReadIOPSDevice, +			WriteIOPS: i.ThrottleWriteIOPSDevice, +		} { +			for _, d := range devices { +				resources.IO.Max = append(resources.IO.Max, Entry{ +					Type:  t, +					Major: d.Major, +					Minor: d.Minor, +					Rate:  d.Rate, +				}) +			} +		} +	} +	if i := spec.Rdma; i != nil { +		resources.RDMA = &RDMA{} +		for device, value := range spec.Rdma { +			if device != "" && (value.HcaHandles != nil && value.HcaObjects != nil) { +				resources.RDMA.Limit = append(resources.RDMA.Limit, RDMAEntry{ +					Device:     device, +					HcaHandles: *value.HcaHandles, +					HcaObjects: *value.HcaObjects, +				}) +			} +		} +	} + +	return &resources +} + +// Gets uint64 parsed content of single value cgroup stat file +func getStatFileContentUint64(filePath string) uint64 { +	contents, err := ioutil.ReadFile(filePath) +	if err != nil { +		return 0 +	} +	trimmed := strings.TrimSpace(string(contents)) +	if trimmed == "max" { +		return math.MaxUint64 +	} + +	res, err := parseUint(trimmed, 10, 64) +	if err != nil { +		logrus.Errorf("unable to parse %q as a uint from Cgroup file %q", string(contents), filePath) +		return res +	} + +	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 _, s := range parts { +			keyPairValue := strings.Split(s, "=") +			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 { +		return []*stats.RdmaEntry{} +	} +	return toRdmaEntry(strings.Split(string(currentData), "\n")) +} + +func parseRdmaKV(raw string, entry *stats.RdmaEntry) { +	var value uint64 +	var err error + +	parts := strings.Split(raw, "=") +	switch len(parts) { +	case 2: +		if parts[1] == "max" { +			value = math.MaxUint32 +		} else { +			value, err = parseUint(parts[1], 10, 32) +			if err != nil { +				return +			} +		} +		if parts[0] == "hca_handle" { +			entry.HcaHandles = uint32(value) +		} else if parts[0] == "hca_object" { +			entry.HcaObjects = uint32(value) +		} +	} +} + +func toRdmaEntry(strEntries []string) []*stats.RdmaEntry { +	var rdmaEntries []*stats.RdmaEntry +	for i := range strEntries { +		parts := strings.Fields(strEntries[i]) +		switch len(parts) { +		case 3: +			entry := new(stats.RdmaEntry) +			entry.Device = parts[0] +			parseRdmaKV(parts[1], entry) +			parseRdmaKV(parts[2], entry) + +			rdmaEntries = append(rdmaEntries, entry) +		default: +			continue +		} +	} +	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 +} + +func readHugeTlbStats(path string) []*stats.HugeTlbStat { +	var usage = []*stats.HugeTlbStat{} +	var keyUsage = make(map[string]*stats.HugeTlbStat) +	f, err := os.Open(path) +	if err != nil { +		return usage +	} +	files, err := f.Readdir(-1) +	f.Close() +	if err != nil { +		return usage +	} + +	for _, file := range files { +		if strings.Contains(file.Name(), "hugetlb") && +			(strings.HasSuffix(file.Name(), "max") || strings.HasSuffix(file.Name(), "current")) { +			var hugeTlb *stats.HugeTlbStat +			var ok bool +			fileName := strings.Split(file.Name(), ".") +			pageSize := fileName[1] +			if hugeTlb, ok = keyUsage[pageSize]; !ok { +				hugeTlb = &stats.HugeTlbStat{} +			} +			hugeTlb.Pagesize = pageSize +			out, err := ioutil.ReadFile(filepath.Join(path, file.Name())) +			if err != nil { +				continue +			} +			var value uint64 +			stringVal := strings.TrimSpace(string(out)) +			if stringVal == "max" { +				value = math.MaxUint64 +			} else { +				value, err = strconv.ParseUint(stringVal, 10, 64) +			} +			if err != nil { +				continue +			} +			switch fileName[2] { +			case "max": +				hugeTlb.Max = value +			case "current": +				hugeTlb.Current = value +			} +			keyUsage[pageSize] = hugeTlb +		} +	} +	for _, entry := range keyUsage { +		usage = append(usage, entry) +	} +	return usage +}  | 
