aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/prometheus
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/prometheus')
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/build_info.go29
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/build_info_pre_1.12.go22
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/doc.go1
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/go_collector.go32
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/http.go505
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/process_collector.go61
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go65
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go112
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go47
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/registry.go14
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/summary.go28
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/wrap.go21
-rw-r--r--vendor/github.com/prometheus/common/model/time.go8
-rw-r--r--vendor/github.com/prometheus/procfs/Makefile1
-rw-r--r--vendor/github.com/prometheus/procfs/Makefile.common9
-rw-r--r--vendor/github.com/prometheus/procfs/README.md44
-rw-r--r--vendor/github.com/prometheus/procfs/arp.go85
-rw-r--r--vendor/github.com/prometheus/procfs/buddyinfo.go12
-rw-r--r--vendor/github.com/prometheus/procfs/crypto.go131
-rw-r--r--vendor/github.com/prometheus/procfs/fixtures.ttar2275
-rw-r--r--vendor/github.com/prometheus/procfs/fs.go8
-rw-r--r--vendor/github.com/prometheus/procfs/go.mod5
-rw-r--r--vendor/github.com/prometheus/procfs/go.sum2
-rw-r--r--vendor/github.com/prometheus/procfs/internal/fs/fs.go3
-rw-r--r--vendor/github.com/prometheus/procfs/internal/util/parse.go88
-rw-r--r--vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go45
-rw-r--r--vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go26
-rw-r--r--vendor/github.com/prometheus/procfs/internal/util/valueparser.go77
-rw-r--r--vendor/github.com/prometheus/procfs/ipvs.go28
-rw-r--r--vendor/github.com/prometheus/procfs/mdstat.go145
-rw-r--r--vendor/github.com/prometheus/procfs/mountinfo.go178
-rw-r--r--vendor/github.com/prometheus/procfs/mountstats.go41
-rw-r--r--vendor/github.com/prometheus/procfs/net_dev.go36
-rw-r--r--vendor/github.com/prometheus/procfs/net_softnet.go91
-rw-r--r--vendor/github.com/prometheus/procfs/net_unix.go275
-rw-r--r--vendor/github.com/prometheus/procfs/proc.go55
-rw-r--r--vendor/github.com/prometheus/procfs/proc_environ.go43
-rw-r--r--vendor/github.com/prometheus/procfs/proc_fdinfo.go132
-rw-r--r--vendor/github.com/prometheus/procfs/proc_io.go4
-rw-r--r--vendor/github.com/prometheus/procfs/proc_limits.go7
-rw-r--r--vendor/github.com/prometheus/procfs/proc_ns.go4
-rw-r--r--vendor/github.com/prometheus/procfs/proc_psi.go17
-rw-r--r--vendor/github.com/prometheus/procfs/proc_stat.go9
-rw-r--r--vendor/github.com/prometheus/procfs/proc_status.go162
-rw-r--r--vendor/github.com/prometheus/procfs/schedstat.go118
-rw-r--r--vendor/github.com/prometheus/procfs/stat.go36
-rw-r--r--vendor/github.com/prometheus/procfs/ttar42
-rw-r--r--vendor/github.com/prometheus/procfs/vm.go210
-rw-r--r--vendor/github.com/prometheus/procfs/zoneinfo.go196
49 files changed, 4784 insertions, 801 deletions
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/build_info.go b/vendor/github.com/prometheus/client_golang/prometheus/build_info.go
new file mode 100644
index 0000000000..288f0e8548
--- /dev/null
+++ b/vendor/github.com/prometheus/client_golang/prometheus/build_info.go
@@ -0,0 +1,29 @@
+// 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 go1.12
+
+package prometheus
+
+import "runtime/debug"
+
+// readBuildInfo is a wrapper around debug.ReadBuildInfo for Go 1.12+.
+func readBuildInfo() (path, version, sum string) {
+ path, version, sum = "unknown", "unknown", "unknown"
+ if bi, ok := debug.ReadBuildInfo(); ok {
+ path = bi.Main.Path
+ version = bi.Main.Version
+ sum = bi.Main.Sum
+ }
+ return
+}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/build_info_pre_1.12.go b/vendor/github.com/prometheus/client_golang/prometheus/build_info_pre_1.12.go
new file mode 100644
index 0000000000..6609e2877c
--- /dev/null
+++ b/vendor/github.com/prometheus/client_golang/prometheus/build_info_pre_1.12.go
@@ -0,0 +1,22 @@
+// 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 !go1.12
+
+package prometheus
+
+// readBuildInfo is a wrapper around debug.ReadBuildInfo for Go versions before
+// 1.12. Remove this whole file once the minimum supported Go version is 1.12.
+func readBuildInfo() (path, version, sum string) {
+ return "unknown", "unknown", "unknown"
+}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/doc.go b/vendor/github.com/prometheus/client_golang/prometheus/doc.go
index 1e0d578ee7..01977de661 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/doc.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/doc.go
@@ -183,7 +183,6 @@
// method can then expose the gathered metrics in some way. Usually, the metrics
// are served via HTTP on the /metrics endpoint. That's happening in the example
// above. The tools to expose metrics via HTTP are in the promhttp sub-package.
-// (The top-level functions in the prometheus package are deprecated.)
//
// Pushing to the Pushgateway
//
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
index b108ec5130..dc9247fed9 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
@@ -36,7 +36,7 @@ type goCollector struct {
msMaxAge time.Duration // Maximum allowed age of old memstats.
}
-// NewGoCollector returns a collector which exports metrics about the current Go
+// NewGoCollector returns a collector that exports metrics about the current Go
// process. This includes memory stats. To collect those, runtime.ReadMemStats
// is called. This requires to “stop the world”, which usually only happens for
// garbage collection (GC). Take the following implications into account when
@@ -364,3 +364,33 @@ type memStatsMetrics []struct {
eval func(*runtime.MemStats) float64
valType ValueType
}
+
+// NewBuildInfoCollector returns a collector collecting a single metric
+// "go_build_info" with the constant value 1 and three labels "path", "version",
+// and "checksum". Their label values contain the main module path, version, and
+// checksum, respectively. The labels will only have meaningful values if the
+// binary is built with Go module support and from source code retrieved from
+// the source repository (rather than the local file system). This is usually
+// accomplished by building from outside of GOPATH, specifying the full address
+// of the main package, e.g. "GO111MODULE=on go run
+// github.com/prometheus/client_golang/examples/random". If built without Go
+// module support, all label values will be "unknown". If built with Go module
+// support but using the source code from the local file system, the "path" will
+// be set appropriately, but "checksum" will be empty and "version" will be
+// "(devel)".
+//
+// This collector uses only the build information for the main module. See
+// https://github.com/povilasv/prommod for an example of a collector for the
+// module dependencies.
+func NewBuildInfoCollector() Collector {
+ path, version, sum := readBuildInfo()
+ c := &selfCollector{MustNewConstMetric(
+ NewDesc(
+ "go_build_info",
+ "Build information about the main Go module.",
+ nil, Labels{"path": path, "version": version, "checksum": sum},
+ ),
+ GaugeValue, 1)}
+ c.init(c.self)
+ return c
+}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/http.go b/vendor/github.com/prometheus/client_golang/prometheus/http.go
deleted file mode 100644
index 19a3e8f493..0000000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/http.go
+++ /dev/null
@@ -1,505 +0,0 @@
-// Copyright 2014 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 prometheus
-
-import (
- "bufio"
- "compress/gzip"
- "io"
- "net"
- "net/http"
- "strconv"
- "strings"
- "sync"
- "time"
-
- "github.com/prometheus/common/expfmt"
-)
-
-// TODO(beorn7): Remove this whole file. It is a partial mirror of
-// promhttp/http.go (to avoid circular import chains) where everything HTTP
-// related should live. The functions here are just for avoiding
-// breakage. Everything is deprecated.
-
-const (
- contentTypeHeader = "Content-Type"
- contentEncodingHeader = "Content-Encoding"
- acceptEncodingHeader = "Accept-Encoding"
-)
-
-var gzipPool = sync.Pool{
- New: func() interface{} {
- return gzip.NewWriter(nil)
- },
-}
-
-// Handler returns an HTTP handler for the DefaultGatherer. It is
-// already instrumented with InstrumentHandler (using "prometheus" as handler
-// name).
-//
-// Deprecated: Please note the issues described in the doc comment of
-// InstrumentHandler. You might want to consider using promhttp.Handler instead.
-func Handler() http.Handler {
- return InstrumentHandler("prometheus", UninstrumentedHandler())
-}
-
-// UninstrumentedHandler returns an HTTP handler for the DefaultGatherer.
-//
-// Deprecated: Use promhttp.HandlerFor(DefaultGatherer, promhttp.HandlerOpts{})
-// instead. See there for further documentation.
-func UninstrumentedHandler() http.Handler {
- return http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) {
- mfs, err := DefaultGatherer.Gather()
- if err != nil {
- httpError(rsp, err)
- return
- }
-
- contentType := expfmt.Negotiate(req.Header)
- header := rsp.Header()
- header.Set(contentTypeHeader, string(contentType))
-
- w := io.Writer(rsp)
- if gzipAccepted(req.Header) {
- header.Set(contentEncodingHeader, "gzip")
- gz := gzipPool.Get().(*gzip.Writer)
- defer gzipPool.Put(gz)
-
- gz.Reset(w)
- defer gz.Close()
-
- w = gz
- }
-
- enc := expfmt.NewEncoder(w, contentType)
-
- for _, mf := range mfs {
- if err := enc.Encode(mf); err != nil {
- httpError(rsp, err)
- return
- }
- }
- })
-}
-
-var instLabels = []string{"method", "code"}
-
-type nower interface {
- Now() time.Time
-}
-
-type nowFunc func() time.Time
-
-func (n nowFunc) Now() time.Time {
- return n()
-}
-
-var now nower = nowFunc(func() time.Time {
- return time.Now()
-})
-
-// InstrumentHandler wraps the given HTTP handler for instrumentation. It
-// registers four metric collectors (if not already done) and reports HTTP
-// metrics to the (newly or already) registered collectors: http_requests_total
-// (CounterVec), http_request_duration_microseconds (Summary),
-// http_request_size_bytes (Summary), http_response_size_bytes (Summary). Each
-// has a constant label named "handler" with the provided handlerName as
-// value. http_requests_total is a metric vector partitioned by HTTP method
-// (label name "method") and HTTP status code (label name "code").
-//
-// Deprecated: InstrumentHandler has several issues. Use the tooling provided in
-// package promhttp instead. The issues are the following: (1) It uses Summaries
-// rather than Histograms. Summaries are not useful if aggregation across
-// multiple instances is required. (2) It uses microseconds as unit, which is
-// deprecated and should be replaced by seconds. (3) The size of the request is
-// calculated in a separate goroutine. Since this calculator requires access to
-// the request header, it creates a race with any writes to the header performed
-// during request handling. httputil.ReverseProxy is a prominent example for a
-// handler performing such writes. (4) It has additional issues with HTTP/2, cf.
-// https://github.com/prometheus/client_golang/issues/272.
-func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFunc {
- return InstrumentHandlerFunc(handlerName, handler.ServeHTTP)
-}
-
-// InstrumentHandlerFunc wraps the given function for instrumentation. It
-// otherwise works in the same way as InstrumentHandler (and shares the same
-// issues).
-//
-// Deprecated: InstrumentHandlerFunc is deprecated for the same reasons as
-// InstrumentHandler is. Use the tooling provided in package promhttp instead.
-func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
- return InstrumentHandlerFuncWithOpts(
- SummaryOpts{
- Subsystem: "http",
- ConstLabels: Labels{"handler": handlerName},
- Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
- },
- handlerFunc,
- )
-}
-
-// InstrumentHandlerWithOpts works like InstrumentHandler (and shares the same
-// issues) but provides more flexibility (at the cost of a more complex call
-// syntax). As InstrumentHandler, this function registers four metric
-// collectors, but it uses the provided SummaryOpts to create them. However, the
-// fields "Name" and "Help" in the SummaryOpts are ignored. "Name" is replaced
-// by "requests_total", "request_duration_microseconds", "request_size_bytes",
-// and "response_size_bytes", respectively. "Help" is replaced by an appropriate
-// help string. The names of the variable labels of the http_requests_total
-// CounterVec are "method" (get, post, etc.), and "code" (HTTP status code).
-//
-// If InstrumentHandlerWithOpts is called as follows, it mimics exactly the
-// behavior of InstrumentHandler:
-//
-// prometheus.InstrumentHandlerWithOpts(
-// prometheus.SummaryOpts{
-// Subsystem: "http",
-// ConstLabels: prometheus.Labels{"handler": handlerName},
-// },
-// handler,
-// )
-//
-// Technical detail: "requests_total" is a CounterVec, not a SummaryVec, so it
-// cannot use SummaryOpts. Instead, a CounterOpts struct is created internally,
-// and all its fields are set to the equally named fields in the provided
-// SummaryOpts.
-//
-// Deprecated: InstrumentHandlerWithOpts is deprecated for the same reasons as
-// InstrumentHandler is. Use the tooling provided in package promhttp instead.
-func InstrumentHandlerWithOpts(opts SummaryOpts, handler http.Handler) http.HandlerFunc {
- return InstrumentHandlerFuncWithOpts(opts, handler.ServeHTTP)
-}
-
-// InstrumentHandlerFuncWithOpts works like InstrumentHandlerFunc (and shares
-// the same issues) but provides more flexibility (at the cost of a more complex
-// call syntax). See InstrumentHandlerWithOpts for details how the provided
-// SummaryOpts are used.
-//
-// Deprecated: InstrumentHandlerFuncWithOpts is deprecated for the same reasons
-// as InstrumentHandler is. Use the tooling provided in package promhttp instead.
-func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
- reqCnt := NewCounterVec(
- CounterOpts{
- Namespace: opts.Namespace,
- Subsystem: opts.Subsystem,
- Name: "requests_total",
- Help: "Total number of HTTP requests made.",
- ConstLabels: opts.ConstLabels,
- },
- instLabels,
- )
- if err := Register(reqCnt); err != nil {
- if are, ok := err.(AlreadyRegisteredError); ok {
- reqCnt = are.ExistingCollector.(*CounterVec)
- } else {
- panic(err)
- }
- }
-
- opts.Name = "request_duration_microseconds"
- opts.Help = "The HTTP request latencies in microseconds."
- reqDur := NewSummary(opts)
- if err := Register(reqDur); err != nil {
- if are, ok := err.(AlreadyRegisteredError); ok {
- reqDur = are.ExistingCollector.(Summary)
- } else {
- panic(err)
- }
- }
-
- opts.Name = "request_size_bytes"
- opts.Help = "The HTTP request sizes in bytes."
- reqSz := NewSummary(opts)
- if err := Register(reqSz); err != nil {
- if are, ok := err.(AlreadyRegisteredError); ok {
- reqSz = are.ExistingCollector.(Summary)
- } else {
- panic(err)
- }
- }
-
- opts.Name = "response_size_bytes"
- opts.Help = "The HTTP response sizes in bytes."
- resSz := NewSummary(opts)
- if err := Register(resSz); err != nil {
- if are, ok := err.(AlreadyRegisteredError); ok {
- resSz = are.ExistingCollector.(Summary)
- } else {
- panic(err)
- }
- }
-
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- now := time.Now()
-
- delegate := &responseWriterDelegator{ResponseWriter: w}
- out := computeApproximateRequestSize(r)
-
- _, cn := w.(http.CloseNotifier)
- _, fl := w.(http.Flusher)
- _, hj := w.(http.Hijacker)
- _, rf := w.(io.ReaderFrom)
- var rw http.ResponseWriter
- if cn && fl && hj && rf {
- rw = &fancyResponseWriterDelegator{delegate}
- } else {
- rw = delegate
- }
- handlerFunc(rw, r)
-
- elapsed := float64(time.Since(now)) / float64(time.Microsecond)
-
- method := sanitizeMethod(r.Method)
- code := sanitizeCode(delegate.status)
- reqCnt.WithLabelValues(method, code).Inc()
- reqDur.Observe(elapsed)
- resSz.Observe(float64(delegate.written))
- reqSz.Observe(float64(<-out))
- })
-}
-
-func computeApproximateRequestSize(r *http.Request) <-chan int {
- // Get URL length in current goroutine for avoiding a race condition.
- // HandlerFunc that runs in parallel may modify the URL.
- s := 0
- if r.URL != nil {
- s += len(r.URL.String())
- }
-
- out := make(chan int, 1)
-
- go func() {
- s += len(r.Method)
- s += len(r.Proto)
- for name, values := range r.Header {
- s += len(name)
- for _, value := range values {
- s += len(value)
- }
- }
- s += len(r.Host)
-
- // N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
-
- if r.ContentLength != -1 {
- s += int(r.ContentLength)
- }
- out <- s
- close(out)
- }()
-
- return out
-}
-
-type responseWriterDelegator struct {
- http.ResponseWriter
-
- status int
- written int64
- wroteHeader bool
-}
-
-func (r *responseWriterDelegator) WriteHeader(code int) {
- r.status = code
- r.wroteHeader = true
- r.ResponseWriter.WriteHeader(code)
-}
-
-func (r *responseWriterDelegator) Write(b []byte) (int, error) {
- if !r.wroteHeader {
- r.WriteHeader(http.StatusOK)
- }
- n, err := r.ResponseWriter.Write(b)
- r.written += int64(n)
- return n, err
-}
-
-type fancyResponseWriterDelegator struct {
- *responseWriterDelegator
-}
-
-func (f *fancyResponseWriterDelegator) CloseNotify() <-chan bool {
- //lint:ignore SA1019 http.CloseNotifier is deprecated but we don't want to
- //remove support from client_golang yet.
- return f.ResponseWriter.(http.CloseNotifier).CloseNotify()
-}
-
-func (f *fancyResponseWriterDelegator) Flush() {
- f.ResponseWriter.(http.Flusher).Flush()
-}
-
-func (f *fancyResponseWriterDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- return f.ResponseWriter.(http.Hijacker).Hijack()
-}
-
-func (f *fancyResponseWriterDelegator) ReadFrom(r io.Reader) (int64, error) {
- if !f.wroteHeader {
- f.WriteHeader(http.StatusOK)
- }
- n, err := f.ResponseWriter.(io.ReaderFrom).ReadFrom(r)
- f.written += n
- return n, err
-}
-
-func sanitizeMethod(m string) string {
- switch m {
- case "GET", "get":
- return "get"
- case "PUT", "put":
- return "put"
- case "HEAD", "head":
- return "head"
- case "POST", "post":
- return "post"
- case "DELETE", "delete":
- return "delete"
- case "CONNECT", "connect":
- return "connect"
- case "OPTIONS", "options":
- return "options"
- case "NOTIFY", "notify":
- return "notify"
- default:
- return strings.ToLower(m)
- }
-}
-
-func sanitizeCode(s int) string {
- switch s {
- case 100:
- return "100"
- case 101:
- return "101"
-
- case 200:
- return "200"
- case 201:
- return "201"
- case 202:
- return "202"
- case 203:
- return "203"
- case 204:
- return "204"
- case 205:
- return "205"
- case 206:
- return "206"
-
- case 300:
- return "300"
- case 301:
- return "301"
- case 302:
- return "302"
- case 304:
- return "304"
- case 305:
- return "305"
- case 307:
- return "307"
-
- case 400:
- return "400"
- case 401:
- return "401"
- case 402:
- return "402"
- case 403:
- return "403"
- case 404:
- return "404"
- case 405:
- return "405"
- case 406:
- return "406"
- case 407:
- return "407"
- case 408:
- return "408"
- case 409:
- return "409"
- case 410:
- return "410"
- case 411:
- return "411"
- case 412:
- return "412"
- case 413:
- return "413"
- case 414:
- return "414"
- case 415:
- return "415"
- case 416:
- return "416"
- case 417:
- return "417"
- case 418:
- return "418"
-
- case 500:
- return "500"
- case 501:
- return "501"
- case 502:
- return "502"
- case 503:
- return "503"
- case 504:
- return "504"
- case 505:
- return "505"
-
- case 428:
- return "428"
- case 429:
- return "429"
- case 431:
- return "431"
- case 511:
- return "511"
-
- default:
- return strconv.Itoa(s)
- }
-}
-
-// gzipAccepted returns whether the client will accept gzip-encoded content.
-func gzipAccepted(header http.Header) bool {
- a := header.Get(acceptEncodingHeader)
- parts := strings.Split(a, ",")
- for _, part := range parts {
- part = strings.TrimSpace(part)
- if part == "gzip" || strings.HasPrefix(part, "gzip;") {
- return true
- }
- }
- return false
-}
-
-// httpError removes any content-encoding header and then calls http.Error with
-// the provided error and http.StatusInternalServerErrer. Error contents is
-// supposed to be uncompressed plain text. However, same as with a plain
-// http.Error, any header settings will be void if the header has already been
-// sent. The error message will still be written to the writer, but it will
-// probably be of limited use.
-func httpError(rsp http.ResponseWriter, err error) {
- rsp.Header().Del(contentEncodingHeader)
- http.Error(
- rsp,
- "An error has occurred while serving metrics:\n\n"+err.Error(),
- http.StatusInternalServerError,
- )
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
index 55176d58ce..9b80979421 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
@@ -16,8 +16,6 @@ package prometheus
import (
"errors"
"os"
-
- "github.com/prometheus/procfs"
)
type processCollector struct {
@@ -59,20 +57,9 @@ type ProcessCollectorOpts struct {
// collector for the current process with an empty namespace string and no error
// reporting.
//
-// Currently, the collector depends on a Linux-style proc filesystem and
-// therefore only exports metrics for Linux.
-//
-// Note: An older version of this function had the following signature:
-//
-// NewProcessCollector(pid int, namespace string) Collector
-//
-// Most commonly, it was called as
-//
-// NewProcessCollector(os.Getpid(), "")
-//
-// The following call of the current version is equivalent to the above:
-//
-// NewProcessCollector(ProcessCollectorOpts{})
+// The collector only works on operating systems with a Linux-style proc
+// filesystem and on Microsoft Windows. On other operating systems, it will not
+// collect any metrics.
func NewProcessCollector(opts ProcessCollectorOpts) Collector {
ns := ""
if len(opts.Namespace) > 0 {
@@ -126,7 +113,7 @@ func NewProcessCollector(opts ProcessCollectorOpts) Collector {
}
// Set up process metric collection if supported by the runtime.
- if _, err := procfs.NewStat(); err == nil {
+ if canCollectProcess() {
c.collectFn = c.processCollect
} else {
c.collectFn = func(ch chan<- Metric) {
@@ -153,46 +140,6 @@ func (c *processCollector) Collect(ch chan<- Metric) {
c.collectFn(ch)
}
-func (c *processCollector) processCollect(ch chan<- Metric) {
- pid, err := c.pidFn()
- if err != nil {
- c.reportError(ch, nil, err)
- return
- }
-
- p, err := procfs.NewProc(pid)
- if err != nil {
- c.reportError(ch, nil, err)
- return
- }
-
- if stat, err := p.NewStat(); err == nil {
- ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
- ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
- ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
- if startTime, err := stat.StartTime(); err == nil {
- ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
- } else {
- c.reportError(ch, c.startTime, err)
- }
- } else {
- c.reportError(ch, nil, err)
- }
-
- if fds, err := p.FileDescriptorsLen(); err == nil {
- ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
- } else {
- c.reportError(ch, c.openFDs, err)
- }
-
- if limits, err := p.NewLimits(); err == nil {
- ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
- ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(limits.AddressSpace))
- } else {
- c.reportError(ch, nil, err)
- }
-}
-
func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) {
if !c.reportErrors {
return
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
new file mode 100644
index 0000000000..3117461cde
--- /dev/null
+++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
@@ -0,0 +1,65 @@
+// 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 prometheus
+
+import (
+ "github.com/prometheus/procfs"
+)
+
+func canCollectProcess() bool {
+ _, err := procfs.NewDefaultFS()
+ return err == nil
+}
+
+func (c *processCollector) processCollect(ch chan<- Metric) {
+ pid, err := c.pidFn()
+ if err != nil {
+ c.reportError(ch, nil, err)
+ return
+ }
+
+ p, err := procfs.NewProc(pid)
+ if err != nil {
+ c.reportError(ch, nil, err)
+ return
+ }
+
+ if stat, err := p.Stat(); err == nil {
+ ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
+ ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
+ ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
+ if startTime, err := stat.StartTime(); err == nil {
+ ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
+ } else {
+ c.reportError(ch, c.startTime, err)
+ }
+ } else {
+ c.reportError(ch, nil, err)
+ }
+
+ if fds, err := p.FileDescriptorsLen(); err == nil {
+ ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
+ } else {
+ c.reportError(ch, c.openFDs, err)
+ }
+
+ if limits, err := p.Limits(); err == nil {
+ ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
+ ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(limits.AddressSpace))
+ } else {
+ c.reportError(ch, nil, err)
+ }
+}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go
new file mode 100644
index 0000000000..e0b935d1fe
--- /dev/null
+++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go
@@ -0,0 +1,112 @@
+// 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 prometheus
+
+import (
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+func canCollectProcess() bool {
+ return true
+}
+
+var (
+ modpsapi = syscall.NewLazyDLL("psapi.dll")
+ modkernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+ procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
+ procGetProcessHandleCount = modkernel32.NewProc("GetProcessHandleCount")
+)
+
+type processMemoryCounters struct {
+ // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-_process_memory_counters_ex
+ _ uint32
+ PageFaultCount uint32
+ PeakWorkingSetSize uint64
+ WorkingSetSize uint64
+ QuotaPeakPagedPoolUsage uint64
+ QuotaPagedPoolUsage uint64
+ QuotaPeakNonPagedPoolUsage uint64
+ QuotaNonPagedPoolUsage uint64
+ PagefileUsage uint64
+ PeakPagefileUsage uint64
+ PrivateUsage uint64
+}
+
+func getProcessMemoryInfo(handle windows.Handle) (processMemoryCounters, error) {
+ mem := processMemoryCounters{}
+ r1, _, err := procGetProcessMemoryInfo.Call(
+ uintptr(handle),
+ uintptr(unsafe.Pointer(&mem)),
+ uintptr(unsafe.Sizeof(mem)),
+ )
+ if r1 != 1 {
+ return mem, err
+ } else {
+ return mem, nil
+ }
+}
+
+func getProcessHandleCount(handle windows.Handle) (uint32, error) {
+ var count uint32
+ r1, _, err := procGetProcessHandleCount.Call(
+ uintptr(handle),
+ uintptr(unsafe.Pointer(&count)),
+ )
+ if r1 != 1 {
+ return 0, err
+ } else {
+ return count, nil
+ }
+}
+
+func (c *processCollector) processCollect(ch chan<- Metric) {
+ h, err := windows.GetCurrentProcess()
+ if err != nil {
+ c.reportError(ch, nil, err)
+ return
+ }
+
+ var startTime, exitTime, kernelTime, userTime windows.Filetime
+ err = windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime)
+ if err != nil {
+ c.reportError(ch, nil, err)
+ return
+ }
+ ch <- MustNewConstMetric(c.startTime, GaugeValue, float64(startTime.Nanoseconds()/1e9))
+ ch <- MustNewConstMetric(c.cpuTotal, CounterValue, fileTimeToSeconds(kernelTime)+fileTimeToSeconds(userTime))
+
+ mem, err := getProcessMemoryInfo(h)
+ if err != nil {
+ c.reportError(ch, nil, err)
+ return
+ }
+ ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(mem.PrivateUsage))
+ ch <- MustNewConstMetric(c.rss, GaugeValue, float64(mem.WorkingSetSize))
+
+ handles, err := getProcessHandleCount(h)
+ if err != nil {
+ c.reportError(ch, nil, err)
+ return
+ }
+ ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(handles))
+ ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(16*1024*1024)) // Windows has a hard-coded max limit, not per-process.
+}
+
+func fileTimeToSeconds(ft windows.Filetime) float64 {
+ return float64(uint64(ft.HighDateTime)<<32+uint64(ft.LowDateTime)) / 1e7
+}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
index b137c88307..cea5a90fd9 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
@@ -84,10 +84,32 @@ func Handler() http.Handler {
// instrumentation. Use the InstrumentMetricHandler function to apply the same
// kind of instrumentation as it is used by the Handler function.
func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
- var inFlightSem chan struct{}
+ var (
+ inFlightSem chan struct{}
+ errCnt = prometheus.NewCounterVec(
+ prometheus.CounterOpts{
+ Name: "promhttp_metric_handler_errors_total",
+ Help: "Total number of internal errors encountered by the promhttp metric handler.",
+ },
+ []string{"cause"},
+ )
+ )
+
if opts.MaxRequestsInFlight > 0 {
inFlightSem = make(chan struct{}, opts.MaxRequestsInFlight)
}
+ if opts.Registry != nil {
+ // Initialize all possibilites that can occur below.
+ errCnt.WithLabelValues("gathering")
+ errCnt.WithLabelValues("encoding")
+ if err := opts.Registry.Register(errCnt); err != nil {
+ if are, ok := err.(prometheus.AlreadyRegisteredError); ok {
+ errCnt = are.ExistingCollector.(*prometheus.CounterVec)
+ } else {
+ panic(err)
+ }
+ }
+ }
h := http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) {
if inFlightSem != nil {
@@ -106,6 +128,7 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
if opts.ErrorLog != nil {
opts.ErrorLog.Println("error gathering metrics:", err)
}
+ errCnt.WithLabelValues("gathering").Inc()
switch opts.ErrorHandling {
case PanicOnError:
panic(err)
@@ -146,6 +169,7 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
if opts.ErrorLog != nil {
opts.ErrorLog.Println("error encoding and sending metric family:", err)
}
+ errCnt.WithLabelValues("encoding").Inc()
switch opts.ErrorHandling {
case PanicOnError:
panic(err)
@@ -236,9 +260,12 @@ const (
// Ignore errors and try to serve as many metrics as possible. However,
// if no metrics can be served, serve an HTTP status code 500 and the
// last error message in the body. Only use this in deliberate "best
- // effort" metrics collection scenarios. It is recommended to at least
- // log errors (by providing an ErrorLog in HandlerOpts) to not mask
- // errors completely.
+ // effort" metrics collection scenarios. In this case, it is highly
+ // recommended to provide other means of detecting errors: By setting an
+ // ErrorLog in HandlerOpts, the errors are logged. By providing a
+ // Registry in HandlerOpts, the exposed metrics include an error counter
+ // "promhttp_metric_handler_errors_total", which can be used for
+ // alerts.
ContinueOnError
// Panic upon the first error encountered (useful for "crash only" apps).
PanicOnError
@@ -261,6 +288,18 @@ type HandlerOpts struct {
// logged regardless of the configured ErrorHandling provided ErrorLog
// is not nil.
ErrorHandling HandlerErrorHandling
+ // If Registry is not nil, it is used to register a metric
+ // "promhttp_metric_handler_errors_total", partitioned by "cause". A
+ // failed registration causes a panic. Note that this error counter is
+ // different from the instrumentation you get from the various
+ // InstrumentHandler... helpers. It counts errors that don't necessarily
+ // result in a non-2xx HTTP status code. There are two typical cases:
+ // (1) Encoding errors that only happen after streaming of the HTTP body
+ // has already started (and the status code 200 has been sent). This
+ // should only happen with custom collectors. (2) Collection errors with
+ // no effect on the HTTP status code because ErrorHandling is set to
+ // ContinueOnError.
+ Registry prometheus.Registerer
// If DisableCompression is true, the handler will never compress the
// response, even if requested by the client.
DisableCompression bool
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/registry.go b/vendor/github.com/prometheus/client_golang/prometheus/registry.go
index f2fb67aeeb..6c32516aa2 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/registry.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/registry.go
@@ -325,9 +325,17 @@ func (r *Registry) Register(c Collector) error {
return nil
}
if existing, exists := r.collectorsByID[collectorID]; exists {
- return AlreadyRegisteredError{
- ExistingCollector: existing,
- NewCollector: c,
+ switch e := existing.(type) {
+ case *wrappingCollector:
+ return AlreadyRegisteredError{
+ ExistingCollector: e.unwrapRecursively(),
+ NewCollector: c,
+ }
+ default:
+ return AlreadyRegisteredError{
+ ExistingCollector: e,
+ NewCollector: c,
+ }
}
}
// If the collectorID is new, but at least one of the descs existed
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/summary.go b/vendor/github.com/prometheus/client_golang/prometheus/summary.go
index 1574b0fe7d..c970fdee0e 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/summary.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/summary.go
@@ -39,7 +39,7 @@ const quantileLabel = "quantile"
// A typical use-case is the observation of request latencies. By default, a
// Summary provides the median, the 90th and the 99th percentile of the latency
// as rank estimations. However, the default behavior will change in the
-// upcoming v0.10 of the library. There will be no rank estimations at all by
+// upcoming v1.0.0 of the library. There will be no rank estimations at all by
// default. For a sane transition, it is recommended to set the desired rank
// estimations explicitly.
//
@@ -58,16 +58,8 @@ type Summary interface {
Observe(float64)
}
-// DefObjectives are the default Summary quantile values.
-//
-// Deprecated: DefObjectives will not be used as the default objectives in
-// v0.10 of the library. The default Summary will have no quantiles then.
-var (
- DefObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}
-
- errQuantileLabelNotAllowed = fmt.Errorf(
- "%q is not allowed as label name in summaries", quantileLabel,
- )
+var errQuantileLabelNotAllowed = fmt.Errorf(
+ "%q is not allowed as label name in summaries", quantileLabel,
)
// Default values for SummaryOpts.
@@ -86,7 +78,7 @@ const (
// mandatory to set Name to a non-empty string. While all other fields are
// optional and can safely be left at their zero value, it is recommended to set
// a help string and to explicitly set the Objectives field to the desired value
-// as the default value will change in the upcoming v0.10 of the library.
+// as the default value will change in the upcoming v1.0.0 of the library.
type SummaryOpts struct {
// Namespace, Subsystem, and Name are components of the fully-qualified
// name of the Summary (created by joining these components with
@@ -123,14 +115,8 @@ type SummaryOpts struct {
// Objectives defines the quantile rank estimates with their respective
// absolute error. If Objectives[q] = e, then the value reported for q
// will be the φ-quantile value for some φ between q-e and q+e. The
- // default value is DefObjectives. It is used if Objectives is left at
- // its zero value (i.e. nil). To create a Summary without Objectives,
- // set it to an empty map (i.e. map[float64]float64{}).
- //
- // Note that the current value of DefObjectives is deprecated. It will
- // be replaced by an empty map in v0.10 of the library. Please
- // explicitly set Objectives to the desired value to avoid problems
- // during the transition.
+ // default value is an empty map, resulting in a summary without
+ // quantiles.
Objectives map[float64]float64
// MaxAge defines the duration for which an observation stays relevant
@@ -199,7 +185,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
}
if opts.Objectives == nil {
- opts.Objectives = DefObjectives
+ opts.Objectives = map[float64]float64{}
}
if opts.MaxAge < 0 {
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go
index 49159bf3eb..e303eef6d3 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go
@@ -32,6 +32,12 @@ import (
// WrapRegistererWith provides a way to add fixed labels to a subset of
// Collectors. It should not be used to add fixed labels to all metrics exposed.
//
+// Conflicts between Collectors registered through the original Registerer with
+// Collectors registered through the wrapping Registerer will still be
+// detected. Any AlreadyRegisteredError returned by the Register method of
+// either Registerer will contain the ExistingCollector in the form it was
+// provided to the respective registry.
+//
// The Collector example demonstrates a use of WrapRegistererWith.
func WrapRegistererWith(labels Labels, reg Registerer) Registerer {
return &wrappingRegisterer{
@@ -54,6 +60,12 @@ func WrapRegistererWith(labels Labels, reg Registerer) Registerer {
// (see NewGoCollector) and the process collector (see NewProcessCollector). (In
// fact, those metrics are already prefixed with “go_” or “process_”,
// respectively.)
+//
+// Conflicts between Collectors registered through the original Registerer with
+// Collectors registered through the wrapping Registerer will still be
+// detected. Any AlreadyRegisteredError returned by the Register method of
+// either Registerer will contain the ExistingCollector in the form it was
+// provided to the respective registry.
func WrapRegistererWithPrefix(prefix string, reg Registerer) Registerer {
return &wrappingRegisterer{
wrappedRegisterer: reg,
@@ -123,6 +135,15 @@ func (c *wrappingCollector) Describe(ch chan<- *Desc) {
}
}
+func (c *wrappingCollector) unwrapRecursively() Collector {
+ switch wc := c.wrappedCollector.(type) {
+ case *wrappingCollector:
+ return wc.unwrapRecursively()
+ default:
+ return wc
+ }
+}
+
type wrappingMetric struct {
wrappedMetric Metric
prefix string
diff --git a/vendor/github.com/prometheus/common/model/time.go b/vendor/github.com/prometheus/common/model/time.go
index 46259b1f10..7b0064fdb2 100644
--- a/vendor/github.com/prometheus/common/model/time.go
+++ b/vendor/github.com/prometheus/common/model/time.go
@@ -150,7 +150,13 @@ func (t *Time) UnmarshalJSON(b []byte) error {
return err
}
- *t = Time(v + va)
+ // If the value was something like -0.1 the negative is lost in the
+ // parsing because of the leading zero, this ensures that we capture it.
+ if len(p[0]) > 0 && p[0][0] == '-' && v+va > 0 {
+ *t = Time(v+va) * -1
+ } else {
+ *t = Time(v + va)
+ }
default:
return fmt.Errorf("invalid time %q", string(b))
diff --git a/vendor/github.com/prometheus/procfs/Makefile b/vendor/github.com/prometheus/procfs/Makefile
index 314d1ba568..616a0d25eb 100644
--- a/vendor/github.com/prometheus/procfs/Makefile
+++ b/vendor/github.com/prometheus/procfs/Makefile
@@ -14,6 +14,7 @@
include Makefile.common
%/.unpacked: %.ttar
+ @echo ">> extracting fixtures"
./ttar -C $(dir $*) -x -f $*.ttar
touch $@
diff --git a/vendor/github.com/prometheus/procfs/Makefile.common b/vendor/github.com/prometheus/procfs/Makefile.common
index 4f18ea5877..d7aea1b86f 100644
--- a/vendor/github.com/prometheus/procfs/Makefile.common
+++ b/vendor/github.com/prometheus/procfs/Makefile.common
@@ -69,7 +69,7 @@ else
GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)
endif
-PROMU_VERSION ?= 0.3.0
+PROMU_VERSION ?= 0.4.0
PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz
GOLANGCI_LINT :=
@@ -86,6 +86,7 @@ endif
PREFIX ?= $(shell pwd)
BIN_DIR ?= $(shell pwd)
DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD))
+DOCKERFILE_PATH ?= ./
DOCKER_REPO ?= prom
DOCKER_ARCHS ?= amd64
@@ -212,7 +213,7 @@ $(BUILD_DOCKER_ARCHS): common-docker-%:
docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" \
--build-arg ARCH="$*" \
--build-arg OS="linux" \
- .
+ $(DOCKERFILE_PATH)
.PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS)
common-docker-publish: $(PUBLISH_DOCKER_ARCHS)
@@ -247,7 +248,9 @@ proto:
ifdef GOLANGCI_LINT
$(GOLANGCI_LINT):
mkdir -p $(FIRST_GOPATH)/bin
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION)
+ curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_LINT_VERSION)/install.sh \
+ | sed -e '/install -d/d' \
+ | sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION)
endif
ifdef GOVENDOR
diff --git a/vendor/github.com/prometheus/procfs/README.md b/vendor/github.com/prometheus/procfs/README.md
index 2095494719..6f8850feb6 100644
--- a/vendor/github.com/prometheus/procfs/README.md
+++ b/vendor/github.com/prometheus/procfs/README.md
@@ -1,7 +1,7 @@
# procfs
This procfs package provides functions to retrieve system, kernel and process
-metrics from the pseudo-filesystem proc.
+metrics from the pseudo-filesystems /proc and /sys.
*WARNING*: This package is a work in progress. Its API may still break in
backwards-incompatible ways without warnings. Use it at your own risk.
@@ -9,3 +9,45 @@ backwards-incompatible ways without warnings. Use it at your own risk.
[![GoDoc](https://godoc.org/github.com/prometheus/procfs?status.png)](https://godoc.org/github.com/prometheus/procfs)
[![Build Status](https://travis-ci.org/prometheus/procfs.svg?branch=master)](https://travis-ci.org/prometheus/procfs)
[![Go Report Card](https://goreportcard.com/badge/github.com/prometheus/procfs)](https://goreportcard.com/report/github.com/prometheus/procfs)
+
+## Usage
+
+The procfs library is organized by packages based on whether the gathered data is coming from
+/proc, /sys, or both. Each package contains an `FS` type which represents the path to either /proc, /sys, or both. For example, current cpu statistics are gathered from
+`/proc/stat` and are available via the root procfs package. First, the proc filesystem mount
+point is initialized, and then the stat information is read.
+
+```go
+fs, err := procfs.NewFS("/proc")
+stats, err := fs.Stat()
+```
+
+Some sub-packages such as `blockdevice`, require access to both the proc and sys filesystems.
+
+```go
+ fs, err := blockdevice.NewFS("/proc", "/sys")
+ stats, err := fs.ProcDiskstats()
+```
+
+## Building and Testing
+
+The procfs library is normally built as part of another application. However, when making
+changes to the library, the `make test` command can be used to run the API test suite.
+
+### Updating Test Fixtures
+
+The procfs library includes a set of test fixtures which include many example files from
+the `/proc` and `/sys` filesystems. These fixtures are included as a [ttar](https://github.com/ideaship/ttar) file
+which is extracted automatically during testing. To add/update the test fixtures, first
+ensure the `fixtures` directory is up to date by removing the existing directory and then
+extracting the ttar file using `make fixtures/.unpacked` or just `make test`.
+
+```bash
+rm -rf fixtures
+make test
+```
+
+Next, make the required changes to the extracted files in the `fixtures` directory. When
+the changes are complete, run `make update_fixtures` to create a new `fixtures.ttar` file
+based on the updated `fixtures` directory. And finally, verify the changes using
+`git diff fixtures.ttar`.
diff --git a/vendor/github.com/prometheus/procfs/arp.go b/vendor/github.com/prometheus/procfs/arp.go
new file mode 100644
index 0000000000..916c9182a8
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/arp.go
@@ -0,0 +1,85 @@
+// 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
+}
diff --git a/vendor/github.com/prometheus/procfs/buddyinfo.go b/vendor/github.com/prometheus/procfs/buddyinfo.go
index 5cd22a837f..63d4229a45 100644
--- a/vendor/github.com/prometheus/procfs/buddyinfo.go
+++ b/vendor/github.com/prometheus/procfs/buddyinfo.go
@@ -31,18 +31,8 @@ type BuddyInfo struct {
Sizes []float64
}
-// NewBuddyInfo reads the buddyinfo statistics.
-func NewBuddyInfo() ([]BuddyInfo, error) {
- fs, err := NewFS(DefaultMountPoint)
- if err != nil {
- return nil, err
- }
-
- return fs.NewBuddyInfo()
-}
-
// NewBuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem.
-func (fs FS) NewBuddyInfo() ([]BuddyInfo, error) {
+func (fs FS) BuddyInfo() ([]BuddyInfo, error) {
file, err := os.Open(fs.proc.Path("buddyinfo"))
if err != nil {
return nil, err
diff --git a/vendor/github.com/prometheus/procfs/crypto.go b/vendor/github.com/prometheus/procfs/crypto.go
new file mode 100644
index 0000000000..19d4041b29
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/crypto.go
@@ -0,0 +1,131 @@
+// 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
+}
diff --git a/vendor/github.com/prometheus/procfs/fixtures.ttar b/vendor/github.com/prometheus/procfs/fixtures.ttar
index f7f84ef362..8591c276ba 100644
--- a/vendor/github.com/prometheus/procfs/fixtures.ttar
+++ b/vendor/github.com/prometheus/procfs/fixtures.ttar
@@ -3,7 +3,7 @@ Directory: fixtures
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/proc
-Mode: 755
+Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/proc/26231
Mode: 755
@@ -21,6 +21,11 @@ Mode: 644
Path: fixtures/proc/26231/cwd
SymlinkTo: /usr/bin
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26231/environ
+Lines: 1
+PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binNULLBYTEHOSTNAME=cd24e11f73a5NULLBYTETERM=xtermNULLBYTEGOLANG_VERSION=1.12.5NULLBYTEGOPATH=/goNULLBYTEHOME=/rootNULLBYTEEOF
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/26231/exe
SymlinkTo: /usr/bin/vim
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -42,6 +47,48 @@ SymlinkTo: ../../symlinktargets/ghi
Path: fixtures/proc/26231/fd/3
SymlinkTo: ../../symlinktargets/uvw
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/proc/26231/fdinfo
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26231/fdinfo/0
+Lines: 6
+pos: 0
+flags: 02004000
+mnt_id: 13
+inotify wd:3 ino:1 sdev:34 mask:fce ignored_mask:0 fhandle-bytes:c fhandle-type:81 f_handle:000000000100000000000000
+inotify wd:2 ino:1300016 sdev:fd00002 mask:fce ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:16003001ed3f022a
+inotify wd:1 ino:2e0001 sdev:fd00000 mask:fce ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:01002e00138e7c65
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26231/fdinfo/1
+Lines: 4
+pos: 0
+flags: 02004002
+mnt_id: 13
+eventfd-count: 0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26231/fdinfo/10
+Lines: 3
+pos: 0
+flags: 02004002
+mnt_id: 9
+Mode: 400
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26231/fdinfo/2
+Lines: 3
+pos: 0
+flags: 02004002
+mnt_id: 9
+Mode: 400
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26231/fdinfo/3
+Lines: 3
+pos: 0
+flags: 02004002
+mnt_id: 9
+Mode: 400
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/26231/io
Lines: 7
rchar: 750339
@@ -75,13 +122,13 @@ Max realtime timeout unlimited unlimited us
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/26231/mountstats
-Lines: 19
+Lines: 20
device rootfs mounted on / with fstype rootfs
device sysfs mounted on /sys with fstype sysfs
device proc mounted on /proc with fstype proc
device /dev/sda1 mounted on / with fstype ext4
device 192.168.1.1:/srv/test mounted on /mnt/nfs/test with fstype nfs4 statvers=1.1
- opts: rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,local_lock=none
+ opts: rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,mountaddr=192.168.1.1,clientaddr=192.168.1.5,local_lock=none
age: 13968
caps: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255
nfsv4: bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured
@@ -94,6 +141,7 @@ device 192.168.1.1:/srv/test mounted on /mnt/nfs/test with fstype nfs4 statvers=
NULL: 0 0 0 0 0 0 0 0
READ: 1298 1298 0 207680 1210292152 6 79386 79407
WRITE: 0 0 0 0 0 0 0 0
+ ACCESS: 2927395007 2927394995 0 526931094212 362996810236 18446743919241604546 1667369447 1953587717
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -120,11 +168,73 @@ SymlinkTo: net:[4026531993]
Path: fixtures/proc/26231/root
SymlinkTo: /
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26231/schedstat
+Lines: 1
+411605849 93680043 79
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/26231/stat
Lines: 1
26231 (vim) R 5392 7446 5392 34835 7446 4218880 32533 309516 26 82 1677 44 158 99 20 0 1 0 82375 56274944 1981 18446744073709551615 4194304 6294284 140736914091744 140736914087944 139965136429984 0 0 12288 1870679807 0 0 0 17 0 0 0 31 0 0 8391624 8481048 16420864 140736914093252 140736914093279 140736914093279 140736914096107 0
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26231/status
+Lines: 53
+
+Name: prometheus
+Umask: 0022
+State: S (sleeping)
+Tgid: 1
+Ngid: 0
+Pid: 1
+PPid: 0
+TracerPid: 0
+Uid: 0 0 0 0
+Gid: 0 0 0 0
+FDSize: 128
+Groups:
+NStgid: 1
+NSpid: 1
+NSpgid: 1
+NSsid: 1
+VmPeak: 58472 kB
+VmSize: 58440 kB
+VmLck: 0 kB
+VmPin: 0 kB
+VmHWM: 8028 kB
+VmRSS: 6716 kB
+RssAnon: 2092 kB
+RssFile: 4624 kB
+RssShmem: 0 kB
+VmData: 2580 kB
+VmStk: 136 kB
+VmExe: 948 kB
+VmLib: 6816 kB
+VmPTE: 128 kB
+VmPMD: 12 kB
+VmSwap: 660 kB
+HugetlbPages: 0 kB
+Threads: 1
+SigQ: 8/63965
+SigPnd: 0000000000000000
+ShdPnd: 0000000000000000
+SigBlk: 7be3c0fe28014a03
+SigIgn: 0000000000001000
+SigCgt: 00000001800004ec
+CapInh: 0000000000000000
+CapPrm: 0000003fffffffff
+CapEff: 0000003fffffffff
+CapBnd: 0000003fffffffff
+CapAmb: 0000000000000000
+Seccomp: 0
+Cpus_allowed: ff
+Cpus_allowed_list: 0-7
+Mems_allowed: 00000000,00000001
+Mems_allowed_list: 0
+voluntary_ctxt_switches: 4742839
+nonvoluntary_ctxt_switches: 1727500
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/proc/26232
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -160,23 +270,23 @@ SymlinkTo: ../../symlinktargets/xyz
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/26232/limits
Lines: 17
-Limit Soft Limit Hard Limit Units
-Max cpu time unlimited unlimited seconds
-Max file size unlimited unlimited bytes
-Max data size unlimited unlimited bytes
-Max stack size 8388608 unlimited bytes
-Max core file size 0 unlimited bytes
-Max resident set unlimited unlimited bytes
-Max processes 29436 29436 processes
-Max open files 1024 4096 files
-Max locked memory 65536 65536 bytes
-Max address space unlimited unlimited bytes
-Max file locks unlimited unlimited locks
-Max pending signals 29436 29436 signals
-Max msgqueue size 819200 819200 bytes
-Max nice priority 0 0
-Max realtime priority 0 0
-Max realtime timeout unlimited unlimited us
+Limit Soft Limit Hard Limit Units
+Max cpu time unlimited unlimited seconds
+Max file size unlimited unlimited bytes
+Max data size unlimited unlimited bytes
+Max stack size 8388608 unlimited bytes
+Max core file size 0 unlimited bytes
+Max resident set unlimited unlimited bytes
+Max processes 29436 29436 processes
+Max open files 1024 4096 files
+Max locked memory 65536 65536 bytes
+Max address space unlimited unlimited bytes
+Max file locks unlimited unlimited locks
+Max pending signals 29436 29436 signals
+Max msgqueue size 819200 819200 bytes
+Max nice priority 0 0
+Max realtime priority 0 0
+Max realtime timeout unlimited unlimited us
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/26232/root
@@ -195,6 +305,18 @@ Lines: 1
com.github.uiautomatorNULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTEEOF
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26233/schedstat
+Lines: 8
+ ____________________________________
+< this is a malformed schedstat file >
+ ------------------------------------
+ \ ^__^
+ \ (oo)\_______
+ (__)\ )\/\
+ ||----w |
+ || ||
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/proc/584
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -206,10 +328,985 @@ Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/buddyinfo
Lines: 3
-Node 0, zone DMA 1 0 1 0 2 1 1 0 1 1 3
-Node 0, zone DMA32 759 572 791 475 194 45 12 0 0 0 0
-Node 0, zone Normal 4381 1093 185 1530 567 102 4 0 0 0 0
-Mode: 644
+Node 0, zone DMA 1 0 1 0 2 1 1 0 1 1 3
+Node 0, zone DMA32 759 572 791 475 194 45 12 0 0 0 0
+Node 0, zone Normal 4381 1093 185 1530 567 102 4 0 0 0 0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/crypto
+Lines: 971
+name : ccm(aes)
+driver : ccm_base(ctr(aes-aesni),cbcmac(aes-aesni))
+module : ccm
+priority : 300
+refcnt : 4
+selftest : passed
+internal : no
+type : aead
+async : no
+blocksize : 1
+ivsize : 16
+maxauthsize : 16
+geniv : <none>
+
+name : cbcmac(aes)
+driver : cbcmac(aes-aesni)
+module : ccm
+priority : 300
+refcnt : 7
+selftest : passed
+internal : no
+type : shash
+blocksize : 1
+digestsize : 16
+
+name : ecdh
+driver : ecdh-generic
+module : ecdh_generic
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : kpp
+
+name : ecb(arc4)
+driver : ecb(arc4)-generic
+module : arc4
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : skcipher
+async : no
+blocksize : 1
+min keysize : 1
+max keysize : 256
+ivsize : 0
+chunksize : 1
+walksize : 1
+
+name : arc4
+driver : arc4-generic
+module : arc4
+priority : 0
+refcnt : 3
+selftest : passed
+internal : no
+type : cipher
+blocksize : 1
+min keysize : 1
+max keysize : 256
+
+name : crct10dif
+driver : crct10dif-pclmul
+module : crct10dif_pclmul
+priority : 200
+refcnt : 2
+selftest : passed
+internal : no
+type : shash
+blocksize : 1
+digestsize : 2
+
+name : crc32
+driver : crc32-pclmul
+module : crc32_pclmul
+priority : 200
+refcnt : 1
+selftest : passed
+internal : no
+type : shash
+blocksize : 1
+digestsize : 4
+
+name : __ghash
+driver : cryptd(__ghash-pclmulqdqni)
+module : kernel
+priority : 50
+refcnt : 1
+selftest : passed
+internal : yes
+type : ahash
+async : yes
+blocksize : 16
+digestsize : 16
+
+name : ghash
+driver : ghash-clmulni
+module : ghash_clmulni_intel
+priority : 400
+refcnt : 1
+selftest : passed
+internal : no
+type : ahash
+async : yes
+blocksize : 16
+digestsize : 16
+
+name : __ghash
+driver : __ghash-pclmulqdqni
+module : ghash_clmulni_intel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : yes
+type : shash
+blocksize : 16
+digestsize : 16
+
+name : crc32c
+driver : crc32c-intel
+module : crc32c_intel
+priority : 200
+refcnt : 5
+selftest : passed
+internal : no
+type : shash
+blocksize : 1
+digestsize : 4
+
+name : cbc(aes)
+driver : cbc(aes-aesni)
+module : kernel
+priority : 300
+refcnt : 1
+selftest : passed
+internal : no
+type : skcipher
+async : no
+blocksize : 16
+min keysize : 16
+max keysize : 32
+ivsize : 16
+chunksize : 16
+walksize : 16
+
+name : ctr(aes)
+driver : ctr(aes-aesni)
+module : kernel
+priority : 300
+refcnt : 5
+selftest : passed
+internal : no
+type : skcipher
+async : no
+blocksize : 1
+min keysize : 16
+max keysize : 32
+ivsize : 16
+chunksize : 16
+walksize : 16
+
+name : pkcs1pad(rsa,sha256)
+driver : pkcs1pad(rsa-generic,sha256)
+module : kernel
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : akcipher
+
+name : __xts(aes)
+driver : cryptd(__xts-aes-aesni)
+module : kernel
+priority : 451
+refcnt : 1
+selftest : passed
+internal : yes
+type : skcipher
+async : yes
+blocksize : 16
+min keysize : 32
+max keysize : 64
+ivsize : 16
+chunksize : 16
+walksize : 16
+
+name : xts(aes)
+driver : xts-aes-aesni
+module : kernel
+priority : 401
+refcnt : 1
+selftest : passed
+internal : no
+type : skcipher
+async : yes
+blocksize : 16
+min keysize : 32
+max keysize : 64
+ivsize : 16
+chunksize : 16
+walksize : 16
+
+name : __ctr(aes)
+driver : cryptd(__ctr-aes-aesni)
+module : kernel
+priority : 450
+refcnt : 1
+selftest : passed
+internal : yes
+type : skcipher
+async : yes
+blocksize : 1
+min keysize : 16
+max keysize : 32
+ivsize : 16
+chunksize : 16
+walksize : 16
+
+name : ctr(aes)
+driver : ctr-aes-aesni
+module : kernel
+priority : 400
+refcnt : 1
+selftest : passed
+internal : no
+type : skcipher
+async : yes
+blocksize : 1
+min keysize : 16
+max keysize : 32
+ivsize : 16
+chunksize : 16
+walksize : 16
+
+name : __cbc(aes)
+driver : cryptd(__cbc-aes-aesni)
+module : kernel
+priority : 450
+refcnt : 1
+selftest : passed
+internal : yes
+type : skcipher
+async : yes
+blocksize : 16
+min keysize : 16
+max keysize : 32
+ivsize : 16
+chunksize : 16
+walksize : 16
+
+name : cbc(aes)
+driver : cbc-aes-aesni
+module : kernel
+priority : 400
+refcnt : 1
+selftest : passed
+internal : no
+type : skcipher
+async : yes
+blocksize : 16
+min keysize : 16
+max keysize : 32
+ivsize : 16
+chunksize : 16
+walksize : 16
+
+name : __ecb(aes)
+driver : cryptd(__ecb-aes-aesni)
+module : kernel
+priority : 450
+refcnt : 1
+selftest : passed
+internal : yes
+type : skcipher
+async : yes
+blocksize : 16
+min keysize : 16
+max keysize : 32
+ivsize : 0
+chunksize : 16
+walksize : 16
+
+name : ecb(aes)
+driver : ecb-aes-aesni
+module : kernel
+priority : 400
+refcnt : 1
+selftest : passed
+internal : no
+type : skcipher
+async : yes
+blocksize : 16
+min keysize : 16
+max keysize : 32
+ivsize : 0
+chunksize : 16
+walksize : 16
+
+name : __generic-gcm-aes-aesni
+driver : cryptd(__driver-generic-gcm-aes-aesni)
+module : kernel
+priority : 50
+refcnt : 1
+selftest : passed
+internal : yes
+type : aead
+async : yes
+blocksize : 1
+ivsize : 12
+maxauthsize : 16
+geniv : <none>
+
+name : gcm(aes)
+driver : generic-gcm-aesni
+module : kernel
+priority : 400
+refcnt : 1
+selftest : passed
+internal : no
+type : aead
+async : yes
+blocksize : 1
+ivsize : 12
+maxauthsize : 16
+geniv : <none>
+
+name : __generic-gcm-aes-aesni
+driver : __driver-generic-gcm-aes-aesni
+module : kernel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : yes
+type : aead
+async : no
+blocksize : 1
+ivsize : 12
+maxauthsize : 16
+geniv : <none>
+
+name : __gcm-aes-aesni
+driver : cryptd(__driver-gcm-aes-aesni)
+module : kernel
+priority : 50
+refcnt : 1
+selftest : passed
+internal : yes
+type : aead
+async : yes
+blocksize : 1
+ivsize : 8
+maxauthsize : 16
+geniv : <none>
+
+name : rfc4106(gcm(aes))
+driver : rfc4106-gcm-aesni
+module : kernel
+priority : 400
+refcnt : 1
+selftest : passed
+internal : no
+type : aead
+async : yes
+blocksize : 1
+ivsize : 8
+maxauthsize : 16
+geniv : <none>
+
+name : __gcm-aes-aesni
+driver : __driver-gcm-aes-aesni
+module : kernel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : yes
+type : aead
+async : no
+blocksize : 1
+ivsize : 8
+maxauthsize : 16
+geniv : <none>
+
+name : __xts(aes)
+driver : __xts-aes-aesni
+module : kernel
+priority : 401
+refcnt : 1
+selftest : passed
+internal : yes
+type : skcipher
+async : no
+blocksize : 16
+min keysize : 32
+max keysize : 64
+ivsize : 16
+chunksize : 16
+walksize : 16
+
+name : __ctr(aes)
+driver : __ctr-aes-aesni
+module : kernel
+priority : 400
+refcnt : 1
+selftest : passed
+internal : yes
+type : skcipher
+async : no
+blocksize : 1
+min keysize : 16
+max keysize : 32
+ivsize : 16
+chunksize : 16
+walksize : 16
+
+name : __cbc(aes)
+driver : __cbc-aes-aesni
+module : kernel
+priority : 400
+refcnt : 1
+selftest : passed
+internal : yes
+type : skcipher
+async : no
+blocksize : 16
+min keysize : 16
+max keysize : 32
+ivsize : 16
+chunksize : 16
+walksize : 16
+
+name : __ecb(aes)
+driver : __ecb-aes-aesni
+module : kernel
+priority : 400
+refcnt : 1
+selftest : passed
+internal : yes
+type : skcipher
+async : no
+blocksize : 16
+min keysize : 16
+max keysize : 32
+ivsize : 0
+chunksize : 16
+walksize : 16
+
+name : __aes
+driver : __aes-aesni
+module : kernel
+priority : 300
+refcnt : 1
+selftest : passed
+internal : yes
+type : cipher
+blocksize : 16
+min keysize : 16
+max keysize : 32
+
+name : aes
+driver : aes-aesni
+module : kernel
+priority : 300
+refcnt : 8
+selftest : passed
+internal : no
+type : cipher
+blocksize : 16
+min keysize : 16
+max keysize : 32
+
+name : hmac(sha1)
+driver : hmac(sha1-generic)
+module : kernel
+priority : 100
+refcnt : 9
+selftest : passed
+internal : no
+type : shash
+blocksize : 64
+digestsize : 20
+
+name : ghash
+driver : ghash-generic
+module : kernel
+priority : 100
+refcnt : 3
+selftest : passed
+internal : no
+type : shash
+blocksize : 16
+digestsize : 16
+
+name : jitterentropy_rng
+driver : jitterentropy_rng
+module : kernel
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_nopr_hmac_sha256
+module : kernel
+priority : 221
+refcnt : 2
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_nopr_hmac_sha512
+module : kernel
+priority : 220
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_nopr_hmac_sha384
+module : kernel
+priority : 219
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_nopr_hmac_sha1
+module : kernel
+priority : 218
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_nopr_sha256
+module : kernel
+priority : 217
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_nopr_sha512
+module : kernel
+priority : 216
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_nopr_sha384
+module : kernel
+priority : 215
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_nopr_sha1
+module : kernel
+priority : 214
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_nopr_ctr_aes256
+module : kernel
+priority : 213
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_nopr_ctr_aes192
+module : kernel
+priority : 212
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_nopr_ctr_aes128
+module : kernel
+priority : 211
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : hmac(sha256)
+driver : hmac(sha256-generic)
+module : kernel
+priority : 100
+refcnt : 10
+selftest : passed
+internal : no
+type : shash
+blocksize : 64
+digestsize : 32
+
+name : stdrng
+driver : drbg_pr_hmac_sha256
+module : kernel
+priority : 210
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_pr_hmac_sha512
+module : kernel
+priority : 209
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_pr_hmac_sha384
+module : kernel
+priority : 208
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_pr_hmac_sha1
+module : kernel
+priority : 207
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_pr_sha256
+module : kernel
+priority : 206
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_pr_sha512
+module : kernel
+priority : 205
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_pr_sha384
+module : kernel
+priority : 204
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_pr_sha1
+module : kernel
+priority : 203
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_pr_ctr_aes256
+module : kernel
+priority : 202
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_pr_ctr_aes192
+module : kernel
+priority : 201
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : stdrng
+driver : drbg_pr_ctr_aes128
+module : kernel
+priority : 200
+refcnt : 1
+selftest : passed
+internal : no
+type : rng
+seedsize : 0
+
+name : 842
+driver : 842-scomp
+module : kernel
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : scomp
+
+name : 842
+driver : 842-generic
+module : kernel
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : compression
+
+name : lzo-rle
+driver : lzo-rle-scomp
+module : kernel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : no
+type : scomp
+
+name : lzo-rle
+driver : lzo-rle-generic
+module : kernel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : no
+type : compression
+
+name : lzo
+driver : lzo-scomp
+module : kernel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : no
+type : scomp
+
+name : lzo
+driver : lzo-generic
+module : kernel
+priority : 0
+refcnt : 9
+selftest : passed
+internal : no
+type : compression
+
+name : crct10dif
+driver : crct10dif-generic
+module : kernel
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : shash
+blocksize : 1
+digestsize : 2
+
+name : crc32c
+driver : crc32c-generic
+module : kernel
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : shash
+blocksize : 1
+digestsize : 4
+
+name : zlib-deflate
+driver : zlib-deflate-scomp
+module : kernel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : no
+type : scomp
+
+name : deflate
+driver : deflate-scomp
+module : kernel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : no
+type : scomp
+
+name : deflate
+driver : deflate-generic
+module : kernel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : no
+type : compression
+
+name : aes
+driver : aes-generic
+module : kernel
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : cipher
+blocksize : 16
+min keysize : 16
+max keysize : 32
+
+name : sha224
+driver : sha224-generic
+module : kernel
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : shash
+blocksize : 64
+digestsize : 28
+
+name : sha256
+driver : sha256-generic
+module : kernel
+priority : 100
+refcnt : 11
+selftest : passed
+internal : no
+type : shash
+blocksize : 64
+digestsize : 32
+
+name : sha1
+driver : sha1-generic
+module : kernel
+priority : 100
+refcnt : 11
+selftest : passed
+internal : no
+type : shash
+blocksize : 64
+digestsize : 20
+
+name : md5
+driver : md5-generic
+module : kernel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : no
+type : shash
+blocksize : 64
+digestsize : 16
+
+name : ecb(cipher_null)
+driver : ecb-cipher_null
+module : kernel
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : skcipher
+async : no
+blocksize : 1
+min keysize : 0
+max keysize : 0
+ivsize : 0
+chunksize : 1
+walksize : 1
+
+name : digest_null
+driver : digest_null-generic
+module : kernel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : no
+type : shash
+blocksize : 1
+digestsize : 0
+
+name : compress_null
+driver : compress_null-generic
+module : kernel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : no
+type : compression
+
+name : cipher_null
+driver : cipher_null-generic
+module : kernel
+priority : 0
+refcnt : 1
+selftest : passed
+internal : no
+type : cipher
+blocksize : 1
+min keysize : 0
+max keysize : 0
+
+name : rsa
+driver : rsa-generic
+module : kernel
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : akcipher
+
+name : dh
+driver : dh-generic
+module : kernel
+priority : 100
+refcnt : 1
+selftest : passed
+internal : no
+type : kpp
+
+name : aes
+driver : aes-asm
+module : kernel
+priority : 200
+refcnt : 1
+selftest : passed
+internal : no
+type : cipher
+blocksize : 16
+min keysize : 16
+max keysize : 32
+
+Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/diskstats
Lines: 49
@@ -298,38 +1395,74 @@ debug 0
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/mdstat
-Lines: 26
+Lines: 56
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
-md3 : active raid6 sda1[8] sdh1[7] sdg1[6] sdf1[5] sde1[11] sdd1[3] sdc1[10] sdb1[9]
+
+md3 : active raid6 sda1[8] sdh1[7] sdg1[6] sdf1[5] sde1[11] sdd1[3] sdc1[10] sdb1[9] sdd1[10](S) sdd2[11](S)
5853468288 blocks super 1.2 level 6, 64k chunk, algorithm 2 [8/8] [UUUUUUUU]
-
+
md127 : active raid1 sdi2[0] sdj2[1]
312319552 blocks [2/2] [UU]
-
-md0 : active raid1 sdk[2](S) sdi1[0] sdj1[1]
+
+md0 : active raid1 sdi1[0] sdj1[1]
248896 blocks [2/2] [UU]
-
-md4 : inactive raid1 sda3[0] sdb3[1]
+
+md4 : inactive raid1 sda3[0](F) sdb3[1](S)
4883648 blocks [2/2] [UU]
-md6 : active raid1 sdb2[2] sda2[0]
+md6 : active raid1 sdb2[2](F) sdc[1](S) sda2[0]
195310144 blocks [2/1] [U_]
[=>...................] recovery = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec
-md8 : active raid1 sdb1[1] sda1[0]
+md8 : active raid1 sdb1[1] sda1[0] sdc[2](S) sde[3](S)
195310144 blocks [2/2] [UU]
[=>...................] resync = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec
-md7 : active raid6 sdb1[0] sde1[3] sdd1[2] sdc1[1]
+md7 : active raid6 sdb1[0] sde1[3] sdd1[2] sdc1[1](F)
7813735424 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/3] [U_UU]
bitmap: 0/30 pages [0KB], 65536KB chunk
+md9 : active raid1 sdc2[2] sdd2[3] sdb2[1] sda2[0] sde[4](F) sdf[5](F) sdg[6](S)
+ 523968 blocks super 1.2 [4/4] [UUUU]
+ resync=DELAYED
+
+md10 : active raid0 sda1[0] sdb1[1]
+ 314159265 blocks 64k chunks
+
+md11 : active (auto-read-only) raid1 sdb2[0] sdc2[1] sdc3[2](F) hda[4](S) ssdc2[3](S)
+ 4190208 blocks super 1.2 [2/2] [UU]
+ resync=PENDING
+
+md12 : active raid0 sdc2[0] sdd2[1]
+ 3886394368 blocks super 1.2 512k chunks
+
+md126 : active raid0 sdb[1] sdc[0]
+ 1855870976 blocks super external:/md127/0 128k chunks
+
+md219 : inactive sdb[2](S) sdc[1](S) sda[0](S)
+ 7932 blocks super external:imsm
+
+md00 : active raid0 xvdb[0]
+ 4186624 blocks super 1.2 256k chunks
+
+md120 : active linear sda1[1] sdb1[0]
+ 2095104 blocks super 1.2 0k rounding
+
+md101 : active (read-only) raid0 sdb[2] sdd[1] sdc[0]
+ 322560 blocks super 1.2 512k chunks
+
unused devices: <none>
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/proc/net
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/net/arp
+Lines: 2
+IP address HW type Flags HW address Mask Device
+192.168.224.1 0x1 0x2 00:50:56:c0:00:08 * ens33
+Mode: 664
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/net/dev
Lines: 6
Inter-| Receive | Transmit
@@ -402,6 +1535,31 @@ proc4 2 2 10853
proc4ops 72 0 0 0 1098 2 0 0 0 0 8179 5896 0 0 0 0 5900 0 0 2 0 2 0 9609 0 2 150 1272 0 0 0 1236 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/net/softnet_stat
+Lines: 1
+00015c73 00020e76 F0000769 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/net/unix
+Lines: 6
+Num RefCount Protocol Flags Type St Inode Path
+0000000000000000: 00000002 00000000 00010000 0001 01 3442596 /var/run/postgresql/.s.PGSQL.5432
+0000000000000000: 0000000a 00000000 00010000 0005 01 10061 /run/udev/control
+0000000000000000: 00000007 00000000 00000000 0002 01 12392 /dev/log
+0000000000000000: 00000003 00000000 00000000 0001 03 4787297 /var/run/postgresql/.s.PGSQL.5432
+0000000000000000: 00000003 00000000 00000000 0001 03 5091797
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/net/unix_without_inode
+Lines: 6
+Num RefCount Protocol Flags Type St Path
+0000000000000000: 00000002 00000000 00010000 0001 01 /var/run/postgresql/.s.PGSQL.5432
+0000000000000000: 0000000a 00000000 00010000 0005 01 /run/udev/control
+0000000000000000: 00000007 00000000 00000000 0002 01 /dev/log
+0000000000000000: 00000003 00000000 00000000 0001 03 /var/run/postgresql/.s.PGSQL.5432
+0000000000000000: 00000003 00000000 00000000 0001 03
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/net/xfrm_stat
Lines: 28
XfrmInError 1
@@ -454,6 +1612,16 @@ some avg10=0.10 avg60=2.00 avg300=3.85 total=15
full avg10=0.20 avg60=3.00 avg300=4.95 total=25
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/schedstat
+Lines: 6
+version 15
+timestamp 15819019232
+cpu0 498494191 0 3533438552 2553969831 3853684107 2465731542 2045936778163039 343796328169361 4767485306
+domain0 00000000,00000003 212499247 210112015 1861015 1860405436 536440 369895 32599 210079416 25368550 24241256 384652 927363878 807233 6366 1647 24239609 2122447165 1886868564 121112060 2848625533 125678146 241025 1032026 1885836538 2545 12 2533 0 0 0 0 0 0 1387952561 21076581 0
+cpu1 518377256 0 4155211005 2778589869 10466382 2867629021 1904686152592476 364107263788241 5145567945
+domain0 00000000,00000003 217653037 215526982 1577949 1580427380 557469 393576 28538 215498444 28721913 27662819 371153 870843407 745912 5523 1639 27661180 2331056874 2107732788 111442342 652402556 123615235 196159 1045245 2106687543 2400 3 2397 0 0 0 0 0 0 1437804657 26220076 0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/self
SymlinkTo: 26231
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -506,6 +1674,493 @@ Path: fixtures/proc/symlinktargets/xyz
Lines: 0
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/proc/sys
+Mode: 775
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/proc/sys/vm
+Mode: 775
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/admin_reserve_kbytes
+Lines: 1
+8192
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/block_dump
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/compact_unevictable_allowed
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/dirty_background_bytes
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/dirty_background_ratio
+Lines: 1
+10
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/dirty_bytes
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/dirty_expire_centisecs
+Lines: 1
+3000
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/dirty_ratio
+Lines: 1
+20
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/dirty_writeback_centisecs
+Lines: 1
+500
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/dirtytime_expire_seconds
+Lines: 1
+43200
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/drop_caches
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/extfrag_threshold
+Lines: 1
+500
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/hugetlb_shm_group
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/laptop_mode
+Lines: 1
+5
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/legacy_va_layout
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/lowmem_reserve_ratio
+Lines: 1
+256 256 32 0 0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/max_map_count
+Lines: 1
+65530
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/memory_failure_early_kill
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/memory_failure_recovery
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/min_free_kbytes
+Lines: 1
+67584
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/min_slab_ratio
+Lines: 1
+5
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/min_unmapped_ratio
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/mmap_min_addr
+Lines: 1
+65536
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/nr_hugepages
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/nr_hugepages_mempolicy
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/nr_overcommit_hugepages
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/numa_stat
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/numa_zonelist_order
+Lines: 1
+Node
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/oom_dump_tasks
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/oom_kill_allocating_task
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/overcommit_kbytes
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/overcommit_memory
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/overcommit_ratio
+Lines: 1
+50
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/page-cluster
+Lines: 1
+3
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/panic_on_oom
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/percpu_pagelist_fraction
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/stat_interval
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/swappiness
+Lines: 1
+60
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/user_reserve_kbytes
+Lines: 1
+131072
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/vfs_cache_pressure
+Lines: 1
+100
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/watermark_boost_factor
+Lines: 1
+15000
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/watermark_scale_factor
+Lines: 1
+10
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/vm/zone_reclaim_mode
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/zoneinfo
+Lines: 262
+Node 0, zone DMA
+ per-node stats
+ nr_inactive_anon 230981
+ nr_active_anon 547580
+ nr_inactive_file 316904
+ nr_active_file 346282
+ nr_unevictable 115467
+ nr_slab_reclaimable 131220
+ nr_slab_unreclaimable 47320
+ nr_isolated_anon 0
+ nr_isolated_file 0
+ workingset_nodes 11627
+ workingset_refault 466886
+ workingset_activate 276925
+ workingset_restore 84055
+ workingset_nodereclaim 487
+ nr_anon_pages 795576
+ nr_mapped 215483
+ nr_file_pages 761874
+ nr_dirty 908
+ nr_writeback 0
+ nr_writeback_temp 0
+ nr_shmem 224925
+ nr_shmem_hugepages 0
+ nr_shmem_pmdmapped 0
+ nr_anon_transparent_hugepages 0
+ nr_unstable 0
+ nr_vmscan_write 12950
+ nr_vmscan_immediate_reclaim 3033
+ nr_dirtied 8007423
+ nr_written 7752121
+ nr_kernel_misc_reclaimable 0
+ pages free 3952
+ min 33
+ low 41
+ high 49
+ spanned 4095
+ present 3975
+ managed 3956
+ protection: (0, 2877, 7826, 7826, 7826)
+ nr_free_pages 3952
+ nr_zone_inactive_anon 0
+ nr_zone_active_anon 0
+ nr_zone_inactive_file 0
+ nr_zone_active_file 0
+ nr_zone_unevictable 0
+ nr_zone_write_pending 0
+ nr_mlock 0
+ nr_page_table_pages 0
+ nr_kernel_stack 0
+ nr_bounce 0
+ nr_zspages 0
+ nr_free_cma 0
+ numa_hit 1
+ numa_miss 0
+ numa_foreign 0
+ numa_interleave 0
+ numa_local 1
+ numa_other 0
+ pagesets
+ cpu: 0
+ count: 0
+ high: 0
+ batch: 1
+ vm stats threshold: 8
+ cpu: 1
+ count: 0
+ high: 0
+ batch: 1
+ vm stats threshold: 8
+ cpu: 2
+ count: 0
+ high: 0
+ batch: 1
+ vm stats threshold: 8
+ cpu: 3
+ count: 0
+ high: 0
+ batch: 1
+ vm stats threshold: 8
+ cpu: 4
+ count: 0
+ high: 0
+ batch: 1
+ vm stats threshold: 8
+ cpu: 5
+ count: 0
+ high: 0
+ batch: 1
+ vm stats threshold: 8
+ cpu: 6
+ count: 0
+ high: 0
+ batch: 1
+ vm stats threshold: 8
+ cpu: 7
+ count: 0
+ high: 0
+ batch: 1
+ vm stats threshold: 8
+ node_unreclaimable: 0
+ start_pfn: 1
+Node 0, zone DMA32
+ pages free 204252
+ min 19510
+ low 21059
+ high 22608
+ spanned 1044480
+ present 759231
+ managed 742806
+ protection: (0, 0, 4949, 4949, 4949)
+ nr_free_pages 204252
+ nr_zone_inactive_anon 118558
+ nr_zone_active_anon 106598
+ nr_zone_inactive_file 75475
+ nr_zone_active_file 70293
+ nr_zone_unevictable 66195
+ nr_zone_write_pending 64
+ nr_mlock 4
+ nr_page_table_pages 1756
+ nr_kernel_stack 2208
+ nr_bounce 0
+ nr_zspages 0
+ nr_free_cma 0
+ numa_hit 113952967
+ numa_miss 0
+ numa_foreign 0
+ numa_interleave 0
+ numa_local 113952967
+ numa_other 0
+ pagesets
+ cpu: 0
+ count: 345
+ high: 378
+ batch: 63
+ vm stats threshold: 48
+ cpu: 1
+ count: 356
+ high: 378
+ batch: 63
+ vm stats threshold: 48
+ cpu: 2
+ count: 325
+ high: 378
+ batch: 63
+ vm stats threshold: 48
+ cpu: 3
+ count: 346
+ high: 378
+ batch: 63
+ vm stats threshold: 48
+ cpu: 4
+ count: 321
+ high: 378
+ batch: 63
+ vm stats threshold: 48
+ cpu: 5
+ count: 316
+ high: 378
+ batch: 63
+ vm stats threshold: 48
+ cpu: 6
+ count: 373
+ high: 378
+ batch: 63
+ vm stats threshold: 48
+ cpu: 7
+ count: 339
+ high: 378
+ batch: 63
+ vm stats threshold: 48
+ node_unreclaimable: 0
+ start_pfn: 4096
+Node 0, zone Normal
+ pages free 18553
+ min 11176
+ low 13842
+ high 16508
+ spanned 1308160
+ present 1308160
+ managed 1268711
+ protection: (0, 0, 0, 0, 0)
+ nr_free_pages 18553
+ nr_zone_inactive_anon 112423
+ nr_zone_active_anon 440982
+ nr_zone_inactive_file 241429
+ nr_zone_active_file 275989
+ nr_zone_unevictable 49272
+ nr_zone_write_pending 844
+ nr_mlock 154
+ nr_page_table_pages 9750
+ nr_kernel_stack 15136
+ nr_bounce 0
+ nr_zspages 0
+ nr_free_cma 0
+ numa_hit 162718019
+ numa_miss 0
+ numa_foreign 0
+ numa_interleave 26812
+ numa_local 162718019
+ numa_other 0
+ pagesets
+ cpu: 0
+ count: 316
+ high: 378
+ batch: 63
+ vm stats threshold: 56
+ cpu: 1
+ count: 366
+ high: 378
+ batch: 63
+ vm stats threshold: 56
+ cpu: 2
+ count: 60
+ high: 378
+ batch: 63
+ vm stats threshold: 56
+ cpu: 3
+ count: 256
+ high: 378
+ batch: 63
+ vm stats threshold: 56
+ cpu: 4
+ count: 253
+ high: 378
+ batch: 63
+ vm stats threshold: 56
+ cpu: 5
+ count: 159
+ high: 378
+ batch: 63
+ vm stats threshold: 56
+ cpu: 6
+ count: 311
+ high: 378
+ batch: 63
+ vm stats threshold: 56
+ cpu: 7
+ count: 264
+ high: 378
+ batch: 63
+ vm stats threshold: 56
+ node_unreclaimable: 0
+ start_pfn: 1048576
+Node 0, zone Movable
+ pages free 0
+ min 0
+ low 0
+ high 0
+ spanned 0
+ present 0
+ managed 0
+ protection: (0, 0, 0, 0, 0)
+Node 0, zone Device
+ pages free 0
+ min 0
+ low 0
+ high 0
+ spanned 0
+ present 0
+ managed 0
+ protection: (0, 0, 0, 0, 0)
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -531,6 +2186,232 @@ Mode: 664
Directory: fixtures/sys/class
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/infiniband
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/infiniband/mlx4_0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/board_id
+Lines: 1
+SM_1141000001000
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/fw_ver
+Lines: 1
+2.31.5050
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/hca_type
+Lines: 1
+MT4099
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/infiniband/mlx4_0/ports
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/infiniband/mlx4_0/ports/1
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/excessive_buffer_overrun_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/link_downed
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/link_error_recovery
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/local_link_integrity_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_constraint_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_data
+Lines: 1
+2221223609
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_packets
+Lines: 1
+87169372
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_remote_physical_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_switch_relay_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_constraint_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_data
+Lines: 1
+26509113295
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_discards
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_packets
+Lines: 1
+85734114
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_wait
+Lines: 1
+3599
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/symbol_error
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/phys_state
+Lines: 1
+5: LinkUp
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/rate
+Lines: 1
+40 Gb/sec (4X QDR)
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/state
+Lines: 1
+4: ACTIVE
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/infiniband/mlx4_0/ports/2
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/excessive_buffer_overrun_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/link_downed
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/link_error_recovery
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/local_link_integrity_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_constraint_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_data
+Lines: 1
+2460436784
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_packets
+Lines: 1
+89332064
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_remote_physical_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_switch_relay_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_constraint_errors
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_data
+Lines: 1
+26540356890
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_discards
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_packets
+Lines: 1
+88622850
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_wait
+Lines: 1
+3846
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/symbol_error
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/phys_state
+Lines: 1
+5: LinkUp
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/rate
+Lines: 1
+40 Gb/sec (4X QDR)
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/state
+Lines: 1
+4: ACTIVE
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/class/net
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -806,6 +2687,42 @@ Mode: 444
Directory: fixtures/sys/class/thermal
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/thermal/cooling_device0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/thermal/cooling_device0/cur_state
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/thermal/cooling_device0/max_state
+Lines: 1
+50
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/thermal/cooling_device0/type
+Lines: 1
+Processor
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/thermal/cooling_device1
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/thermal/cooling_device1/cur_state
+Lines: 1
+-1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/thermal/cooling_device1/max_state
+Lines: 1
+27
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/thermal/cooling_device1/type
+Lines: 1
+intel_powerclamp
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/class/thermal/thermal_zone0
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1104,9 +3021,54 @@ Lines: 1
0
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/devices/rbd
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/devices/rbd/0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/devices/rbd/0/name
+Lines: 1
+demo
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/devices/rbd/0/pool
+Lines: 1
+iscsi-images
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/devices/rbd/1
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/devices/rbd/1/name
+Lines: 1
+wrong
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/devices/rbd/1/pool
+Lines: 1
+wrong-images
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/devices/system
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/devices/system/clocksource
+Mode: 775
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/devices/system/clocksource/clocksource0
+Mode: 775
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/devices/system/clocksource/clocksource0/available_clocksource
+Lines: 1
+tsc hpet acpi_pm
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/devices/system/clocksource/clocksource0/current_clocksource
+Lines: 1
+tsc
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/devices/system/cpu
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1712,3 +3674,248 @@ Lines: 1
extent_alloc 2 0 0 0
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/core
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/core/fileio_0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/core/fileio_1
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/core/fileio_1/file_lio_1G
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/core/fileio_1/file_lio_1G/enable
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/core/fileio_1/file_lio_1G/udev_path
+Lines: 1
+/home/iscsi/file_back_1G
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/core/iblock_0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/core/iblock_0/block_lio_rbd1
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/core/iblock_0/block_lio_rbd1/enable
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/core/iblock_0/block_lio_rbd1/udev_path
+Lines: 1
+/dev/rbd1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/core/rbd_0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/core/rbd_0/iscsi-images-demo
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/core/rbd_0/iscsi-images-demo/enable
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/core/rbd_0/iscsi-images-demo/udev_path
+Lines: 1
+/dev/rbd/iscsi-images/demo
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/core/rd_mcp_119
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/core/rd_mcp_119/ramdisk_lio_1G
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/core/rd_mcp_119/ramdisk_lio_1G/enable
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/core/rd_mcp_119/ramdisk_lio_1G/udev_path
+Lines: 0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/enable
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/7f4a4eb56d
+SymlinkTo: ../../../../../../target/core/rd_mcp_119/ramdisk_lio_1G
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/in_cmds
+Lines: 1
+204950
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/read_mbytes
+Lines: 1
+10325
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/write_mbytes
+Lines: 1
+40325
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/enable
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/795b7c7026
+SymlinkTo: ../../../../../../target/core/iblock_0/block_lio_rbd1
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics/scsi_tgt_port
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/in_cmds
+Lines: 1
+104950
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/read_mbytes
+Lines: 1
+20095
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/write_mbytes
+Lines: 1
+71235
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/enable
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/fff5e16686
+SymlinkTo: ../../../../../../target/core/fileio_1/file_lio_1G
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/in_cmds
+Lines: 1
+301950
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/read_mbytes
+Lines: 1
+10195
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/write_mbytes
+Lines: 1
+30195
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/enable
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/eba1edf893
+SymlinkTo: ../../../../../../target/core/rbd_0/iscsi-images-demo
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics/scsi_tgt_port
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/in_cmds
+Lines: 1
+1234
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/read_mbytes
+Lines: 1
+1504
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/write_mbytes
+Lines: 1
+4733
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/vendor/github.com/prometheus/procfs/fs.go b/vendor/github.com/prometheus/procfs/fs.go
index 9c56c83954..0102ab0fd8 100644
--- a/vendor/github.com/prometheus/procfs/fs.go
+++ b/vendor/github.com/prometheus/procfs/fs.go
@@ -26,8 +26,14 @@ type FS struct {
// DefaultMountPoint is the common mount point of the proc filesystem.
const DefaultMountPoint = fs.DefaultProcMountPoint
+// NewDefaultFS returns a new proc FS mounted under the default proc mountPoint.
+// It will error if the mount point directory can't be read or is a file.
+func NewDefaultFS() (FS, error) {
+ return NewFS(DefaultMountPoint)
+}
+
// NewFS returns a new proc FS mounted under the given proc mountPoint. It will error
-// if the mount point dirctory can't be read or is a file.
+// if the mount point directory can't be read or is a file.
func NewFS(mountPoint string) (FS, error) {
fs, err := fs.NewFS(mountPoint)
if err != nil {
diff --git a/vendor/github.com/prometheus/procfs/go.mod b/vendor/github.com/prometheus/procfs/go.mod
index 8a1b839fd2..b2f8cca933 100644
--- a/vendor/github.com/prometheus/procfs/go.mod
+++ b/vendor/github.com/prometheus/procfs/go.mod
@@ -1,3 +1,6 @@
module github.com/prometheus/procfs
-require golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4
+require (
+ github.com/google/go-cmp v0.3.0
+ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4
+)
diff --git a/vendor/github.com/prometheus/procfs/go.sum b/vendor/github.com/prometheus/procfs/go.sum
index 7827dd3d56..db54133d7c 100644
--- a/vendor/github.com/prometheus/procfs/go.sum
+++ b/vendor/github.com/prometheus/procfs/go.sum
@@ -1,2 +1,4 @@
+github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
diff --git a/vendor/github.com/prometheus/procfs/internal/fs/fs.go b/vendor/github.com/prometheus/procfs/internal/fs/fs.go
index c66a1cf80e..7ddfd6b6ed 100644
--- a/vendor/github.com/prometheus/procfs/internal/fs/fs.go
+++ b/vendor/github.com/prometheus/procfs/internal/fs/fs.go
@@ -25,6 +25,9 @@ const (
// DefaultSysMountPoint is the common mount point of the sys filesystem.
DefaultSysMountPoint = "/sys"
+
+ // DefaultConfigfsMountPoint is the commont mount point of the configfs
+ DefaultConfigfsMountPoint = "/sys/kernel/config"
)
// FS represents a pseudo-filesystem, normally /proc or /sys, which provides an
diff --git a/vendor/github.com/prometheus/procfs/internal/util/parse.go b/vendor/github.com/prometheus/procfs/internal/util/parse.go
new file mode 100644
index 0000000000..755591d9a5
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/internal/util/parse.go
@@ -0,0 +1,88 @@
+// 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
+}
diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go
new file mode 100644
index 0000000000..68b37c4b3c
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go
@@ -0,0 +1,45 @@
+// 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
+}
diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go
new file mode 100644
index 0000000000..bd55b45377
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go
@@ -0,0 +1,26 @@
+// 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")
+}
diff --git a/vendor/github.com/prometheus/procfs/internal/util/valueparser.go b/vendor/github.com/prometheus/procfs/internal/util/valueparser.go
new file mode 100644
index 0000000000..ac93cb42d2
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/internal/util/valueparser.go
@@ -0,0 +1,77 @@
+// 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
+}
diff --git a/vendor/github.com/prometheus/procfs/ipvs.go b/vendor/github.com/prometheus/procfs/ipvs.go
index 41e645d23e..2d6cb8d1c6 100644
--- a/vendor/github.com/prometheus/procfs/ipvs.go
+++ b/vendor/github.com/prometheus/procfs/ipvs.go
@@ -62,18 +62,8 @@ type IPVSBackendStatus struct {
Weight uint64
}
-// NewIPVSStats reads the IPVS statistics.
-func NewIPVSStats() (IPVSStats, error) {
- fs, err := NewFS(DefaultMountPoint)
- if err != nil {
- return IPVSStats{}, err
- }
-
- return fs.NewIPVSStats()
-}
-
-// NewIPVSStats reads the IPVS statistics from the specified `proc` filesystem.
-func (fs FS) NewIPVSStats() (IPVSStats, error) {
+// IPVSStats reads the IPVS statistics from the specified `proc` filesystem.
+func (fs FS) IPVSStats() (IPVSStats, error) {
file, err := os.Open(fs.proc.Path("net/ip_vs_stats"))
if err != nil {
return IPVSStats{}, err
@@ -131,18 +121,8 @@ func parseIPVSStats(file io.Reader) (IPVSStats, error) {
return stats, nil
}
-// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs.
-func NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
- fs, err := NewFS(DefaultMountPoint)
- if err != nil {
- return []IPVSBackendStatus{}, err
- }
-
- return fs.NewIPVSBackendStatus()
-}
-
-// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
-func (fs FS) NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
+// IPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
+func (fs FS) IPVSBackendStatus() ([]IPVSBackendStatus, error) {
file, err := os.Open(fs.proc.Path("net/ip_vs"))
if err != nil {
return nil, err
diff --git a/vendor/github.com/prometheus/procfs/mdstat.go b/vendor/github.com/prometheus/procfs/mdstat.go
index 6ac7a12f97..2af3ada180 100644
--- a/vendor/github.com/prometheus/procfs/mdstat.go
+++ b/vendor/github.com/prometheus/procfs/mdstat.go
@@ -22,8 +22,8 @@ import (
)
var (
- statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`)
- buildlineRE = regexp.MustCompile(`\((\d+)/\d+\)`)
+ statusLineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`)
+ recoveryLineRE = regexp.MustCompile(`\((\d+)/\d+\)`)
)
// MDStat holds info parsed from /proc/mdstat.
@@ -34,117 +34,160 @@ type MDStat struct {
ActivityState string
// Number of active disks.
DisksActive int64
- // Total number of disks the device consists of.
+ // Total number of disks the device requires.
DisksTotal int64
+ // Number of failed disks.
+ DisksFailed int64
+ // Spare disks in the device.
+ DisksSpare int64
// Number of blocks the device holds.
BlocksTotal int64
// Number of blocks on the device that are in sync.
BlocksSynced int64
}
-// ParseMDStat parses an mdstat-file and returns a struct with the relevant infos.
-func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
- mdStatusFilePath := fs.proc.Path("mdstat")
- content, err := ioutil.ReadFile(mdStatusFilePath)
+// MDStat parses an mdstat-file (/proc/mdstat) and returns a slice of
+// structs containing the relevant info. More information available here:
+// https://raid.wiki.kernel.org/index.php/Mdstat
+func (fs FS) MDStat() ([]MDStat, error) {
+ data, err := ioutil.ReadFile(fs.proc.Path("mdstat"))
if err != nil {
- return []MDStat{}, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
+ return nil, fmt.Errorf("error parsing mdstat %s: %s", fs.proc.Path("mdstat"), err)
}
+ mdstat, err := parseMDStat(data)
+ if err != nil {
+ return nil, fmt.Errorf("error parsing mdstat %s: %s", fs.proc.Path("mdstat"), err)
+ }
+ return mdstat, nil
+}
- mdStates := []MDStat{}
- lines := strings.Split(string(content), "\n")
- for i, l := range lines {
- if l == "" {
- continue
- }
- if l[0] == ' ' {
- continue
- }
- if strings.HasPrefix(l, "Personalities") || strings.HasPrefix(l, "unused") {
+// parseMDStat parses data from mdstat file (/proc/mdstat) and returns a slice of
+// structs containing the relevant info.
+func parseMDStat(mdStatData []byte) ([]MDStat, error) {
+ mdStats := []MDStat{}
+ lines := strings.Split(string(mdStatData), "\n")
+
+ for i, line := range lines {
+ if strings.TrimSpace(line) == "" || line[0] == ' ' ||
+ strings.HasPrefix(line, "Personalities") ||
+ strings.HasPrefix(line, "unused") {
continue
}
- mainLine := strings.Split(l, " ")
- if len(mainLine) < 3 {
- return mdStates, fmt.Errorf("error parsing mdline: %s", l)
+ deviceFields := strings.Fields(line)
+ if len(deviceFields) < 3 {
+ return nil, fmt.Errorf("not enough fields in mdline (expected at least 3): %s", line)
}
- mdName := mainLine[0]
- activityState := mainLine[2]
+ mdName := deviceFields[0] // mdx
+ state := deviceFields[2] // active or inactive
if len(lines) <= i+3 {
- return mdStates, fmt.Errorf(
- "error parsing %s: too few lines for md device %s",
- mdStatusFilePath,
+ return nil, fmt.Errorf(
+ "error parsing %s: too few lines for md device",
mdName,
)
}
- active, total, size, err := evalStatusline(lines[i+1])
+ // Failed disks have the suffix (F) & Spare disks have the suffix (S).
+ fail := int64(strings.Count(line, "(F)"))
+ spare := int64(strings.Count(line, "(S)"))
+ active, total, size, err := evalStatusLine(lines[i], lines[i+1])
+
if err != nil {
- return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
+ return nil, fmt.Errorf("error parsing md device lines: %s", err)
}
- // j is the line number of the syncing-line.
- j := i + 2
+ syncLineIdx := i + 2
if strings.Contains(lines[i+2], "bitmap") { // skip bitmap line
- j = i + 3
+ syncLineIdx++
}
// If device is syncing at the moment, get the number of currently
// synced bytes, otherwise that number equals the size of the device.
syncedBlocks := size
- if strings.Contains(lines[j], "recovery") || strings.Contains(lines[j], "resync") {
- syncedBlocks, err = evalBuildline(lines[j])
- if err != nil {
- return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
+ recovering := strings.Contains(lines[syncLineIdx], "recovery")
+ resyncing := strings.Contains(lines[syncLineIdx], "resync")
+
+ // Append recovery and resyncing state info.
+ if recovering || resyncing {
+ if recovering {
+ state = "recovering"
+ } else {
+ state = "resyncing"
+ }
+
+ // Handle case when resync=PENDING or resync=DELAYED.
+ if strings.Contains(lines[syncLineIdx], "PENDING") ||
+ strings.Contains(lines[syncLineIdx], "DELAYED") {
+ syncedBlocks = 0
+ } else {
+ syncedBlocks, err = evalRecoveryLine(lines[syncLineIdx])
+ if err != nil {
+ return nil, fmt.Errorf("error parsing sync line in md device %s: %s", mdName, err)
+ }
}
}
- mdStates = append(mdStates, MDStat{
+ mdStats = append(mdStats, MDStat{
Name: mdName,
- ActivityState: activityState,
+ ActivityState: state,
DisksActive: active,
+ DisksFailed: fail,
+ DisksSpare: spare,
DisksTotal: total,
BlocksTotal: size,
BlocksSynced: syncedBlocks,
})
}
- return mdStates, nil
+ return mdStats, nil
}
-func evalStatusline(statusline string) (active, total, size int64, err error) {
- matches := statuslineRE.FindStringSubmatch(statusline)
- if len(matches) != 4 {
- return 0, 0, 0, fmt.Errorf("unexpected statusline: %s", statusline)
- }
+func evalStatusLine(deviceLine, statusLine string) (active, total, size int64, err error) {
- size, err = strconv.ParseInt(matches[1], 10, 64)
+ sizeStr := strings.Fields(statusLine)[0]
+ size, err = strconv.ParseInt(sizeStr, 10, 64)
if err != nil {
- return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
+ return 0, 0, 0, fmt.Errorf("unexpected statusLine %s: %s", statusLine, err)
+ }
+
+ if strings.Contains(deviceLine, "raid0") || strings.Contains(deviceLine, "linear") {
+ // In the device deviceLine, only disks have a number associated with them in [].
+ total = int64(strings.Count(deviceLine, "["))
+ return total, total, size, nil
+ }
+
+ if strings.Contains(deviceLine, "inactive") {
+ return 0, 0, size, nil
+ }
+
+ matches := statusLineRE.FindStringSubmatch(statusLine)
+ if len(matches) != 4 {
+ return 0, 0, 0, fmt.Errorf("couldn't find all the substring matches: %s", statusLine)
}
total, err = strconv.ParseInt(matches[2], 10, 64)
if err != nil {
- return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
+ return 0, 0, 0, fmt.Errorf("unexpected statusLine %s: %s", statusLine, err)
}
active, err = strconv.ParseInt(matches[3], 10, 64)
if err != nil {
- return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
+ return 0, 0, 0, fmt.Errorf("unexpected statusLine %s: %s", statusLine, err)
}
return active, total, size, nil
}
-func evalBuildline(buildline string) (syncedBlocks int64, err error) {
- matches := buildlineRE.FindStringSubmatch(buildline)
+func evalRecoveryLine(recoveryLine string) (syncedBlocks int64, err error) {
+ matches := recoveryLineRE.FindStringSubmatch(recoveryLine)
if len(matches) != 2 {
- return 0, fmt.Errorf("unexpected buildline: %s", buildline)
+ return 0, fmt.Errorf("unexpected recoveryLine: %s", recoveryLine)
}
syncedBlocks, err = strconv.ParseInt(matches[1], 10, 64)
if err != nil {
- return 0, fmt.Errorf("%s in buildline: %s", err, buildline)
+ return 0, fmt.Errorf("%s in recoveryLine: %s", err, recoveryLine)
}
return syncedBlocks, nil
diff --git a/vendor/github.com/prometheus/procfs/mountinfo.go b/vendor/github.com/prometheus/procfs/mountinfo.go
new file mode 100644
index 0000000000..61fa618874
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/mountinfo.go
@@ -0,0 +1,178 @@
+// 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"
+ "os"
+ "strconv"
+ "strings"
+)
+
+var validOptionalFields = map[string]bool{
+ "shared": true,
+ "master": true,
+ "propagate_from": true,
+ "unbindable": true,
+}
+
+// A MountInfo is a type that describes the details, options
+// for each mount, parsed from /proc/self/mountinfo.
+// The fields described in each entry of /proc/self/mountinfo
+// is described in the following man page.
+// http://man7.org/linux/man-pages/man5/proc.5.html
+type MountInfo struct {
+ // Unique Id for the mount
+ MountId int
+ // The Id of the parent mount
+ ParentId int
+ // The value of `st_dev` for the files on this FS
+ MajorMinorVer string
+ // The pathname of the directory in the FS that forms
+ // the root for this mount
+ Root string
+ // The pathname of the mount point relative to the root
+ MountPoint string
+ // Mount options
+ Options map[string]string
+ // Zero or more optional fields
+ OptionalFields map[string]string
+ // The Filesystem type
+ FSType string
+ // FS specific information or "none"
+ Source string
+ // Superblock options
+ SuperOptions map[string]string
+}
+
+// Returns part of the mountinfo line, if it exists, else an empty string.
+func getStringSliceElement(parts []string, idx int, defaultValue string) string {
+ if idx >= len(parts) {
+ return defaultValue
+ }
+ return parts[idx]
+}
+
+// Reads each line of the mountinfo file, and returns a list of formatted MountInfo structs.
+func parseMountInfo(r io.Reader) ([]*MountInfo, error) {
+ mounts := []*MountInfo{}
+ scanner := bufio.NewScanner(r)
+ for scanner.Scan() {
+ mountString := scanner.Text()
+ parsedMounts, err := parseMountInfoString(mountString)
+ if err != nil {
+ return nil, err
+ }
+ mounts = append(mounts, parsedMounts)
+ }
+
+ err := scanner.Err()
+ return mounts, err
+}
+
+// Parses a mountinfo file line, and converts it to a MountInfo struct.
+// An important check here is to see if the hyphen separator, as if it does not exist,
+// it means that the line is malformed.
+func parseMountInfoString(mountString string) (*MountInfo, error) {
+ var err error
+
+ // OptionalFields can be zero, hence these checks to ensure we do not populate the wrong values in the wrong spots
+ separatorIndex := strings.Index(mountString, "-")
+ if separatorIndex == -1 {
+ return nil, fmt.Errorf("no separator found in mountinfo string: %s", mountString)
+ }
+ beforeFields := strings.Fields(mountString[:separatorIndex])
+ afterFields := strings.Fields(mountString[separatorIndex+1:])
+ if (len(beforeFields) + len(afterFields)) < 7 {
+ return nil, fmt.Errorf("too few fields")
+ }
+
+ mount := &MountInfo{
+ MajorMinorVer: getStringSliceElement(beforeFields, 2, ""),
+ Root: getStringSliceElement(beforeFields, 3, ""),
+ MountPoint: getStringSliceElement(beforeFields, 4, ""),
+ Options: mountOptionsParser(getStringSliceElement(beforeFields, 5, "")),
+ OptionalFields: nil,
+ FSType: getStringSliceElement(afterFields, 0, ""),
+ Source: getStringSliceElement(afterFields, 1, ""),
+ SuperOptions: mountOptionsParser(getStringSliceElement(afterFields, 2, "")),
+ }
+
+ mount.MountId, err = strconv.Atoi(getStringSliceElement(beforeFields, 0, ""))
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse mount ID")
+ }
+ mount.ParentId, err = strconv.Atoi(getStringSliceElement(beforeFields, 1, ""))
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse parent ID")
+ }
+ // Has optional fields, which is a space separated list of values.
+ // Example: shared:2 master:7
+ if len(beforeFields) > 6 {
+ mount.OptionalFields = make(map[string]string)
+ optionalFields := beforeFields[6:]
+ for _, field := range optionalFields {
+ optionSplit := strings.Split(field, ":")
+ target, value := optionSplit[0], ""
+ if len(optionSplit) == 2 {
+ value = optionSplit[1]
+ }
+ // Checks if the 'keys' in the optional fields in the mountinfo line are acceptable.
+ // Allowed 'keys' are shared, master, propagate_from, unbindable.
+ if _, ok := validOptionalFields[target]; ok {
+ mount.OptionalFields[target] = value
+ }
+ }
+ }
+ return mount, nil
+}
+
+// Parses the mount options, superblock options.
+func mountOptionsParser(mountOptions string) map[string]string {
+ opts := make(map[string]string)
+ options := strings.Split(mountOptions, ",")
+ for _, opt := range options {
+ splitOption := strings.Split(opt, "=")
+ if len(splitOption) < 2 {
+ key := splitOption[0]
+ opts[key] = ""
+ } else {
+ key, value := splitOption[0], splitOption[1]
+ opts[key] = value
+ }
+ }
+ return opts
+}
+
+// Retrieves mountinfo information from `/proc/self/mountinfo`.
+func GetMounts() ([]*MountInfo, error) {
+ f, err := os.Open("/proc/self/mountinfo")
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ return parseMountInfo(f)
+}
+
+// Retrieves mountinfo information from a processes' `/proc/<pid>/mountinfo`.
+func GetProcMounts(pid int) ([]*MountInfo, error) {
+ f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid))
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ return parseMountInfo(f)
+}
diff --git a/vendor/github.com/prometheus/procfs/mountstats.go b/vendor/github.com/prometheus/procfs/mountstats.go
index fc385afcfe..35b2ef3513 100644
--- a/vendor/github.com/prometheus/procfs/mountstats.go
+++ b/vendor/github.com/prometheus/procfs/mountstats.go
@@ -69,8 +69,8 @@ type MountStats interface {
type MountStatsNFS struct {
// The version of statistics provided.
StatVersion string
- // The optional mountaddr of the NFS mount.
- MountAddress string
+ // The mount options of the NFS mount.
+ Opts map[string]string
// The age of the NFS mount.
Age time.Duration
// Statistics related to byte counters for various operations.
@@ -181,11 +181,11 @@ type NFSOperationStats struct {
// Number of bytes received for this operation, including RPC headers and payload.
BytesReceived uint64
// Duration all requests spent queued for transmission before they were sent.
- CumulativeQueueTime time.Duration
+ CumulativeQueueMilliseconds uint64
// Duration it took to get a reply back after the request was transmitted.
- CumulativeTotalResponseTime time.Duration
+ CumulativeTotalResponseMilliseconds uint64
// Duration from when a request was enqueued to when it was completely handled.
- CumulativeTotalRequestTime time.Duration
+ CumulativeTotalRequestMilliseconds uint64
}
// A NFSTransportStats contains statistics for the NFS mount RPC requests and
@@ -204,7 +204,7 @@ type NFSTransportStats struct {
// spent waiting for connections to the server to be established.
ConnectIdleTime uint64
// Duration since the NFS mount last saw any RPC traffic.
- IdleTime time.Duration
+ IdleTimeSeconds uint64
// Number of RPC requests for this mount sent to the NFS server.
Sends uint64
// Number of RPC responses for this mount received from the NFS server.
@@ -342,10 +342,15 @@ func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, e
switch ss[0] {
case fieldOpts:
+ if stats.Opts == nil {
+ stats.Opts = map[string]string{}
+ }
for _, opt := range strings.Split(ss[1], ",") {
split := strings.Split(opt, "=")
- if len(split) == 2 && split[0] == "mountaddr" {
- stats.MountAddress = split[1]
+ if len(split) == 2 {
+ stats.Opts[split[0]] = split[1]
+ } else {
+ stats.Opts[opt] = ""
}
}
case fieldAge:
@@ -519,15 +524,15 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
}
ops = append(ops, NFSOperationStats{
- Operation: strings.TrimSuffix(ss[0], ":"),
- Requests: ns[0],
- Transmissions: ns[1],
- MajorTimeouts: ns[2],
- BytesSent: ns[3],
- BytesReceived: ns[4],
- CumulativeQueueTime: time.Duration(ns[5]) * time.Millisecond,
- CumulativeTotalResponseTime: time.Duration(ns[6]) * time.Millisecond,
- CumulativeTotalRequestTime: time.Duration(ns[7]) * time.Millisecond,
+ Operation: strings.TrimSuffix(ss[0], ":"),
+ Requests: ns[0],
+ Transmissions: ns[1],
+ MajorTimeouts: ns[2],
+ BytesSent: ns[3],
+ BytesReceived: ns[4],
+ CumulativeQueueMilliseconds: ns[5],
+ CumulativeTotalResponseMilliseconds: ns[6],
+ CumulativeTotalRequestMilliseconds: ns[7],
})
}
@@ -603,7 +608,7 @@ func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats
Bind: ns[1],
Connect: ns[2],
ConnectIdleTime: ns[3],
- IdleTime: time.Duration(ns[4]) * time.Second,
+ IdleTimeSeconds: ns[4],
Sends: ns[5],
Receives: ns[6],
BadTransactionIDs: ns[7],
diff --git a/vendor/github.com/prometheus/procfs/net_dev.go b/vendor/github.com/prometheus/procfs/net_dev.go
index 0063594e69..a0b7a01196 100644
--- a/vendor/github.com/prometheus/procfs/net_dev.go
+++ b/vendor/github.com/prometheus/procfs/net_dev.go
@@ -47,23 +47,13 @@ type NetDevLine struct {
// are interface names.
type NetDev map[string]NetDevLine
-// NewNetDev returns kernel/system statistics read from /proc/net/dev.
-func NewNetDev() (NetDev, error) {
- fs, err := NewFS(DefaultMountPoint)
- if err != nil {
- return nil, err
- }
-
- return fs.NewNetDev()
-}
-
-// NewNetDev returns kernel/system statistics read from /proc/net/dev.
-func (fs FS) NewNetDev() (NetDev, error) {
+// NetDev returns kernel/system statistics read from /proc/net/dev.
+func (fs FS) NetDev() (NetDev, error) {
return newNetDev(fs.proc.Path("net/dev"))
}
-// NewNetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
-func (p Proc) NewNetDev() (NetDev, error) {
+// NetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
+func (p Proc) NetDev() (NetDev, error) {
return newNetDev(p.path("net/dev"))
}
@@ -75,7 +65,7 @@ func newNetDev(file string) (NetDev, error) {
}
defer f.Close()
- nd := NetDev{}
+ netDev := NetDev{}
s := bufio.NewScanner(f)
for n := 0; s.Scan(); n++ {
// Skip the 2 header lines.
@@ -83,20 +73,20 @@ func newNetDev(file string) (NetDev, error) {
continue
}
- line, err := nd.parseLine(s.Text())
+ line, err := netDev.parseLine(s.Text())
if err != nil {
- return nd, err
+ return netDev, err
}
- nd[line.Name] = *line
+ netDev[line.Name] = *line
}
- return nd, s.Err()
+ return netDev, s.Err()
}
// parseLine parses a single line from the /proc/net/dev file. Header lines
// must be filtered prior to calling this method.
-func (nd NetDev) parseLine(rawLine string) (*NetDevLine, error) {
+func (netDev NetDev) parseLine(rawLine string) (*NetDevLine, error) {
parts := strings.SplitN(rawLine, ":", 2)
if len(parts) != 2 {
return nil, errors.New("invalid net/dev line, missing colon")
@@ -185,11 +175,11 @@ func (nd NetDev) parseLine(rawLine string) (*NetDevLine, error) {
// Total aggregates the values across interfaces and returns a new NetDevLine.
// The Name field will be a sorted comma separated list of interface names.
-func (nd NetDev) Total() NetDevLine {
+func (netDev NetDev) Total() NetDevLine {
total := NetDevLine{}
- names := make([]string, 0, len(nd))
- for _, ifc := range nd {
+ names := make([]string, 0, len(netDev))
+ for _, ifc := range netDev {
names = append(names, ifc.Name)
total.RxBytes += ifc.RxBytes
total.RxPackets += ifc.RxPackets
diff --git a/vendor/github.com/prometheus/procfs/net_softnet.go b/vendor/github.com/prometheus/procfs/net_softnet.go
new file mode 100644
index 0000000000..6fcad20afc
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/net_softnet.go
@@ -0,0 +1,91 @@
+// 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
+}
diff --git a/vendor/github.com/prometheus/procfs/net_unix.go b/vendor/github.com/prometheus/procfs/net_unix.go
new file mode 100644
index 0000000000..240340a83a
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/net_unix.go
@@ -0,0 +1,275 @@
+// 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 procfs
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "strconv"
+ "strings"
+)
+
+// For the proc file format details,
+// see https://elixir.bootlin.com/linux/v4.17/source/net/unix/af_unix.c#L2815
+// and https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/net.h#L48.
+
+const (
+ netUnixKernelPtrIdx = iota
+ netUnixRefCountIdx
+ _
+ netUnixFlagsIdx
+ netUnixTypeIdx
+ netUnixStateIdx
+ netUnixInodeIdx
+
+ // Inode and Path are optional.
+ netUnixStaticFieldsCnt = 6
+)
+
+const (
+ netUnixTypeStream = 1
+ netUnixTypeDgram = 2
+ netUnixTypeSeqpacket = 5
+
+ netUnixFlagListen = 1 << 16
+
+ netUnixStateUnconnected = 1
+ netUnixStateConnecting = 2
+ netUnixStateConnected = 3
+ netUnixStateDisconnected = 4
+)
+
+var errInvalidKernelPtrFmt = errors.New("Invalid Num(the kernel table slot number) format")
+
+// NetUnixType is the type of the type field.
+type NetUnixType uint64
+
+// NetUnixFlags is the type of the flags field.
+type NetUnixFlags uint64
+
+// NetUnixState is the type of the state field.
+type NetUnixState uint64
+
+// NetUnixLine represents a line of /proc/net/unix.
+type NetUnixLine struct {
+ KernelPtr string
+ RefCount uint64
+ Protocol uint64
+ Flags NetUnixFlags
+ Type NetUnixType
+ State NetUnixState
+ Inode uint64
+ Path string
+}
+
+// NetUnix holds the data read from /proc/net/unix.
+type NetUnix struct {
+ Rows []*NetUnixLine
+}
+
+// NewNetUnix returns data read from /proc/net/unix.
+func NewNetUnix() (*NetUnix, error) {
+ fs, err := NewFS(DefaultMountPoint)
+ if err != nil {
+ return nil, err
+ }
+
+ return fs.NewNetUnix()
+}
+
+// NewNetUnix returns data read from /proc/net/unix.
+func (fs FS) NewNetUnix() (*NetUnix, error) {
+ return NewNetUnixByPath(fs.proc.Path("net/unix"))
+}
+
+// NewNetUnixByPath returns data read from /proc/net/unix by file path.
+// It might returns an error with partial parsed data, if an error occur after some data parsed.
+func NewNetUnixByPath(path string) (*NetUnix, error) {
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ return NewNetUnixByReader(f)
+}
+
+// NewNetUnixByReader returns data read from /proc/net/unix by a reader.
+// It might returns an error with partial parsed data, if an error occur after some data parsed.
+func NewNetUnixByReader(reader io.Reader) (*NetUnix, error) {
+ nu := &NetUnix{
+ Rows: make([]*NetUnixLine, 0, 32),
+ }
+ scanner := bufio.NewScanner(reader)
+ // Omit the header line.
+ scanner.Scan()
+ header := scanner.Text()
+ // From the man page of proc(5), it does not contain an Inode field,
+ // but in actually it exists.
+ // This code works for both cases.
+ hasInode := strings.Contains(header, "Inode")
+
+ minFieldsCnt := netUnixStaticFieldsCnt
+ if hasInode {
+ minFieldsCnt++
+ }
+ for scanner.Scan() {
+ line := scanner.Text()
+ item, err := nu.parseLine(line, hasInode, minFieldsCnt)
+ if err != nil {
+ return nu, err
+ }
+ nu.Rows = append(nu.Rows, item)
+ }
+
+ return nu, scanner.Err()
+}
+
+func (u *NetUnix) parseLine(line string, hasInode bool, minFieldsCnt int) (*NetUnixLine, error) {
+ fields := strings.Fields(line)
+ fieldsLen := len(fields)
+ if fieldsLen < minFieldsCnt {
+ return nil, fmt.Errorf(
+ "Parse Unix domain failed: expect at least %d fields but got %d",
+ minFieldsCnt, fieldsLen)
+ }
+ kernelPtr, err := u.parseKernelPtr(fields[netUnixKernelPtrIdx])
+ if err != nil {
+ return nil, fmt.Errorf("Parse Unix domain num(%s) failed: %s", fields[netUnixKernelPtrIdx], err)
+ }
+ users, err := u.parseUsers(fields[netUnixRefCountIdx])
+ if err != nil {
+ return nil, fmt.Errorf("Parse Unix domain ref count(%s) failed: %s", fields[netUnixRefCountIdx], err)
+ }
+ flags, err := u.parseFlags(fields[netUnixFlagsIdx])
+ if err != nil {
+ return nil, fmt.Errorf("Parse Unix domain flags(%s) failed: %s", fields[netUnixFlagsIdx], err)
+ }
+ typ, err := u.parseType(fields[netUnixTypeIdx])
+ if err != nil {
+ return nil, fmt.Errorf("Parse Unix domain type(%s) failed: %s", fields[netUnixTypeIdx], err)
+ }
+ state, err := u.parseState(fields[netUnixStateIdx])
+ if err != nil {
+ return nil, fmt.Errorf("Parse Unix domain state(%s) failed: %s", fields[netUnixStateIdx], err)
+ }
+ var inode uint64
+ if hasInode {
+ inodeStr := fields[netUnixInodeIdx]
+ inode, err = u.parseInode(inodeStr)
+ if err != nil {
+ return nil, fmt.Errorf("Parse Unix domain inode(%s) failed: %s", inodeStr, err)
+ }
+ }
+
+ nuLine := &NetUnixLine{
+ KernelPtr: kernelPtr,
+ RefCount: users,
+ Type: typ,
+ Flags: flags,
+ State: state,
+ Inode: inode,
+ }
+
+ // Path field is optional.
+ if fieldsLen > minFieldsCnt {
+ pathIdx := netUnixInodeIdx + 1
+ if !hasInode {
+ pathIdx--
+ }
+ nuLine.Path = fields[pathIdx]
+ }
+
+ return nuLine, nil
+}
+
+func (u NetUnix) parseKernelPtr(str string) (string, error) {
+ if !strings.HasSuffix(str, ":") {
+ return "", errInvalidKernelPtrFmt
+ }
+ return str[:len(str)-1], nil
+}
+
+func (u NetUnix) parseUsers(hexStr string) (uint64, error) {
+ return strconv.ParseUint(hexStr, 16, 32)
+}
+
+func (u NetUnix) parseProtocol(hexStr string) (uint64, error) {
+ return strconv.ParseUint(hexStr, 16, 32)
+}
+
+func (u NetUnix) parseType(hexStr string) (NetUnixType, error) {
+ typ, err := strconv.ParseUint(hexStr, 16, 16)
+ if err != nil {
+ return 0, err
+ }
+ return NetUnixType(typ), nil
+}
+
+func (u NetUnix) parseFlags(hexStr string) (NetUnixFlags, error) {
+ flags, err := strconv.ParseUint(hexStr, 16, 32)
+ if err != nil {
+ return 0, err
+ }
+ return NetUnixFlags(flags), nil
+}
+
+func (u NetUnix) parseState(hexStr string) (NetUnixState, error) {
+ st, err := strconv.ParseInt(hexStr, 16, 8)
+ if err != nil {
+ return 0, err
+ }
+ return NetUnixState(st), nil
+}
+
+func (u NetUnix) parseInode(inodeStr string) (uint64, error) {
+ return strconv.ParseUint(inodeStr, 10, 64)
+}
+
+func (t NetUnixType) String() string {
+ switch t {
+ case netUnixTypeStream:
+ return "stream"
+ case netUnixTypeDgram:
+ return "dgram"
+ case netUnixTypeSeqpacket:
+ return "seqpacket"
+ }
+ return "unknown"
+}
+
+func (f NetUnixFlags) String() string {
+ switch f {
+ case netUnixFlagListen:
+ return "listen"
+ default:
+ return "default"
+ }
+}
+
+func (s NetUnixState) String() string {
+ switch s {
+ case netUnixStateUnconnected:
+ return "unconnected"
+ case netUnixStateConnecting:
+ return "connecting"
+ case netUnixStateConnected:
+ return "connected"
+ case netUnixStateDisconnected:
+ return "disconnected"
+ }
+ return "unknown"
+}
diff --git a/vendor/github.com/prometheus/procfs/proc.go b/vendor/github.com/prometheus/procfs/proc.go
index 8e38493a89..b7c79cf77b 100644
--- a/vendor/github.com/prometheus/procfs/proc.go
+++ b/vendor/github.com/prometheus/procfs/proc.go
@@ -54,7 +54,7 @@ func NewProc(pid int) (Proc, error) {
if err != nil {
return Proc{}, err
}
- return fs.NewProc(pid)
+ return fs.Proc(pid)
}
// AllProcs returns a list of all currently available processes under /proc.
@@ -76,11 +76,18 @@ func (fs FS) Self() (Proc, error) {
if err != nil {
return Proc{}, err
}
- return fs.NewProc(pid)
+ return fs.Proc(pid)
}
// NewProc returns a process for the given pid.
+//
+// Deprecated: use fs.Proc() instead
func (fs FS) NewProc(pid int) (Proc, error) {
+ return fs.Proc(pid)
+}
+
+// Proc returns a process for the given pid.
+func (fs FS) Proc(pid int) (Proc, error) {
if _, err := os.Stat(fs.proc.Path(strconv.Itoa(pid))); err != nil {
return Proc{}, err
}
@@ -240,6 +247,20 @@ func (p Proc) MountStats() ([]*Mount, error) {
return parseMountStats(f)
}
+// MountInfo retrieves mount information for mount points in a
+// process's namespace.
+// It supplies information missing in `/proc/self/mounts` and
+// fixes various other problems with that file too.
+func (p Proc) MountInfo() ([]*MountInfo, error) {
+ f, err := os.Open(p.path("mountinfo"))
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ return parseMountInfo(f)
+}
+
func (p Proc) fileDescriptors() ([]string, error) {
d, err := os.Open(p.path("fd"))
if err != nil {
@@ -258,3 +279,33 @@ 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))
+}
diff --git a/vendor/github.com/prometheus/procfs/proc_environ.go b/vendor/github.com/prometheus/procfs/proc_environ.go
new file mode 100644
index 0000000000..7172bb586e
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/proc_environ.go
@@ -0,0 +1,43 @@
+// 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 (
+ "io/ioutil"
+ "os"
+ "strings"
+)
+
+// Environ reads process environments from /proc/<pid>/environ
+func (p Proc) Environ() ([]string, error) {
+ environments := make([]string, 0)
+
+ f, err := os.Open(p.path("environ"))
+ if err != nil {
+ return environments, err
+ }
+ defer f.Close()
+
+ data, err := ioutil.ReadAll(f)
+ if err != nil {
+ return environments, err
+ }
+
+ environments = strings.Split(string(data), "\000")
+ if len(environments) > 0 {
+ environments = environments[:len(environments)-1]
+ }
+
+ return environments, nil
+}
diff --git a/vendor/github.com/prometheus/procfs/proc_fdinfo.go b/vendor/github.com/prometheus/procfs/proc_fdinfo.go
new file mode 100644
index 0000000000..83b67d1bde
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/proc_fdinfo.go
@@ -0,0 +1,132 @@
+// 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
+}
diff --git a/vendor/github.com/prometheus/procfs/proc_io.go b/vendor/github.com/prometheus/procfs/proc_io.go
index 0251c83bfe..0ff89b1cef 100644
--- a/vendor/github.com/prometheus/procfs/proc_io.go
+++ b/vendor/github.com/prometheus/procfs/proc_io.go
@@ -39,8 +39,8 @@ type ProcIO struct {
CancelledWriteBytes int64
}
-// NewIO creates a new ProcIO instance from a given Proc instance.
-func (p Proc) NewIO() (ProcIO, error) {
+// IO creates a new ProcIO instance from a given Proc instance.
+func (p Proc) IO() (ProcIO, error) {
pio := ProcIO{}
f, err := os.Open(p.path("io"))
diff --git a/vendor/github.com/prometheus/procfs/proc_limits.go b/vendor/github.com/prometheus/procfs/proc_limits.go
index f04ba6fda8..91ee24df8b 100644
--- a/vendor/github.com/prometheus/procfs/proc_limits.go
+++ b/vendor/github.com/prometheus/procfs/proc_limits.go
@@ -78,7 +78,14 @@ var (
)
// NewLimits returns the current soft limits of the process.
+//
+// Deprecated: use p.Limits() instead
func (p Proc) NewLimits() (ProcLimits, error) {
+ return p.Limits()
+}
+
+// Limits returns the current soft limits of the process.
+func (p Proc) Limits() (ProcLimits, error) {
f, err := os.Open(p.path("limits"))
if err != nil {
return ProcLimits{}, err
diff --git a/vendor/github.com/prometheus/procfs/proc_ns.go b/vendor/github.com/prometheus/procfs/proc_ns.go
index d06c26ebad..c66740ff74 100644
--- a/vendor/github.com/prometheus/procfs/proc_ns.go
+++ b/vendor/github.com/prometheus/procfs/proc_ns.go
@@ -29,9 +29,9 @@ type Namespace struct {
// Namespaces contains all of the namespaces that the process is contained in.
type Namespaces map[string]Namespace
-// NewNamespaces reads from /proc/[pid/ns/* to get the namespaces of which the
+// Namespaces reads from /proc/<pid>/ns/* to get the namespaces of which the
// process is a member.
-func (p Proc) NewNamespaces() (Namespaces, error) {
+func (p Proc) Namespaces() (Namespaces, error) {
d, err := os.Open(p.path("ns"))
if err != nil {
return nil, err
diff --git a/vendor/github.com/prometheus/procfs/proc_psi.go b/vendor/github.com/prometheus/procfs/proc_psi.go
index a23d4c0f05..46fe266263 100644
--- a/vendor/github.com/prometheus/procfs/proc_psi.go
+++ b/vendor/github.com/prometheus/procfs/proc_psi.go
@@ -51,19 +51,10 @@ type PSIStats struct {
Full *PSILine
}
-// NewPSIStatsForResource reads pressure stall information for the specified
-// resource. At time of writing this can be either "cpu", "memory" or "io".
-func NewPSIStatsForResource(resource string) (PSIStats, error) {
- fs, err := NewFS(DefaultMountPoint)
- if err != nil {
- return PSIStats{}, err
- }
-
- return fs.NewPSIStatsForResource(resource)
-}
-
-// NewPSIStatsForResource reads pressure stall information from /proc/pressure/<resource>
-func (fs FS) NewPSIStatsForResource(resource string) (PSIStats, error) {
+// PSIStatsForResource reads pressure stall information for the specified
+// resource from /proc/pressure/<resource>. At time of writing this can be
+// either "cpu", "memory" or "io".
+func (fs FS) PSIStatsForResource(resource string) (PSIStats, error) {
file, err := os.Open(fs.proc.Path(fmt.Sprintf("%s/%s", "pressure", resource)))
if err != nil {
return PSIStats{}, fmt.Errorf("psi_stats: unavailable for %s", resource)
diff --git a/vendor/github.com/prometheus/procfs/proc_stat.go b/vendor/github.com/prometheus/procfs/proc_stat.go
index 4c8b03ced4..dbde1fa0d6 100644
--- a/vendor/github.com/prometheus/procfs/proc_stat.go
+++ b/vendor/github.com/prometheus/procfs/proc_stat.go
@@ -105,7 +105,14 @@ type ProcStat struct {
}
// NewStat returns the current status information of the process.
+//
+// Deprecated: use p.Stat() instead
func (p Proc) NewStat() (ProcStat, error) {
+ return p.Stat()
+}
+
+// Stat returns the current status information of the process.
+func (p Proc) Stat() (ProcStat, error) {
f, err := os.Open(p.path("stat"))
if err != nil {
return ProcStat{}, err
@@ -178,7 +185,7 @@ func (s ProcStat) ResidentMemory() int {
// StartTime returns the unix timestamp of the process in seconds.
func (s ProcStat) StartTime() (float64, error) {
fs := FS{proc: s.proc}
- stat, err := fs.NewStat()
+ stat, err := fs.Stat()
if err != nil {
return 0, err
}
diff --git a/vendor/github.com/prometheus/procfs/proc_status.go b/vendor/github.com/prometheus/procfs/proc_status.go
new file mode 100644
index 0000000000..6b4b61f71c
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/proc_status.go
@@ -0,0 +1,162 @@
+// 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 procfs
+
+import (
+ "bytes"
+ "io/ioutil"
+ "os"
+ "strconv"
+ "strings"
+)
+
+// ProcStat provides status information about the process,
+// read from /proc/[pid]/stat.
+type ProcStatus struct {
+ // The process ID.
+ PID int
+ // The process name.
+ Name string
+
+ // Peak virtual memory size.
+ VmPeak uint64
+ // Virtual memory size.
+ VmSize uint64
+ // Locked memory size.
+ VmLck uint64
+ // Pinned memory size.
+ VmPin uint64
+ // Peak resident set size.
+ VmHWM uint64
+ // Resident set size (sum of RssAnnon RssFile and RssShmem).
+ VmRSS uint64
+ // Size of resident anonymous memory.
+ RssAnon uint64
+ // Size of resident file mappings.
+ RssFile uint64
+ // Size of resident shared memory.
+ RssShmem uint64
+ // Size of data segments.
+ VmData uint64
+ // Size of stack segments.
+ VmStk uint64
+ // Size of text segments.
+ VmExe uint64
+ // Shared library code size.
+ VmLib uint64
+ // Page table entries size.
+ VmPTE uint64
+ // Size of second-level page tables.
+ VmPMD uint64
+ // Swapped-out virtual memory size by anonymous private.
+ VmSwap uint64
+ // Size of hugetlb memory portions
+ HugetlbPages uint64
+
+ // Number of voluntary context switches.
+ VoluntaryCtxtSwitches uint64
+ // Number of involuntary context switches.
+ NonVoluntaryCtxtSwitches uint64
+}
+
+// NewStatus returns the current status information of the process.
+func (p Proc) NewStatus() (ProcStatus, error) {
+ f, err := os.Open(p.path("status"))
+ if err != nil {
+ return ProcStatus{}, err
+ }
+ defer f.Close()
+
+ data, err := ioutil.ReadAll(f)
+ if err != nil {
+ return ProcStatus{}, err
+ }
+
+ s := ProcStatus{PID: p.PID}
+
+ lines := strings.Split(string(data), "\n")
+ for _, line := range lines {
+ if !bytes.Contains([]byte(line), []byte(":")) {
+ continue
+ }
+
+ kv := strings.SplitN(line, ":", 2)
+
+ // removes spaces
+ k := string(strings.TrimSpace(kv[0]))
+ v := string(strings.TrimSpace(kv[1]))
+ // removes "kB"
+ v = string(bytes.Trim([]byte(v), " kB"))
+
+ // value to int when possible
+ // we can skip error check here, 'cause vKBytes is not used when value is a string
+ vKBytes, _ := strconv.ParseUint(v, 10, 64)
+ // convert kB to B
+ vBytes := vKBytes * 1024
+
+ s.fillStatus(k, v, vKBytes, vBytes)
+ }
+
+ return s, nil
+}
+
+func (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintBytes uint64) {
+ switch k {
+ case "Name":
+ s.Name = vString
+ case "VmPeak":
+ s.VmPeak = vUintBytes
+ case "VmSize":
+ s.VmSize = vUintBytes
+ case "VmLck":
+ s.VmLck = vUintBytes
+ case "VmPin":
+ s.VmPin = vUintBytes
+ case "VmHWM":
+ s.VmHWM = vUintBytes
+ case "VmRSS":
+ s.VmRSS = vUintBytes
+ case "RssAnon":
+ s.RssAnon = vUintBytes
+ case "RssFile":
+ s.RssFile = vUintBytes
+ case "RssShmem":
+ s.RssShmem = vUintBytes
+ case "VmData":
+ s.VmData = vUintBytes
+ case "VmStk":
+ s.VmStk = vUintBytes
+ case "VmExe":
+ s.VmExe = vUintBytes
+ case "VmLib":
+ s.VmLib = vUintBytes
+ case "VmPTE":
+ s.VmPTE = vUintBytes
+ case "VmPMD":
+ s.VmPMD = vUintBytes
+ case "VmSwap":
+ s.VmSwap = vUintBytes
+ case "HugetlbPages":
+ s.HugetlbPages = vUintBytes
+ case "voluntary_ctxt_switches":
+ s.VoluntaryCtxtSwitches = vUint
+ case "nonvoluntary_ctxt_switches":
+ s.NonVoluntaryCtxtSwitches = vUint
+ }
+}
+
+// TotalCtxtSwitches returns the total context switch.
+func (s ProcStatus) TotalCtxtSwitches() uint64 {
+ return s.VoluntaryCtxtSwitches + s.NonVoluntaryCtxtSwitches
+}
diff --git a/vendor/github.com/prometheus/procfs/schedstat.go b/vendor/github.com/prometheus/procfs/schedstat.go
new file mode 100644
index 0000000000..98221e3689
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/schedstat.go
@@ -0,0 +1,118 @@
+// 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/schedstats
+//
+// 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
+}
+
+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
+}
diff --git a/vendor/github.com/prometheus/procfs/stat.go b/vendor/github.com/prometheus/procfs/stat.go
index 44c9af1b0b..6661ee03a6 100644
--- a/vendor/github.com/prometheus/procfs/stat.go
+++ b/vendor/github.com/prometheus/procfs/stat.go
@@ -20,6 +20,8 @@ import (
"os"
"strconv"
"strings"
+
+ "github.com/prometheus/procfs/internal/fs"
)
// CPUStat shows how much time the cpu spend in various stages.
@@ -78,16 +80,6 @@ type Stat struct {
SoftIRQ SoftIRQStat
}
-// NewStat returns kernel/system statistics read from /proc/stat.
-func NewStat() (Stat, error) {
- fs, err := NewFS(DefaultMountPoint)
- if err != nil {
- return Stat{}, err
- }
-
- return fs.NewStat()
-}
-
// Parse a cpu statistics line and returns the CPUStat struct plus the cpu id (or -1 for the overall sum).
func parseCPUStat(line string) (CPUStat, int64, error) {
cpuStat := CPUStat{}
@@ -149,9 +141,29 @@ func parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) {
return softIRQStat, total, nil
}
-// NewStat returns an information about current kernel/system statistics.
+// NewStat returns information about current cpu/process statistics.
+// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
+//
+// Deprecated: use fs.Stat() instead
+func NewStat() (Stat, error) {
+ fs, err := NewFS(fs.DefaultProcMountPoint)
+ if err != nil {
+ return Stat{}, err
+ }
+ return fs.Stat()
+}
+
+// NewStat returns information about current cpu/process statistics.
+// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
+//
+// Deprecated: use fs.Stat() instead
func (fs FS) NewStat() (Stat, error) {
- // See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
+ return fs.Stat()
+}
+
+// Stat returns information about current cpu/process statistics.
+// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
+func (fs FS) Stat() (Stat, error) {
f, err := os.Open(fs.proc.Path("stat"))
if err != nil {
diff --git a/vendor/github.com/prometheus/procfs/ttar b/vendor/github.com/prometheus/procfs/ttar
index b0171a12b5..19ef02b8d4 100644
--- a/vendor/github.com/prometheus/procfs/ttar
+++ b/vendor/github.com/prometheus/procfs/ttar
@@ -86,8 +86,10 @@ Usage: $bname [-C <DIR>] -c -f <ARCHIVE> <FILE...> (create archive)
$bname [-C <DIR>] -x -f <ARCHIVE> (extract archive)
Options:
- -C <DIR> (change directory)
- -v (verbose)
+ -C <DIR> (change directory)
+ -v (verbose)
+ --recursive-unlink (recursively delete existing directory if path
+ collides with file or directory to extract)
Example: Change to sysfs directory, create ttar file from fixtures directory
$bname -C sysfs -c -f sysfs/fixtures.ttar fixtures/
@@ -111,8 +113,9 @@ function set_cmd {
}
unset VERBOSE
+unset RECURSIVE_UNLINK
-while getopts :cf:htxvC: opt; do
+while getopts :cf:-:htxvC: opt; do
case $opt in
c)
set_cmd "create"
@@ -136,6 +139,18 @@ while getopts :cf:htxvC: opt; do
C)
CDIR=$OPTARG
;;
+ -)
+ case $OPTARG in
+ recursive-unlink)
+ RECURSIVE_UNLINK="yes"
+ ;;
+ *)
+ echo -e "Error: invalid option -$OPTARG"
+ echo
+ usage 1
+ ;;
+ esac
+ ;;
*)
echo >&2 "ERROR: invalid option -$OPTARG"
echo
@@ -212,16 +227,16 @@ function extract {
local eof_without_newline
if [ "$size" -gt 0 ]; then
if [[ "$line" =~ [^\\]EOF ]]; then
- # An EOF not preceeded by a backslash indicates that the line
+ # An EOF not preceded by a backslash indicates that the line
# does not end with a newline
eof_without_newline=1
else
eof_without_newline=0
fi
# Replace NULLBYTE with null byte if at beginning of line
- # Replace NULLBYTE with null byte unless preceeded by backslash
+ # Replace NULLBYTE with null byte unless preceded by backslash
# Remove one backslash in front of NULLBYTE (if any)
- # Remove EOF unless preceeded by backslash
+ # Remove EOF unless preceded by backslash
# Remove one backslash in front of EOF
if [ $USE_PYTHON -eq 1 ]; then
echo -n "$line" | python -c "$PYTHON_EXTRACT_FILTER" >> "$path"
@@ -245,7 +260,16 @@ function extract {
fi
if [[ $line =~ ^Path:\ (.*)$ ]]; then
path=${BASH_REMATCH[1]}
- if [ -e "$path" ] || [ -L "$path" ]; then
+ if [ -L "$path" ]; then
+ rm "$path"
+ elif [ -d "$path" ]; then
+ if [ "${RECURSIVE_UNLINK:-}" == "yes" ]; then
+ rm -r "$path"
+ else
+ # Safe because symlinks to directories are dealt with above
+ rmdir "$path"
+ fi
+ elif [ -e "$path" ]; then
rm "$path"
fi
elif [[ $line =~ ^Lines:\ (.*)$ ]]; then
@@ -338,8 +362,8 @@ function _create {
else
< "$file" \
sed 's/EOF/\\EOF/g;
- s/NULLBYTE/\\NULLBYTE/g;
- s/\x0/NULLBYTE/g;
+ s/NULLBYTE/\\NULLBYTE/g;
+ s/\x0/NULLBYTE/g;
'
fi
if [[ "$eof_without_newline" -eq 1 ]]; then
diff --git a/vendor/github.com/prometheus/procfs/vm.go b/vendor/github.com/prometheus/procfs/vm.go
new file mode 100644
index 0000000000..cb13891414
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/vm.go
@@ -0,0 +1,210 @@
+// 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
+}
diff --git a/vendor/github.com/prometheus/procfs/zoneinfo.go b/vendor/github.com/prometheus/procfs/zoneinfo.go
new file mode 100644
index 0000000000..e941503d5c
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/zoneinfo.go
@@ -0,0 +1,196 @@
+// 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
+}