mirror of
https://github.com/containers/podman.git
synced 2025-09-26 16:25:00 +08:00
new "image" mount type
Add a new "image" mount type to `--mount`. The source of the mount is the name or ID of an image. The destination is the path inside the container. Image mounts further support an optional `rw,readwrite` parameter which if set to "true" will yield the mount writable inside the container. Note that no changes are propagated to the image mount on the host (which in any case is read only). Mounts are overlay mounts. To support read-only overlay mounts, vendor a non-release version of Buildah. Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
85
vendor/github.com/prometheus/procfs/arp.go
generated
vendored
85
vendor/github.com/prometheus/procfs/arp.go
generated
vendored
@ -1,85 +0,0 @@
|
||||
// Copyright 2019 The Prometheus 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 procfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ARPEntry contains a single row of the columnar data represented in
|
||||
// /proc/net/arp.
|
||||
type ARPEntry struct {
|
||||
// IP address
|
||||
IPAddr net.IP
|
||||
// MAC address
|
||||
HWAddr net.HardwareAddr
|
||||
// Name of the device
|
||||
Device string
|
||||
}
|
||||
|
||||
// GatherARPEntries retrieves all the ARP entries, parse the relevant columns,
|
||||
// and then return a slice of ARPEntry's.
|
||||
func (fs FS) GatherARPEntries() ([]ARPEntry, error) {
|
||||
data, err := ioutil.ReadFile(fs.proc.Path("net/arp"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading arp %s: %s", fs.proc.Path("net/arp"), err)
|
||||
}
|
||||
|
||||
return parseARPEntries(data)
|
||||
}
|
||||
|
||||
func parseARPEntries(data []byte) ([]ARPEntry, error) {
|
||||
lines := strings.Split(string(data), "\n")
|
||||
entries := make([]ARPEntry, 0)
|
||||
var err error
|
||||
const (
|
||||
expectedDataWidth = 6
|
||||
expectedHeaderWidth = 9
|
||||
)
|
||||
for _, line := range lines {
|
||||
columns := strings.Fields(line)
|
||||
width := len(columns)
|
||||
|
||||
if width == expectedHeaderWidth || width == 0 {
|
||||
continue
|
||||
} else if width == expectedDataWidth {
|
||||
entry, err := parseARPEntry(columns)
|
||||
if err != nil {
|
||||
return []ARPEntry{}, fmt.Errorf("failed to parse ARP entry: %s", err)
|
||||
}
|
||||
entries = append(entries, entry)
|
||||
} else {
|
||||
return []ARPEntry{}, fmt.Errorf("%d columns were detected, but %d were expected", width, expectedDataWidth)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return entries, err
|
||||
}
|
||||
|
||||
func parseARPEntry(columns []string) (ARPEntry, error) {
|
||||
ip := net.ParseIP(columns[0])
|
||||
mac := net.HardwareAddr(columns[3])
|
||||
|
||||
entry := ARPEntry{
|
||||
IPAddr: ip,
|
||||
HWAddr: mac,
|
||||
Device: columns[5],
|
||||
}
|
||||
|
||||
return entry, nil
|
||||
}
|
2
vendor/github.com/prometheus/procfs/buddyinfo.go
generated
vendored
2
vendor/github.com/prometheus/procfs/buddyinfo.go
generated
vendored
@ -31,7 +31,7 @@ type BuddyInfo struct {
|
||||
Sizes []float64
|
||||
}
|
||||
|
||||
// BuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem.
|
||||
// NewBuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem.
|
||||
func (fs FS) BuddyInfo() ([]BuddyInfo, error) {
|
||||
file, err := os.Open(fs.proc.Path("buddyinfo"))
|
||||
if err != nil {
|
||||
|
166
vendor/github.com/prometheus/procfs/cpuinfo.go
generated
vendored
166
vendor/github.com/prometheus/procfs/cpuinfo.go
generated
vendored
@ -1,166 +0,0 @@
|
||||
// Copyright 2019 The Prometheus 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 procfs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CPUInfo contains general information about a system CPU found in /proc/cpuinfo
|
||||
type CPUInfo struct {
|
||||
Processor uint
|
||||
VendorID string
|
||||
CPUFamily string
|
||||
Model string
|
||||
ModelName string
|
||||
Stepping string
|
||||
Microcode string
|
||||
CPUMHz float64
|
||||
CacheSize string
|
||||
PhysicalID string
|
||||
Siblings uint
|
||||
CoreID string
|
||||
CPUCores uint
|
||||
APICID string
|
||||
InitialAPICID string
|
||||
FPU string
|
||||
FPUException string
|
||||
CPUIDLevel uint
|
||||
WP string
|
||||
Flags []string
|
||||
Bugs []string
|
||||
BogoMips float64
|
||||
CLFlushSize uint
|
||||
CacheAlignment uint
|
||||
AddressSizes string
|
||||
PowerManagement string
|
||||
}
|
||||
|
||||
// CPUInfo returns information about current system CPUs.
|
||||
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
|
||||
func (fs FS) CPUInfo() ([]CPUInfo, error) {
|
||||
data, err := ioutil.ReadFile(fs.proc.Path("cpuinfo"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseCPUInfo(data)
|
||||
}
|
||||
|
||||
// parseCPUInfo parses data from /proc/cpuinfo
|
||||
func parseCPUInfo(info []byte) ([]CPUInfo, error) {
|
||||
cpuinfo := []CPUInfo{}
|
||||
i := -1
|
||||
scanner := bufio.NewScanner(bytes.NewReader(info))
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if strings.TrimSpace(line) == "" {
|
||||
continue
|
||||
}
|
||||
field := strings.SplitN(line, ": ", 2)
|
||||
switch strings.TrimSpace(field[0]) {
|
||||
case "processor":
|
||||
cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor
|
||||
i++
|
||||
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cpuinfo[i].Processor = uint(v)
|
||||
case "vendor_id":
|
||||
cpuinfo[i].VendorID = field[1]
|
||||
case "cpu family":
|
||||
cpuinfo[i].CPUFamily = field[1]
|
||||
case "model":
|
||||
cpuinfo[i].Model = field[1]
|
||||
case "model name":
|
||||
cpuinfo[i].ModelName = field[1]
|
||||
case "stepping":
|
||||
cpuinfo[i].Stepping = field[1]
|
||||
case "microcode":
|
||||
cpuinfo[i].Microcode = field[1]
|
||||
case "cpu MHz":
|
||||
v, err := strconv.ParseFloat(field[1], 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cpuinfo[i].CPUMHz = v
|
||||
case "cache size":
|
||||
cpuinfo[i].CacheSize = field[1]
|
||||
case "physical id":
|
||||
cpuinfo[i].PhysicalID = field[1]
|
||||
case "siblings":
|
||||
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cpuinfo[i].Siblings = uint(v)
|
||||
case "core id":
|
||||
cpuinfo[i].CoreID = field[1]
|
||||
case "cpu cores":
|
||||
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cpuinfo[i].CPUCores = uint(v)
|
||||
case "apicid":
|
||||
cpuinfo[i].APICID = field[1]
|
||||
case "initial apicid":
|
||||
cpuinfo[i].InitialAPICID = field[1]
|
||||
case "fpu":
|
||||
cpuinfo[i].FPU = field[1]
|
||||
case "fpu_exception":
|
||||
cpuinfo[i].FPUException = field[1]
|
||||
case "cpuid level":
|
||||
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cpuinfo[i].CPUIDLevel = uint(v)
|
||||
case "wp":
|
||||
cpuinfo[i].WP = field[1]
|
||||
case "flags":
|
||||
cpuinfo[i].Flags = strings.Fields(field[1])
|
||||
case "bugs":
|
||||
cpuinfo[i].Bugs = strings.Fields(field[1])
|
||||
case "bogomips":
|
||||
v, err := strconv.ParseFloat(field[1], 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cpuinfo[i].BogoMips = v
|
||||
case "clflush size":
|
||||
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cpuinfo[i].CLFlushSize = uint(v)
|
||||
case "cache_alignment":
|
||||
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cpuinfo[i].CacheAlignment = uint(v)
|
||||
case "address sizes":
|
||||
cpuinfo[i].AddressSizes = field[1]
|
||||
case "power management":
|
||||
cpuinfo[i].PowerManagement = field[1]
|
||||
}
|
||||
}
|
||||
return cpuinfo, nil
|
||||
|
||||
}
|
131
vendor/github.com/prometheus/procfs/crypto.go
generated
vendored
131
vendor/github.com/prometheus/procfs/crypto.go
generated
vendored
@ -1,131 +0,0 @@
|
||||
// Copyright 2019 The Prometheus 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 procfs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
)
|
||||
|
||||
// Crypto holds info parsed from /proc/crypto.
|
||||
type Crypto struct {
|
||||
Alignmask *uint64
|
||||
Async bool
|
||||
Blocksize *uint64
|
||||
Chunksize *uint64
|
||||
Ctxsize *uint64
|
||||
Digestsize *uint64
|
||||
Driver string
|
||||
Geniv string
|
||||
Internal string
|
||||
Ivsize *uint64
|
||||
Maxauthsize *uint64
|
||||
MaxKeysize *uint64
|
||||
MinKeysize *uint64
|
||||
Module string
|
||||
Name string
|
||||
Priority *int64
|
||||
Refcnt *int64
|
||||
Seedsize *uint64
|
||||
Selftest string
|
||||
Type string
|
||||
Walksize *uint64
|
||||
}
|
||||
|
||||
// Crypto parses an crypto-file (/proc/crypto) and returns a slice of
|
||||
// structs containing the relevant info. More information available here:
|
||||
// https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html
|
||||
func (fs FS) Crypto() ([]Crypto, error) {
|
||||
data, err := ioutil.ReadFile(fs.proc.Path("crypto"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing crypto %s: %s", fs.proc.Path("crypto"), err)
|
||||
}
|
||||
crypto, err := parseCrypto(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing crypto %s: %s", fs.proc.Path("crypto"), err)
|
||||
}
|
||||
return crypto, nil
|
||||
}
|
||||
|
||||
func parseCrypto(cryptoData []byte) ([]Crypto, error) {
|
||||
crypto := []Crypto{}
|
||||
|
||||
cryptoBlocks := bytes.Split(cryptoData, []byte("\n\n"))
|
||||
|
||||
for _, block := range cryptoBlocks {
|
||||
var newCryptoElem Crypto
|
||||
|
||||
lines := strings.Split(string(block), "\n")
|
||||
for _, line := range lines {
|
||||
if strings.TrimSpace(line) == "" || line[0] == ' ' {
|
||||
continue
|
||||
}
|
||||
fields := strings.Split(line, ":")
|
||||
key := strings.TrimSpace(fields[0])
|
||||
value := strings.TrimSpace(fields[1])
|
||||
vp := util.NewValueParser(value)
|
||||
|
||||
switch strings.TrimSpace(key) {
|
||||
case "async":
|
||||
b, err := strconv.ParseBool(value)
|
||||
if err == nil {
|
||||
newCryptoElem.Async = b
|
||||
}
|
||||
case "blocksize":
|
||||
newCryptoElem.Blocksize = vp.PUInt64()
|
||||
case "chunksize":
|
||||
newCryptoElem.Chunksize = vp.PUInt64()
|
||||
case "digestsize":
|
||||
newCryptoElem.Digestsize = vp.PUInt64()
|
||||
case "driver":
|
||||
newCryptoElem.Driver = value
|
||||
case "geniv":
|
||||
newCryptoElem.Geniv = value
|
||||
case "internal":
|
||||
newCryptoElem.Internal = value
|
||||
case "ivsize":
|
||||
newCryptoElem.Ivsize = vp.PUInt64()
|
||||
case "maxauthsize":
|
||||
newCryptoElem.Maxauthsize = vp.PUInt64()
|
||||
case "max keysize":
|
||||
newCryptoElem.MaxKeysize = vp.PUInt64()
|
||||
case "min keysize":
|
||||
newCryptoElem.MinKeysize = vp.PUInt64()
|
||||
case "module":
|
||||
newCryptoElem.Module = value
|
||||
case "name":
|
||||
newCryptoElem.Name = value
|
||||
case "priority":
|
||||
newCryptoElem.Priority = vp.PInt64()
|
||||
case "refcnt":
|
||||
newCryptoElem.Refcnt = vp.PInt64()
|
||||
case "seedsize":
|
||||
newCryptoElem.Seedsize = vp.PUInt64()
|
||||
case "selftest":
|
||||
newCryptoElem.Selftest = value
|
||||
case "type":
|
||||
newCryptoElem.Type = value
|
||||
case "walksize":
|
||||
newCryptoElem.Walksize = vp.PUInt64()
|
||||
}
|
||||
}
|
||||
crypto = append(crypto, newCryptoElem)
|
||||
}
|
||||
return crypto, nil
|
||||
}
|
2483
vendor/github.com/prometheus/procfs/fixtures.ttar
generated
vendored
2483
vendor/github.com/prometheus/procfs/fixtures.ttar
generated
vendored
File diff suppressed because it is too large
Load Diff
88
vendor/github.com/prometheus/procfs/internal/util/parse.go
generated
vendored
88
vendor/github.com/prometheus/procfs/internal/util/parse.go
generated
vendored
@ -1,88 +0,0 @@
|
||||
// Copyright 2018 The Prometheus 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 util
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ParseUint32s parses a slice of strings into a slice of uint32s.
|
||||
func ParseUint32s(ss []string) ([]uint32, error) {
|
||||
us := make([]uint32, 0, len(ss))
|
||||
for _, s := range ss {
|
||||
u, err := strconv.ParseUint(s, 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
us = append(us, uint32(u))
|
||||
}
|
||||
|
||||
return us, nil
|
||||
}
|
||||
|
||||
// ParseUint64s parses a slice of strings into a slice of uint64s.
|
||||
func ParseUint64s(ss []string) ([]uint64, error) {
|
||||
us := make([]uint64, 0, len(ss))
|
||||
for _, s := range ss {
|
||||
u, err := strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
us = append(us, u)
|
||||
}
|
||||
|
||||
return us, nil
|
||||
}
|
||||
|
||||
// ParsePInt64s parses a slice of strings into a slice of int64 pointers.
|
||||
func ParsePInt64s(ss []string) ([]*int64, error) {
|
||||
us := make([]*int64, 0, len(ss))
|
||||
for _, s := range ss {
|
||||
u, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
us = append(us, &u)
|
||||
}
|
||||
|
||||
return us, nil
|
||||
}
|
||||
|
||||
// ReadUintFromFile reads a file and attempts to parse a uint64 from it.
|
||||
func ReadUintFromFile(path string) (uint64, error) {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
|
||||
}
|
||||
|
||||
// ParseBool parses a string into a boolean pointer.
|
||||
func ParseBool(b string) *bool {
|
||||
var truth bool
|
||||
switch b {
|
||||
case "enabled":
|
||||
truth = true
|
||||
case "disabled":
|
||||
truth = false
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
return &truth
|
||||
}
|
45
vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go
generated
vendored
45
vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go
generated
vendored
@ -1,45 +0,0 @@
|
||||
// Copyright 2018 The Prometheus 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.
|
||||
|
||||
// +build linux,!appengine
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// SysReadFile is a simplified ioutil.ReadFile that invokes syscall.Read directly.
|
||||
// https://github.com/prometheus/node_exporter/pull/728/files
|
||||
func SysReadFile(file string) (string, error) {
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// On some machines, hwmon drivers are broken and return EAGAIN. This causes
|
||||
// Go's ioutil.ReadFile implementation to poll forever.
|
||||
//
|
||||
// Since we either want to read data or bail immediately, do the simplest
|
||||
// possible read using syscall directly.
|
||||
b := make([]byte, 128)
|
||||
n, err := syscall.Read(int(f.Fd()), b)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(bytes.TrimSpace(b[:n])), nil
|
||||
}
|
26
vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go
generated
vendored
26
vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go
generated
vendored
@ -1,26 +0,0 @@
|
||||
// Copyright 2019 The Prometheus 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.
|
||||
|
||||
// +build linux,appengine !linux
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// SysReadFile is here implemented as a noop for builds that do not support
|
||||
// the read syscall. For example Windows, or Linux on Google App Engine.
|
||||
func SysReadFile(file string) (string, error) {
|
||||
return "", fmt.Errorf("not supported on this platform")
|
||||
}
|
77
vendor/github.com/prometheus/procfs/internal/util/valueparser.go
generated
vendored
77
vendor/github.com/prometheus/procfs/internal/util/valueparser.go
generated
vendored
@ -1,77 +0,0 @@
|
||||
// Copyright 2019 The Prometheus 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 util
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TODO(mdlayher): util packages are an anti-pattern and this should be moved
|
||||
// somewhere else that is more focused in the future.
|
||||
|
||||
// A ValueParser enables parsing a single string into a variety of data types
|
||||
// in a concise and safe way. The Err method must be invoked after invoking
|
||||
// any other methods to ensure a value was successfully parsed.
|
||||
type ValueParser struct {
|
||||
v string
|
||||
err error
|
||||
}
|
||||
|
||||
// NewValueParser creates a ValueParser using the input string.
|
||||
func NewValueParser(v string) *ValueParser {
|
||||
return &ValueParser{v: v}
|
||||
}
|
||||
|
||||
// PInt64 interprets the underlying value as an int64 and returns a pointer to
|
||||
// that value.
|
||||
func (vp *ValueParser) PInt64() *int64 {
|
||||
if vp.err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// A base value of zero makes ParseInt infer the correct base using the
|
||||
// string's prefix, if any.
|
||||
const base = 0
|
||||
v, err := strconv.ParseInt(vp.v, base, 64)
|
||||
if err != nil {
|
||||
vp.err = err
|
||||
return nil
|
||||
}
|
||||
|
||||
return &v
|
||||
}
|
||||
|
||||
// PUInt64 interprets the underlying value as an uint64 and returns a pointer to
|
||||
// that value.
|
||||
func (vp *ValueParser) PUInt64() *uint64 {
|
||||
if vp.err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// A base value of zero makes ParseInt infer the correct base using the
|
||||
// string's prefix, if any.
|
||||
const base = 0
|
||||
v, err := strconv.ParseUint(vp.v, base, 64)
|
||||
if err != nil {
|
||||
vp.err = err
|
||||
return nil
|
||||
}
|
||||
|
||||
return &v
|
||||
}
|
||||
|
||||
// Err returns the last error, if any, encountered by the ValueParser.
|
||||
func (vp *ValueParser) Err() error {
|
||||
return vp.err
|
||||
}
|
91
vendor/github.com/prometheus/procfs/net_softnet.go
generated
vendored
91
vendor/github.com/prometheus/procfs/net_softnet.go
generated
vendored
@ -1,91 +0,0 @@
|
||||
// Copyright 2019 The Prometheus 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 procfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// For the proc file format details,
|
||||
// see https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162
|
||||
// and https://elixir.bootlin.com/linux/v4.17/source/include/linux/netdevice.h#L2810.
|
||||
|
||||
// SoftnetEntry contains a single row of data from /proc/net/softnet_stat
|
||||
type SoftnetEntry struct {
|
||||
// Number of processed packets
|
||||
Processed uint
|
||||
// Number of dropped packets
|
||||
Dropped uint
|
||||
// Number of times processing packets ran out of quota
|
||||
TimeSqueezed uint
|
||||
}
|
||||
|
||||
// GatherSoftnetStats reads /proc/net/softnet_stat, parse the relevant columns,
|
||||
// and then return a slice of SoftnetEntry's.
|
||||
func (fs FS) GatherSoftnetStats() ([]SoftnetEntry, error) {
|
||||
data, err := ioutil.ReadFile(fs.proc.Path("net/softnet_stat"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading softnet %s: %s", fs.proc.Path("net/softnet_stat"), err)
|
||||
}
|
||||
|
||||
return parseSoftnetEntries(data)
|
||||
}
|
||||
|
||||
func parseSoftnetEntries(data []byte) ([]SoftnetEntry, error) {
|
||||
lines := strings.Split(string(data), "\n")
|
||||
entries := make([]SoftnetEntry, 0)
|
||||
var err error
|
||||
const (
|
||||
expectedColumns = 11
|
||||
)
|
||||
for _, line := range lines {
|
||||
columns := strings.Fields(line)
|
||||
width := len(columns)
|
||||
if width == 0 {
|
||||
continue
|
||||
}
|
||||
if width != expectedColumns {
|
||||
return []SoftnetEntry{}, fmt.Errorf("%d columns were detected, but %d were expected", width, expectedColumns)
|
||||
}
|
||||
var entry SoftnetEntry
|
||||
if entry, err = parseSoftnetEntry(columns); err != nil {
|
||||
return []SoftnetEntry{}, err
|
||||
}
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func parseSoftnetEntry(columns []string) (SoftnetEntry, error) {
|
||||
var err error
|
||||
var processed, dropped, timeSqueezed uint64
|
||||
if processed, err = strconv.ParseUint(columns[0], 16, 32); err != nil {
|
||||
return SoftnetEntry{}, fmt.Errorf("Unable to parse column 0: %s", err)
|
||||
}
|
||||
if dropped, err = strconv.ParseUint(columns[1], 16, 32); err != nil {
|
||||
return SoftnetEntry{}, fmt.Errorf("Unable to parse column 1: %s", err)
|
||||
}
|
||||
if timeSqueezed, err = strconv.ParseUint(columns[2], 16, 32); err != nil {
|
||||
return SoftnetEntry{}, fmt.Errorf("Unable to parse column 2: %s", err)
|
||||
}
|
||||
return SoftnetEntry{
|
||||
Processed: uint(processed),
|
||||
Dropped: uint(dropped),
|
||||
TimeSqueezed: uint(timeSqueezed),
|
||||
}, nil
|
||||
}
|
30
vendor/github.com/prometheus/procfs/proc.go
generated
vendored
30
vendor/github.com/prometheus/procfs/proc.go
generated
vendored
@ -279,33 +279,3 @@ func (p Proc) fileDescriptors() ([]string, error) {
|
||||
func (p Proc) path(pa ...string) string {
|
||||
return p.fs.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...)
|
||||
}
|
||||
|
||||
// FileDescriptorsInfo retrieves information about all file descriptors of
|
||||
// the process.
|
||||
func (p Proc) FileDescriptorsInfo() (ProcFDInfos, error) {
|
||||
names, err := p.fileDescriptors()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var fdinfos ProcFDInfos
|
||||
|
||||
for _, n := range names {
|
||||
fdinfo, err := p.FDInfo(n)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
fdinfos = append(fdinfos, *fdinfo)
|
||||
}
|
||||
|
||||
return fdinfos, nil
|
||||
}
|
||||
|
||||
// Schedstat returns task scheduling information for the process.
|
||||
func (p Proc) Schedstat() (ProcSchedstat, error) {
|
||||
contents, err := ioutil.ReadFile(p.path("schedstat"))
|
||||
if err != nil {
|
||||
return ProcSchedstat{}, err
|
||||
}
|
||||
return parseProcSchedstat(string(contents))
|
||||
}
|
||||
|
132
vendor/github.com/prometheus/procfs/proc_fdinfo.go
generated
vendored
132
vendor/github.com/prometheus/procfs/proc_fdinfo.go
generated
vendored
@ -1,132 +0,0 @@
|
||||
// Copyright 2019 The Prometheus 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 procfs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Regexp variables
|
||||
var (
|
||||
rPos = regexp.MustCompile(`^pos:\s+(\d+)$`)
|
||||
rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`)
|
||||
rMntID = regexp.MustCompile(`^mnt_id:\s+(\d+)$`)
|
||||
rInotify = regexp.MustCompile(`^inotify`)
|
||||
)
|
||||
|
||||
// ProcFDInfo contains represents file descriptor information.
|
||||
type ProcFDInfo struct {
|
||||
// File descriptor
|
||||
FD string
|
||||
// File offset
|
||||
Pos string
|
||||
// File access mode and status flags
|
||||
Flags string
|
||||
// Mount point ID
|
||||
MntID string
|
||||
// List of inotify lines (structed) in the fdinfo file (kernel 3.8+ only)
|
||||
InotifyInfos []InotifyInfo
|
||||
}
|
||||
|
||||
// FDInfo constructor. On kernels older than 3.8, InotifyInfos will always be empty.
|
||||
func (p Proc) FDInfo(fd string) (*ProcFDInfo, error) {
|
||||
f, err := os.Open(p.path("fdinfo", fd))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
fdinfo, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not read %s: %s", f.Name(), err)
|
||||
}
|
||||
|
||||
var text, pos, flags, mntid string
|
||||
var inotify []InotifyInfo
|
||||
|
||||
scanner := bufio.NewScanner(strings.NewReader(string(fdinfo)))
|
||||
for scanner.Scan() {
|
||||
text = scanner.Text()
|
||||
if rPos.MatchString(text) {
|
||||
pos = rPos.FindStringSubmatch(text)[1]
|
||||
} else if rFlags.MatchString(text) {
|
||||
flags = rFlags.FindStringSubmatch(text)[1]
|
||||
} else if rMntID.MatchString(text) {
|
||||
mntid = rMntID.FindStringSubmatch(text)[1]
|
||||
} else if rInotify.MatchString(text) {
|
||||
newInotify, err := parseInotifyInfo(text)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inotify = append(inotify, *newInotify)
|
||||
}
|
||||
}
|
||||
|
||||
i := &ProcFDInfo{
|
||||
FD: fd,
|
||||
Pos: pos,
|
||||
Flags: flags,
|
||||
MntID: mntid,
|
||||
InotifyInfos: inotify,
|
||||
}
|
||||
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// InotifyInfo represents a single inotify line in the fdinfo file.
|
||||
type InotifyInfo struct {
|
||||
// Watch descriptor number
|
||||
WD string
|
||||
// Inode number
|
||||
Ino string
|
||||
// Device ID
|
||||
Sdev string
|
||||
// Mask of events being monitored
|
||||
Mask string
|
||||
}
|
||||
|
||||
// InotifyInfo constructor. Only available on kernel 3.8+.
|
||||
func parseInotifyInfo(line string) (*InotifyInfo, error) {
|
||||
r := regexp.MustCompile(`^inotify\s+wd:([0-9a-f]+)\s+ino:([0-9a-f]+)\s+sdev:([0-9a-f]+)\s+mask:([0-9a-f]+)`)
|
||||
m := r.FindStringSubmatch(line)
|
||||
i := &InotifyInfo{
|
||||
WD: m[1],
|
||||
Ino: m[2],
|
||||
Sdev: m[3],
|
||||
Mask: m[4],
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// ProcFDInfos represents a list of ProcFDInfo structs.
|
||||
type ProcFDInfos []ProcFDInfo
|
||||
|
||||
func (p ProcFDInfos) Len() int { return len(p) }
|
||||
func (p ProcFDInfos) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
func (p ProcFDInfos) Less(i, j int) bool { return p[i].FD < p[j].FD }
|
||||
|
||||
// InotifyWatchLen returns the total number of inotify watches
|
||||
func (p ProcFDInfos) InotifyWatchLen() (int, error) {
|
||||
length := 0
|
||||
for _, f := range p {
|
||||
length += len(f.InotifyInfos)
|
||||
}
|
||||
|
||||
return length, nil
|
||||
}
|
7
vendor/github.com/prometheus/procfs/proc_status.go
generated
vendored
7
vendor/github.com/prometheus/procfs/proc_status.go
generated
vendored
@ -21,7 +21,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ProcStatus provides status information about the process,
|
||||
// ProcStat provides status information about the process,
|
||||
// read from /proc/[pid]/stat.
|
||||
type ProcStatus struct {
|
||||
// The process ID.
|
||||
@ -29,9 +29,6 @@ type ProcStatus struct {
|
||||
// The process name.
|
||||
Name string
|
||||
|
||||
// Thread group ID.
|
||||
TGID int
|
||||
|
||||
// Peak virtual memory size.
|
||||
VmPeak uint64
|
||||
// Virtual memory size.
|
||||
@ -116,8 +113,6 @@ func (p Proc) NewStatus() (ProcStatus, error) {
|
||||
|
||||
func (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintBytes uint64) {
|
||||
switch k {
|
||||
case "Tgid":
|
||||
s.TGID = int(vUint)
|
||||
case "Name":
|
||||
s.Name = vString
|
||||
case "VmPeak":
|
||||
|
118
vendor/github.com/prometheus/procfs/schedstat.go
generated
vendored
118
vendor/github.com/prometheus/procfs/schedstat.go
generated
vendored
@ -1,118 +0,0 @@
|
||||
// Copyright 2019 The Prometheus 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 procfs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var (
|
||||
cpuLineRE = regexp.MustCompile(`cpu(\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+)`)
|
||||
procLineRE = regexp.MustCompile(`(\d+) (\d+) (\d+)`)
|
||||
)
|
||||
|
||||
// Schedstat contains scheduler statistics from /proc/schedstat
|
||||
//
|
||||
// See
|
||||
// https://www.kernel.org/doc/Documentation/scheduler/sched-stats.txt
|
||||
// for a detailed description of what these numbers mean.
|
||||
//
|
||||
// Note the current kernel documentation claims some of the time units are in
|
||||
// jiffies when they are actually in nanoseconds since 2.6.23 with the
|
||||
// introduction of CFS. A fix to the documentation is pending. See
|
||||
// https://lore.kernel.org/patchwork/project/lkml/list/?series=403473
|
||||
type Schedstat struct {
|
||||
CPUs []*SchedstatCPU
|
||||
}
|
||||
|
||||
// SchedstatCPU contains the values from one "cpu<N>" line
|
||||
type SchedstatCPU struct {
|
||||
CPUNum string
|
||||
|
||||
RunningNanoseconds uint64
|
||||
WaitingNanoseconds uint64
|
||||
RunTimeslices uint64
|
||||
}
|
||||
|
||||
// ProcSchedstat contains the values from /proc/<pid>/schedstat
|
||||
type ProcSchedstat struct {
|
||||
RunningNanoseconds uint64
|
||||
WaitingNanoseconds uint64
|
||||
RunTimeslices uint64
|
||||
}
|
||||
|
||||
// Schedstat reads data from /proc/schedstat
|
||||
func (fs FS) Schedstat() (*Schedstat, error) {
|
||||
file, err := os.Open(fs.proc.Path("schedstat"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
stats := &Schedstat{}
|
||||
scanner := bufio.NewScanner(file)
|
||||
|
||||
for scanner.Scan() {
|
||||
match := cpuLineRE.FindStringSubmatch(scanner.Text())
|
||||
if match != nil {
|
||||
cpu := &SchedstatCPU{}
|
||||
cpu.CPUNum = match[1]
|
||||
|
||||
cpu.RunningNanoseconds, err = strconv.ParseUint(match[8], 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
cpu.WaitingNanoseconds, err = strconv.ParseUint(match[9], 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
cpu.RunTimeslices, err = strconv.ParseUint(match[10], 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
stats.CPUs = append(stats.CPUs, cpu)
|
||||
}
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
func parseProcSchedstat(contents string) (stats ProcSchedstat, err error) {
|
||||
match := procLineRE.FindStringSubmatch(contents)
|
||||
|
||||
if match != nil {
|
||||
stats.RunningNanoseconds, err = strconv.ParseUint(match[1], 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
stats.WaitingNanoseconds, err = strconv.ParseUint(match[2], 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
stats.RunTimeslices, err = strconv.ParseUint(match[3], 10, 64)
|
||||
return
|
||||
}
|
||||
|
||||
err = errors.New("could not parse schedstat")
|
||||
return
|
||||
}
|
210
vendor/github.com/prometheus/procfs/vm.go
generated
vendored
210
vendor/github.com/prometheus/procfs/vm.go
generated
vendored
@ -1,210 +0,0 @@
|
||||
// Copyright 2019 The Prometheus 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.
|
||||
|
||||
// +build !windows
|
||||
|
||||
package procfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
)
|
||||
|
||||
// The VM interface is described at
|
||||
// https://www.kernel.org/doc/Documentation/sysctl/vm.txt
|
||||
// Each setting is exposed as a single file.
|
||||
// Each file contains one line with a single numerical value, except lowmem_reserve_ratio which holds an array
|
||||
// and numa_zonelist_order (deprecated) which is a string
|
||||
type VM struct {
|
||||
AdminReserveKbytes *int64 // /proc/sys/vm/admin_reserve_kbytes
|
||||
BlockDump *int64 // /proc/sys/vm/block_dump
|
||||
CompactUnevictableAllowed *int64 // /proc/sys/vm/compact_unevictable_allowed
|
||||
DirtyBackgroundBytes *int64 // /proc/sys/vm/dirty_background_bytes
|
||||
DirtyBackgroundRatio *int64 // /proc/sys/vm/dirty_background_ratio
|
||||
DirtyBytes *int64 // /proc/sys/vm/dirty_bytes
|
||||
DirtyExpireCentisecs *int64 // /proc/sys/vm/dirty_expire_centisecs
|
||||
DirtyRatio *int64 // /proc/sys/vm/dirty_ratio
|
||||
DirtytimeExpireSeconds *int64 // /proc/sys/vm/dirtytime_expire_seconds
|
||||
DirtyWritebackCentisecs *int64 // /proc/sys/vm/dirty_writeback_centisecs
|
||||
DropCaches *int64 // /proc/sys/vm/drop_caches
|
||||
ExtfragThreshold *int64 // /proc/sys/vm/extfrag_threshold
|
||||
HugetlbShmGroup *int64 // /proc/sys/vm/hugetlb_shm_group
|
||||
LaptopMode *int64 // /proc/sys/vm/laptop_mode
|
||||
LegacyVaLayout *int64 // /proc/sys/vm/legacy_va_layout
|
||||
LowmemReserveRatio []*int64 // /proc/sys/vm/lowmem_reserve_ratio
|
||||
MaxMapCount *int64 // /proc/sys/vm/max_map_count
|
||||
MemoryFailureEarlyKill *int64 // /proc/sys/vm/memory_failure_early_kill
|
||||
MemoryFailureRecovery *int64 // /proc/sys/vm/memory_failure_recovery
|
||||
MinFreeKbytes *int64 // /proc/sys/vm/min_free_kbytes
|
||||
MinSlabRatio *int64 // /proc/sys/vm/min_slab_ratio
|
||||
MinUnmappedRatio *int64 // /proc/sys/vm/min_unmapped_ratio
|
||||
MmapMinAddr *int64 // /proc/sys/vm/mmap_min_addr
|
||||
NrHugepages *int64 // /proc/sys/vm/nr_hugepages
|
||||
NrHugepagesMempolicy *int64 // /proc/sys/vm/nr_hugepages_mempolicy
|
||||
NrOvercommitHugepages *int64 // /proc/sys/vm/nr_overcommit_hugepages
|
||||
NumaStat *int64 // /proc/sys/vm/numa_stat
|
||||
NumaZonelistOrder string // /proc/sys/vm/numa_zonelist_order
|
||||
OomDumpTasks *int64 // /proc/sys/vm/oom_dump_tasks
|
||||
OomKillAllocatingTask *int64 // /proc/sys/vm/oom_kill_allocating_task
|
||||
OvercommitKbytes *int64 // /proc/sys/vm/overcommit_kbytes
|
||||
OvercommitMemory *int64 // /proc/sys/vm/overcommit_memory
|
||||
OvercommitRatio *int64 // /proc/sys/vm/overcommit_ratio
|
||||
PageCluster *int64 // /proc/sys/vm/page-cluster
|
||||
PanicOnOom *int64 // /proc/sys/vm/panic_on_oom
|
||||
PercpuPagelistFraction *int64 // /proc/sys/vm/percpu_pagelist_fraction
|
||||
StatInterval *int64 // /proc/sys/vm/stat_interval
|
||||
Swappiness *int64 // /proc/sys/vm/swappiness
|
||||
UserReserveKbytes *int64 // /proc/sys/vm/user_reserve_kbytes
|
||||
VfsCachePressure *int64 // /proc/sys/vm/vfs_cache_pressure
|
||||
WatermarkBoostFactor *int64 // /proc/sys/vm/watermark_boost_factor
|
||||
WatermarkScaleFactor *int64 // /proc/sys/vm/watermark_scale_factor
|
||||
ZoneReclaimMode *int64 // /proc/sys/vm/zone_reclaim_mode
|
||||
}
|
||||
|
||||
// VM reads the VM statistics from the specified `proc` filesystem.
|
||||
func (fs FS) VM() (*VM, error) {
|
||||
path := fs.proc.Path("sys/vm")
|
||||
file, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !file.Mode().IsDir() {
|
||||
return nil, fmt.Errorf("%s is not a directory", path)
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var vm VM
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
name := filepath.Join(path, f.Name())
|
||||
// ignore errors on read, as there are some write only
|
||||
// in /proc/sys/vm
|
||||
value, err := util.SysReadFile(name)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
vp := util.NewValueParser(value)
|
||||
|
||||
switch f.Name() {
|
||||
case "admin_reserve_kbytes":
|
||||
vm.AdminReserveKbytes = vp.PInt64()
|
||||
case "block_dump":
|
||||
vm.BlockDump = vp.PInt64()
|
||||
case "compact_unevictable_allowed":
|
||||
vm.CompactUnevictableAllowed = vp.PInt64()
|
||||
case "dirty_background_bytes":
|
||||
vm.DirtyBackgroundBytes = vp.PInt64()
|
||||
case "dirty_background_ratio":
|
||||
vm.DirtyBackgroundRatio = vp.PInt64()
|
||||
case "dirty_bytes":
|
||||
vm.DirtyBytes = vp.PInt64()
|
||||
case "dirty_expire_centisecs":
|
||||
vm.DirtyExpireCentisecs = vp.PInt64()
|
||||
case "dirty_ratio":
|
||||
vm.DirtyRatio = vp.PInt64()
|
||||
case "dirtytime_expire_seconds":
|
||||
vm.DirtytimeExpireSeconds = vp.PInt64()
|
||||
case "dirty_writeback_centisecs":
|
||||
vm.DirtyWritebackCentisecs = vp.PInt64()
|
||||
case "drop_caches":
|
||||
vm.DropCaches = vp.PInt64()
|
||||
case "extfrag_threshold":
|
||||
vm.ExtfragThreshold = vp.PInt64()
|
||||
case "hugetlb_shm_group":
|
||||
vm.HugetlbShmGroup = vp.PInt64()
|
||||
case "laptop_mode":
|
||||
vm.LaptopMode = vp.PInt64()
|
||||
case "legacy_va_layout":
|
||||
vm.LegacyVaLayout = vp.PInt64()
|
||||
case "lowmem_reserve_ratio":
|
||||
stringSlice := strings.Fields(value)
|
||||
pint64Slice := make([]*int64, 0, len(stringSlice))
|
||||
for _, value := range stringSlice {
|
||||
vp := util.NewValueParser(value)
|
||||
pint64Slice = append(pint64Slice, vp.PInt64())
|
||||
}
|
||||
vm.LowmemReserveRatio = pint64Slice
|
||||
case "max_map_count":
|
||||
vm.MaxMapCount = vp.PInt64()
|
||||
case "memory_failure_early_kill":
|
||||
vm.MemoryFailureEarlyKill = vp.PInt64()
|
||||
case "memory_failure_recovery":
|
||||
vm.MemoryFailureRecovery = vp.PInt64()
|
||||
case "min_free_kbytes":
|
||||
vm.MinFreeKbytes = vp.PInt64()
|
||||
case "min_slab_ratio":
|
||||
vm.MinSlabRatio = vp.PInt64()
|
||||
case "min_unmapped_ratio":
|
||||
vm.MinUnmappedRatio = vp.PInt64()
|
||||
case "mmap_min_addr":
|
||||
vm.MmapMinAddr = vp.PInt64()
|
||||
case "nr_hugepages":
|
||||
vm.NrHugepages = vp.PInt64()
|
||||
case "nr_hugepages_mempolicy":
|
||||
vm.NrHugepagesMempolicy = vp.PInt64()
|
||||
case "nr_overcommit_hugepages":
|
||||
vm.NrOvercommitHugepages = vp.PInt64()
|
||||
case "numa_stat":
|
||||
vm.NumaStat = vp.PInt64()
|
||||
case "numa_zonelist_order":
|
||||
vm.NumaZonelistOrder = value
|
||||
case "oom_dump_tasks":
|
||||
vm.OomDumpTasks = vp.PInt64()
|
||||
case "oom_kill_allocating_task":
|
||||
vm.OomKillAllocatingTask = vp.PInt64()
|
||||
case "overcommit_kbytes":
|
||||
vm.OvercommitKbytes = vp.PInt64()
|
||||
case "overcommit_memory":
|
||||
vm.OvercommitMemory = vp.PInt64()
|
||||
case "overcommit_ratio":
|
||||
vm.OvercommitRatio = vp.PInt64()
|
||||
case "page-cluster":
|
||||
vm.PageCluster = vp.PInt64()
|
||||
case "panic_on_oom":
|
||||
vm.PanicOnOom = vp.PInt64()
|
||||
case "percpu_pagelist_fraction":
|
||||
vm.PercpuPagelistFraction = vp.PInt64()
|
||||
case "stat_interval":
|
||||
vm.StatInterval = vp.PInt64()
|
||||
case "swappiness":
|
||||
vm.Swappiness = vp.PInt64()
|
||||
case "user_reserve_kbytes":
|
||||
vm.UserReserveKbytes = vp.PInt64()
|
||||
case "vfs_cache_pressure":
|
||||
vm.VfsCachePressure = vp.PInt64()
|
||||
case "watermark_boost_factor":
|
||||
vm.WatermarkBoostFactor = vp.PInt64()
|
||||
case "watermark_scale_factor":
|
||||
vm.WatermarkScaleFactor = vp.PInt64()
|
||||
case "zone_reclaim_mode":
|
||||
vm.ZoneReclaimMode = vp.PInt64()
|
||||
}
|
||||
if err := vp.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &vm, nil
|
||||
}
|
196
vendor/github.com/prometheus/procfs/zoneinfo.go
generated
vendored
196
vendor/github.com/prometheus/procfs/zoneinfo.go
generated
vendored
@ -1,196 +0,0 @@
|
||||
// Copyright 2019 The Prometheus 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.
|
||||
|
||||
// +build !windows
|
||||
|
||||
package procfs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
)
|
||||
|
||||
// Zoneinfo holds info parsed from /proc/zoneinfo.
|
||||
type Zoneinfo struct {
|
||||
Node string
|
||||
Zone string
|
||||
NrFreePages *int64
|
||||
Min *int64
|
||||
Low *int64
|
||||
High *int64
|
||||
Scanned *int64
|
||||
Spanned *int64
|
||||
Present *int64
|
||||
Managed *int64
|
||||
NrActiveAnon *int64
|
||||
NrInactiveAnon *int64
|
||||
NrIsolatedAnon *int64
|
||||
NrAnonPages *int64
|
||||
NrAnonTransparentHugepages *int64
|
||||
NrActiveFile *int64
|
||||
NrInactiveFile *int64
|
||||
NrIsolatedFile *int64
|
||||
NrFilePages *int64
|
||||
NrSlabReclaimable *int64
|
||||
NrSlabUnreclaimable *int64
|
||||
NrMlockStack *int64
|
||||
NrKernelStack *int64
|
||||
NrMapped *int64
|
||||
NrDirty *int64
|
||||
NrWriteback *int64
|
||||
NrUnevictable *int64
|
||||
NrShmem *int64
|
||||
NrDirtied *int64
|
||||
NrWritten *int64
|
||||
NumaHit *int64
|
||||
NumaMiss *int64
|
||||
NumaForeign *int64
|
||||
NumaInterleave *int64
|
||||
NumaLocal *int64
|
||||
NumaOther *int64
|
||||
Protection []*int64
|
||||
}
|
||||
|
||||
var nodeZoneRE = regexp.MustCompile(`(\d+), zone\s+(\w+)`)
|
||||
|
||||
// Zoneinfo parses an zoneinfo-file (/proc/zoneinfo) and returns a slice of
|
||||
// structs containing the relevant info. More information available here:
|
||||
// https://www.kernel.org/doc/Documentation/sysctl/vm.txt
|
||||
func (fs FS) Zoneinfo() ([]Zoneinfo, error) {
|
||||
data, err := ioutil.ReadFile(fs.proc.Path("zoneinfo"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading zoneinfo %s: %s", fs.proc.Path("zoneinfo"), err)
|
||||
}
|
||||
zoneinfo, err := parseZoneinfo(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing zoneinfo %s: %s", fs.proc.Path("zoneinfo"), err)
|
||||
}
|
||||
return zoneinfo, nil
|
||||
}
|
||||
|
||||
func parseZoneinfo(zoneinfoData []byte) ([]Zoneinfo, error) {
|
||||
|
||||
zoneinfo := []Zoneinfo{}
|
||||
|
||||
zoneinfoBlocks := bytes.Split(zoneinfoData, []byte("\nNode"))
|
||||
for _, block := range zoneinfoBlocks {
|
||||
var zoneinfoElement Zoneinfo
|
||||
lines := strings.Split(string(block), "\n")
|
||||
for _, line := range lines {
|
||||
|
||||
if nodeZone := nodeZoneRE.FindStringSubmatch(line); nodeZone != nil {
|
||||
zoneinfoElement.Node = nodeZone[1]
|
||||
zoneinfoElement.Zone = nodeZone[2]
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(strings.TrimSpace(line), "per-node stats") {
|
||||
zoneinfoElement.Zone = ""
|
||||
continue
|
||||
}
|
||||
parts := strings.Fields(strings.TrimSpace(line))
|
||||
if len(parts) < 2 {
|
||||
continue
|
||||
}
|
||||
vp := util.NewValueParser(parts[1])
|
||||
switch parts[0] {
|
||||
case "nr_free_pages":
|
||||
zoneinfoElement.NrFreePages = vp.PInt64()
|
||||
case "min":
|
||||
zoneinfoElement.Min = vp.PInt64()
|
||||
case "low":
|
||||
zoneinfoElement.Low = vp.PInt64()
|
||||
case "high":
|
||||
zoneinfoElement.High = vp.PInt64()
|
||||
case "scanned":
|
||||
zoneinfoElement.Scanned = vp.PInt64()
|
||||
case "spanned":
|
||||
zoneinfoElement.Spanned = vp.PInt64()
|
||||
case "present":
|
||||
zoneinfoElement.Present = vp.PInt64()
|
||||
case "managed":
|
||||
zoneinfoElement.Managed = vp.PInt64()
|
||||
case "nr_active_anon":
|
||||
zoneinfoElement.NrActiveAnon = vp.PInt64()
|
||||
case "nr_inactive_anon":
|
||||
zoneinfoElement.NrInactiveAnon = vp.PInt64()
|
||||
case "nr_isolated_anon":
|
||||
zoneinfoElement.NrIsolatedAnon = vp.PInt64()
|
||||
case "nr_anon_pages":
|
||||
zoneinfoElement.NrAnonPages = vp.PInt64()
|
||||
case "nr_anon_transparent_hugepages":
|
||||
zoneinfoElement.NrAnonTransparentHugepages = vp.PInt64()
|
||||
case "nr_active_file":
|
||||
zoneinfoElement.NrActiveFile = vp.PInt64()
|
||||
case "nr_inactive_file":
|
||||
zoneinfoElement.NrInactiveFile = vp.PInt64()
|
||||
case "nr_isolated_file":
|
||||
zoneinfoElement.NrIsolatedFile = vp.PInt64()
|
||||
case "nr_file_pages":
|
||||
zoneinfoElement.NrFilePages = vp.PInt64()
|
||||
case "nr_slab_reclaimable":
|
||||
zoneinfoElement.NrSlabReclaimable = vp.PInt64()
|
||||
case "nr_slab_unreclaimable":
|
||||
zoneinfoElement.NrSlabUnreclaimable = vp.PInt64()
|
||||
case "nr_mlock_stack":
|
||||
zoneinfoElement.NrMlockStack = vp.PInt64()
|
||||
case "nr_kernel_stack":
|
||||
zoneinfoElement.NrKernelStack = vp.PInt64()
|
||||
case "nr_mapped":
|
||||
zoneinfoElement.NrMapped = vp.PInt64()
|
||||
case "nr_dirty":
|
||||
zoneinfoElement.NrDirty = vp.PInt64()
|
||||
case "nr_writeback":
|
||||
zoneinfoElement.NrWriteback = vp.PInt64()
|
||||
case "nr_unevictable":
|
||||
zoneinfoElement.NrUnevictable = vp.PInt64()
|
||||
case "nr_shmem":
|
||||
zoneinfoElement.NrShmem = vp.PInt64()
|
||||
case "nr_dirtied":
|
||||
zoneinfoElement.NrDirtied = vp.PInt64()
|
||||
case "nr_written":
|
||||
zoneinfoElement.NrWritten = vp.PInt64()
|
||||
case "numa_hit":
|
||||
zoneinfoElement.NumaHit = vp.PInt64()
|
||||
case "numa_miss":
|
||||
zoneinfoElement.NumaMiss = vp.PInt64()
|
||||
case "numa_foreign":
|
||||
zoneinfoElement.NumaForeign = vp.PInt64()
|
||||
case "numa_interleave":
|
||||
zoneinfoElement.NumaInterleave = vp.PInt64()
|
||||
case "numa_local":
|
||||
zoneinfoElement.NumaLocal = vp.PInt64()
|
||||
case "numa_other":
|
||||
zoneinfoElement.NumaOther = vp.PInt64()
|
||||
case "protection:":
|
||||
protectionParts := strings.Split(line, ":")
|
||||
protectionValues := strings.Replace(protectionParts[1], "(", "", 1)
|
||||
protectionValues = strings.Replace(protectionValues, ")", "", 1)
|
||||
protectionValues = strings.TrimSpace(protectionValues)
|
||||
protectionStringMap := strings.Split(protectionValues, ", ")
|
||||
val, err := util.ParsePInt64s(protectionStringMap)
|
||||
if err == nil {
|
||||
zoneinfoElement.Protection = val
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
zoneinfo = append(zoneinfo, zoneinfoElement)
|
||||
}
|
||||
return zoneinfo, nil
|
||||
}
|
Reference in New Issue
Block a user