pax_global_header00006660000000000000000000000064135135100310014502gustar00rootroot0000000000000052 comment=c4b9ac5c7601384c965b9646fc515884e091ebb9 cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/000077500000000000000000000000001351351003100200535ustar00rootroot00000000000000cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/.gitignore000066400000000000000000000000201351351003100220330ustar00rootroot00000000000000example/example cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/.travis.yml000066400000000000000000000023371351351003100221710ustar00rootroot00000000000000language: go go: - 1.11.x - 1.12.x go_import_path: github.com/containerd/cgroups install: - mkdir -p $GOPATH/src/github.com/prometheus $GOPATH/src/github.com/opencontainers $GOPATH/src/github.com/coreos $GOPATH/src/github.com/godbus - cd $GOPATH/src/github.com/opencontainers && git clone https://github.com/opencontainers/runtime-spec && cd runtime-spec && git checkout fa4b36aa9c99e00c2ef7b5c0013c84100ede5f4e - cd $GOPATH/src/github.com/coreos && git clone https://github.com/coreos/go-systemd && cd go-systemd && git checkout 48702e0da86bd25e76cfef347e2adeb434a0d0a6 - cd $GOPATH/src/github.com/godbus && git clone https://github.com/godbus/dbus && cd dbus && git checkout c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f - cd $GOPATH/src/github.com/containerd/cgroups - go get -d -t ./... - go get -u github.com/vbatts/git-validation - go get -u github.com/kunalkushwaha/ltag before_script: - pushd ..; git clone https://github.com/containerd/project; popd script: - DCO_VERBOSITY=-q ../project/script/validate/dco - ../project/script/validate/fileheader ../project/ - go test -race -coverprofile=coverage.txt -covermode=atomic after_success: - bash <(curl -s https://codecov.io/bash) cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/LICENSE000066400000000000000000000261351351351003100210670ustar00rootroot00000000000000 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. cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/Makefile000066400000000000000000000013061351351003100215130ustar00rootroot00000000000000# 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: go build -v proto: protobuild --quiet ${PACKAGES} cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/Protobuild.toml000066400000000000000000000030711351351003100230740ustar00rootroot00000000000000version = "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"] # 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" target = "metrics.pb.txt" ignore_files = [ "google/protobuf/descriptor.proto", "gogoproto/gogo.proto" ] cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/README.md000066400000000000000000000061441351351003100213370ustar00rootroot00000000000000# cgroups [![Build Status](https://travis-ci.org/containerd/cgroups.svg?branch=master)](https://travis-ci.org/containerd/cgroups) [![codecov](https://codecov.io/gh/containerd/cgroups/branch/master/graph/badge.svg)](https://codecov.io/gh/containerd/cgroups) [![GoDoc](https://godoc.org/github.com/containerd/cgroups?status.svg)](https://godoc.org/github.com/containerd/cgroups) [![Go Report Card](https://goreportcard.com/badge/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.CPU{ 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.CPU{ 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) ``` ## 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/master/GOVERNANCE.md), * [Maintainers](https://github.com/containerd/project/blob/master/MAINTAINERS), * and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md) information in our [`containerd/project`](https://github.com/containerd/project) repository. cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/blkio.go000066400000000000000000000171351351351003100215110ustar00rootroot00000000000000/* 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" "io/ioutil" "os" "path/filepath" "strconv" "strings" specs "github.com/opencontainers/runtime-spec/specs-go" ) func NewBlkio(root string) *blkioController { return &blkioController{ root: filepath.Join(root, string(Blkio)), } } type blkioController struct { root 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 := ioutil.WriteFile( filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", 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 *Metrics) error { stats.Blkio = &BlkIOStat{} settings := []blkioStatSettings{ { name: "throttle.io_serviced", entry: &stats.Blkio.IoServicedRecursive, }, { name: "throttle.io_service_bytes", entry: &stats.Blkio.IoServiceBytesRecursive, }, } // Try to read CFQ stats available on all CFQ enabled kernels first if _, err := os.Lstat(filepath.Join(b.Path(path), fmt.Sprintf("blkio.io_serviced_recursive"))); err == nil { settings = []blkioStatSettings{} settings = append(settings, blkioStatSettings{ name: "sectors_recursive", entry: &stats.Blkio.SectorsRecursive, }, blkioStatSettings{ name: "io_service_bytes_recursive", entry: &stats.Blkio.IoServiceBytesRecursive, }, blkioStatSettings{ name: "io_serviced_recursive", entry: &stats.Blkio.IoServicedRecursive, }, blkioStatSettings{ name: "io_queued_recursive", entry: &stats.Blkio.IoQueuedRecursive, }, blkioStatSettings{ name: "io_service_time_recursive", entry: &stats.Blkio.IoServiceTimeRecursive, }, blkioStatSettings{ name: "io_wait_time_recursive", entry: &stats.Blkio.IoWaitTimeRecursive, }, blkioStatSettings{ name: "io_merged_recursive", entry: &stats.Blkio.IoMergedRecursive, }, blkioStatSettings{ name: "time_recursive", entry: &stats.Blkio.IoTimeRecursive, }, ) } f, err := os.Open("/proc/diskstats") if err != nil { return err } defer f.Close() devices, err := getDevices(f) if err != nil { return err } 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 *[]*BlkIOEntry) error { f, err := os.Open(filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", name))) if err != nil { return err } defer f.Close() sc := bufio.NewScanner(f) for sc.Scan() { if err := sc.Err(); err != nil { return err } // 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, &BlkIOEntry{ Device: devices[deviceKey{major, minor}], Major: major, Minor: minor, Op: op, Value: v, }) } return nil } 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 *[]*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 s.Scan() { 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[2]) } return devices, s.Err() } func major(devNumber uint64) uint64 { return (devNumber >> 8) & 0xfff } func minor(devNumber uint64) uint64 { return (devNumber & 0xff) | ((devNumber >> 12) & 0xfff00) } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/blkio_test.go000066400000000000000000000032071351351003100225430ustar00rootroot00000000000000/* 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 ( "strings" "testing" ) const data = ` 7 0 loop0 0 0 0 0 0 0 0 0 0 0 0 7 1 loop1 0 0 0 0 0 0 0 0 0 0 0 7 2 loop2 0 0 0 0 0 0 0 0 0 0 0 7 3 loop3 0 0 0 0 0 0 0 0 0 0 0 7 4 loop4 0 0 0 0 0 0 0 0 0 0 0 7 5 loop5 0 0 0 0 0 0 0 0 0 0 0 7 6 loop6 0 0 0 0 0 0 0 0 0 0 0 7 7 loop7 0 0 0 0 0 0 0 0 0 0 0 8 0 sda 1892042 187697 63489222 1246284 1389086 2887005 134903104 11390608 1 1068060 12692228 8 1 sda1 1762875 37086 61241570 1200512 1270037 2444415 131214808 11152764 1 882624 12409308 8 2 sda2 2 0 4 0 0 0 0 0 0 0 0 8 5 sda5 129102 150611 2244440 45716 18447 442590 3688296 67268 0 62584 112984` func TestGetDevices(t *testing.T) { r := strings.NewReader(data) devices, err := getDevices(r) if err != nil { t.Fatal(err) } name, ok := devices[deviceKey{8, 0}] if !ok { t.Fatal("no device found for 8,0") } const expected = "/dev/sda" if name != expected { t.Fatalf("expected device name %q but received %q", expected, name) } } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/cgroup.go000066400000000000000000000266341351351003100217140ustar00rootroot00000000000000/* 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" "os" "path/filepath" "strconv" "strings" "sync" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" ) // 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 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 os.IsNotExist(errors.Cause(err)) { 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 } // Add moves the provided process into the new cgroup func (c *cgroup) Add(process Process) error { if process.Pid <= 0 { return ErrInvalidPid } c.mu.Lock() defer c.mu.Unlock() if c.err != nil { return c.err } return c.add(process) } func (c *cgroup) add(process Process) error { for _, s := range pathers(c.subsystems) { p, err := c.path(s.Name()) if err != nil { return err } if err := ioutil.WriteFile( filepath.Join(s.Path(p), cgroupProcs), []byte(strconv.Itoa(process.Pid)), defaultFilePerm, ); err != nil { return err } } return nil } // AddTask moves the provided tasks (threads) into the new cgroup func (c *cgroup) AddTask(process Process) error { if process.Pid <= 0 { return ErrInvalidPid } c.mu.Lock() defer c.mu.Unlock() if c.err != nil { return c.err } return c.addTask(process) } func (c *cgroup) addTask(process Process) error { for _, s := range pathers(c.subsystems) { p, err := c.path(s.Name()) if err != nil { return err } if err := ioutil.WriteFile( filepath.Join(s.Path(p), cgroupTasks), []byte(strconv.Itoa(process.Pid)), defaultFilePerm, ); 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 errors []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 { errors = append(errors, 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 { errors = append(errors, path) } } } if len(errors) > 0 { return fmt.Errorf("cgroups: unable to remove paths %s", strings.Join(errors, ", ")) } c.err = ErrCgroupDeleted return nil } // Stat returns the current metrics for the cgroup func (c *cgroup) Stat(handlers ...ErrorHandler) (*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 = &Metrics{ CPU: &CPUStat{ Throttling: &Throttle{}, Usage: &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) } func (c *cgroup) processes(subsystem Name, recursive bool) ([]Process, error) { s := c.getSubsystem(subsystem) sp, err := c.path(subsystem) if err != nil { return nil, err } 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 != cgroupProcs { return nil } procs, err := readPids(dir, subsystem) if err != nil { return err } processes = append(processes, procs...) return nil }) return processes, err } // 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.tasks(subsystem, recursive) } func (c *cgroup) tasks(subsystem Name, recursive bool) ([]Task, error) { s := c.getSubsystem(subsystem) sp, err := c.path(subsystem) if err != nil { return nil, err } path := s.(pather).Path(sp) var tasks []Task 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 != cgroupTasks { return nil } procs, err := readTasksPids(dir, subsystem) if err != nil { return err } tasks = append(tasks, procs...) return nil }) return tasks, 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).OOMEventFD(sp) } // 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) 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 } } } } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/cgroup_test.go000066400000000000000000000223631351351003100227460ustar00rootroot00000000000000/* 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" "os" "path/filepath" "strconv" "testing" specs "github.com/opencontainers/runtime-spec/specs-go" ) // using t.Error in test were defers do cleanup on the filesystem func TestCreate(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() control, err := New(mock.hierarchy, StaticPath("test"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } if control == nil { t.Error("control is nil") return } for _, s := range Subsystems() { if _, err := os.Stat(filepath.Join(mock.root, string(s), "test")); err != nil { if os.IsNotExist(err) { t.Errorf("group %s was not created", s) return } t.Errorf("group %s was not created correctly %s", s, err) return } } } func TestStat(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() control, err := New(mock.hierarchy, StaticPath("test"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } s, err := control.Stat(IgnoreNotExist) if err != nil { t.Error(err) return } if s == nil { t.Error("stat result is nil") return } } func TestAdd(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() control, err := New(mock.hierarchy, StaticPath("test"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } if err := control.Add(Process{Pid: 1234}); err != nil { t.Error(err) return } for _, s := range Subsystems() { if err := checkPid(mock, filepath.Join(string(s), "test"), 1234); err != nil { t.Error(err) return } } } func TestAddTask(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() control, err := New(mock.hierarchy, StaticPath("test"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } if err := control.AddTask(Process{Pid: 1234}); err != nil { t.Error(err) return } for _, s := range Subsystems() { if err := checkTaskid(mock, filepath.Join(string(s), "test"), 1234); err != nil { t.Error(err) return } } } func TestListPids(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() control, err := New(mock.hierarchy, StaticPath("test"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } if err := control.Add(Process{Pid: 1234}); err != nil { t.Error(err) return } for _, s := range Subsystems() { if err := checkPid(mock, filepath.Join(string(s), "test"), 1234); err != nil { t.Error(err) return } } procs, err := control.Processes(Freezer, false) if err != nil { t.Error(err) return } if l := len(procs); l != 1 { t.Errorf("should have one process but received %d", l) return } if procs[0].Pid != 1234 { t.Errorf("expected pid %d but received %d", 1234, procs[0].Pid) } } func TestListTasksPids(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() control, err := New(mock.hierarchy, StaticPath("test"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } if err := control.AddTask(Process{Pid: 1234}); err != nil { t.Error(err) return } for _, s := range Subsystems() { if err := checkTaskid(mock, filepath.Join(string(s), "test"), 1234); err != nil { t.Error(err) return } } tasks, err := control.Tasks(Freezer, false) if err != nil { t.Error(err) return } if l := len(tasks); l != 1 { t.Errorf("should have one task but received %d", l) return } if tasks[0].Pid != 1234 { t.Errorf("expected task pid %d but received %d", 1234, tasks[0].Pid) } } func readValue(mock *mockCgroup, path string) (string, error) { data, err := ioutil.ReadFile(filepath.Join(mock.root, path)) if err != nil { return "", err } return string(data), nil } func checkPid(mock *mockCgroup, path string, expected int) error { data, err := readValue(mock, filepath.Join(path, cgroupProcs)) if err != nil { return err } v, err := strconv.Atoi(string(data)) if err != nil { return err } if v != expected { return fmt.Errorf("expected pid %d but received %d", expected, v) } return nil } func checkTaskid(mock *mockCgroup, path string, expected int) error { data, err := readValue(mock, filepath.Join(path, cgroupTasks)) if err != nil { return err } v, err := strconv.Atoi(string(data)) if err != nil { return err } if v != expected { return fmt.Errorf("expected task id %d but received %d", expected, v) } return nil } func mockNewNotInRdma(subsystems []Subsystem, path Path, resources *specs.LinuxResources) (Cgroup, error) { for _, s := range subsystems { if s.Name() != Rdma { if err := initializeSubsystem(s, path, resources); err != nil { return nil, err } } } return &cgroup{ path: path, subsystems: subsystems, }, nil } func TestLoad(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() control, err := New(mock.hierarchy, StaticPath("test"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } if control, err = Load(mock.hierarchy, StaticPath("test")); err != nil { t.Error(err) return } if control == nil { t.Error("control is nil") return } } func TestLoadWithMissingSubsystems(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() subsystems, err := mock.hierarchy() if err != nil { t.Error(err) return } control, err := mockNewNotInRdma(subsystems, StaticPath("test"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } if control == nil { t.Error("control is nil") return } if control, err = Load(mock.hierarchy, StaticPath("test")); err != nil { t.Error(err) return } if control == nil { t.Error("control is nil") return } if len(control.Subsystems()) != len(subsystems)-1 { t.Error("wrong number of active subsystems") return } } func TestDelete(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() control, err := New(mock.hierarchy, StaticPath("test"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } if err := control.Delete(); err != nil { t.Error(err) } } func TestCreateSubCgroup(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() control, err := New(mock.hierarchy, StaticPath("test"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } sub, err := control.New("child", &specs.LinuxResources{}) if err != nil { t.Error(err) return } if err := sub.Add(Process{Pid: 1234}); err != nil { t.Error(err) return } for _, s := range Subsystems() { if err := checkPid(mock, filepath.Join(string(s), "test", "child"), 1234); err != nil { t.Error(err) return } } if err := sub.AddTask(Process{Pid: 5678}); err != nil { t.Error(err) return } for _, s := range Subsystems() { if err := checkTaskid(mock, filepath.Join(string(s), "test", "child"), 5678); err != nil { t.Error(err) return } } } func TestFreezeThaw(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() control, err := New(mock.hierarchy, StaticPath("test"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } if err := control.Freeze(); err != nil { t.Error(err) return } if state := control.State(); state != Frozen { t.Errorf("expected %q but received %q", Frozen, state) return } if err := control.Thaw(); err != nil { t.Error(err) return } if state := control.State(); state != Thawed { t.Errorf("expected %q but received %q", Thawed, state) return } } func TestSubsystems(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() control, err := New(mock.hierarchy, StaticPath("test"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } cache := make(map[Name]struct{}) for _, s := range control.Subsystems() { cache[s.Name()] = struct{}{} } for _, s := range Subsystems() { if _, ok := cache[s]; !ok { t.Errorf("expected subsystem %q but not found", s) } } } func TestCpusetParent(t *testing.T) { const expected = "0-3" mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() control, err := New(mock.hierarchy, StaticPath("/parent/child"), &specs.LinuxResources{}) if err != nil { t.Error(err) return } defer control.Delete() for _, file := range []string{ "parent/cpuset.cpus", "parent/cpuset.mems", "parent/child/cpuset.cpus", "parent/child/cpuset.mems", } { v, err := readValue(mock, filepath.Join(string(Cpuset), file)) if err != nil { t.Error(err) return } if v != expected { t.Errorf("expected %q for %s but received %q", expected, file, v) } } } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/control.go000066400000000000000000000060641351351003100220700ustar00rootroot00000000000000/* 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" specs "github.com/opencontainers/runtime-spec/specs-go" ) const ( cgroupProcs = "cgroup.procs" cgroupTasks = "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 is in Subsystem Name // Pid is the process id of the process Pid int // Path is the full path of the subsystem and location that the process is in Path string } type Task struct { // Subsystem is the name of the subsystem that the task is in Subsystem Name // Pid is the process id of the task Pid int // Path is the full path of the subsystem and location that the task is in Path string } // 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) Add(Process) error // AddTask adds a process to the cgroup (tasks) AddTask(Process) 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) (*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) // State returns the cgroups current state State() State // Subsystems returns all the subsystems in the cgroup Subsystems() []Subsystem } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/cpu.go000066400000000000000000000054551351351003100212020ustar00rootroot00000000000000/* 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/ioutil" "os" "path/filepath" "strconv" 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 := ioutil.WriteFile( filepath.Join(c.Path(path), fmt.Sprintf("cpu.%s", 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 *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() { if err := sc.Err(); err != nil { return err } 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 nil } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/cpuacct.go000066400000000000000000000054631351351003100220340ustar00rootroot00000000000000/* 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" ) 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 *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 } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/cpuset.go000066400000000000000000000075571351351003100217230ustar00rootroot00000000000000/* 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 NewCputset(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 := ioutil.WriteFile( filepath.Join(c.Path(path), fmt.Sprintf("cpuset.%s", 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 := ioutil.WriteFile( filepath.Join(current, "cpuset.cpus"), parentCpus, defaultFilePerm, ); err != nil { return err } } if isEmpty(currentMems) { if err := ioutil.WriteFile( 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 } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/devices.go000066400000000000000000000041161351351003100220260ustar00rootroot00000000000000/* 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" "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 := ioutil.WriteFile( 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) } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/errors.go000066400000000000000000000030631351351003100217200ustar00rootroot00000000000000/* 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 } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/freezer.go000066400000000000000000000036511351351003100220510ustar00rootroot00000000000000/* 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 ioutil.WriteFile( 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) } } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/hierarchy.go000066400000000000000000000013231351351003100223570ustar00rootroot00000000000000/* 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 enableds both unified and split hierarchy for cgroups type Hierarchy func() ([]Subsystem, error) cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/hugetlb.go000066400000000000000000000046251351351003100220430ustar00rootroot00000000000000/* 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" 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 := ioutil.WriteFile( 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 *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) (*HugetlbStat, error) { s := 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 } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/memory.go000066400000000000000000000174601351351003100217220ustar00rootroot00000000000000/* 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" "io/ioutil" "os" "path/filepath" "strconv" "strings" "syscall" "golang.org/x/sys/unix" specs "github.com/opencontainers/runtime-spec/specs-go" ) func NewMemory(root string) *memoryController { return &memoryController{ root: filepath.Join(root, string(Memory)), } } type memoryController struct { root string } 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 } if resources.Memory.Kernel != nil { // Check if kernel memory is enabled // We have to limit the kernel memory here as it won't be accounted at all // until a limit is set on the cgroup and limit cannot be set once the // cgroup has children, or if there are already tasks in the cgroup. for _, i := range []int64{1, -1} { if err := ioutil.WriteFile( filepath.Join(m.Path(path), "memory.kmem.limit_in_bytes"), []byte(strconv.FormatInt(i, 10)), defaultFilePerm, ); err != nil { return checkEBUSY(err) } } } 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 *Metrics) error { f, err := os.Open(filepath.Join(m.Path(path), "memory.stat")) if err != nil { return err } defer f.Close() stats.Memory = &MemoryStat{ Usage: &MemoryEntry{}, Swap: &MemoryEntry{}, Kernel: &MemoryEntry{}, KernelTCP: &MemoryEntry{}, } if err := m.parseStats(f, stats.Memory); err != nil { return err } for _, t := range []struct { module string entry *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, }, } { 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) OOMEventFD(path string) (uintptr, error) { root := m.Path(path) f, err := os.Open(filepath.Join(root, "memory.oom_control")) if err != nil { return 0, err } defer f.Close() fd, _, serr := unix.RawSyscall(unix.SYS_EVENTFD2, 0, unix.EFD_CLOEXEC, 0) if serr != 0 { return 0, serr } if err := writeEventFD(root, f.Fd(), fd); err != nil { unix.Close(int(fd)) return 0, err } return fd, nil } func writeEventFD(root string, cfd, efd uintptr) error { f, err := os.OpenFile(filepath.Join(root, "cgroup.event_control"), os.O_WRONLY, 0) if err != nil { return err } _, err = f.WriteString(fmt.Sprintf("%d %d", efd, cfd)) f.Close() return err } func (m *memoryController) parseStats(r io.Reader, stat *MemoryStat) error { var ( raw = make(map[string]uint64) sc = bufio.NewScanner(r) line int ) for sc.Scan() { if err := sc.Err(); err != nil { return err } key, v, err := parseKV(sc.Text()) if err != nil { return fmt.Errorf("%d: %v", line, err) } raw[key] = v line++ } 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) set(path string, settings []memorySettings) error { for _, t := range settings { if t.value != nil { if err := ioutil.WriteFile( filepath.Join(m.Path(path), fmt.Sprintf("memory.%s", 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 checkEBUSY(err error) error { if pathErr, ok := err.(*os.PathError); ok { if errNo, ok := pathErr.Err.(syscall.Errno); ok { if errNo == unix.EBUSY { return fmt.Errorf( "failed to set memory.kmem.limit_in_bytes, because either tasks have already joined this cgroup or it has children") } } } return err } func getOomControlValue(mem *specs.LinuxMemory) *int64 { if mem.DisableOOMKiller != nil && *mem.DisableOOMKiller { i := int64(1) return &i } return nil } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/memory_test.go000066400000000000000000000040701351351003100227520ustar00rootroot00000000000000/* 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 ( "strings" "testing" ) const memoryData = `cache 1 rss 2 rss_huge 3 mapped_file 4 dirty 5 writeback 6 pgpgin 7 pgpgout 8 pgfault 9 pgmajfault 10 inactive_anon 11 active_anon 12 inactive_file 13 active_file 14 unevictable 15 hierarchical_memory_limit 16 hierarchical_memsw_limit 17 total_cache 18 total_rss 19 total_rss_huge 20 total_mapped_file 21 total_dirty 22 total_writeback 23 total_pgpgin 24 total_pgpgout 25 total_pgfault 26 total_pgmajfault 27 total_inactive_anon 28 total_active_anon 29 total_inactive_file 30 total_active_file 31 total_unevictable 32 ` func TestParseMemoryStats(t *testing.T) { var ( c = &memoryController{} m = &MemoryStat{} r = strings.NewReader(memoryData) ) if err := c.parseStats(r, m); err != nil { t.Fatal(err) } index := []uint64{ m.Cache, m.RSS, m.RSSHuge, m.MappedFile, m.Dirty, m.Writeback, m.PgPgIn, m.PgPgOut, m.PgFault, m.PgMajFault, m.InactiveAnon, m.ActiveAnon, m.InactiveFile, m.ActiveFile, m.Unevictable, m.HierarchicalMemoryLimit, m.HierarchicalSwapLimit, m.TotalCache, m.TotalRSS, m.TotalRSSHuge, m.TotalMappedFile, m.TotalDirty, m.TotalWriteback, m.TotalPgPgIn, m.TotalPgPgOut, m.TotalPgFault, m.TotalPgMajFault, m.TotalInactiveAnon, m.TotalActiveAnon, m.TotalInactiveFile, m.TotalActiveFile, m.TotalUnevictable, } for i, v := range index { if v != uint64(i)+1 { t.Errorf("expected value at index %d to be %d but received %d", i, i+1, v) } } } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/metrics.pb.go000066400000000000000000003544051351351003100224630ustar00rootroot00000000000000// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: github.com/containerd/cgroups/metrics.proto /* Package cgroups is a generated protocol buffer package. It is generated from these files: github.com/containerd/cgroups/metrics.proto It has these top-level messages: Metrics HugetlbStat PidsStat CPUStat CPUUsage Throttle MemoryStat MemoryEntry BlkIOStat BlkIOEntry RdmaStat RdmaEntry NetworkStat */ package cgroups import proto "github.com/gogo/protobuf/proto" import fmt "fmt" import math "math" import _ "github.com/gogo/protobuf/gogoproto" import strings "strings" import reflect "reflect" import io "io" // 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.GoGoProtoPackageIsVersion2 // please upgrade the proto package type Metrics struct { Hugetlb []*HugetlbStat `protobuf:"bytes,1,rep,name=hugetlb" json:"hugetlb,omitempty"` Pids *PidsStat `protobuf:"bytes,2,opt,name=pids" json:"pids,omitempty"` CPU *CPUStat `protobuf:"bytes,3,opt,name=cpu" json:"cpu,omitempty"` Memory *MemoryStat `protobuf:"bytes,4,opt,name=memory" json:"memory,omitempty"` Blkio *BlkIOStat `protobuf:"bytes,5,opt,name=blkio" json:"blkio,omitempty"` Rdma *RdmaStat `protobuf:"bytes,6,opt,name=rdma" json:"rdma,omitempty"` Network []*NetworkStat `protobuf:"bytes,7,rep,name=network" json:"network,omitempty"` } func (m *Metrics) Reset() { *m = Metrics{} } func (*Metrics) ProtoMessage() {} func (*Metrics) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{0} } 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"` } func (m *HugetlbStat) Reset() { *m = HugetlbStat{} } func (*HugetlbStat) ProtoMessage() {} func (*HugetlbStat) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{1} } 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"` } func (m *PidsStat) Reset() { *m = PidsStat{} } func (*PidsStat) ProtoMessage() {} func (*PidsStat) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{2} } type CPUStat struct { Usage *CPUUsage `protobuf:"bytes,1,opt,name=usage" json:"usage,omitempty"` Throttling *Throttle `protobuf:"bytes,2,opt,name=throttling" json:"throttling,omitempty"` } func (m *CPUStat) Reset() { *m = CPUStat{} } func (*CPUStat) ProtoMessage() {} func (*CPUStat) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{3} } 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" json:"per_cpu,omitempty"` } func (m *CPUUsage) Reset() { *m = CPUUsage{} } func (*CPUUsage) ProtoMessage() {} func (*CPUUsage) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{4} } 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"` } func (m *Throttle) Reset() { *m = Throttle{} } func (*Throttle) ProtoMessage() {} func (*Throttle) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{5} } 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" json:"usage,omitempty"` Swap *MemoryEntry `protobuf:"bytes,34,opt,name=swap" json:"swap,omitempty"` Kernel *MemoryEntry `protobuf:"bytes,35,opt,name=kernel" json:"kernel,omitempty"` KernelTCP *MemoryEntry `protobuf:"bytes,36,opt,name=kernel_tcp,json=kernelTcp" json:"kernel_tcp,omitempty"` } func (m *MemoryStat) Reset() { *m = MemoryStat{} } func (*MemoryStat) ProtoMessage() {} func (*MemoryStat) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{6} } 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"` } func (m *MemoryEntry) Reset() { *m = MemoryEntry{} } func (*MemoryEntry) ProtoMessage() {} func (*MemoryEntry) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{7} } type BlkIOStat struct { IoServiceBytesRecursive []*BlkIOEntry `protobuf:"bytes,1,rep,name=io_service_bytes_recursive,json=ioServiceBytesRecursive" json:"io_service_bytes_recursive,omitempty"` IoServicedRecursive []*BlkIOEntry `protobuf:"bytes,2,rep,name=io_serviced_recursive,json=ioServicedRecursive" json:"io_serviced_recursive,omitempty"` IoQueuedRecursive []*BlkIOEntry `protobuf:"bytes,3,rep,name=io_queued_recursive,json=ioQueuedRecursive" json:"io_queued_recursive,omitempty"` IoServiceTimeRecursive []*BlkIOEntry `protobuf:"bytes,4,rep,name=io_service_time_recursive,json=ioServiceTimeRecursive" json:"io_service_time_recursive,omitempty"` IoWaitTimeRecursive []*BlkIOEntry `protobuf:"bytes,5,rep,name=io_wait_time_recursive,json=ioWaitTimeRecursive" json:"io_wait_time_recursive,omitempty"` IoMergedRecursive []*BlkIOEntry `protobuf:"bytes,6,rep,name=io_merged_recursive,json=ioMergedRecursive" json:"io_merged_recursive,omitempty"` IoTimeRecursive []*BlkIOEntry `protobuf:"bytes,7,rep,name=io_time_recursive,json=ioTimeRecursive" json:"io_time_recursive,omitempty"` SectorsRecursive []*BlkIOEntry `protobuf:"bytes,8,rep,name=sectors_recursive,json=sectorsRecursive" json:"sectors_recursive,omitempty"` } func (m *BlkIOStat) Reset() { *m = BlkIOStat{} } func (*BlkIOStat) ProtoMessage() {} func (*BlkIOStat) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{8} } 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"` } func (m *BlkIOEntry) Reset() { *m = BlkIOEntry{} } func (*BlkIOEntry) ProtoMessage() {} func (*BlkIOEntry) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{9} } type RdmaStat struct { Current []*RdmaEntry `protobuf:"bytes,1,rep,name=current" json:"current,omitempty"` Limit []*RdmaEntry `protobuf:"bytes,2,rep,name=limit" json:"limit,omitempty"` } func (m *RdmaStat) Reset() { *m = RdmaStat{} } func (*RdmaStat) ProtoMessage() {} func (*RdmaStat) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{10} } 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"` } func (m *RdmaEntry) Reset() { *m = RdmaEntry{} } func (*RdmaEntry) ProtoMessage() {} func (*RdmaEntry) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{11} } 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"` } func (m *NetworkStat) Reset() { *m = NetworkStat{} } func (*NetworkStat) ProtoMessage() {} func (*NetworkStat) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{12} } 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((*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") } func (m *Metrics) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *Metrics) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Hugetlb) > 0 { for _, msg := range m.Hugetlb { dAtA[i] = 0xa i++ i = encodeVarintMetrics(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } if m.Pids != nil { dAtA[i] = 0x12 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Pids.Size())) n1, err := m.Pids.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n1 } if m.CPU != nil { dAtA[i] = 0x1a i++ i = encodeVarintMetrics(dAtA, i, uint64(m.CPU.Size())) n2, err := m.CPU.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n2 } if m.Memory != nil { dAtA[i] = 0x22 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Memory.Size())) n3, err := m.Memory.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n3 } if m.Blkio != nil { dAtA[i] = 0x2a i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Blkio.Size())) n4, err := m.Blkio.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n4 } if m.Rdma != nil { dAtA[i] = 0x32 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Rdma.Size())) n5, err := m.Rdma.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n5 } if len(m.Network) > 0 { for _, msg := range m.Network { dAtA[i] = 0x3a i++ i = encodeVarintMetrics(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } return i, nil } func (m *HugetlbStat) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *HugetlbStat) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Usage != 0 { dAtA[i] = 0x8 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Usage)) } if m.Max != 0 { dAtA[i] = 0x10 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Max)) } if m.Failcnt != 0 { dAtA[i] = 0x18 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Failcnt)) } if len(m.Pagesize) > 0 { dAtA[i] = 0x22 i++ i = encodeVarintMetrics(dAtA, i, uint64(len(m.Pagesize))) i += copy(dAtA[i:], m.Pagesize) } return i, nil } func (m *PidsStat) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *PidsStat) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Current != 0 { dAtA[i] = 0x8 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Current)) } if m.Limit != 0 { dAtA[i] = 0x10 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Limit)) } return i, nil } func (m *CPUStat) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *CPUStat) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Usage != nil { dAtA[i] = 0xa i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Usage.Size())) n6, err := m.Usage.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n6 } if m.Throttling != nil { dAtA[i] = 0x12 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Throttling.Size())) n7, err := m.Throttling.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n7 } return i, nil } func (m *CPUUsage) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *CPUUsage) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Total != 0 { dAtA[i] = 0x8 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Total)) } if m.Kernel != 0 { dAtA[i] = 0x10 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Kernel)) } if m.User != 0 { dAtA[i] = 0x18 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.User)) } if len(m.PerCPU) > 0 { dAtA9 := make([]byte, len(m.PerCPU)*10) var j8 int for _, num := range m.PerCPU { for num >= 1<<7 { dAtA9[j8] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 j8++ } dAtA9[j8] = uint8(num) j8++ } dAtA[i] = 0x22 i++ i = encodeVarintMetrics(dAtA, i, uint64(j8)) i += copy(dAtA[i:], dAtA9[:j8]) } return i, nil } func (m *Throttle) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *Throttle) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Periods != 0 { dAtA[i] = 0x8 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Periods)) } if m.ThrottledPeriods != 0 { dAtA[i] = 0x10 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.ThrottledPeriods)) } if m.ThrottledTime != 0 { dAtA[i] = 0x18 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.ThrottledTime)) } return i, nil } func (m *MemoryStat) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *MemoryStat) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Cache != 0 { dAtA[i] = 0x8 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Cache)) } if m.RSS != 0 { dAtA[i] = 0x10 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.RSS)) } if m.RSSHuge != 0 { dAtA[i] = 0x18 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.RSSHuge)) } if m.MappedFile != 0 { dAtA[i] = 0x20 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.MappedFile)) } if m.Dirty != 0 { dAtA[i] = 0x28 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Dirty)) } if m.Writeback != 0 { dAtA[i] = 0x30 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Writeback)) } if m.PgPgIn != 0 { dAtA[i] = 0x38 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.PgPgIn)) } if m.PgPgOut != 0 { dAtA[i] = 0x40 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.PgPgOut)) } if m.PgFault != 0 { dAtA[i] = 0x48 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.PgFault)) } if m.PgMajFault != 0 { dAtA[i] = 0x50 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.PgMajFault)) } if m.InactiveAnon != 0 { dAtA[i] = 0x58 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.InactiveAnon)) } if m.ActiveAnon != 0 { dAtA[i] = 0x60 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.ActiveAnon)) } if m.InactiveFile != 0 { dAtA[i] = 0x68 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.InactiveFile)) } if m.ActiveFile != 0 { dAtA[i] = 0x70 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.ActiveFile)) } if m.Unevictable != 0 { dAtA[i] = 0x78 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Unevictable)) } if m.HierarchicalMemoryLimit != 0 { dAtA[i] = 0x80 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.HierarchicalMemoryLimit)) } if m.HierarchicalSwapLimit != 0 { dAtA[i] = 0x88 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.HierarchicalSwapLimit)) } if m.TotalCache != 0 { dAtA[i] = 0x90 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalCache)) } if m.TotalRSS != 0 { dAtA[i] = 0x98 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalRSS)) } if m.TotalRSSHuge != 0 { dAtA[i] = 0xa0 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalRSSHuge)) } if m.TotalMappedFile != 0 { dAtA[i] = 0xa8 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalMappedFile)) } if m.TotalDirty != 0 { dAtA[i] = 0xb0 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalDirty)) } if m.TotalWriteback != 0 { dAtA[i] = 0xb8 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalWriteback)) } if m.TotalPgPgIn != 0 { dAtA[i] = 0xc0 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalPgPgIn)) } if m.TotalPgPgOut != 0 { dAtA[i] = 0xc8 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalPgPgOut)) } if m.TotalPgFault != 0 { dAtA[i] = 0xd0 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalPgFault)) } if m.TotalPgMajFault != 0 { dAtA[i] = 0xd8 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalPgMajFault)) } if m.TotalInactiveAnon != 0 { dAtA[i] = 0xe0 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalInactiveAnon)) } if m.TotalActiveAnon != 0 { dAtA[i] = 0xe8 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalActiveAnon)) } if m.TotalInactiveFile != 0 { dAtA[i] = 0xf0 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalInactiveFile)) } if m.TotalActiveFile != 0 { dAtA[i] = 0xf8 i++ dAtA[i] = 0x1 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalActiveFile)) } if m.TotalUnevictable != 0 { dAtA[i] = 0x80 i++ dAtA[i] = 0x2 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TotalUnevictable)) } if m.Usage != nil { dAtA[i] = 0x8a i++ dAtA[i] = 0x2 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Usage.Size())) n10, err := m.Usage.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n10 } if m.Swap != nil { dAtA[i] = 0x92 i++ dAtA[i] = 0x2 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Swap.Size())) n11, err := m.Swap.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n11 } if m.Kernel != nil { dAtA[i] = 0x9a i++ dAtA[i] = 0x2 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Kernel.Size())) n12, err := m.Kernel.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n12 } if m.KernelTCP != nil { dAtA[i] = 0xa2 i++ dAtA[i] = 0x2 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.KernelTCP.Size())) n13, err := m.KernelTCP.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n13 } return i, nil } func (m *MemoryEntry) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *MemoryEntry) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Limit != 0 { dAtA[i] = 0x8 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Limit)) } if m.Usage != 0 { dAtA[i] = 0x10 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Usage)) } if m.Max != 0 { dAtA[i] = 0x18 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Max)) } if m.Failcnt != 0 { dAtA[i] = 0x20 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Failcnt)) } return i, nil } func (m *BlkIOStat) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *BlkIOStat) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.IoServiceBytesRecursive) > 0 { for _, msg := range m.IoServiceBytesRecursive { dAtA[i] = 0xa i++ i = encodeVarintMetrics(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } if len(m.IoServicedRecursive) > 0 { for _, msg := range m.IoServicedRecursive { dAtA[i] = 0x12 i++ i = encodeVarintMetrics(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } if len(m.IoQueuedRecursive) > 0 { for _, msg := range m.IoQueuedRecursive { dAtA[i] = 0x1a i++ i = encodeVarintMetrics(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } if len(m.IoServiceTimeRecursive) > 0 { for _, msg := range m.IoServiceTimeRecursive { dAtA[i] = 0x22 i++ i = encodeVarintMetrics(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } if len(m.IoWaitTimeRecursive) > 0 { for _, msg := range m.IoWaitTimeRecursive { dAtA[i] = 0x2a i++ i = encodeVarintMetrics(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } if len(m.IoMergedRecursive) > 0 { for _, msg := range m.IoMergedRecursive { dAtA[i] = 0x32 i++ i = encodeVarintMetrics(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } if len(m.IoTimeRecursive) > 0 { for _, msg := range m.IoTimeRecursive { dAtA[i] = 0x3a i++ i = encodeVarintMetrics(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } if len(m.SectorsRecursive) > 0 { for _, msg := range m.SectorsRecursive { dAtA[i] = 0x42 i++ i = encodeVarintMetrics(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } return i, nil } func (m *BlkIOEntry) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *BlkIOEntry) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Op) > 0 { dAtA[i] = 0xa i++ i = encodeVarintMetrics(dAtA, i, uint64(len(m.Op))) i += copy(dAtA[i:], m.Op) } if len(m.Device) > 0 { dAtA[i] = 0x12 i++ i = encodeVarintMetrics(dAtA, i, uint64(len(m.Device))) i += copy(dAtA[i:], m.Device) } if m.Major != 0 { dAtA[i] = 0x18 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Major)) } if m.Minor != 0 { dAtA[i] = 0x20 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Minor)) } if m.Value != 0 { dAtA[i] = 0x28 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.Value)) } return i, nil } func (m *RdmaStat) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *RdmaStat) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Current) > 0 { for _, msg := range m.Current { dAtA[i] = 0xa i++ i = encodeVarintMetrics(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } if len(m.Limit) > 0 { for _, msg := range m.Limit { dAtA[i] = 0x12 i++ i = encodeVarintMetrics(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } return i, nil } func (m *RdmaEntry) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *RdmaEntry) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Device) > 0 { dAtA[i] = 0xa i++ i = encodeVarintMetrics(dAtA, i, uint64(len(m.Device))) i += copy(dAtA[i:], m.Device) } if m.HcaHandles != 0 { dAtA[i] = 0x10 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.HcaHandles)) } if m.HcaObjects != 0 { dAtA[i] = 0x18 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.HcaObjects)) } return i, nil } func (m *NetworkStat) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } return dAtA[:n], nil } func (m *NetworkStat) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Name) > 0 { dAtA[i] = 0xa i++ i = encodeVarintMetrics(dAtA, i, uint64(len(m.Name))) i += copy(dAtA[i:], m.Name) } if m.RxBytes != 0 { dAtA[i] = 0x10 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.RxBytes)) } if m.RxPackets != 0 { dAtA[i] = 0x18 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.RxPackets)) } if m.RxErrors != 0 { dAtA[i] = 0x20 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.RxErrors)) } if m.RxDropped != 0 { dAtA[i] = 0x28 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.RxDropped)) } if m.TxBytes != 0 { dAtA[i] = 0x30 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TxBytes)) } if m.TxPackets != 0 { dAtA[i] = 0x38 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TxPackets)) } if m.TxErrors != 0 { dAtA[i] = 0x40 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TxErrors)) } if m.TxDropped != 0 { dAtA[i] = 0x48 i++ i = encodeVarintMetrics(dAtA, i, uint64(m.TxDropped)) } return i, nil } func encodeVarintMetrics(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ } dAtA[offset] = uint8(v) return offset + 1 } func (m *Metrics) Size() (n int) { 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)) } } return n } func (m *HugetlbStat) Size() (n int) { 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)) } return n } func (m *PidsStat) Size() (n int) { var l int _ = l if m.Current != 0 { n += 1 + sovMetrics(uint64(m.Current)) } if m.Limit != 0 { n += 1 + sovMetrics(uint64(m.Limit)) } return n } func (m *CPUStat) Size() (n int) { 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)) } return n } func (m *CPUUsage) Size() (n int) { 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 } return n } func (m *Throttle) Size() (n int) { 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)) } return n } func (m *MemoryStat) Size() (n int) { 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)) } return n } func (m *MemoryEntry) Size() (n int) { 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)) } return n } func (m *BlkIOStat) Size() (n int) { 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)) } } return n } func (m *BlkIOEntry) Size() (n int) { 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)) } return n } func (m *RdmaStat) Size() (n int) { 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)) } } return n } func (m *RdmaEntry) Size() (n int) { 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)) } return n } func (m *NetworkStat) Size() (n int) { 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)) } return n } func sovMetrics(x uint64) (n int) { for { n++ x >>= 7 if x == 0 { break } } return n } 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" } s := strings.Join([]string{`&Metrics{`, `Hugetlb:` + strings.Replace(fmt.Sprintf("%v", this.Hugetlb), "HugetlbStat", "HugetlbStat", 1) + `,`, `Pids:` + strings.Replace(fmt.Sprintf("%v", this.Pids), "PidsStat", "PidsStat", 1) + `,`, `CPU:` + strings.Replace(fmt.Sprintf("%v", this.CPU), "CPUStat", "CPUStat", 1) + `,`, `Memory:` + strings.Replace(fmt.Sprintf("%v", this.Memory), "MemoryStat", "MemoryStat", 1) + `,`, `Blkio:` + strings.Replace(fmt.Sprintf("%v", this.Blkio), "BlkIOStat", "BlkIOStat", 1) + `,`, `Rdma:` + strings.Replace(fmt.Sprintf("%v", this.Rdma), "RdmaStat", "RdmaStat", 1) + `,`, `Network:` + strings.Replace(fmt.Sprintf("%v", this.Network), "NetworkStat", "NetworkStat", 1) + `,`, `}`, }, "") 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) + `,`, `}`, }, "") 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) + `,`, `}`, }, "") return s } func (this *CPUStat) String() string { if this == nil { return "nil" } s := strings.Join([]string{`&CPUStat{`, `Usage:` + strings.Replace(fmt.Sprintf("%v", this.Usage), "CPUUsage", "CPUUsage", 1) + `,`, `Throttling:` + strings.Replace(fmt.Sprintf("%v", this.Throttling), "Throttle", "Throttle", 1) + `,`, `}`, }, "") 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) + `,`, `}`, }, "") 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) + `,`, `}`, }, "") 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(fmt.Sprintf("%v", this.Usage), "MemoryEntry", "MemoryEntry", 1) + `,`, `Swap:` + strings.Replace(fmt.Sprintf("%v", this.Swap), "MemoryEntry", "MemoryEntry", 1) + `,`, `Kernel:` + strings.Replace(fmt.Sprintf("%v", this.Kernel), "MemoryEntry", "MemoryEntry", 1) + `,`, `KernelTCP:` + strings.Replace(fmt.Sprintf("%v", this.KernelTCP), "MemoryEntry", "MemoryEntry", 1) + `,`, `}`, }, "") 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) + `,`, `}`, }, "") return s } func (this *BlkIOStat) String() string { if this == nil { return "nil" } s := strings.Join([]string{`&BlkIOStat{`, `IoServiceBytesRecursive:` + strings.Replace(fmt.Sprintf("%v", this.IoServiceBytesRecursive), "BlkIOEntry", "BlkIOEntry", 1) + `,`, `IoServicedRecursive:` + strings.Replace(fmt.Sprintf("%v", this.IoServicedRecursive), "BlkIOEntry", "BlkIOEntry", 1) + `,`, `IoQueuedRecursive:` + strings.Replace(fmt.Sprintf("%v", this.IoQueuedRecursive), "BlkIOEntry", "BlkIOEntry", 1) + `,`, `IoServiceTimeRecursive:` + strings.Replace(fmt.Sprintf("%v", this.IoServiceTimeRecursive), "BlkIOEntry", "BlkIOEntry", 1) + `,`, `IoWaitTimeRecursive:` + strings.Replace(fmt.Sprintf("%v", this.IoWaitTimeRecursive), "BlkIOEntry", "BlkIOEntry", 1) + `,`, `IoMergedRecursive:` + strings.Replace(fmt.Sprintf("%v", this.IoMergedRecursive), "BlkIOEntry", "BlkIOEntry", 1) + `,`, `IoTimeRecursive:` + strings.Replace(fmt.Sprintf("%v", this.IoTimeRecursive), "BlkIOEntry", "BlkIOEntry", 1) + `,`, `SectorsRecursive:` + strings.Replace(fmt.Sprintf("%v", this.SectorsRecursive), "BlkIOEntry", "BlkIOEntry", 1) + `,`, `}`, }, "") 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) + `,`, `}`, }, "") return s } func (this *RdmaStat) String() string { if this == nil { return "nil" } s := strings.Join([]string{`&RdmaStat{`, `Current:` + strings.Replace(fmt.Sprintf("%v", this.Current), "RdmaEntry", "RdmaEntry", 1) + `,`, `Limit:` + strings.Replace(fmt.Sprintf("%v", this.Limit), "RdmaEntry", "RdmaEntry", 1) + `,`, `}`, }, "") 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) + `,`, `}`, }, "") 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) + `,`, `}`, }, "") 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 > 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 > 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 > 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 > 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 > 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 > 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 > 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 default: iNdEx = preIndex skippy, err := skipMetrics(dAtA[iNdEx:]) if err != nil { return err } if skippy < 0 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } 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 > 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 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } 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 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } 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 > 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 > 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 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } 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 > l { return io.ErrUnexpectedEOF } 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 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } 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 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } 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 > 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 > 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 > 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 > 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 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } 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 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } 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 > 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 > 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 > 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 > 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 > 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 > 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 > 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 > 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 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } 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 > 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 > 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 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } 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 > 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 > 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 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } 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 > 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 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } 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 > 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 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } iNdEx += skippy } } if iNdEx > l { return io.ErrUnexpectedEOF } return nil } func skipMetrics(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 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 } } return iNdEx, nil case 1: iNdEx += 8 return iNdEx, nil 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 } } iNdEx += length if length < 0 { return 0, ErrInvalidLengthMetrics } return iNdEx, nil case 3: for { var innerWire uint64 var start int = iNdEx for shift := uint(0); ; shift += 7 { if shift >= 64 { return 0, ErrIntOverflowMetrics } if iNdEx >= l { return 0, io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ innerWire |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } innerWireType := int(innerWire & 0x7) if innerWireType == 4 { break } next, err := skipMetrics(dAtA[start:]) if err != nil { return 0, err } iNdEx = start + next } return iNdEx, nil case 4: return iNdEx, nil case 5: iNdEx += 4 return iNdEx, nil default: return 0, fmt.Errorf("proto: illegal wireType %d", wireType) } } panic("unreachable") } var ( ErrInvalidLengthMetrics = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowMetrics = fmt.Errorf("proto: integer overflow") ) func init() { proto.RegisterFile("github.com/containerd/cgroups/metrics.proto", fileDescriptorMetrics) } var fileDescriptorMetrics = []byte{ // 1549 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x57, 0x4d, 0x6f, 0x1b, 0xb7, 0x16, 0x8d, 0x2c, 0xd9, 0xd2, 0x5c, 0xd9, 0x8e, 0x4d, 0x27, 0xce, 0xd8, 0x49, 0x2c, 0x47, 0xb6, 0xdf, 0xf3, 0x7b, 0x06, 0x64, 0xbc, 0x3c, 0x20, 0x68, 0xd2, 0x04, 0x45, 0xe4, 0x24, 0x48, 0xd0, 0xba, 0x51, 0x46, 0x36, 0xd2, 0xae, 0x06, 0xd4, 0x88, 0x19, 0xd1, 0x96, 0x86, 0x13, 0x0e, 0xc7, 0x96, 0xbb, 0xea, 0xa2, 0x40, 0x57, 0xfd, 0x33, 0xfd, 0x15, 0x59, 0x76, 0x53, 0xa0, 0xdd, 0x18, 0x8d, 0x7e, 0x49, 0x41, 0x72, 0x3e, 0xa8, 0x24, 0x8e, 0xab, 0xdd, 0x90, 0x3c, 0xe7, 0xdc, 0xcb, 0x3b, 0x87, 0xc3, 0x3b, 0xb0, 0xe3, 0x53, 0xd1, 0x8b, 0x3b, 0x0d, 0x8f, 0x0d, 0x76, 0x3d, 0x16, 0x08, 0x4c, 0x03, 0xc2, 0xbb, 0xbb, 0x9e, 0xcf, 0x59, 0x1c, 0x46, 0xbb, 0x03, 0x22, 0x38, 0xf5, 0xa2, 0x46, 0xc8, 0x99, 0x60, 0xc8, 0xa6, 0xac, 0x91, 0x83, 0x1a, 0x09, 0xa8, 0x71, 0xf2, 0xbf, 0xd5, 0x6b, 0x3e, 0xf3, 0x99, 0x02, 0xed, 0xca, 0x27, 0x8d, 0xaf, 0xff, 0x5a, 0x84, 0xf2, 0xbe, 0x56, 0x40, 0x5f, 0x41, 0xb9, 0x17, 0xfb, 0x44, 0xf4, 0x3b, 0x76, 0x61, 0xbd, 0xb8, 0x5d, 0xbd, 0xbb, 0xd5, 0xb8, 0x48, 0xad, 0xf1, 0x5c, 0x03, 0xdb, 0x02, 0x0b, 0x27, 0x65, 0xa1, 0x7b, 0x50, 0x0a, 0x69, 0x37, 0xb2, 0xa7, 0xd6, 0x0b, 0xdb, 0xd5, 0xbb, 0xf5, 0x8b, 0xd9, 0x2d, 0xda, 0x8d, 0x14, 0x55, 0xe1, 0xd1, 0x43, 0x28, 0x7a, 0x61, 0x6c, 0x17, 0x15, 0xed, 0xce, 0xc5, 0xb4, 0xbd, 0xd6, 0xa1, 0x64, 0x35, 0xcb, 0xa3, 0xf3, 0x5a, 0x71, 0xaf, 0x75, 0xe8, 0x48, 0x1a, 0x7a, 0x08, 0x33, 0x03, 0x32, 0x60, 0xfc, 0xcc, 0x2e, 0x29, 0x81, 0xcd, 0x8b, 0x05, 0xf6, 0x15, 0x4e, 0x45, 0x4e, 0x38, 0xe8, 0x3e, 0x4c, 0x77, 0xfa, 0xc7, 0x94, 0xd9, 0xd3, 0x8a, 0xbc, 0x71, 0x31, 0xb9, 0xd9, 0x3f, 0x7e, 0xf1, 0x52, 0x71, 0x35, 0x43, 0x6e, 0x97, 0x77, 0x07, 0xd8, 0x9e, 0xb9, 0x6c, 0xbb, 0x4e, 0x77, 0x80, 0xf5, 0x76, 0x25, 0x5e, 0xd6, 0x39, 0x20, 0xe2, 0x94, 0xf1, 0x63, 0xbb, 0x7c, 0x59, 0x9d, 0xbf, 0xd5, 0x40, 0x5d, 0xe7, 0x84, 0x55, 0x3f, 0x86, 0xaa, 0x51, 0x7f, 0x74, 0x0d, 0xa6, 0xe3, 0x08, 0xfb, 0xc4, 0x2e, 0xac, 0x17, 0xb6, 0x4b, 0x8e, 0x1e, 0xa0, 0x05, 0x28, 0x0e, 0xf0, 0x50, 0xbd, 0x8b, 0x92, 0x23, 0x1f, 0x91, 0x0d, 0xe5, 0x37, 0x98, 0xf6, 0xbd, 0x40, 0xa8, 0x52, 0x97, 0x9c, 0x74, 0x88, 0x56, 0xa1, 0x12, 0x62, 0x9f, 0x44, 0xf4, 0x07, 0xa2, 0x8a, 0x68, 0x39, 0xd9, 0xb8, 0xfe, 0x00, 0x2a, 0xe9, 0xeb, 0x92, 0x0a, 0x5e, 0xcc, 0x39, 0x09, 0x44, 0x12, 0x2b, 0x1d, 0xca, 0x1c, 0xfa, 0x74, 0x40, 0x45, 0x12, 0x4f, 0x0f, 0xea, 0x3f, 0x17, 0xa0, 0x9c, 0xbc, 0x34, 0xf4, 0x85, 0x99, 0xe5, 0x67, 0xcb, 0xb5, 0xd7, 0x3a, 0x3c, 0x94, 0xc8, 0x74, 0x27, 0x4d, 0x00, 0xd1, 0xe3, 0x4c, 0x88, 0x3e, 0x0d, 0xfc, 0xcb, 0xcd, 0x75, 0xa0, 0xb1, 0xc4, 0x31, 0x58, 0xf5, 0xb7, 0x50, 0x49, 0x65, 0x65, 0xae, 0x82, 0x09, 0xdc, 0x4f, 0xeb, 0xa5, 0x06, 0x68, 0x19, 0x66, 0x8e, 0x09, 0x0f, 0x48, 0x3f, 0xd9, 0x42, 0x32, 0x42, 0x08, 0x4a, 0x71, 0x44, 0x78, 0x52, 0x32, 0xf5, 0x8c, 0x36, 0xa0, 0x1c, 0x12, 0xee, 0x4a, 0xd3, 0x96, 0xd6, 0x8b, 0xdb, 0xa5, 0x26, 0x8c, 0xce, 0x6b, 0x33, 0x2d, 0xc2, 0xa5, 0x29, 0x67, 0x42, 0xc2, 0xf7, 0xc2, 0xb8, 0x3e, 0x84, 0x4a, 0x9a, 0x8a, 0x2c, 0x5c, 0x48, 0x38, 0x65, 0xdd, 0x28, 0x2d, 0x5c, 0x32, 0x44, 0x3b, 0xb0, 0x98, 0xa4, 0x49, 0xba, 0x6e, 0x8a, 0xd1, 0x19, 0x2c, 0x64, 0x0b, 0xad, 0x04, 0xbc, 0x05, 0xf3, 0x39, 0x58, 0xd0, 0x01, 0x49, 0xb2, 0x9a, 0xcb, 0x66, 0x0f, 0xe8, 0x80, 0xd4, 0xff, 0xac, 0x02, 0xe4, 0x56, 0x97, 0xfb, 0xf5, 0xb0, 0xd7, 0xcb, 0xfc, 0xa1, 0x06, 0x68, 0x05, 0x8a, 0x3c, 0x4a, 0x42, 0xe9, 0x13, 0xe5, 0xb4, 0xdb, 0x8e, 0x9c, 0x43, 0xff, 0x82, 0x0a, 0x8f, 0x22, 0x57, 0x1e, 0x6b, 0x1d, 0xa0, 0x59, 0x1d, 0x9d, 0xd7, 0xca, 0x4e, 0xbb, 0x2d, 0x6d, 0xe7, 0x94, 0x79, 0x14, 0xc9, 0x07, 0x54, 0x83, 0xea, 0x00, 0x87, 0x21, 0xe9, 0xba, 0x6f, 0x68, 0x5f, 0x3b, 0xa7, 0xe4, 0x80, 0x9e, 0x7a, 0x46, 0xfb, 0xaa, 0xd2, 0x5d, 0xca, 0xc5, 0x99, 0x3a, 0x5c, 0x25, 0x47, 0x0f, 0xd0, 0x2d, 0xb0, 0x4e, 0x39, 0x15, 0xa4, 0x83, 0xbd, 0x63, 0x75, 0x78, 0x4a, 0x4e, 0x3e, 0x81, 0x6c, 0xa8, 0x84, 0xbe, 0x1b, 0xfa, 0x2e, 0x0d, 0xec, 0xb2, 0x7e, 0x13, 0xa1, 0xdf, 0xf2, 0x5f, 0x04, 0x68, 0x15, 0x2c, 0xbd, 0xc2, 0x62, 0x61, 0x57, 0x92, 0x32, 0xfa, 0x2d, 0xff, 0x65, 0x2c, 0xd0, 0x8a, 0x62, 0xbd, 0xc1, 0x71, 0x5f, 0xd8, 0x56, 0xba, 0xf4, 0x4c, 0x0e, 0xd1, 0x3a, 0xcc, 0x86, 0xbe, 0x3b, 0xc0, 0x47, 0xc9, 0x32, 0xe8, 0x34, 0x43, 0x7f, 0x1f, 0x1f, 0x69, 0xc4, 0x06, 0xcc, 0xd1, 0x00, 0x7b, 0x82, 0x9e, 0x10, 0x17, 0x07, 0x2c, 0xb0, 0xab, 0x0a, 0x32, 0x9b, 0x4e, 0x3e, 0x0e, 0x58, 0x20, 0x37, 0x6b, 0x42, 0x66, 0xb5, 0x8a, 0x01, 0x30, 0x55, 0x54, 0x3d, 0xe6, 0xc6, 0x55, 0x54, 0x45, 0x72, 0x15, 0x05, 0x99, 0x37, 0x55, 0x14, 0x60, 0x1d, 0xaa, 0x71, 0x40, 0x4e, 0xa8, 0x27, 0x70, 0xa7, 0x4f, 0xec, 0xab, 0x0a, 0x60, 0x4e, 0xa1, 0x07, 0xb0, 0xd2, 0xa3, 0x84, 0x63, 0xee, 0xf5, 0xa8, 0x87, 0xfb, 0xae, 0xfe, 0x90, 0xb9, 0xfa, 0xf8, 0x2d, 0x28, 0xfc, 0x0d, 0x13, 0xa0, 0x9d, 0xf0, 0x8d, 0x5c, 0x46, 0xf7, 0x60, 0x6c, 0xc9, 0x8d, 0x4e, 0x71, 0x98, 0x30, 0x17, 0x15, 0xf3, 0xba, 0xb9, 0xdc, 0x3e, 0xc5, 0xa1, 0xe6, 0xd5, 0xa0, 0xaa, 0x4e, 0x89, 0xab, 0x8d, 0x84, 0x74, 0xda, 0x6a, 0x6a, 0x4f, 0xb9, 0xe9, 0x3f, 0x60, 0x69, 0x80, 0xf4, 0xd4, 0x92, 0xf2, 0xcc, 0xec, 0xe8, 0xbc, 0x56, 0x39, 0x90, 0x93, 0xd2, 0x58, 0x15, 0xb5, 0xec, 0x44, 0x11, 0xba, 0x07, 0xf3, 0x19, 0x54, 0x7b, 0xec, 0x9a, 0xc2, 0x2f, 0x8c, 0xce, 0x6b, 0xb3, 0x29, 0x5e, 0x19, 0x6d, 0x36, 0xe5, 0x28, 0xb7, 0xfd, 0x17, 0x16, 0x35, 0xcf, 0xf4, 0xdc, 0x75, 0x95, 0xc9, 0x55, 0xb5, 0xb0, 0x9f, 0x1b, 0x2f, 0xcb, 0x57, 0xdb, 0x6f, 0xd9, 0xc8, 0xf7, 0x89, 0xf2, 0xe0, 0xbf, 0x41, 0x73, 0xdc, 0xdc, 0x89, 0x37, 0x14, 0x48, 0xe7, 0xf6, 0x3a, 0xb3, 0xe3, 0x46, 0x9a, 0x6d, 0x66, 0x4a, 0x5b, 0xbf, 0x12, 0x35, 0xdb, 0xd2, 0xce, 0xdc, 0x4a, 0xd5, 0x72, 0x7f, 0xae, 0xe8, 0x97, 0x9f, 0xa1, 0xa4, 0x49, 0x37, 0x0d, 0x2d, 0xed, 0xc5, 0xd5, 0x31, 0x94, 0x76, 0xe3, 0x0e, 0xa0, 0x0c, 0x95, 0xbb, 0xf6, 0xa6, 0xb1, 0xd1, 0x56, 0x6e, 0xdd, 0x06, 0x2c, 0x69, 0xf0, 0xb8, 0x81, 0x6f, 0x29, 0xb4, 0xae, 0xd7, 0x0b, 0xd3, 0xc5, 0x59, 0x11, 0x4d, 0xf4, 0x6d, 0x43, 0xfb, 0x71, 0x8e, 0xfd, 0x58, 0x5b, 0x95, 0x7c, 0xed, 0x13, 0xda, 0xaa, 0xe8, 0x1f, 0x6a, 0x2b, 0x74, 0xed, 0x23, 0x6d, 0x85, 0xdd, 0x49, 0xb1, 0xa6, 0xd9, 0xd7, 0x93, 0xcf, 0x9e, 0x5c, 0x38, 0x34, 0x1c, 0xff, 0x65, 0x7a, 0x75, 0xdc, 0x51, 0xdf, 0xfe, 0xad, 0xcb, 0x2e, 0xf8, 0xa7, 0x81, 0xe0, 0x67, 0xe9, 0xed, 0x71, 0x1f, 0x4a, 0xd2, 0xe5, 0x76, 0x7d, 0x12, 0xae, 0xa2, 0xa0, 0x47, 0xd9, 0x95, 0xb0, 0x31, 0x09, 0x39, 0xbd, 0x39, 0xda, 0x00, 0xfa, 0xc9, 0x15, 0x5e, 0x68, 0x6f, 0x4e, 0x20, 0xd1, 0x9c, 0x1b, 0x9d, 0xd7, 0xac, 0xaf, 0x15, 0xf9, 0x60, 0xaf, 0xe5, 0x58, 0x5a, 0xe7, 0xc0, 0x0b, 0xeb, 0x04, 0xaa, 0x06, 0x30, 0xbf, 0x77, 0x0b, 0xc6, 0xbd, 0x9b, 0x77, 0x04, 0x53, 0x9f, 0xe8, 0x08, 0x8a, 0x9f, 0xec, 0x08, 0x4a, 0x63, 0x1d, 0x41, 0xfd, 0xf7, 0x69, 0xb0, 0xb2, 0x86, 0x07, 0x61, 0x58, 0xa5, 0xcc, 0x8d, 0x08, 0x3f, 0xa1, 0x1e, 0x71, 0x3b, 0x67, 0x82, 0x44, 0x2e, 0x27, 0x5e, 0xcc, 0x23, 0x7a, 0x42, 0x92, 0x66, 0x71, 0xf3, 0x92, 0xce, 0x49, 0xd7, 0xe6, 0x06, 0x65, 0x6d, 0x2d, 0xd3, 0x94, 0x2a, 0x4e, 0x2a, 0x82, 0xbe, 0x83, 0xeb, 0x79, 0x88, 0xae, 0xa1, 0x3e, 0x35, 0x81, 0xfa, 0x52, 0xa6, 0xde, 0xcd, 0x95, 0x0f, 0x60, 0x89, 0x32, 0xf7, 0x6d, 0x4c, 0xe2, 0x31, 0xdd, 0xe2, 0x04, 0xba, 0x8b, 0x94, 0xbd, 0x52, 0xfc, 0x5c, 0xd5, 0x85, 0x15, 0xa3, 0x24, 0xf2, 0x2e, 0x36, 0xb4, 0x4b, 0x13, 0x68, 0x2f, 0x67, 0x39, 0xcb, 0xbb, 0x3b, 0x0f, 0xf0, 0x3d, 0x2c, 0x53, 0xe6, 0x9e, 0x62, 0x2a, 0x3e, 0x54, 0x9f, 0x9e, 0xac, 0x22, 0xaf, 0x31, 0x15, 0xe3, 0xd2, 0xba, 0x22, 0x03, 0xc2, 0xfd, 0xb1, 0x8a, 0xcc, 0x4c, 0x56, 0x91, 0x7d, 0xc5, 0xcf, 0x55, 0x5b, 0xb0, 0x48, 0xd9, 0x87, 0xb9, 0x96, 0x27, 0xd0, 0xbc, 0x4a, 0xd9, 0x78, 0x9e, 0xaf, 0x60, 0x31, 0x22, 0x9e, 0x60, 0xdc, 0x74, 0x5b, 0x65, 0x02, 0xc5, 0x85, 0x84, 0x9e, 0x49, 0xd6, 0x4f, 0x00, 0xf2, 0x75, 0x34, 0x0f, 0x53, 0x2c, 0x54, 0x47, 0xc7, 0x72, 0xa6, 0x58, 0x28, 0x7b, 0xc0, 0xae, 0xfc, 0xec, 0xe8, 0x83, 0x63, 0x39, 0xc9, 0x48, 0x9e, 0xa7, 0x01, 0x3e, 0x62, 0x69, 0x13, 0xa8, 0x07, 0x6a, 0x96, 0x06, 0x8c, 0x27, 0x67, 0x47, 0x0f, 0xe4, 0xec, 0x09, 0xee, 0xc7, 0x24, 0xed, 0x79, 0xd4, 0xa0, 0xfe, 0x53, 0x01, 0x2a, 0xe9, 0x6f, 0x00, 0x7a, 0x64, 0xb6, 0xd1, 0xc5, 0xcf, 0xff, 0x75, 0x48, 0x92, 0xde, 0x4c, 0xd6, 0x6b, 0xdf, 0xcf, 0x7b, 0xed, 0x7f, 0x4c, 0x4e, 0x1a, 0x72, 0x02, 0x56, 0x36, 0x67, 0xec, 0xb6, 0x30, 0xb6, 0xdb, 0x1a, 0x54, 0x7b, 0x1e, 0x76, 0x7b, 0x38, 0xe8, 0xf6, 0x89, 0xee, 0x10, 0xe7, 0x1c, 0xe8, 0x79, 0xf8, 0xb9, 0x9e, 0x49, 0x01, 0xac, 0x73, 0x44, 0x3c, 0x11, 0xa9, 0xa2, 0x68, 0xc0, 0x4b, 0x3d, 0x53, 0xff, 0x65, 0x0a, 0xaa, 0xc6, 0x9f, 0x8b, 0xec, 0xa1, 0x03, 0x3c, 0x48, 0xe3, 0xa8, 0x67, 0xd9, 0xb1, 0xf1, 0xa1, 0xfe, 0x96, 0x24, 0x9f, 0xa9, 0x32, 0x1f, 0xaa, 0x8f, 0x02, 0xba, 0x0d, 0xc0, 0x87, 0x6e, 0x88, 0xbd, 0x63, 0x92, 0xc8, 0x97, 0x1c, 0x8b, 0x0f, 0x5b, 0x7a, 0x02, 0xdd, 0x04, 0x8b, 0x0f, 0x5d, 0xc2, 0x39, 0xe3, 0x51, 0x52, 0xfb, 0x0a, 0x1f, 0x3e, 0x55, 0xe3, 0x84, 0xdb, 0xe5, 0x4c, 0xf6, 0x02, 0xc9, 0x3b, 0xb0, 0xf8, 0xf0, 0x89, 0x9e, 0x90, 0x51, 0x45, 0x1a, 0x55, 0xb7, 0x9e, 0x65, 0x91, 0x47, 0x15, 0x79, 0x54, 0xdd, 0x7a, 0x5a, 0xc2, 0x8c, 0x2a, 0xb2, 0xa8, 0xba, 0xfb, 0xac, 0x08, 0x23, 0xaa, 0xc8, 0xa3, 0x5a, 0x29, 0x37, 0x89, 0xda, 0xb4, 0xdf, 0xbd, 0x5f, 0xbb, 0xf2, 0xc7, 0xfb, 0xb5, 0x2b, 0x3f, 0x8e, 0xd6, 0x0a, 0xef, 0x46, 0x6b, 0x85, 0xdf, 0x46, 0x6b, 0x85, 0xbf, 0x46, 0x6b, 0x85, 0xce, 0x8c, 0xfa, 0x0d, 0xff, 0xff, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x19, 0x9d, 0xe2, 0xd3, 0xe5, 0x0f, 0x00, 0x00, } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/metrics.pb.txt000077500000000000000000000350641351351003100226750ustar00rootroot00000000000000file { name: "github.com/containerd/cgroups/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" } } 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: "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" } } syntax: "proto3" } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/metrics.proto000066400000000000000000000057601351351003100226160ustar00rootroot00000000000000syntax = "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; } 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 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; } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/mock_test.go000066400000000000000000000032411351351003100223720ustar00rootroot00000000000000/* 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" ) func init() { defaultFilePerm = 0666 } func newMock() (*mockCgroup, error) { root, err := ioutil.TempDir("", "cgroups") if err != nil { return nil, err } subsystems, err := defaults(root) if err != nil { return nil, err } for _, s := range subsystems { if err := os.MkdirAll(filepath.Join(root, string(s.Name())), defaultDirPerm); err != nil { return nil, err } } // make cpuset root files for _, v := range []struct { name string value []byte }{ { name: "cpuset.cpus", value: []byte("0-3"), }, { name: "cpuset.mems", value: []byte("0-3"), }, } { if err := ioutil.WriteFile(filepath.Join(root, "cpuset", v.name), v.value, defaultFilePerm); err != nil { return nil, err } } return &mockCgroup{ root: root, subsystems: subsystems, }, nil } type mockCgroup struct { root string subsystems []Subsystem } func (m *mockCgroup) delete() error { return os.RemoveAll(m.root) } func (m *mockCgroup) hierarchy() ([]Subsystem, error) { return m.subsystems, nil } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/named.go000066400000000000000000000017201351351003100214660ustar00rootroot00000000000000/* 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) } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/named_test.go000066400000000000000000000020331351351003100225230ustar00rootroot00000000000000/* 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 "testing" func TestNamedNameValue(t *testing.T) { n := NewNamed("/sys/fs/cgroup", "systemd") if n.name != "systemd" { t.Fatalf("expected name %q to be systemd", n.name) } } func TestNamedPath(t *testing.T) { n := NewNamed("/sys/fs/cgroup", "systemd") path := n.Path("/test") if expected := "/sys/fs/cgroup/systemd/test"; path != expected { t.Fatalf("expected %q but received %q from named cgroup", expected, path) } } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/net_cls.go000066400000000000000000000027551351351003100220420ustar00rootroot00000000000000/* 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" 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 ioutil.WriteFile( filepath.Join(n.Path(path), "net_cls.classid"), []byte(strconv.FormatUint(uint64(*resources.Network.ClassID), 10)), defaultFilePerm, ) } return nil } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/net_prio.go000066400000000000000000000031341351351003100222220ustar00rootroot00000000000000/* 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" "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 := ioutil.WriteFile( 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)) } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/opts.go000066400000000000000000000035141351351003100213720ustar00rootroot00000000000000/* 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 ( "github.com/pkg/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(s Subsystem, p Path, err error) error { return ErrIgnoreSubsystem } // RequireDevices requires the device subsystem but no others func RequireDevices(s Subsystem, p Path, err error) error { if s.Name() == Devices { return ErrDevicesRequired } return ErrIgnoreSubsystem } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/paths.go000066400000000000000000000053561351351003100215320ustar00rootroot00000000000000/* 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" "path/filepath" "github.com/pkg/errors" ) type Path func(subsystem Name) (string, error) func RootPath(subsysem 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(errors.Wrapf(err, "parse cgroup file %s", p)) } 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(string(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[fmt.Sprintf("name=%s", 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 } } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/paths_test.go000066400000000000000000000066031351351003100225650ustar00rootroot00000000000000/* 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" "strings" "testing" ) func TestStaticPath(t *testing.T) { path := StaticPath("test") p, err := path("") if err != nil { t.Fatal(err) } if p != "test" { t.Fatalf("expected static path of \"test\" but received %q", p) } } func TestSelfPath(t *testing.T) { _, err := v1MountPoint() if err == ErrMountPointNotExist { t.Skip("skipping test that requires cgroup hierarchy") } else if err != nil { t.Fatal(err) } paths, err := parseCgroupFile("/proc/self/cgroup") if err != nil { t.Fatal(err) } dp := strings.TrimPrefix(paths["devices"], "/") path := NestedPath("test") p, err := path("devices") if err != nil { t.Fatal(err) } if p != filepath.Join("/", dp, "test") { t.Fatalf("expected self path of %q but received %q", filepath.Join("/", dp, "test"), p) } } func TestPidPath(t *testing.T) { _, err := v1MountPoint() if err == ErrMountPointNotExist { t.Skip("skipping test that requires cgroup hierarchy") } else if err != nil { t.Fatal(err) } paths, err := parseCgroupFile("/proc/self/cgroup") if err != nil { t.Fatal(err) } dp := strings.TrimPrefix(paths["devices"], "/") path := PidPath(os.Getpid()) p, err := path("devices") if err != nil { t.Fatal(err) } if p != filepath.Join("/", dp) { t.Fatalf("expected self path of %q but received %q", filepath.Join("/", dp), p) } } func TestRootPath(t *testing.T) { p, err := RootPath(Cpu) if err != nil { t.Error(err) return } if p != "/" { t.Errorf("expected / but received %q", p) } } func TestEmptySubsystem(t *testing.T) { const data = `10:devices:/user.slice 9:net_cls,net_prio:/ 8:blkio:/ 7:freezer:/ 6:perf_event:/ 5:cpuset:/ 4:memory:/ 3:pids:/user.slice/user-1000.slice/user@1000.service 2:cpu,cpuacct:/ 1:name=systemd:/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service 0::/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service` r := strings.NewReader(data) paths, err := parseCgroupFromReader(r) if err != nil { t.Fatal(err) } for subsystem, path := range paths { if subsystem == "" { t.Fatalf("empty subsystem for %q", path) } } } func TestSystemd240(t *testing.T) { const data = `8:net_cls:/ 7:memory:/system.slice/docker.service 6:freezer:/ 5:blkio:/system.slice/docker.service 4:devices:/system.slice/docker.service 3:cpuset:/ 2:cpu,cpuacct:/system.slice/docker.service 1:name=systemd:/system.slice/docker.service 0::/system.slice/docker.service` r := strings.NewReader(data) paths, err := parseCgroupFromReader(r) if err != nil { t.Fatal(err) } path := existingPath(paths, "") _, err = path("net_prio") if err == nil { t.Fatal("error for net_prio shoulld not be nil") } if err != ErrControllerNotActive { t.Fatalf("expected error %q but received %q", ErrControllerNotActive, err) } } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/perf_event.go000066400000000000000000000017311351351003100225410ustar00rootroot00000000000000/* 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) } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/pids.go000066400000000000000000000040361351351003100213440ustar00rootroot00000000000000/* 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" 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 ioutil.WriteFile( 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 *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 = &PidsStat{ Current: current, Limit: max, } return nil } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/pids_test.go000066400000000000000000000075211351351003100224050ustar00rootroot00000000000000/* 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 ( "encoding/hex" "io/ioutil" "os" "path/filepath" "strconv" "testing" "github.com/opencontainers/runtime-spec/specs-go" ) func TestPids(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() pids := NewPids(mock.root) if pids == nil { t.Fatal("pids is nil") } resources := specs.LinuxResources{} resources.Pids = &specs.LinuxPids{} resources.Pids.Limit = int64(10) err = pids.Create("test", &resources) if err != nil { t.Fatal(err) } current := filepath.Join(mock.root, "pids", "test", "pids.current") if err = ioutil.WriteFile( current, []byte(strconv.Itoa(5)), defaultFilePerm, ); err != nil { t.Fatal(err) } metrics := Metrics{} err = pids.Stat("test", &metrics) if err != nil { t.Fatal(err) } if metrics.Pids.Limit != uint64(10) { t.Fatalf("expected pids limit %q but received %q", uint64(10), metrics.Pids.Limit) } if metrics.Pids.Current != uint64(5) { t.Fatalf("expected pids limit %q but received %q", uint64(5), metrics.Pids.Current) } resources.Pids.Limit = int64(15) err = pids.Update("test", &resources) if err != nil { t.Fatal(err) } err = pids.Stat("test", &metrics) if err != nil { t.Fatal(err) } if metrics.Pids.Limit != uint64(15) { t.Fatalf("expected pids limit %q but received %q", uint64(15), metrics.Pids.Limit) } if metrics.Pids.Current != uint64(5) { t.Fatalf("expected pids limit %q but received %q", uint64(5), metrics.Pids.Current) } } func TestPidsMissingCurrent(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() pids := NewPids(mock.root) if pids == nil { t.Fatal("pids is nil") } metrics := Metrics{} err = pids.Stat("test", &metrics) if err == nil { t.Fatal("expected not nil err") } } func TestPidsMissingMax(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() pids := NewPids(mock.root) if pids == nil { t.Fatal("pids is nil") } err = os.Mkdir(filepath.Join(mock.root, "pids", "test"), defaultDirPerm) if err != nil { t.Fatal(err) } current := filepath.Join(mock.root, "pids", "test", "pids.current") if err = ioutil.WriteFile( current, []byte(strconv.Itoa(5)), defaultFilePerm, ); err != nil { t.Fatal(err) } metrics := Metrics{} err = pids.Stat("test", &metrics) if err == nil { t.Fatal("expected not nil err") } } func TestPidsOverflowMax(t *testing.T) { mock, err := newMock() if err != nil { t.Fatal(err) } defer mock.delete() pids := NewPids(mock.root) if pids == nil { t.Fatal("pids is nil") } err = os.Mkdir(filepath.Join(mock.root, "pids", "test"), defaultDirPerm) if err != nil { t.Fatal(err) } current := filepath.Join(mock.root, "pids", "test", "pids.current") if err = ioutil.WriteFile( current, []byte(strconv.Itoa(5)), defaultFilePerm, ); err != nil { t.Fatal(err) } max := filepath.Join(mock.root, "pids", "test", "pids.max") bytes, err := hex.DecodeString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") if err != nil { t.Fatal(err) } if err = ioutil.WriteFile( max, bytes, defaultFilePerm, ); err != nil { t.Fatal(err) } metrics := Metrics{} err = pids.Stat("test", &metrics) if err == nil { t.Fatal("expected not nil err") } } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/rdma.go000066400000000000000000000070551351351003100213340ustar00rootroot00000000000000/* 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" 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) { return ioutil.WriteFile( 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 *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) []*RdmaEntry { var rdmaEntries []*RdmaEntry for i := range strEntries { parts := strings.Fields(strEntries[i]) switch len(parts) { case 3: entry := new(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 *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 = &RdmaStat{ Current: currentEntries, Limit: maxEntries, } return nil } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/state.go000066400000000000000000000015111351351003100215200ustar00rootroot00000000000000/* 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" ) cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/subsystem.go000066400000000000000000000044461351351003100224500ustar00rootroot00000000000000/* 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" 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{ Hugetlb, Freezer, Pids, NetCLS, NetPrio, PerfEvent, Cpuset, Cpu, Cpuacct, Memory, Blkio, Rdma, } if !isUserNS { n = append(n, Devices) } 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 *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) } } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/systemd.go000066400000000000000000000076501351351003100221020ustar00rootroot00000000000000/* 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" "path/filepath" "strings" "sync" systemdDbus "github.com/coreos/go-systemd/dbus" "github.com/godbus/dbus" 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, resources *specs.LinuxResources) error { conn, err := systemdDbus.New() 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.StartTransientUnit(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.StopUnit(slice, "testDelegate", nil) } once.Do(checkDelegate) properties := []systemdDbus.Property{ systemdDbus.PropDescription(fmt.Sprintf("cgroup %s", 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.StartTransientUnit(name, "replace", properties, ch) if err != nil { return err } <-ch return nil } func (s *SystemdController) Delete(path string) error { conn, err := systemdDbus.New() if err != nil { return err } defer conn.Close() _, name := splitName(path) ch := make(chan string) _, err = conn.StopUnit(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 unitName(name string) string { return fmt.Sprintf("%s.slice", name) } func splitName(path string) (slice string, unit string) { slice, unit = filepath.Split(path) return strings.TrimSuffix(slice, "/"), unit } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/ticks.go000066400000000000000000000015671351351003100215300ustar00rootroot00000000000000/* 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 } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/utils.go000066400000000000000000000163301351351003100215450ustar00rootroot00000000000000/* 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" "io/ioutil" "os" "path/filepath" "strconv" "strings" "time" units "github.com/docker/go-units" specs "github.com/opencontainers/runtime-spec/specs-go" ) var isUserNS = runningInUserNS() // runningInUserNS detects whether we are currently running in a user namespace. // Copied from github.com/lxc/lxd/shared/util.go func runningInUserNS() bool { file, err := os.Open("/proc/self/uid_map") if err != nil { // This kernel-provided file only exists if user namespaces are supported return false } defer file.Close() buf := bufio.NewReader(file) l, _, err := buf.ReadLine() if err != nil { return false } 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 false } return true } // 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), NewCputset(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 !isUserNS { 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 in a cgroup by the provided path func readPids(path string, subsystem Name) ([]Process, error) { f, err := os.Open(filepath.Join(path, cgroupProcs)) 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, }) } } return out, nil } // readTasksPids will read all the pids of tasks in a cgroup by the provided path func readTasksPids(path string, subsystem Name) ([]Task, error) { f, err := os.Open(filepath.Join(path, cgroupTasks)) if err != nil { return nil, err } defer f.Close() var ( out []Task 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, Task{ Pid: pid, Subsystem: subsystem, Path: path, }) } } 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 } } func parseCgroupFile(path string) (map[string]string, error) { f, err := os.Open(path) if err != nil { return nil, err } defer f.Close() return parseCgroupFromReader(f) } func parseCgroupFromReader(r io.Reader) (map[string]string, error) { var ( cgroups = make(map[string]string) s = bufio.NewScanner(r) ) for s.Scan() { if err := s.Err(); err != nil { return nil, err } var ( text = s.Text() parts = strings.SplitN(text, ":", 3) ) if len(parts) < 3 { return nil, fmt.Errorf("invalid cgroup entry: %q", text) } for _, subs := range strings.Split(parts[1], ",") { if subs != "" { cgroups[subs] = parts[2] } } } return cgroups, 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() { if err := s.Err(); err != nil { return "", err } fields := strings.Fields(s.Text()) for _, opt := range strings.Split(fields[len(fields)-1], ",") { if opt == subsystem { return fields[3], nil } } } 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 filepath.Clean(path) } cgroups-c4b9ac5c7601384c965b9646fc515884e091ebb9/v1.go000066400000000000000000000043451351351003100207360ustar00rootroot00000000000000/* 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() { if err := scanner.Err(); err != nil { return "", err } var ( text = scanner.Text() fields = strings.Split(text, " ") // safe as mountinfo encodes mountpoints with spaces as \040. index = strings.Index(text, " - ") postSeparatorFields = strings.Fields(text[index+3:]) numPostFields = len(postSeparatorFields) ) // this is an error as we can't detect if the mount is for "cgroup" if numPostFields == 0 { return "", fmt.Errorf("Found no fields post '-' in %q", text) } if postSeparatorFields[0] == "cgroup" { // check that the mount is properly formated. if numPostFields < 3 { return "", fmt.Errorf("Error found less than 3 fields post '-' in %q", text) } return filepath.Dir(fields[4]), nil } } return "", ErrMountPointNotExist }