vendor: github.com/containerd/cgroups/v3 v3.1.0

Notable changes:

- support network metrics for cgroupv2
- cgroupv2: simplify parseCgroupFile
- introduce cpu burst stat
- add cgroupV2 CPUQuotaPeriodUSec support
    - addresses: cgroup v2 does not set CPUQuotaPeriodUSec
- read cpu.stat regardless if controller enabled
    - addresses: support cgroup v2 CPU stats when controller not enabled
- add cgroup2 hugetlb failcnt metric
- cgroup2: should add IN_CLOEXEC for inotify fd
- cgroup2: cpu shares: follow the behavior of runc v1.3.2
- cgroup2: fix event loss and resource issues in EventChan

full diff: https://github.com/containerd/cgroups/compare/v3.0.5...v3.1.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-11-11 09:53:02 +01:00
parent d166f42ef2
commit ebcf9bb0c4
11 changed files with 924 additions and 310 deletions

2
go.mod
View File

@@ -20,7 +20,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.58.5
github.com/aws/smithy-go v1.23.1
github.com/cloudflare/cfssl v1.6.4
github.com/containerd/cgroups/v3 v3.0.5
github.com/containerd/cgroups/v3 v3.1.0
github.com/containerd/containerd/api v1.9.0
github.com/containerd/containerd/v2 v2.1.5
github.com/containerd/continuity v0.4.5

4
go.sum
View File

@@ -123,8 +123,8 @@ github.com/container-storage-interface/spec v1.5.0 h1:lvKxe3uLgqQeVQcrnL2CPQKISo
github.com/container-storage-interface/spec v1.5.0/go.mod h1:8K96oQNkJ7pFcC2R9Z1ynGGBB1I93kcS6PGg3SsOk8s=
github.com/containerd/accelerated-container-image v1.3.0 h1:sFbTgSuMboeKHa9f7MY11hWF1XxVWjFoiTsXYtOtvdU=
github.com/containerd/accelerated-container-image v1.3.0/go.mod h1:EvKVWor6ZQNUyYp0MZm5hw4k21ropuz7EegM+m/Jb/Q=
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
github.com/containerd/cgroups/v3 v3.1.0 h1:azxYVj+91ZgSnIBp2eI3k9y2iYQSR/ZQIgh9vKO+HSY=
github.com/containerd/cgroups/v3 v3.1.0/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
github.com/containerd/console v1.0.5 h1:R0ymNeydRqH2DmakFNdmjR2k0t7UPuiOV/N/27/qqsc=
github.com/containerd/console v1.0.5/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/containerd/containerd/api v1.9.0 h1:HZ/licowTRazus+wt9fM6r/9BQO7S0vD5lMcWspGIg0=

143
vendor/github.com/containerd/cgroups/v3/Vagrantfile generated vendored Normal file
View File

@@ -0,0 +1,143 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# 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.
Vagrant.configure("2") do |config|
config.vm.box = ENV["BOX"] ? ENV["BOX"].split("@")[0] : "almalinux/8"
# BOX_VERSION is deprecated. Use "BOX=<BOX>@<BOX_VERSION>".
config.vm.box_version = ENV["BOX_VERSION"] || (ENV["BOX"].split("@")[1] if ENV["BOX"])
memory = 4096
cpus = 2
disk_size = 60
config.vm.provider :virtualbox do |v, o|
v.memory = memory
v.cpus = cpus
# Needs env var VAGRANT_EXPERIMENTAL="disks"
o.vm.disk :disk, size: "#{disk_size}GB", primary: true
v.customize ["modifyvm", :id, "--firmware", "efi"]
end
config.vm.provider :libvirt do |v|
v.memory = memory
v.cpus = cpus
v.machine_virtual_size = disk_size
# https://github.com/vagrant-libvirt/vagrant-libvirt/issues/1725#issuecomment-1454058646
# Needs `sudo cp /usr/share/OVMF/OVMF_VARS_4M.fd /var/lib/libvirt/qemu/nvram/`
v.loader = '/usr/share/OVMF/OVMF_CODE_4M.fd'
v.nvram = '/var/lib/libvirt/qemu/nvram/OVMF_VARS_4M.fd'
end
config.vm.synced_folder ".", "/vagrant", type: "rsync"
config.vm.provision 'shell', path: 'script/resize-vagrant-root.sh'
# To re-run, installing CNI from RPM:
# INSTALL_PACKAGES="containernetworking-plugins" vagrant up --provision-with=install-packages
#
config.vm.provision "install-packages", type: "shell", run: "once" do |sh|
sh.upload_path = "/tmp/vagrant-install-packages"
sh.env = {
'INSTALL_PACKAGES': ENV['INSTALL_PACKAGES'],
}
sh.inline = <<~SHELL
#!/usr/bin/env bash
set -eux -o pipefail
dnf -y install \
curl \
gcc \
git \
make \
${INSTALL_PACKAGES}
SHELL
end
# AlmaLinux does not have /usr/local/{bin,sbin} in the PATH by default
config.vm.provision "setup-etc-environment", type: "shell", run: "once" do |sh|
sh.upload_path = "/tmp/vagrant-setup-etc-environment"
sh.inline = <<~SHELL
#!/usr/bin/env bash
set -eux -o pipefail
cat >> /etc/environment <<EOF
PATH=/usr/local/go/bin:/usr/local/bin:/usr/local/sbin:$PATH
EOF
source /etc/environment
SHELL
end
# To re-run this provisioner, installing a different version of go:
# GO_VERSION="1.14.6" vagrant up --provision-with=install-golang
#
config.vm.provision "install-golang", type: "shell", run: "once" do |sh|
sh.upload_path = "/tmp/vagrant-install-golang"
sh.env = {
'GO_VERSION': ENV['GO_VERSION'] || "1.24.3",
}
sh.inline = <<~SHELL
#!/usr/bin/env bash
set -eux -o pipefail
curl -fsSL "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz" | tar Cxz /usr/local
cat >> /etc/profile.d/sh.local <<EOF
GOPATH=\\$HOME/go
PATH=\\$GOPATH/bin:\\$PATH
export GOPATH PATH
git config --global --add safe.directory /vagrant
EOF
source /etc/profile.d/sh.local
SHELL
end
config.vm.provision "setup-gopath", type: "shell", run: "once" do |sh|
sh.upload_path = "/tmp/vagrant-setup-gopath"
sh.inline = <<~SHELL
#!/usr/bin/env bash
source /etc/environment
source /etc/profile.d/sh.local
set -eux -o pipefail
mkdir -p ${GOPATH}/src/github.com/containerd
ln -fnsv /vagrant ${GOPATH}/src/github.com/containerd/cgroups
SHELL
end
config.vm.provision "test", type: "shell", run: "never" do |sh|
sh.upload_path = "/tmp/test"
sh.env = {
'GOTEST': ENV['GOTEST'] || "go test",
'GOTESTSUM_JUNITFILE': ENV['GOTESTSUM_JUNITFILE'],
'GOTESTSUM_JSONFILE': ENV['GOTESTSUM_JSONFILE'],
}
sh.inline = <<~SHELL
#!/usr/bin/env bash
source /etc/environment
source /etc/profile.d/sh.local
set -eux -o pipefail
cd ${GOPATH}/src/github.com/containerd/cgroups
go env -w CGO_ENABLED=1
go test -exec "sudo" -v -race -coverprofile=coverage.txt -covermode=atomic ./...
SHELL
end
config.vm.provision "build-cgctl", type: "shell", run: "never" do |sh|
sh.upload_path = "/tmp/build-cgctl"
sh.inline = <<~SHELL
#!/usr/bin/env bash
source /etc/environment
source /etc/profile.d/sh.local
set -eux -o pipefail
cd ${GOPATH}/src/github.com/containerd/cgroups
make all
SHELL
end
end

View File

@@ -86,11 +86,13 @@ func (c *cpusetController) Update(path string, resources *specs.LinuxResources)
}
func (c *cpusetController) getValues(path string) (cpus []byte, mems []byte, err error) {
if cpus, err = os.ReadFile(filepath.Join(path, "cpuset.cpus")); err != nil && !os.IsNotExist(err) {
return
cpus, err = os.ReadFile(filepath.Join(path, "cpuset.cpus"))
if err != nil && !os.IsNotExist(err) {
return nil, nil, err
}
if mems, err = os.ReadFile(filepath.Join(path, "cpuset.mems")); err != nil && !os.IsNotExist(err) {
return
mems, err = os.ReadFile(filepath.Join(path, "cpuset.mems"))
if err != nil && !os.IsNotExist(err) {
return nil, nil, err
}
return cpus, mems, nil
}

View File

@@ -24,12 +24,26 @@ import (
type CPUMax string
const (
// Default kernel value for cpu quota period is 100000 us (100 ms), same for v1 and v2.
// v1: https://www.kernel.org/doc/html/latest/scheduler/sched-bwc.html and
// v2: https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html
defaultCPUMax = "max"
defaultCPUMaxPeriod = 100000
defaultCPUMaxPeriodStr = "100000"
)
func NewCPUMax(quota *int64, period *uint64) CPUMax {
max := "max"
max := defaultCPUMax
if quota != nil {
max = strconv.FormatInt(*quota, 10)
}
return CPUMax(strings.Join([]string{max, strconv.FormatUint(*period, 10)}, " "))
duration := defaultCPUMaxPeriodStr
if period != nil {
duration = strconv.FormatUint(*period, 10)
}
return CPUMax(strings.Join([]string{max, duration}, " "))
}
type CPU struct {
@@ -39,19 +53,34 @@ type CPU struct {
Mems string
}
func (c CPUMax) extractQuotaAndPeriod() (int64, uint64) {
func (c CPUMax) extractQuotaAndPeriod() (int64, uint64, error) {
var (
quota int64
period uint64
quota int64 = math.MaxInt64
period uint64 = defaultCPUMaxPeriod
err error
)
// value: quota [period]
values := strings.Split(string(c), " ")
if values[0] == "max" {
quota = math.MaxInt64
} else {
quota, _ = strconv.ParseInt(values[0], 10, 64)
if len(values) < 1 || len(values) > 2 {
return 0, 0, ErrInvalidFormat
}
period, _ = strconv.ParseUint(values[1], 10, 64)
return quota, period
if strings.ToLower(values[0]) != defaultCPUMax {
quota, err = strconv.ParseInt(values[0], 10, 64)
if err != nil {
return 0, 0, err
}
}
if len(values) == 2 {
period, err = strconv.ParseUint(values[1], 10, 64)
if err != nil {
return 0, 0, err
}
}
return quota, period, nil
}
func (r *CPU) Values() (o []Value) {

View File

@@ -27,6 +27,7 @@ import (
"path/filepath"
"strconv"
"strings"
"sync"
"time"
"github.com/containerd/cgroups/v3/cgroup2/stats"
@@ -45,9 +46,17 @@ const (
typeFile = "cgroup.type"
defaultCgroup2Path = "/sys/fs/cgroup"
defaultSlice = "system.slice"
// systemd only supports CPUQuotaPeriodUSec since v2.42.0
cpuQuotaPeriodUSecSupportedVersion = 242
)
var canDelegate bool
var (
canDelegate bool
versionOnce sync.Once
version int
)
type Event struct {
Low uint64
@@ -550,108 +559,134 @@ func (c *Manager) MoveTo(destination *Manager) error {
}
func (c *Manager) Stat() (*stats.Metrics, error) {
controllers, err := c.Controllers()
if err != nil {
return nil, err
}
// Sizing this avoids an allocation to increase the map at runtime;
// currently the default bucket size is 8 and we put 40+ elements
// in it so we'd always end up allocating.
out := make(map[string]uint64, 50)
for _, controller := range controllers {
switch controller {
case "cpu", "memory":
if err := readKVStatsFile(c.path, controller+".stat", out); err != nil {
if os.IsNotExist(err) {
continue
}
return nil, err
}
}
}
memoryEvents := make(map[string]uint64)
if err := readKVStatsFile(c.path, "memory.events", memoryEvents); err != nil {
if !os.IsNotExist(err) {
return nil, err
}
}
var metrics stats.Metrics
var err error
metrics.Pids = &stats.PidsStat{
Current: getStatFileContentUint64(filepath.Join(c.path, "pids.current")),
Limit: getStatFileContentUint64(filepath.Join(c.path, "pids.max")),
}
metrics.CPU = &stats.CPUStat{
UsageUsec: out["usage_usec"],
UserUsec: out["user_usec"],
SystemUsec: out["system_usec"],
NrPeriods: out["nr_periods"],
NrThrottled: out["nr_throttled"],
ThrottledUsec: out["throttled_usec"],
PSI: getStatPSIFromFile(filepath.Join(c.path, "cpu.pressure")),
metrics.CPU, err = readCPUStats(c.path)
if err != nil {
return nil, err
}
metrics.Memory = &stats.MemoryStat{
Anon: out["anon"],
File: out["file"],
KernelStack: out["kernel_stack"],
Slab: out["slab"],
Sock: out["sock"],
Shmem: out["shmem"],
FileMapped: out["file_mapped"],
FileDirty: out["file_dirty"],
FileWriteback: out["file_writeback"],
AnonThp: out["anon_thp"],
InactiveAnon: out["inactive_anon"],
ActiveAnon: out["active_anon"],
InactiveFile: out["inactive_file"],
ActiveFile: out["active_file"],
Unevictable: out["unevictable"],
SlabReclaimable: out["slab_reclaimable"],
SlabUnreclaimable: out["slab_unreclaimable"],
Pgfault: out["pgfault"],
Pgmajfault: out["pgmajfault"],
WorkingsetRefault: out["workingset_refault"],
WorkingsetActivate: out["workingset_activate"],
WorkingsetNodereclaim: out["workingset_nodereclaim"],
Pgrefill: out["pgrefill"],
Pgscan: out["pgscan"],
Pgsteal: out["pgsteal"],
Pgactivate: out["pgactivate"],
Pgdeactivate: out["pgdeactivate"],
Pglazyfree: out["pglazyfree"],
Pglazyfreed: out["pglazyfreed"],
ThpFaultAlloc: out["thp_fault_alloc"],
ThpCollapseAlloc: out["thp_collapse_alloc"],
Usage: getStatFileContentUint64(filepath.Join(c.path, "memory.current")),
UsageLimit: getStatFileContentUint64(filepath.Join(c.path, "memory.max")),
MaxUsage: getStatFileContentUint64(filepath.Join(c.path, "memory.peak")),
SwapUsage: getStatFileContentUint64(filepath.Join(c.path, "memory.swap.current")),
SwapLimit: getStatFileContentUint64(filepath.Join(c.path, "memory.swap.max")),
SwapMaxUsage: getStatFileContentUint64(filepath.Join(c.path, "memory.swap.peak")),
PSI: getStatPSIFromFile(filepath.Join(c.path, "memory.pressure")),
metrics.Memory, err = readMemoryStats(c.path)
if err != nil {
return nil, err
}
if len(memoryEvents) > 0 {
metrics.MemoryEvents = &stats.MemoryEvents{
Low: memoryEvents["low"],
High: memoryEvents["high"],
Max: memoryEvents["max"],
Oom: memoryEvents["oom"],
OomKill: memoryEvents["oom_kill"],
}
metrics.MemoryEvents, err = readMemoryEvents(c.path)
if err != nil {
return nil, err
}
metrics.Io = &stats.IOStat{
Usage: readIoStats(c.path),
PSI: getStatPSIFromFile(filepath.Join(c.path, "io.pressure")),
}
metrics.Rdma = &stats.RdmaStat{
Current: rdmaStats(filepath.Join(c.path, "rdma.current")),
Limit: rdmaStats(filepath.Join(c.path, "rdma.max")),
}
metrics.Hugetlb = readHugeTlbStats(c.path)
return &metrics, nil
}
func readCPUStats(cgroupPath string) (*stats.CPUStat, error) {
cpuStat := make(map[string]uint64)
if err := readKVStatsFile(cgroupPath, "cpu.stat", cpuStat); err != nil {
if os.IsNotExist(err) {
return &stats.CPUStat{}, nil
}
return nil, err
}
return &stats.CPUStat{
UsageUsec: cpuStat["usage_usec"],
UserUsec: cpuStat["user_usec"],
SystemUsec: cpuStat["system_usec"],
NrPeriods: cpuStat["nr_periods"],
NrThrottled: cpuStat["nr_throttled"],
ThrottledUsec: cpuStat["throttled_usec"],
NrBursts: cpuStat["nr_bursts"],
BurstUsec: cpuStat["burst_usec"],
PSI: getStatPSIFromFile(filepath.Join(cgroupPath, "cpu.pressure")),
}, nil
}
func readMemoryStats(cgroupPath string) (*stats.MemoryStat, error) {
memoryStat := make(map[string]uint64, 40)
if err := readKVStatsFile(cgroupPath, "memory.stat", memoryStat); err != nil {
if os.IsNotExist(err) {
return &stats.MemoryStat{}, nil
}
return nil, err
}
return &stats.MemoryStat{
Anon: memoryStat["anon"],
File: memoryStat["file"],
KernelStack: memoryStat["kernel_stack"],
Slab: memoryStat["slab"],
Sock: memoryStat["sock"],
Shmem: memoryStat["shmem"],
FileMapped: memoryStat["file_mapped"],
FileDirty: memoryStat["file_dirty"],
FileWriteback: memoryStat["file_writeback"],
AnonThp: memoryStat["anon_thp"],
InactiveAnon: memoryStat["inactive_anon"],
ActiveAnon: memoryStat["active_anon"],
InactiveFile: memoryStat["inactive_file"],
ActiveFile: memoryStat["active_file"],
Unevictable: memoryStat["unevictable"],
SlabReclaimable: memoryStat["slab_reclaimable"],
SlabUnreclaimable: memoryStat["slab_unreclaimable"],
Pgfault: memoryStat["pgfault"],
Pgmajfault: memoryStat["pgmajfault"],
WorkingsetRefault: memoryStat["workingset_refault"],
WorkingsetActivate: memoryStat["workingset_activate"],
WorkingsetNodereclaim: memoryStat["workingset_nodereclaim"],
Pgrefill: memoryStat["pgrefill"],
Pgscan: memoryStat["pgscan"],
Pgsteal: memoryStat["pgsteal"],
Pgactivate: memoryStat["pgactivate"],
Pgdeactivate: memoryStat["pgdeactivate"],
Pglazyfree: memoryStat["pglazyfree"],
Pglazyfreed: memoryStat["pglazyfreed"],
ThpFaultAlloc: memoryStat["thp_fault_alloc"],
ThpCollapseAlloc: memoryStat["thp_collapse_alloc"],
Usage: getStatFileContentUint64(filepath.Join(cgroupPath, "memory.current")),
UsageLimit: getStatFileContentUint64(filepath.Join(cgroupPath, "memory.max")),
MaxUsage: getStatFileContentUint64(filepath.Join(cgroupPath, "memory.peak")),
SwapUsage: getStatFileContentUint64(filepath.Join(cgroupPath, "memory.swap.current")),
SwapLimit: getStatFileContentUint64(filepath.Join(cgroupPath, "memory.swap.max")),
SwapMaxUsage: getStatFileContentUint64(filepath.Join(cgroupPath, "memory.swap.peak")),
PSI: getStatPSIFromFile(filepath.Join(cgroupPath, "memory.pressure")),
}, nil
}
func readMemoryEvents(cgroupPath string) (*stats.MemoryEvents, error) {
memoryEvents := make(map[string]uint64)
if err := readKVStatsFile(cgroupPath, "memory.events", memoryEvents); err != nil {
if !os.IsNotExist(err) {
return nil, err
}
}
if len(memoryEvents) == 0 {
return nil, nil
}
return &stats.MemoryEvents{
Low: memoryEvents["low"],
High: memoryEvents["high"],
Max: memoryEvents["max"],
Oom: memoryEvents["oom"],
OomKill: memoryEvents["oom_kill"],
}, nil
}
func readKVStatsFile(path string, file string, out map[string]uint64) error {
f, err := os.Open(filepath.Join(path, file))
if err != nil {
@@ -710,7 +745,7 @@ func (c *Manager) isCgroupEmpty() bool {
// MemoryEventFD returns inotify file descriptor and 'memory.events' inotify watch descriptor
func (c *Manager) MemoryEventFD() (int, uint32, error) {
fpath := filepath.Join(c.path, "memory.events")
fd, err := unix.InotifyInit()
fd, err := unix.InotifyInit1(unix.IN_CLOEXEC)
if err != nil {
return 0, 0, fmt.Errorf("failed to create inotify fd: %w", err)
}
@@ -729,32 +764,69 @@ func (c *Manager) MemoryEventFD() (int, uint32, error) {
return fd, uint32(wd), nil
}
func (c *Manager) EventChan() (<-chan Event, <-chan error) {
ec := make(chan Event)
errCh := make(chan error, 1)
go c.waitForEvents(ec, errCh)
// memoryEventNonBlockFD returns a non-blocking inotify file descriptor monitoring memory.events.
//
// NOTE: Block FD is expensive because unix.Read will block that thread once there is
// available data to read. In high scale scenarios, it will create a lot of threads.
func (c *Manager) memoryEventNonBlockFD() (_ *os.File, retErr error) {
return ec, errCh
rawFd, err := unix.InotifyInit1(unix.IN_CLOEXEC | unix.IN_NONBLOCK)
if err != nil {
return nil, fmt.Errorf("failed to create inotify fd: %w", err)
}
fd := os.NewFile(uintptr(rawFd), "inotifyfd")
defer func() {
if retErr != nil {
fd.Close()
}
}()
fpath := filepath.Join(c.path, "memory.events")
if _, err := unix.InotifyAddWatch(rawFd, fpath, unix.IN_MODIFY); err != nil {
return nil, fmt.Errorf("failed to add inotify watch for %q: %w", fpath, err)
}
// monitor to detect process exit/cgroup deletion
evpath := filepath.Join(c.path, "cgroup.events")
if _, err = unix.InotifyAddWatch(rawFd, evpath, unix.IN_MODIFY); err != nil {
return nil, fmt.Errorf("failed to add inotify watch for %q: %w", evpath, err)
}
return fd, nil
}
func (c *Manager) waitForEvents(ec chan<- Event, errCh chan<- error) {
defer close(errCh)
func (c *Manager) EventChan() (<-chan Event, <-chan error) {
ec := make(chan Event, 1)
errCh := make(chan error, 1)
fd, _, err := c.MemoryEventFD()
fd, err := c.memoryEventNonBlockFD()
if err != nil {
errCh <- err
return
return ec, errCh
}
defer unix.Close(fd)
for {
buffer := make([]byte, unix.SizeofInotifyEvent*10)
bytesRead, err := unix.Read(fd, buffer)
if err != nil {
errCh <- err
return
}
if bytesRead >= unix.SizeofInotifyEvent {
go func() {
defer close(errCh)
defer fd.Close()
for {
buffer := make([]byte, unix.SizeofInotifyEvent*10)
bytesRead, err := fd.Read(buffer)
if err != nil {
errCh <- err
return
}
if bytesRead < unix.SizeofInotifyEvent {
continue
}
// Check cgroup.events first
shouldExit := false
if c.isCgroupEmpty() {
shouldExit = true
}
out := make(map[string]uint64)
if err := readKVStatsFile(c.path, "memory.events", out); err != nil {
// When cgroup is deleted read may return -ENODEV instead of -ENOENT from open.
@@ -763,6 +835,7 @@ func (c *Manager) waitForEvents(ec chan<- Event, errCh chan<- error) {
}
return
}
ec <- Event{
Low: out["low"],
High: out["high"],
@@ -770,11 +843,13 @@ func (c *Manager) waitForEvents(ec chan<- Event, errCh chan<- error) {
OOM: out["oom"],
OOMKill: out["oom_kill"],
}
if c.isCgroupEmpty() {
if shouldExit {
return
}
}
}
}()
return ec, errCh
}
func setDevices(path string, devices []specs.LinuxDeviceCgroup) error {
@@ -875,7 +950,19 @@ func NewSystemd(slice, group string, pid int, resources *Resources) (*Manager, e
}
if resources.CPU != nil && resources.CPU.Max != "" {
quota, period := resources.CPU.Max.extractQuotaAndPeriod()
quota, period, err := resources.CPU.Max.extractQuotaAndPeriod()
if err != nil {
return &Manager{}, err
}
if period != 0 {
if sdVer := systemdVersion(conn); sdVer >= cpuQuotaPeriodUSecSupportedVersion {
properties = append(properties, newSystemdProperty("CPUQuotaPeriodUSec", period))
} else {
log.G(context.TODO()).WithField("version", sdVer).Debug("Systemd version is too old to support CPUQuotaPeriodUSec")
}
}
// cpu.cfs_quota_us and cpu.cfs_period_us are controlled by systemd.
// corresponds to USEC_INFINITY in systemd
// if USEC_INFINITY is provided, CPUQuota is left unbound by systemd
@@ -915,6 +1002,41 @@ func NewSystemd(slice, group string, pid int, resources *Resources) (*Manager, e
}, nil
}
// Adapted from https://github.com/opencontainers/cgroups/blob/9657f5a18b8d60a0f39fbb34d0cb7771e28e6278/systemd/common.go#L245-L281
func systemdVersion(conn *systemdDbus.Conn) int {
versionOnce.Do(func() {
version = -1
verStr, err := conn.GetManagerProperty("Version")
if err == nil {
version, err = systemdVersionAtoi(verStr)
}
if err != nil {
log.G(context.TODO()).WithError(err).Error("Unable to get systemd version")
}
})
return version
}
func systemdVersionAtoi(str string) (int, error) {
// Unconditionally remove the leading prefix ("v).
str = strings.TrimLeft(str, `"v`)
// Match on the first integer we can grab.
for i := range len(str) {
if str[i] < '0' || str[i] > '9' {
// First non-digit: cut the tail.
str = str[:i]
break
}
}
ver, err := strconv.Atoi(str)
if err != nil {
return -1, fmt.Errorf("can't parse version: %w", err)
}
return ver, nil
}
func startUnit(conn *systemdDbus.Conn, group string, properties []systemdDbus.Property, ignoreExists bool) error {
ctx := context.TODO()

View File

@@ -32,6 +32,7 @@ type Metrics struct {
Io *IOStat `protobuf:"bytes,6,opt,name=io,proto3" json:"io,omitempty"`
Hugetlb []*HugeTlbStat `protobuf:"bytes,7,rep,name=hugetlb,proto3" json:"hugetlb,omitempty"`
MemoryEvents *MemoryEvents `protobuf:"bytes,8,opt,name=memory_events,json=memoryEvents,proto3" json:"memory_events,omitempty"`
Network []*NetworkStat `protobuf:"bytes,9,rep,name=network,proto3" json:"network,omitempty"`
}
func (x *Metrics) Reset() {
@@ -115,6 +116,13 @@ func (x *Metrics) GetMemoryEvents() *MemoryEvents {
return nil
}
func (x *Metrics) GetNetwork() []*NetworkStat {
if x != nil {
return x.Network
}
return nil
}
type PSIData struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -308,6 +316,8 @@ type CPUStat struct {
NrThrottled uint64 `protobuf:"varint,5,opt,name=nr_throttled,json=nrThrottled,proto3" json:"nr_throttled,omitempty"`
ThrottledUsec uint64 `protobuf:"varint,6,opt,name=throttled_usec,json=throttledUsec,proto3" json:"throttled_usec,omitempty"`
PSI *PSIStats `protobuf:"bytes,7,opt,name=psi,proto3" json:"psi,omitempty"`
NrBursts uint64 `protobuf:"varint,8,opt,name=nr_bursts,json=nrBursts,proto3" json:"nr_bursts,omitempty"`
BurstUsec uint64 `protobuf:"varint,9,opt,name=burst_usec,json=burstUsec,proto3" json:"burst_usec,omitempty"`
}
func (x *CPUStat) Reset() {
@@ -391,6 +401,20 @@ func (x *CPUStat) GetPSI() *PSIStats {
return nil
}
func (x *CPUStat) GetNrBursts() uint64 {
if x != nil {
return x.NrBursts
}
return 0
}
func (x *CPUStat) GetBurstUsec() uint64 {
if x != nil {
return x.BurstUsec
}
return 0
}
type MemoryStat struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1081,6 +1105,7 @@ type HugeTlbStat struct {
Current uint64 `protobuf:"varint,1,opt,name=current,proto3" json:"current,omitempty"`
Max uint64 `protobuf:"varint,2,opt,name=max,proto3" json:"max,omitempty"`
Pagesize string `protobuf:"bytes,3,opt,name=pagesize,proto3" json:"pagesize,omitempty"`
Failcnt uint64 `protobuf:"varint,4,opt,name=failcnt,proto3" json:"failcnt,omitempty"`
}
func (x *HugeTlbStat) Reset() {
@@ -1136,6 +1161,124 @@ func (x *HugeTlbStat) GetPagesize() string {
return ""
}
func (x *HugeTlbStat) GetFailcnt() uint64 {
if x != nil {
return x.Failcnt
}
return 0
}
type NetworkStat struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
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 (x *NetworkStat) Reset() {
*x = NetworkStat{}
if protoimpl.UnsafeEnabled {
mi := &file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *NetworkStat) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NetworkStat) ProtoMessage() {}
func (x *NetworkStat) ProtoReflect() protoreflect.Message {
mi := &file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NetworkStat.ProtoReflect.Descriptor instead.
func (*NetworkStat) Descriptor() ([]byte, []int) {
return file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_rawDescGZIP(), []int{12}
}
func (x *NetworkStat) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *NetworkStat) GetRxBytes() uint64 {
if x != nil {
return x.RxBytes
}
return 0
}
func (x *NetworkStat) GetRxPackets() uint64 {
if x != nil {
return x.RxPackets
}
return 0
}
func (x *NetworkStat) GetRxErrors() uint64 {
if x != nil {
return x.RxErrors
}
return 0
}
func (x *NetworkStat) GetRxDropped() uint64 {
if x != nil {
return x.RxDropped
}
return 0
}
func (x *NetworkStat) GetTxBytes() uint64 {
if x != nil {
return x.TxBytes
}
return 0
}
func (x *NetworkStat) GetTxPackets() uint64 {
if x != nil {
return x.TxPackets
}
return 0
}
func (x *NetworkStat) GetTxErrors() uint64 {
if x != nil {
return x.TxErrors
}
return 0
}
func (x *NetworkStat) GetTxDropped() uint64 {
if x != nil {
return x.TxDropped
}
return 0
}
var File_github_com_containerd_cgroups_cgroup2_stats_metrics_proto protoreflect.FileDescriptor
var file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_rawDesc = []byte{
@@ -1144,7 +1287,7 @@ var file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_rawDesc = []b
0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x32, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2f, 0x6d, 0x65,
0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x69, 0x6f, 0x2e,
0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x63, 0x67, 0x72, 0x6f, 0x75,
0x70, 0x73, 0x2e, 0x76, 0x32, 0x22, 0xac, 0x03, 0x0a, 0x07, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
0x70, 0x73, 0x2e, 0x76, 0x32, 0x22, 0xed, 0x03, 0x0a, 0x07, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
0x73, 0x12, 0x36, 0x0a, 0x04, 0x70, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x22, 0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e,
0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x69, 0x64, 0x73, 0x53,
@@ -1171,169 +1314,196 @@ var file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_rawDesc = []b
0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x63,
0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79,
0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x76,
0x65, 0x6e, 0x74, 0x73, 0x22, 0x63, 0x0a, 0x07, 0x50, 0x53, 0x49, 0x44, 0x61, 0x74, 0x61, 0x12,
0x14, 0x0a, 0x05, 0x61, 0x76, 0x67, 0x31, 0x30, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05,
0x61, 0x76, 0x67, 0x31, 0x30, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x76, 0x67, 0x36, 0x30, 0x18, 0x02,
0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x61, 0x76, 0x67, 0x36, 0x30, 0x12, 0x16, 0x0a, 0x06, 0x61,
0x76, 0x67, 0x33, 0x30, 0x30, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x61, 0x76, 0x67,
0x33, 0x30, 0x30, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01,
0x28, 0x04, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x78, 0x0a, 0x08, 0x50, 0x53, 0x49,
0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x35, 0x0a, 0x04, 0x73, 0x6f, 0x6d, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x64, 0x2e, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50,
0x53, 0x49, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x73, 0x6f, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x04,
0x66, 0x75, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x6f, 0x2e,
0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x63, 0x67, 0x72, 0x6f, 0x75,
0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x53, 0x49, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x66,
0x75, 0x6c, 0x6c, 0x22, 0x3a, 0x0a, 0x08, 0x50, 0x69, 0x64, 0x73, 0x53, 0x74, 0x61, 0x74, 0x12,
0x18, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
0x52, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d,
0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22,
0x85, 0x02, 0x0a, 0x07, 0x43, 0x50, 0x55, 0x53, 0x74, 0x61, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75,
0x73, 0x61, 0x67, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
0x09, 0x75, 0x73, 0x61, 0x67, 0x65, 0x55, 0x73, 0x65, 0x63, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73,
0x65, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x75,
0x73, 0x65, 0x72, 0x55, 0x73, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x79, 0x73, 0x74, 0x65,
0x6d, 0x5f, 0x75, 0x73, 0x65, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x73, 0x79,
0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x72, 0x5f, 0x70,
0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6e, 0x72,
0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x72, 0x5f, 0x74, 0x68,
0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e,
0x72, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x68,
0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x5f, 0x75, 0x73, 0x65, 0x63, 0x18, 0x06, 0x20, 0x01,
0x28, 0x04, 0x52, 0x0d, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x55, 0x73, 0x65,
0x63, 0x12, 0x34, 0x0a, 0x03, 0x70, 0x73, 0x69, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22,
0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x63,
0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x53, 0x49, 0x53, 0x74, 0x61,
0x74, 0x73, 0x52, 0x03, 0x70, 0x73, 0x69, 0x22, 0x88, 0x0a, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x6f,
0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x6e, 0x6f, 0x6e, 0x18, 0x01,
0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x6e, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69,
0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x21,
0x0a, 0x0c, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x03,
0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x63,
0x6b, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6c, 0x61, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52,
0x04, 0x73, 0x6c, 0x61, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6f, 0x63, 0x6b, 0x18, 0x05, 0x20,
0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x6f, 0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x6d,
0x65, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x68, 0x6d, 0x65, 0x6d, 0x12,
0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x18, 0x07,
0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x65, 0x64,
0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x74, 0x79, 0x18, 0x08,
0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x69, 0x72, 0x74, 0x79, 0x12,
0x25, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x62, 0x61, 0x63,
0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x57, 0x72, 0x69,
0x74, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x6e, 0x6f, 0x6e, 0x5f, 0x74,
0x68, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x61, 0x6e, 0x6f, 0x6e, 0x54, 0x68,
0x70, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x6e,
0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69,
0x76, 0x65, 0x41, 0x6e, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65,
0x5f, 0x61, 0x6e, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x61, 0x63, 0x74,
0x69, 0x76, 0x65, 0x41, 0x6e, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x61, 0x63, 0x74,
0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c,
0x69, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x0b,
0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28,
0x04, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x20, 0x0a,
0x0b, 0x75, 0x6e, 0x65, 0x76, 0x69, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0f, 0x20, 0x01,
0x28, 0x04, 0x52, 0x0b, 0x75, 0x6e, 0x65, 0x76, 0x69, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12,
0x29, 0x0a, 0x10, 0x73, 0x6c, 0x61, 0x62, 0x5f, 0x72, 0x65, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x61,
0x62, 0x6c, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x73, 0x6c, 0x61, 0x62, 0x52,
0x65, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x73, 0x6c,
0x61, 0x62, 0x5f, 0x75, 0x6e, 0x72, 0x65, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x61, 0x62, 0x6c, 0x65,
0x18, 0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x73, 0x6c, 0x61, 0x62, 0x55, 0x6e, 0x72, 0x65,
0x63, 0x6c, 0x61, 0x69, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x67, 0x66,
0x61, 0x75, 0x6c, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x70, 0x67, 0x66, 0x61,
0x75, 0x6c, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x67, 0x6d, 0x61, 0x6a, 0x66, 0x61, 0x75, 0x6c,
0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x70, 0x67, 0x6d, 0x61, 0x6a, 0x66, 0x61,
0x75, 0x6c, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x65,
0x74, 0x5f, 0x72, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, 0x52,
0x11, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x74, 0x52, 0x65, 0x66, 0x61, 0x75,
0x6c, 0x74, 0x12, 0x2f, 0x0a, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x74,
0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x04, 0x52,
0x12, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76,
0x61, 0x74, 0x65, 0x12, 0x35, 0x0a, 0x16, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x65,
0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x72, 0x65, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x18, 0x16, 0x20,
0x01, 0x28, 0x04, 0x52, 0x15, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x74, 0x4e,
0x6f, 0x64, 0x65, 0x72, 0x65, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x67,
0x72, 0x65, 0x66, 0x69, 0x6c, 0x6c, 0x18, 0x17, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x70, 0x67,
0x72, 0x65, 0x66, 0x69, 0x6c, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x67, 0x73, 0x63, 0x61, 0x6e,
0x18, 0x18, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x70, 0x67, 0x73, 0x63, 0x61, 0x6e, 0x12, 0x18,
0x0a, 0x07, 0x70, 0x67, 0x73, 0x74, 0x65, 0x61, 0x6c, 0x18, 0x19, 0x20, 0x01, 0x28, 0x04, 0x52,
0x07, 0x70, 0x67, 0x73, 0x74, 0x65, 0x61, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x67, 0x61, 0x63,
0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x70, 0x67,
0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x67, 0x64, 0x65,
0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c,
0x70, 0x67, 0x64, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0a,
0x70, 0x67, 0x6c, 0x61, 0x7a, 0x79, 0x66, 0x72, 0x65, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x04,
0x52, 0x0a, 0x70, 0x67, 0x6c, 0x61, 0x7a, 0x79, 0x66, 0x72, 0x65, 0x65, 0x12, 0x20, 0x0a, 0x0b,
0x70, 0x67, 0x6c, 0x61, 0x7a, 0x79, 0x66, 0x72, 0x65, 0x65, 0x64, 0x18, 0x1d, 0x20, 0x01, 0x28,
0x04, 0x52, 0x0b, 0x70, 0x67, 0x6c, 0x61, 0x7a, 0x79, 0x66, 0x72, 0x65, 0x65, 0x64, 0x12, 0x26,
0x0a, 0x0f, 0x74, 0x68, 0x70, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x61, 0x6c, 0x6c, 0x6f,
0x63, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x68, 0x70, 0x46, 0x61, 0x75, 0x6c,
0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x68, 0x70, 0x5f, 0x63, 0x6f,
0x6c, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x18, 0x1f, 0x20, 0x01,
0x28, 0x04, 0x52, 0x10, 0x74, 0x68, 0x70, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x41,
0x6c, 0x6c, 0x6f, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x20, 0x20,
0x01, 0x28, 0x04, 0x52, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x73,
0x61, 0x67, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x21, 0x20, 0x01, 0x28, 0x04, 0x52,
0x0a, 0x75, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73,
0x77, 0x61, 0x70, 0x5f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x22, 0x20, 0x01, 0x28, 0x04, 0x52,
0x09, 0x73, 0x77, 0x61, 0x70, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x77,
0x61, 0x70, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x23, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09,
0x73, 0x77, 0x61, 0x70, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78,
0x5f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x24, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61,
0x78, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x6d,
0x61, 0x78, 0x5f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c,
0x73, 0x77, 0x61, 0x70, 0x4d, 0x61, 0x78, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x34, 0x0a, 0x03,
0x70, 0x73, 0x69, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x6f, 0x2e, 0x63,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70,
0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x53, 0x49, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x03, 0x70,
0x73, 0x69, 0x22, 0x73, 0x0a, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e,
0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
0x03, 0x6c, 0x6f, 0x77, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x67, 0x68, 0x18, 0x02, 0x20, 0x01,
0x28, 0x04, 0x52, 0x04, 0x68, 0x69, 0x67, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18,
0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x6f,
0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6f, 0x6f, 0x6d, 0x12, 0x19, 0x0a, 0x08,
0x6f, 0x6f, 0x6d, 0x5f, 0x6b, 0x69, 0x6c, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07,
0x6f, 0x6f, 0x6d, 0x4b, 0x69, 0x6c, 0x6c, 0x22, 0x84, 0x01, 0x0a, 0x08, 0x52, 0x64, 0x6d, 0x61,
0x53, 0x74, 0x61, 0x74, 0x12, 0x3d, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18,
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x65, 0x6e, 0x74, 0x73, 0x12, 0x3f, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18,
0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x32,
0x2e, 0x52, 0x64, 0x6d, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72,
0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x03,
0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x52, 0x07, 0x6e, 0x65,
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x22, 0x63, 0x0a, 0x07, 0x50, 0x53, 0x49, 0x44, 0x61, 0x74, 0x61,
0x12, 0x14, 0x0a, 0x05, 0x61, 0x76, 0x67, 0x31, 0x30, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52,
0x05, 0x61, 0x76, 0x67, 0x31, 0x30, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x76, 0x67, 0x36, 0x30, 0x18,
0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x61, 0x76, 0x67, 0x36, 0x30, 0x12, 0x16, 0x0a, 0x06,
0x61, 0x76, 0x67, 0x33, 0x30, 0x30, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x61, 0x76,
0x67, 0x33, 0x30, 0x30, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x04, 0x20,
0x01, 0x28, 0x04, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x78, 0x0a, 0x08, 0x50, 0x53,
0x49, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x35, 0x0a, 0x04, 0x73, 0x6f, 0x6d, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x64, 0x2e, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e,
0x50, 0x53, 0x49, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x73, 0x6f, 0x6d, 0x65, 0x12, 0x35, 0x0a,
0x04, 0x66, 0x75, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x6f,
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x63, 0x67, 0x72, 0x6f,
0x75, 0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x53, 0x49, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04,
0x66, 0x75, 0x6c, 0x6c, 0x22, 0x3a, 0x0a, 0x08, 0x50, 0x69, 0x64, 0x73, 0x53, 0x74, 0x61, 0x74,
0x12, 0x18, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
0x04, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69,
0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74,
0x22, 0xc1, 0x02, 0x0a, 0x07, 0x43, 0x50, 0x55, 0x53, 0x74, 0x61, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
0x52, 0x09, 0x75, 0x73, 0x61, 0x67, 0x65, 0x55, 0x73, 0x65, 0x63, 0x12, 0x1b, 0x0a, 0x09, 0x75,
0x73, 0x65, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08,
0x75, 0x73, 0x65, 0x72, 0x55, 0x73, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x79, 0x73, 0x74,
0x65, 0x6d, 0x5f, 0x75, 0x73, 0x65, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x73,
0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x72, 0x5f,
0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6e,
0x72, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x72, 0x5f, 0x74,
0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b,
0x6e, 0x72, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x74,
0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x5f, 0x75, 0x73, 0x65, 0x63, 0x18, 0x06, 0x20,
0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x55, 0x73,
0x65, 0x63, 0x12, 0x34, 0x0a, 0x03, 0x70, 0x73, 0x69, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x22, 0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e,
0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x53, 0x49, 0x53, 0x74,
0x61, 0x74, 0x73, 0x52, 0x03, 0x70, 0x73, 0x69, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x72, 0x5f, 0x62,
0x75, 0x72, 0x73, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6e, 0x72, 0x42,
0x75, 0x72, 0x73, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x75, 0x72, 0x73, 0x74, 0x5f, 0x75,
0x73, 0x65, 0x63, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x75, 0x72, 0x73, 0x74,
0x55, 0x73, 0x65, 0x63, 0x22, 0x88, 0x0a, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53,
0x74, 0x61, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x6e, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
0x04, 0x52, 0x04, 0x61, 0x6e, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6b,
0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28,
0x04, 0x52, 0x0b, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x12,
0x0a, 0x04, 0x73, 0x6c, 0x61, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x6c,
0x61, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6f, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04,
0x52, 0x04, 0x73, 0x6f, 0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x6d, 0x65, 0x6d, 0x18,
0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x68, 0x6d, 0x65, 0x6d, 0x12, 0x1f, 0x0a, 0x0b,
0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28,
0x04, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x12, 0x1d, 0x0a,
0x0a, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28,
0x04, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x69, 0x72, 0x74, 0x79, 0x12, 0x25, 0x0a, 0x0e,
0x66, 0x69, 0x6c, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x09,
0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x62,
0x61, 0x63, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x6e, 0x6f, 0x6e, 0x5f, 0x74, 0x68, 0x70, 0x18,
0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x61, 0x6e, 0x6f, 0x6e, 0x54, 0x68, 0x70, 0x12, 0x23,
0x0a, 0x0d, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x6e, 0x6f, 0x6e, 0x18,
0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41,
0x6e, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x6e,
0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65,
0x41, 0x6e, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65,
0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x69, 0x6e, 0x61,
0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74,
0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a,
0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x75, 0x6e,
0x65, 0x76, 0x69, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52,
0x0b, 0x75, 0x6e, 0x65, 0x76, 0x69, 0x63, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x29, 0x0a, 0x10,
0x73, 0x6c, 0x61, 0x62, 0x5f, 0x72, 0x65, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x61, 0x62, 0x6c, 0x65,
0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x73, 0x6c, 0x61, 0x62, 0x52, 0x65, 0x63, 0x6c,
0x61, 0x69, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x73, 0x6c, 0x61, 0x62, 0x5f,
0x75, 0x6e, 0x72, 0x65, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x11, 0x20,
0x01, 0x28, 0x04, 0x52, 0x11, 0x73, 0x6c, 0x61, 0x62, 0x55, 0x6e, 0x72, 0x65, 0x63, 0x6c, 0x61,
0x69, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x67, 0x66, 0x61, 0x75, 0x6c,
0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x70, 0x67, 0x66, 0x61, 0x75, 0x6c, 0x74,
0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x67, 0x6d, 0x61, 0x6a, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x13,
0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x70, 0x67, 0x6d, 0x61, 0x6a, 0x66, 0x61, 0x75, 0x6c, 0x74,
0x12, 0x2d, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x74, 0x5f, 0x72,
0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x77, 0x6f,
0x72, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x74, 0x52, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12,
0x2f, 0x0a, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x63,
0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x77, 0x6f,
0x72, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65,
0x12, 0x35, 0x0a, 0x16, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x74, 0x5f, 0x6e,
0x6f, 0x64, 0x65, 0x72, 0x65, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x18, 0x16, 0x20, 0x01, 0x28, 0x04,
0x52, 0x15, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65,
0x72, 0x65, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x67, 0x72, 0x65, 0x66,
0x69, 0x6c, 0x6c, 0x18, 0x17, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x70, 0x67, 0x72, 0x65, 0x66,
0x69, 0x6c, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x67, 0x73, 0x63, 0x61, 0x6e, 0x18, 0x18, 0x20,
0x01, 0x28, 0x04, 0x52, 0x06, 0x70, 0x67, 0x73, 0x63, 0x61, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x70,
0x67, 0x73, 0x74, 0x65, 0x61, 0x6c, 0x18, 0x19, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x70, 0x67,
0x73, 0x74, 0x65, 0x61, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x67, 0x61, 0x63, 0x74, 0x69, 0x76,
0x61, 0x74, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x70, 0x67, 0x61, 0x63, 0x74,
0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x67, 0x64, 0x65, 0x61, 0x63, 0x74,
0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70, 0x67, 0x64,
0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x67, 0x6c,
0x61, 0x7a, 0x79, 0x66, 0x72, 0x65, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x70,
0x67, 0x6c, 0x61, 0x7a, 0x79, 0x66, 0x72, 0x65, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x67, 0x6c,
0x61, 0x7a, 0x79, 0x66, 0x72, 0x65, 0x65, 0x64, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b,
0x70, 0x67, 0x6c, 0x61, 0x7a, 0x79, 0x66, 0x72, 0x65, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x74,
0x68, 0x70, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x18, 0x1e,
0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x68, 0x70, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x6c,
0x6c, 0x6f, 0x63, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x68, 0x70, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x61,
0x70, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x04, 0x52,
0x10, 0x74, 0x68, 0x70, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x41, 0x6c, 0x6c, 0x6f,
0x63, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x20, 0x20, 0x01, 0x28, 0x04,
0x52, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x73, 0x61, 0x67, 0x65,
0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x21, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x75, 0x73,
0x61, 0x67, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x77, 0x61, 0x70,
0x5f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x22, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x77,
0x61, 0x70, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x77, 0x61, 0x70, 0x5f,
0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x23, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x77, 0x61,
0x70, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x73,
0x61, 0x67, 0x65, 0x18, 0x24, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x55, 0x73,
0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x6d, 0x61, 0x78, 0x5f,
0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x73, 0x77, 0x61,
0x70, 0x4d, 0x61, 0x78, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x34, 0x0a, 0x03, 0x70, 0x73, 0x69,
0x18, 0x26, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76,
0x32, 0x2e, 0x50, 0x53, 0x49, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x03, 0x70, 0x73, 0x69, 0x22,
0x73, 0x0a, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12,
0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6c, 0x6f,
0x77, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x67, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
0x04, 0x68, 0x69, 0x67, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x03, 0x20, 0x01,
0x28, 0x04, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x6f, 0x6d, 0x18, 0x04,
0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6f, 0x6f, 0x6d, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x6f, 0x6d,
0x5f, 0x6b, 0x69, 0x6c, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6f, 0x6f, 0x6d,
0x4b, 0x69, 0x6c, 0x6c, 0x22, 0x84, 0x01, 0x0a, 0x08, 0x52, 0x64, 0x6d, 0x61, 0x53, 0x74, 0x61,
0x74, 0x12, 0x3d, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x23, 0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x64, 0x2e, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x64,
0x6d, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x65,
0x0a, 0x09, 0x52, 0x64, 0x6d, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x64,
0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x76,
0x69, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x63, 0x61, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c,
0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x68, 0x63, 0x61, 0x48, 0x61, 0x6e,
0x64, 0x6c, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x63, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x68, 0x63, 0x61, 0x4f, 0x62,
0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x77, 0x0a, 0x06, 0x49, 0x4f, 0x53, 0x74, 0x61, 0x74, 0x12,
0x37, 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21,
0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x63,
0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x4f, 0x45, 0x6e, 0x74, 0x72,
0x79, 0x52, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x12, 0x34, 0x0a, 0x03, 0x70, 0x73, 0x69, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x32,
0x2e, 0x50, 0x53, 0x49, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x03, 0x70, 0x73, 0x69, 0x22, 0x8d,
0x01, 0x0a, 0x07, 0x49, 0x4f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61,
0x6a, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72,
0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x62, 0x79, 0x74, 0x65, 0x73,
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x72, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x16,
0x0a, 0x06, 0x77, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06,
0x77, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x69, 0x6f, 0x73, 0x18, 0x05,
0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x72, 0x69, 0x6f, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x69,
0x6f, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x77, 0x69, 0x6f, 0x73, 0x22, 0x55,
0x0a, 0x0b, 0x48, 0x75, 0x67, 0x65, 0x54, 0x6c, 0x62, 0x53, 0x74, 0x61, 0x74, 0x12, 0x18, 0x0a,
0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07,
0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x02,
0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67,
0x65, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x67,
0x65, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63,
0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x32, 0x2f, 0x73,
0x74, 0x61, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6d, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
0x12, 0x39, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x23, 0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e,
0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x64, 0x6d, 0x61, 0x45,
0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x65, 0x0a, 0x09, 0x52,
0x64, 0x6d, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69,
0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x63, 0x61, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x68, 0x63, 0x61, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65,
0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x63, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x68, 0x63, 0x61, 0x4f, 0x62, 0x6a, 0x65, 0x63,
0x74, 0x73, 0x22, 0x77, 0x0a, 0x06, 0x49, 0x4f, 0x53, 0x74, 0x61, 0x74, 0x12, 0x37, 0x0a, 0x05,
0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x6f,
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x63, 0x67, 0x72, 0x6f,
0x75, 0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x4f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05,
0x75, 0x73, 0x61, 0x67, 0x65, 0x12, 0x34, 0x0a, 0x03, 0x70, 0x73, 0x69, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x64, 0x2e, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x53,
0x49, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x03, 0x70, 0x73, 0x69, 0x22, 0x8d, 0x01, 0x0a, 0x07,
0x49, 0x4f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72,
0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a,
0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6d, 0x69,
0x6e, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20,
0x01, 0x28, 0x04, 0x52, 0x06, 0x72, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x77,
0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x77, 0x62, 0x79,
0x74, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x69, 0x6f, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28,
0x04, 0x52, 0x04, 0x72, 0x69, 0x6f, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x69, 0x6f, 0x73, 0x18,
0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x77, 0x69, 0x6f, 0x73, 0x22, 0x6f, 0x0a, 0x0b, 0x48,
0x75, 0x67, 0x65, 0x54, 0x6c, 0x62, 0x53, 0x74, 0x61, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x75,
0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x63, 0x75, 0x72,
0x72, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28,
0x04, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67, 0x65, 0x73, 0x69,
0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x73, 0x69,
0x7a, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x63, 0x6e, 0x74, 0x18, 0x04, 0x20,
0x01, 0x28, 0x04, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x63, 0x6e, 0x74, 0x22, 0x8d, 0x02, 0x0a,
0x0b, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x12, 0x12, 0x0a, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x12, 0x19, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01,
0x28, 0x04, 0x52, 0x07, 0x72, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72,
0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52,
0x09, 0x72, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x78,
0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x72,
0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x78, 0x5f, 0x64, 0x72,
0x6f, 0x70, 0x70, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x72, 0x78, 0x44,
0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74,
0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65,
0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18,
0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73,
0x12, 0x1b, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x08, 0x20,
0x01, 0x28, 0x04, 0x52, 0x08, 0x74, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x1d, 0x0a,
0x0a, 0x74, 0x78, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28,
0x04, 0x52, 0x09, 0x74, 0x78, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x42, 0x2d, 0x5a, 0x2b,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x63, 0x67,
0x72, 0x6f, 0x75, 0x70, 0x32, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
}
var (
@@ -1348,7 +1518,7 @@ func file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_rawDescGZIP(
return file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_rawDescData
}
var file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
var file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_goTypes = []interface{}{
(*Metrics)(nil), // 0: io.containerd.cgroups.v2.Metrics
(*PSIData)(nil), // 1: io.containerd.cgroups.v2.PSIData
@@ -1362,6 +1532,7 @@ var file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_goTypes = []i
(*IOStat)(nil), // 9: io.containerd.cgroups.v2.IOStat
(*IOEntry)(nil), // 10: io.containerd.cgroups.v2.IOEntry
(*HugeTlbStat)(nil), // 11: io.containerd.cgroups.v2.HugeTlbStat
(*NetworkStat)(nil), // 12: io.containerd.cgroups.v2.NetworkStat
}
var file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_depIdxs = []int32{
3, // 0: io.containerd.cgroups.v2.Metrics.pids:type_name -> io.containerd.cgroups.v2.PidsStat
@@ -1371,19 +1542,20 @@ var file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_depIdxs = []i
9, // 4: io.containerd.cgroups.v2.Metrics.io:type_name -> io.containerd.cgroups.v2.IOStat
11, // 5: io.containerd.cgroups.v2.Metrics.hugetlb:type_name -> io.containerd.cgroups.v2.HugeTlbStat
6, // 6: io.containerd.cgroups.v2.Metrics.memory_events:type_name -> io.containerd.cgroups.v2.MemoryEvents
1, // 7: io.containerd.cgroups.v2.PSIStats.some:type_name -> io.containerd.cgroups.v2.PSIData
1, // 8: io.containerd.cgroups.v2.PSIStats.full:type_name -> io.containerd.cgroups.v2.PSIData
2, // 9: io.containerd.cgroups.v2.CPUStat.psi:type_name -> io.containerd.cgroups.v2.PSIStats
2, // 10: io.containerd.cgroups.v2.MemoryStat.psi:type_name -> io.containerd.cgroups.v2.PSIStats
8, // 11: io.containerd.cgroups.v2.RdmaStat.current:type_name -> io.containerd.cgroups.v2.RdmaEntry
8, // 12: io.containerd.cgroups.v2.RdmaStat.limit:type_name -> io.containerd.cgroups.v2.RdmaEntry
10, // 13: io.containerd.cgroups.v2.IOStat.usage:type_name -> io.containerd.cgroups.v2.IOEntry
2, // 14: io.containerd.cgroups.v2.IOStat.psi:type_name -> io.containerd.cgroups.v2.PSIStats
15, // [15:15] is the sub-list for method output_type
15, // [15:15] is the sub-list for method input_type
15, // [15:15] is the sub-list for extension type_name
15, // [15:15] is the sub-list for extension extendee
0, // [0:15] is the sub-list for field type_name
12, // 7: io.containerd.cgroups.v2.Metrics.network:type_name -> io.containerd.cgroups.v2.NetworkStat
1, // 8: io.containerd.cgroups.v2.PSIStats.some:type_name -> io.containerd.cgroups.v2.PSIData
1, // 9: io.containerd.cgroups.v2.PSIStats.full:type_name -> io.containerd.cgroups.v2.PSIData
2, // 10: io.containerd.cgroups.v2.CPUStat.psi:type_name -> io.containerd.cgroups.v2.PSIStats
2, // 11: io.containerd.cgroups.v2.MemoryStat.psi:type_name -> io.containerd.cgroups.v2.PSIStats
8, // 12: io.containerd.cgroups.v2.RdmaStat.current:type_name -> io.containerd.cgroups.v2.RdmaEntry
8, // 13: io.containerd.cgroups.v2.RdmaStat.limit:type_name -> io.containerd.cgroups.v2.RdmaEntry
10, // 14: io.containerd.cgroups.v2.IOStat.usage:type_name -> io.containerd.cgroups.v2.IOEntry
2, // 15: io.containerd.cgroups.v2.IOStat.psi:type_name -> io.containerd.cgroups.v2.PSIStats
16, // [16:16] is the sub-list for method output_type
16, // [16:16] is the sub-list for method input_type
16, // [16:16] is the sub-list for extension type_name
16, // [16:16] is the sub-list for extension extendee
0, // [0:16] is the sub-list for field type_name
}
func init() { file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_init() }
@@ -1536,6 +1708,18 @@ func file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_init() {
return nil
}
}
file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NetworkStat); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -1543,7 +1727,7 @@ func file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_github_com_containerd_cgroups_cgroup2_stats_metrics_proto_rawDesc,
NumEnums: 0,
NumMessages: 12,
NumMessages: 13,
NumExtensions: 0,
NumServices: 0,
},

View File

@@ -59,6 +59,14 @@ file {
type_name: ".io.containerd.cgroups.v2.MemoryEvents"
json_name: "memoryEvents"
}
field {
name: "network"
number: 9
label: LABEL_REPEATED
type: TYPE_MESSAGE
type_name: ".io.containerd.cgroups.v2.NetworkStat"
json_name: "network"
}
}
message_type {
name: "PSIData"
@@ -179,6 +187,20 @@ file {
type_name: ".io.containerd.cgroups.v2.PSIStats"
json_name: "psi"
}
field {
name: "nr_bursts"
number: 8
label: LABEL_OPTIONAL
type: TYPE_UINT64
json_name: "nrBursts"
}
field {
name: "burst_usec"
number: 9
label: LABEL_OPTIONAL
type: TYPE_UINT64
json_name: "burstUsec"
}
}
message_type {
name: "MemoryStat"
@@ -618,6 +640,79 @@ file {
type: TYPE_STRING
json_name: "pagesize"
}
field {
name: "failcnt"
number: 4
label: LABEL_OPTIONAL
type: TYPE_UINT64
json_name: "failcnt"
}
}
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"
}
}
options {
go_package: "github.com/containerd/cgroups/cgroup2/stats"

View File

@@ -12,6 +12,7 @@ message Metrics {
IOStat io = 6;
repeated HugeTlbStat hugetlb = 7;
MemoryEvents memory_events = 8;
repeated NetworkStat network = 9;
}
message PSIData {
@@ -39,6 +40,8 @@ message CPUStat {
uint64 nr_throttled = 5;
uint64 throttled_usec = 6;
PSIStats psi = 7;
uint64 nr_bursts = 8;
uint64 burst_usec = 9;
}
message MemoryStat {
@@ -119,4 +122,17 @@ message HugeTlbStat {
uint64 current = 1;
uint64 max = 2;
string pagesize = 3;
uint64 failcnt = 4;
}
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;
}

View File

@@ -135,16 +135,9 @@ func parseCgroupFile(path string) (string, error) {
func parseCgroupFromReader(r io.Reader) (string, error) {
s := bufio.NewScanner(r)
for s.Scan() {
var (
text = s.Text()
parts = strings.SplitN(text, ":", 3)
)
if len(parts) < 3 {
return "", fmt.Errorf("invalid cgroup entry: %q", text)
}
// text is like "0::/user.slice/user-1001.slice/session-1.scope"
if parts[0] == "0" && parts[1] == "" {
return parts[2], nil
// "0::/user.slice/user-1001.slice/session-1.scope"
if path, ok := strings.CutPrefix(s.Text(), "0::"); ok {
return path, nil
}
}
if err := s.Err(); err != nil {
@@ -153,6 +146,35 @@ func parseCgroupFromReader(r io.Reader) (string, error) {
return "", fmt.Errorf("cgroup path not found")
}
// ConvertCPUSharesToCgroupV2Value converts CPU shares, used by cgroup v1,
// to CPU weight, used by cgroup v2.
//
// Cgroup v1 CPU shares has a range of [2^1...2^18], i.e. [2...262144],
// and the default value is 1024.
//
// Cgroup v2 CPU weight has a range of [10^0...10^4], i.e. [1...10000],
// and the default value is 100.
//
// Taken from https://github.com/opencontainers/cgroups/blob/v0.0.5/utils.go#L417-L441
// (Apache License 2.0)
func ConvertCPUSharesToCgroupV2Value(cpuShares uint64) uint64 {
// The value of 0 means "unset".
if cpuShares == 0 {
return 0
}
if cpuShares <= 2 {
return 1
}
if cpuShares >= 262144 {
return 10000
}
l := math.Log2(float64(cpuShares))
// Quadratic function which fits min, max, and default.
exponent := (l*l+125*l)/612.0 - 7.0/34.0
return uint64(math.Ceil(math.Pow(10, exponent)))
}
// ToResources converts the oci LinuxResources struct into a
// v2 Resources type for use with this package.
//
@@ -166,7 +188,7 @@ func ToResources(spec *specs.LinuxResources) *Resources {
Mems: cpu.Mems,
}
if shares := cpu.Shares; shares != nil {
convertedWeight := 1 + ((*shares-2)*9999)/262142
convertedWeight := ConvertCPUSharesToCgroupV2Value(*shares)
resources.CPU.Weight = &convertedWeight
}
if period := cpu.Period; period != nil {
@@ -401,6 +423,7 @@ func readHugeTlbStats(path string) []*stats.HugeTlbStat {
Max: getStatFileContentUint64(filepath.Join(path, "hugetlb."+pagesize+".max")),
Current: getStatFileContentUint64(filepath.Join(path, "hugetlb."+pagesize+".current")),
Pagesize: pagesize,
Failcnt: getStatFileContentUint64(filepath.Join(path, "hugetlb."+pagesize+".events")),
}
}
return usage

2
vendor/modules.txt vendored
View File

@@ -314,7 +314,7 @@ github.com/container-storage-interface/spec/lib/go/csi
github.com/containerd/accelerated-container-image/pkg/label
github.com/containerd/accelerated-container-image/pkg/types
github.com/containerd/accelerated-container-image/pkg/utils
# github.com/containerd/cgroups/v3 v3.0.5
# github.com/containerd/cgroups/v3 v3.1.0
## explicit; go 1.22.0
github.com/containerd/cgroups/v3
github.com/containerd/cgroups/v3/cgroup1