From e1aa00f7d41e587ae8e5c7045e7235b5f35bd895 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 17:12:53 +0000 Subject: [PATCH] Bump github.com/prometheus/procfs from 0.20.1 to 0.21.1 Bumps [github.com/prometheus/procfs](https://github.com/prometheus/procfs) from 0.20.1 to 0.21.1. - [Release notes](https://github.com/prometheus/procfs/releases) - [Commits](https://github.com/prometheus/procfs/compare/v0.20.1...v0.21.1) --- updated-dependencies: - dependency-name: github.com/prometheus/procfs dependency-version: 0.21.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 +- go.sum | 8 +- .../prometheus/procfs/Makefile.common | 84 +--------- vendor/github.com/prometheus/procfs/README.md | 2 +- .../github.com/prometheus/procfs/SECURITY.md | 2 +- vendor/github.com/prometheus/procfs/crypto.go | 8 +- .../github.com/prometheus/procfs/mountinfo.go | 22 ++- .../prometheus/procfs/net_wireless.go | 18 +- .../prometheus/procfs/proc_cgroup.go | 2 +- .../procfs/sysfs/class_fibrechannel.go | 3 + .../prometheus/procfs/sysfs/class_mei.go | 117 +++++++++++++ .../prometheus/procfs/sysfs/class_nvme.go | 2 +- .../procfs/sysfs/class_nvme_subsystem.go | 158 ++++++++++++++++++ .../prometheus/procfs/sysfs/class_thermal.go | 44 +++-- .../prometheus/procfs/sysfs/mdraid.go | 42 ++++- .../prometheus/procfs/sysfs/system_cpu.go | 15 +- vendor/golang.org/x/sync/errgroup/errgroup.go | 2 +- vendor/modules.txt | 4 +- 18 files changed, 392 insertions(+), 145 deletions(-) create mode 100644 vendor/github.com/prometheus/procfs/sysfs/class_mei.go create mode 100644 vendor/github.com/prometheus/procfs/sysfs/class_nvme_subsystem.go diff --git a/go.mod b/go.mod index 10e370e..fce3093 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/prometheus/client_golang v1.23.2 github.com/prometheus/common v0.69.0 github.com/prometheus/exporter-toolkit v0.16.0 - github.com/prometheus/procfs v0.20.1 + github.com/prometheus/procfs v0.21.1 github.com/stretchr/testify v1.11.1 golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc golang.org/x/sys v0.46.0 @@ -44,7 +44,7 @@ require ( golang.org/x/crypto v0.51.0 // indirect golang.org/x/net v0.55.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sync v0.20.0 // indirect + golang.org/x/sync v0.21.0 // indirect golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.15.0 // indirect google.golang.org/protobuf v1.36.11 // indirect diff --git a/go.sum b/go.sum index e1401bf..aaa7b91 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ github.com/prometheus/common v0.69.0 h1:OA85nJQS/T/MaYh/Q2CcgDKSGWqNIgrBDvDH85Cu github.com/prometheus/common v0.69.0/go.mod h1:ZzL3f6u94qUxh9p+tJTrF+FvBS1XXbbRAZCQkytAL0Y= github.com/prometheus/exporter-toolkit v0.16.0 h1:xT/j7L2XKF+VJd6B4fpUw6xWabHrSmsUf6mYmFqyu0s= github.com/prometheus/exporter-toolkit v0.16.0/go.mod h1:d1EL8Z9674xQe/iWhwP2wDyCEoBPbXVeqDbqAUsgJWY= -github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= -github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= +github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI= +github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/siebenmann/go-kstat v0.0.0-20210513183136-173c9b0a9973 h1:GfSdC6wKfTGcgCS7BtzF5694Amne1pGCSTY252WhlEY= @@ -96,8 +96,8 @@ golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= +golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= diff --git a/vendor/github.com/prometheus/procfs/Makefile.common b/vendor/github.com/prometheus/procfs/Makefile.common index cce3ef1..a7c5f55 100644 --- a/vendor/github.com/prometheus/procfs/Makefile.common +++ b/vendor/github.com/prometheus/procfs/Makefile.common @@ -55,13 +55,13 @@ ifneq ($(shell command -v gotestsum 2> /dev/null),) endif endif -PROMU_VERSION ?= 0.18.0 +PROMU_VERSION ?= 0.20.0 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz SKIP_GOLANGCI_LINT := GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v2.10.1 +GOLANGCI_LINT_VERSION ?= v2.11.4 GOLANGCI_FMT_OPTS ?= # golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64. # windows isn't included here because of the path separator being different. @@ -90,8 +90,8 @@ ifdef DOCKERFILE_PATH $(error DOCKERFILE_PATH is deprecated. Use DOCKERFILE_VARIANTS ?= $(DOCKERFILE_PATH) in the Makefile) endif -DOCKER_ARCHS ?= amd64 -DOCKERFILE_VARIANTS ?= Dockerfile $(wildcard Dockerfile.*) +DOCKER_ARCHS ?= amd64 arm64 armv7 ppc64le riscv64 s390x +DOCKERFILE_VARIANTS ?= $(wildcard Dockerfile Dockerfile.*) # Function to extract variant from Dockerfile label. # Returns the variant name from io.prometheus.image.variant label, or "default" if not found. @@ -109,24 +109,6 @@ endif # Build variant:dockerfile pairs for shell iteration. DOCKERFILE_VARIANTS_WITH_NAMES := $(foreach df,$(DOCKERFILE_VARIANTS),$(call dockerfile_variant,$(df)):$(df)) -# Shell helper to check whether a dockerfile/arch pair is excluded. -define dockerfile_arch_is_excluded -case " $(DOCKERFILE_ARCH_EXCLUSIONS) " in \ - *" $$dockerfile:$(1) "*) true ;; \ - *) false ;; \ -esac -endef - -# Shell helper to check whether a registry/arch pair is excluded. -# Extracts registry from DOCKER_REPO (e.g., quay.io/prometheus -> quay.io) -define registry_arch_is_excluded -registry=$$(echo "$(DOCKER_REPO)" | cut -d'/' -f1); \ -case " $(DOCKER_REGISTRY_ARCH_EXCLUSIONS) " in \ - *" $$registry:$(1) "*) true ;; \ - *) false ;; \ -esac -endef - BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS)) PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS)) TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS)) @@ -268,10 +250,6 @@ $(BUILD_DOCKER_ARCHS): common-docker-%: @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \ dockerfile=$${variant#*:}; \ variant_name=$${variant%%:*}; \ - if $(call dockerfile_arch_is_excluded,$*); then \ - echo "Skipping $$variant_name variant for linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ distroless_arch="$*"; \ if [ "$*" = "armv7" ]; then \ distroless_arch="arm"; \ @@ -306,14 +284,6 @@ $(PUBLISH_DOCKER_ARCHS): common-docker-publish-%: @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \ dockerfile=$${variant#*:}; \ variant_name=$${variant%%:*}; \ - if $(call dockerfile_arch_is_excluded,$*); then \ - echo "Skipping push for $$variant_name variant on linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$*); then \ - echo "Skipping push for $$variant_name variant on linux-$* to $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \ echo "Pushing $$variant_name variant for linux-$*"; \ docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \ @@ -341,14 +311,6 @@ $(TAG_DOCKER_ARCHS): common-docker-tag-latest-%: @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \ dockerfile=$${variant#*:}; \ variant_name=$${variant%%:*}; \ - if $(call dockerfile_arch_is_excluded,$*); then \ - echo "Skipping tag for $$variant_name variant on linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$*); then \ - echo "Skipping tag for $$variant_name variant on linux-$* for $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \ echo "Tagging $$variant_name variant for linux-$* as latest"; \ docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest-$$variant_name"; \ @@ -370,14 +332,6 @@ common-docker-manifest: echo "Creating manifest for $$variant_name variant"; \ refs=""; \ for arch in $(DOCKER_ARCHS); do \ - if $(call dockerfile_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for $$variant_name (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for $$variant_name on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \ done; \ if [ -z "$$refs" ]; then \ @@ -391,14 +345,6 @@ common-docker-manifest: echo "Creating default variant ($$variant_name) manifest"; \ refs=""; \ for arch in $(DOCKER_ARCHS); do \ - if $(call dockerfile_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for default variant (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for default variant on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:$(SANITIZED_DOCKER_IMAGE_TAG)"; \ done; \ if [ -z "$$refs" ]; then \ @@ -413,14 +359,6 @@ common-docker-manifest: echo "Creating manifest for $$variant_name variant version tag"; \ refs=""; \ for arch in $(DOCKER_ARCHS); do \ - if $(call dockerfile_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for $$variant_name version tag (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for $$variant_name version tag on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \ done; \ if [ -z "$$refs" ]; then \ @@ -434,14 +372,6 @@ common-docker-manifest: echo "Creating default variant version tag manifest"; \ refs=""; \ for arch in $(DOCKER_ARCHS); do \ - if $(call dockerfile_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for default variant version tag (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for default variant version tag on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:v$(DOCKER_MAJOR_VERSION_TAG)"; \ done; \ if [ -z "$$refs" ]; then \ @@ -495,9 +425,3 @@ $(1)_precheck: exit 1; \ fi endef - -govulncheck: install-govulncheck - govulncheck ./... - -install-govulncheck: - command -v govulncheck > /dev/null || go install golang.org/x/vuln/cmd/govulncheck@latest diff --git a/vendor/github.com/prometheus/procfs/README.md b/vendor/github.com/prometheus/procfs/README.md index 0718239..3635240 100644 --- a/vendor/github.com/prometheus/procfs/README.md +++ b/vendor/github.com/prometheus/procfs/README.md @@ -7,7 +7,7 @@ metrics from the pseudo-filesystems /proc and /sys. backwards-incompatible ways without warnings. Use it at your own risk. [![Go Reference](https://pkg.go.dev/badge/github.com/prometheus/procfs.svg)](https://pkg.go.dev/github.com/prometheus/procfs) -[![CircleCI](https://circleci.com/gh/prometheus/procfs/tree/master.svg?style=svg)](https://circleci.com/gh/prometheus/procfs/tree/master) +[![Build Status](https://github.com/prometheus/procfs/actions/workflows/ci.yml/badge.svg)](https://github.com/prometheus/procfs/actions/workflows/ci.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/prometheus/procfs)](https://goreportcard.com/report/github.com/prometheus/procfs) ## Usage diff --git a/vendor/github.com/prometheus/procfs/SECURITY.md b/vendor/github.com/prometheus/procfs/SECURITY.md index fed02d8..5e6f976 100644 --- a/vendor/github.com/prometheus/procfs/SECURITY.md +++ b/vendor/github.com/prometheus/procfs/SECURITY.md @@ -3,4 +3,4 @@ The Prometheus security policy, including how to report vulnerabilities, can be found here: - +[https://prometheus.io/docs/operating/security/](https://prometheus.io/docs/operating/security/) diff --git a/vendor/github.com/prometheus/procfs/crypto.go b/vendor/github.com/prometheus/procfs/crypto.go index e4a5876..d93b712 100644 --- a/vendor/github.com/prometheus/procfs/crypto.go +++ b/vendor/github.com/prometheus/procfs/crypto.go @@ -48,11 +48,13 @@ type Crypto struct { Walksize *uint64 } +var cryptoFile = "crypto" + // 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) { - path := fs.proc.Path("crypto") + path := fs.proc.Path(cryptoFile) b, err := util.ReadFileNoStat(path) if err != nil { return nil, fmt.Errorf("%w: Cannot read file %v: %w", ErrFileRead, b, err) @@ -82,6 +84,10 @@ func parseCrypto(r io.Reader) ([]Crypto, error) { continue } + if len(out) == 0 { + return nil, fmt.Errorf("%w: parsed invalid line before name parsed: %q", ErrFileParse, text) + } + kv := strings.Split(text, ":") if len(kv) != 2 { return nil, fmt.Errorf("%w: Cannot parse line: %q", ErrFileParse, text) diff --git a/vendor/github.com/prometheus/procfs/mountinfo.go b/vendor/github.com/prometheus/procfs/mountinfo.go index 9414a12..8594ae7 100644 --- a/vendor/github.com/prometheus/procfs/mountinfo.go +++ b/vendor/github.com/prometheus/procfs/mountinfo.go @@ -17,10 +17,10 @@ import ( "bufio" "bytes" "fmt" + "io" + "os" "strconv" "strings" - - "github.com/prometheus/procfs/internal/util" ) // A MountInfo is a type that describes the details, options @@ -160,9 +160,19 @@ func mountOptionsParser(mountOptions string) map[string]string { return opts } +// readMountInfo reads a full mountinfo file (no 1 MiB cap, unlike util.ReadFileNoStat). +func readMountInfo(path string) ([]byte, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + return io.ReadAll(f) +} + // GetMounts retrieves mountinfo information from `/proc/self/mountinfo`. func GetMounts() ([]*MountInfo, error) { - data, err := util.ReadFileNoStat("/proc/self/mountinfo") + data, err := readMountInfo("/proc/self/mountinfo") if err != nil { return nil, err } @@ -171,7 +181,7 @@ func GetMounts() ([]*MountInfo, error) { // GetProcMounts retrieves mountinfo information from a processes' `/proc//mountinfo`. func GetProcMounts(pid int) ([]*MountInfo, error) { - data, err := util.ReadFileNoStat(fmt.Sprintf("/proc/%d/mountinfo", pid)) + data, err := readMountInfo(fmt.Sprintf("/proc/%d/mountinfo", pid)) if err != nil { return nil, err } @@ -180,7 +190,7 @@ func GetProcMounts(pid int) ([]*MountInfo, error) { // GetMounts retrieves mountinfo information from `/proc/self/mountinfo`. func (fs FS) GetMounts() ([]*MountInfo, error) { - data, err := util.ReadFileNoStat(fs.proc.Path("self/mountinfo")) + data, err := readMountInfo(fs.proc.Path("self/mountinfo")) if err != nil { return nil, err } @@ -189,7 +199,7 @@ func (fs FS) GetMounts() ([]*MountInfo, error) { // GetProcMounts retrieves mountinfo information from a processes' `/proc//mountinfo`. func (fs FS) GetProcMounts(pid int) ([]*MountInfo, error) { - data, err := util.ReadFileNoStat(fs.proc.Path(fmt.Sprintf("%d/mountinfo", pid))) + data, err := readMountInfo(fs.proc.Path(fmt.Sprintf("%d/mountinfo", pid))) if err != nil { return nil, err } diff --git a/vendor/github.com/prometheus/procfs/net_wireless.go b/vendor/github.com/prometheus/procfs/net_wireless.go index 69d0794..f74dd3b 100644 --- a/vendor/github.com/prometheus/procfs/net_wireless.go +++ b/vendor/github.com/prometheus/procfs/net_wireless.go @@ -114,47 +114,47 @@ func parseWireless(r io.Reader) ([]*Wireless, error) { qlink, err := strconv.Atoi(strings.TrimSuffix(stats[1], ".")) if err != nil { - return nil, fmt.Errorf("%w: parse Quality:link as integer %q: %w", ErrFileParse, qlink, err) + return nil, fmt.Errorf("%w: parse Quality:link as integer %q: %w", ErrFileParse, stats[1], err) } qlevel, err := strconv.Atoi(strings.TrimSuffix(stats[2], ".")) if err != nil { - return nil, fmt.Errorf("%w: Quality:level as integer %q: %w", ErrFileParse, qlevel, err) + return nil, fmt.Errorf("%w: Quality:level as integer %q: %w", ErrFileParse, stats[2], err) } qnoise, err := strconv.Atoi(strings.TrimSuffix(stats[3], ".")) if err != nil { - return nil, fmt.Errorf("%w: Quality:noise as integer %q: %w", ErrFileParse, qnoise, err) + return nil, fmt.Errorf("%w: Quality:noise as integer %q: %w", ErrFileParse, stats[3], err) } dnwid, err := strconv.Atoi(stats[4]) if err != nil { - return nil, fmt.Errorf("%w: Discarded:nwid as integer %q: %w", ErrFileParse, dnwid, err) + return nil, fmt.Errorf("%w: Discarded:nwid as integer %q: %w", ErrFileParse, stats[4], err) } dcrypt, err := strconv.Atoi(stats[5]) if err != nil { - return nil, fmt.Errorf("%w: Discarded:crypt as integer %q: %w", ErrFileParse, dcrypt, err) + return nil, fmt.Errorf("%w: Discarded:crypt as integer %q: %w", ErrFileParse, stats[5], err) } dfrag, err := strconv.Atoi(stats[6]) if err != nil { - return nil, fmt.Errorf("%w: Discarded:frag as integer %q: %w", ErrFileParse, dfrag, err) + return nil, fmt.Errorf("%w: Discarded:frag as integer %q: %w", ErrFileParse, stats[6], err) } dretry, err := strconv.Atoi(stats[7]) if err != nil { - return nil, fmt.Errorf("%w: Discarded:retry as integer %q: %w", ErrFileParse, dretry, err) + return nil, fmt.Errorf("%w: Discarded:retry as integer %q: %w", ErrFileParse, stats[7], err) } dmisc, err := strconv.Atoi(stats[8]) if err != nil { - return nil, fmt.Errorf("%w: Discarded:misc as integer %q: %w", ErrFileParse, dmisc, err) + return nil, fmt.Errorf("%w: Discarded:misc as integer %q: %w", ErrFileParse, stats[8], err) } mbeacon, err := strconv.Atoi(stats[9]) if err != nil { - return nil, fmt.Errorf("%w: Missed:beacon as integer %q: %w", ErrFileParse, mbeacon, err) + return nil, fmt.Errorf("%w: Missed:beacon as integer %q: %w", ErrFileParse, stats[9], err) } w := &Wireless{ diff --git a/vendor/github.com/prometheus/procfs/proc_cgroup.go b/vendor/github.com/prometheus/procfs/proc_cgroup.go index 535c08d..7e8a122 100644 --- a/vendor/github.com/prometheus/procfs/proc_cgroup.go +++ b/vendor/github.com/prometheus/procfs/proc_cgroup.go @@ -60,7 +60,7 @@ func parseCgroupString(cgroupStr string) (*Cgroup, error) { } cgroup.HierarchyID, err = strconv.Atoi(fields[0]) if err != nil { - return nil, fmt.Errorf("%w: hierarchy ID: %q", ErrFileParse, cgroup.HierarchyID) + return nil, fmt.Errorf("%w: hierarchy ID: %q", ErrFileParse, fields[0]) } if fields[1] != "" { ssNames := strings.Split(fields[1], ",") diff --git a/vendor/github.com/prometheus/procfs/sysfs/class_fibrechannel.go b/vendor/github.com/prometheus/procfs/sysfs/class_fibrechannel.go index 7b46e02..a7844f1 100644 --- a/vendor/github.com/prometheus/procfs/sysfs/class_fibrechannel.go +++ b/vendor/github.com/prometheus/procfs/sysfs/class_fibrechannel.go @@ -154,6 +154,9 @@ func parseFibreChannelStatistics(hostPath string) (*FibreChannelCounters, error) path := filepath.Join(hostPath, "statistics") files, err := os.ReadDir(path) if err != nil { + if errors.Is(err, os.ErrNotExist) { + return &counters, nil + } return nil, err } diff --git a/vendor/github.com/prometheus/procfs/sysfs/class_mei.go b/vendor/github.com/prometheus/procfs/sysfs/class_mei.go new file mode 100644 index 0000000..93eee22 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/sysfs/class_mei.go @@ -0,0 +1,117 @@ +// Copyright 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. + +//go:build linux + +package sysfs + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/prometheus/procfs/internal/util" +) + +const meiClassPath = "class/mei" + +type MEIDev struct { + Dev *string + DevState *string + FWStatus *string + FWVersion *string + HBMVersion *string + HBMVersionDrv *string + Kind *string + Trc *string + TxQueueLimit *string +} + +type MEIClass map[string]MEIDev + +// MEIClass returns Management Engine Interface (MEI) information read from /sys/class/mei/. +func (fs FS) MEIClass() (*MEIClass, error) { + path := fs.sys.Path(meiClassPath) + + subdirs, err := os.ReadDir(path) + if err != nil { + return nil, fmt.Errorf("failed to list MEI devices at %q: %w", path, err) + } + + mei := make(MEIClass, len(subdirs)) + for _, d := range subdirs { + dev, err := fs.parseMEI(d.Name()) + if err != nil { + return nil, err + } + + mei[d.Name()] = dev + } + + return &mei, nil +} + +func (fs FS) parseMEI(meiDev string) (MEIDev, error) { + path := fs.sys.Path(meiClassPath, meiDev) + + var mei MEIDev + + files, err := os.ReadDir(path) + if err != nil { + return mei, fmt.Errorf("failed to read directory %q: %w", path, err) + } + + for _, f := range files { + if !f.Type().IsRegular() { + continue + } + + name := f.Name() + if name == "uevent" { + continue + } + + filename := filepath.Join(path, name) + value, err := util.SysReadFile(filename) + if err != nil { + if os.IsPermission(err) { + continue + } + + return mei, fmt.Errorf("failed to read file %q: %w", filename, err) + } + + switch name { + case "dev": + mei.Dev = &value + case "dev_state": + mei.DevState = &value + case "fw_status": + mei.FWStatus = &value + case "fw_ver": + mei.FWVersion = &value + case "hbm_ver": + mei.HBMVersion = &value + case "hbm_ver_drv": + mei.HBMVersionDrv = &value + case "kind": + mei.Kind = &value + case "trc": + mei.Trc = &value + case "tx_queue_limit": + mei.TxQueueLimit = &value + } + } + + return mei, nil +} diff --git a/vendor/github.com/prometheus/procfs/sysfs/class_nvme.go b/vendor/github.com/prometheus/procfs/sysfs/class_nvme.go index 7c4abb0..7c3638a 100644 --- a/vendor/github.com/prometheus/procfs/sysfs/class_nvme.go +++ b/vendor/github.com/prometheus/procfs/sysfs/class_nvme.go @@ -27,7 +27,7 @@ import ( const nvmeClassPath = "class/nvme" -var nvmeNamespacePattern = regexp.MustCompile(`nvme\d+c\d+n(\d+)`) +var nvmeNamespacePattern = regexp.MustCompile(`nvme\d+n(\d+)`) // NVMeNamespace contains info from files in /sys/class/nvme//. type NVMeNamespace struct { diff --git a/vendor/github.com/prometheus/procfs/sysfs/class_nvme_subsystem.go b/vendor/github.com/prometheus/procfs/sysfs/class_nvme_subsystem.go new file mode 100644 index 0000000..c222609 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/sysfs/class_nvme_subsystem.go @@ -0,0 +1,158 @@ +// Copyright 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. + +//go:build linux + +package sysfs + +import ( + "fmt" + "os" + "regexp" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +const nvmeSubsystemClassPath = "class/nvme-subsystem" + +var ( + nvmeSubsystemControllerRE = regexp.MustCompile(`^nvme\d+$`) + nvmeNamespaceRE = regexp.MustCompile(`^nvme\d+n\d+$`) +) + +// NVMeSubsystem contains info from /sys/class/nvme-subsystem//. +type NVMeSubsystem struct { + // Name is the subsystem directory name, e.g. "nvme-subsys0". + Name string + // NQN is the NVMe Qualified Name from subsysnqn. + NQN string + // Model is the subsystem model string. + Model string + // Serial is the subsystem serial number. + Serial string + // IOPolicy is the multipath I/O policy, e.g. "numa", "round-robin". + IOPolicy string + // Controllers lists the NVMe controllers under this subsystem. + Controllers []NVMeSubsystemController + // Namespaces lists the NVMe namespace block devices (e.g. "nvme0n1") + // that belong to this subsystem. + Namespaces []string +} + +// NVMeSubsystemController contains info about a single NVMe controller +// within an NVMe subsystem. +type NVMeSubsystemController struct { + // Name is the controller directory name, e.g. "nvme0". + Name string + // State is the controller state, e.g. "live", "connecting", "dead". + State string + // Transport is the transport type, e.g. "tcp", "fc", "rdma". + Transport string + // Address is the controller address string. + Address string +} + +// NVMeSubsystemClass is a collection of NVMe subsystems from +// /sys/class/nvme-subsystem. +type NVMeSubsystemClass []NVMeSubsystem + +// NVMeSubsystemClass returns info for all NVMe subsystems read from +// /sys/class/nvme-subsystem. +func (fs FS) NVMeSubsystemClass() (NVMeSubsystemClass, error) { + path := fs.sys.Path(nvmeSubsystemClassPath) + + entries, err := os.ReadDir(path) + if err != nil { + return nil, err + } + + var subsystems NVMeSubsystemClass + for _, entry := range entries { + if !strings.HasPrefix(entry.Name(), "nvme-subsys") { + continue + } + subsys, err := fs.parseNVMeSubsystem(entry.Name()) + if err != nil { + return nil, err + } + subsystems = append(subsystems, *subsys) + } + + return subsystems, nil +} + +func (fs FS) parseNVMeSubsystem(name string) (*NVMeSubsystem, error) { + path := fs.sys.Path(nvmeSubsystemClassPath, name) + subsys := &NVMeSubsystem{Name: name} + + for _, attr := range [...]struct { + file string + dest *string + }{ + {"subsysnqn", &subsys.NQN}, + {"model", &subsys.Model}, + {"serial", &subsys.Serial}, + {"iopolicy", &subsys.IOPolicy}, + } { + val, err := util.SysReadFile(fs.sys.Path(nvmeSubsystemClassPath, name, attr.file)) + if err != nil { + return nil, fmt.Errorf("failed to read %s for %s: %w", attr.file, name, err) + } + *attr.dest = val + } + + entries, err := os.ReadDir(path) + if err != nil { + return nil, fmt.Errorf("failed to list controllers for %s: %w", name, err) + } + + seen := make(map[string]bool) + for _, entry := range entries { + eName := entry.Name() + if nvmeSubsystemControllerRE.MatchString(eName) { + ctrl, err := fs.parseNVMeSubsystemController(name, eName) + if err != nil { + return nil, err + } + subsys.Controllers = append(subsys.Controllers, *ctrl) + } + if nvmeNamespaceRE.MatchString(eName) && !seen[eName] { + seen[eName] = true + subsys.Namespaces = append(subsys.Namespaces, eName) + } + } + + return subsys, nil +} + +func (fs FS) parseNVMeSubsystemController(subsysName, ctrlName string) (*NVMeSubsystemController, error) { + ctrl := &NVMeSubsystemController{Name: ctrlName} + + for _, attr := range [...]struct { + file string + dest *string + }{ + {"state", &ctrl.State}, + {"transport", &ctrl.Transport}, + {"address", &ctrl.Address}, + } { + val, err := util.SysReadFile(fs.sys.Path(nvmeSubsystemClassPath, subsysName, ctrlName, attr.file)) + if err != nil { + return nil, fmt.Errorf("failed to read %s for %s/%s: %w", attr.file, subsysName, ctrlName, err) + } + *attr.dest = val + } + + return ctrl, nil +} diff --git a/vendor/github.com/prometheus/procfs/sysfs/class_thermal.go b/vendor/github.com/prometheus/procfs/sysfs/class_thermal.go index db83286..8372f13 100644 --- a/vendor/github.com/prometheus/procfs/sysfs/class_thermal.go +++ b/vendor/github.com/prometheus/procfs/sysfs/class_thermal.go @@ -17,12 +17,10 @@ package sysfs import ( "errors" + "fmt" "os" "path/filepath" "strings" - "syscall" - - fsp "io/fs" "github.com/prometheus/procfs/internal/util" ) @@ -37,6 +35,9 @@ type ClassThermalZoneStats struct { Policy string // One of the various thermal governors used for a particular zone. Mode *bool // Optional: One of the predefined values in [enabled, disabled]. Passive *uint64 // Optional: millidegrees Celsius. (0 for disabled, > 1000 for enabled+value) + + // ReadError contains any errors returned when gathering data. + ReadErrors error } // ClassThermalZoneStats returns Thermal Zone metrics for all zones. @@ -48,39 +49,33 @@ func (fs FS) ClassThermalZoneStats() ([]ClassThermalZoneStats, error) { stats := make([]ClassThermalZoneStats, 0, len(zones)) for _, zone := range zones { - zoneStats, err := parseClassThermalZone(zone) - if err != nil { - if errors.Is(err, syscall.ENODATA) || errors.As(err, new(*fsp.PathError)) || errors.Is(err, syscall.EAGAIN) || - errors.Is(err, syscall.EINVAL) { - continue - } - return nil, err - } + zoneStats := parseClassThermalZone(zone) zoneStats.Name = strings.TrimPrefix(filepath.Base(zone), "thermal_zone") stats = append(stats, zoneStats) } return stats, nil } -func parseClassThermalZone(zone string) (ClassThermalZoneStats, error) { +func parseClassThermalZone(zone string) ClassThermalZoneStats { + var errs []error // Required attributes. zoneType, err := util.SysReadFile(filepath.Join(zone, "type")) if err != nil { - return ClassThermalZoneStats{}, err + errs = append(errs, fmt.Errorf("error reading type: %w", err)) } zonePolicy, err := util.SysReadFile(filepath.Join(zone, "policy")) if err != nil { - return ClassThermalZoneStats{}, err + errs = append(errs, fmt.Errorf("error reading policy: %w", err)) } zoneTemp, err := util.SysReadIntFromFile(filepath.Join(zone, "temp")) - if err != nil { - return ClassThermalZoneStats{}, err + if err != nil && !errors.Is(err, os.ErrInvalid) { + errs = append(errs, fmt.Errorf("error reading temp: %w", err)) } // Optional attributes. mode, err := util.SysReadFile(filepath.Join(zone, "mode")) if err != nil && !os.IsNotExist(err) && !os.IsPermission(err) { - return ClassThermalZoneStats{}, err + errs = append(errs, fmt.Errorf("error reading mode: %w", err)) } zoneMode := util.ParseBool(mode) @@ -90,16 +85,17 @@ func parseClassThermalZone(zone string) (ClassThermalZoneStats, error) { case os.IsNotExist(err), os.IsPermission(err): zonePassive = nil case err != nil: - return ClassThermalZoneStats{}, err + errs = append(errs, fmt.Errorf("error reading passive: %w", err)) default: zonePassive = &passive } return ClassThermalZoneStats{ - Type: zoneType, - Policy: zonePolicy, - Temp: zoneTemp, - Mode: zoneMode, - Passive: zonePassive, - }, nil + Type: zoneType, + Policy: zonePolicy, + Temp: zoneTemp, + Mode: zoneMode, + Passive: zonePassive, + ReadErrors: errors.Join(errs...), + } } diff --git a/vendor/github.com/prometheus/procfs/sysfs/mdraid.go b/vendor/github.com/prometheus/procfs/sysfs/mdraid.go index 139c7eb..d706d21 100644 --- a/vendor/github.com/prometheus/procfs/sysfs/mdraid.go +++ b/vendor/github.com/prometheus/procfs/sysfs/mdraid.go @@ -17,7 +17,9 @@ package sysfs import ( "fmt" + "os" "path/filepath" + "strconv" "strings" "github.com/prometheus/procfs/internal/util" @@ -26,10 +28,10 @@ import ( // Mdraid holds info parsed from relevant files in the /sys/block/md*/md directory. type Mdraid struct { Device string // Kernel device name of array. - Level string // mdraid level. + Level string // mdraid level. Empty if level file is unreadable. ArrayState string // State of the array. MetadataVersion string // mdraid metadata version. - Disks uint64 // Number of devices in a fully functional array. + Disks *uint64 // Number of devices in a fully functional array. Nil when unavailable (e.g. container/imsm/ddf, empty level, or empty raid_disks). Components []MdraidComponent // mdraid component devices. UUID string // UUID of the array. @@ -81,10 +83,38 @@ func (fs FS) Mdraids() ([]Mdraid, error) { return mdraids, err } - if val, err := util.ReadUintFromFile(filepath.Join(path, "raid_disks")); err == nil { - md.Disks = val - } else { - return mdraids, err + // Parse raid_disks: + // - Container types (container/imsm/ddf) have no physical disks assigned. + // - Empty level file means we can't determine the array type, skip parsing. + // - During reshape/grow, raid_disks may contain "current (previous)" (e.g. "11 (10)"). + // - Normal case is a plain integer. + switch md.Level { + case "container", "imsm", "ddf": + // No disks for container-type arrays, Disks remains nil. + case "": + // Empty level file, cannot determine disk count, Disks remains nil. + default: + data, err := os.ReadFile(filepath.Join(path, "raid_disks")) + if err != nil { + return mdraids, fmt.Errorf("reading raid_disks for %s: %w", md.Device, err) + } + content := strings.TrimSpace(string(data)) + if content == "" { + // Empty file, Disks remains nil. + break + } + + // Try normal integer parse first. + if val, parseErr := strconv.ParseUint(content, 10, 64); parseErr == nil { + md.Disks = &val + } else if idx := strings.Index(content, " "); idx > 0 { + // Reshape format: "current (previous)", extract the first number. + if val, parseErr := strconv.ParseUint(content[:idx], 10, 64); parseErr == nil { + md.Disks = &val + } + // If parsing fails, Disks remains nil (reshape in progress, count may be inaccurate). + } + // If neither format matches, Disks remains nil. } if val, err := util.SysReadFile(filepath.Join(path, "uuid")); err == nil { diff --git a/vendor/github.com/prometheus/procfs/sysfs/system_cpu.go b/vendor/github.com/prometheus/procfs/sysfs/system_cpu.go index 1db7e0c..12c5b0b 100644 --- a/vendor/github.com/prometheus/procfs/sysfs/system_cpu.go +++ b/vendor/github.com/prometheus/procfs/sysfs/system_cpu.go @@ -53,6 +53,7 @@ type CPUThermalThrottle struct { type SystemCPUCpufreqStats struct { Name string CpuinfoCurrentFrequency *uint64 + CpuinfoAverageFrequency *uint64 CpuinfoMinimumFrequency *uint64 CpuinfoMaximumFrequency *uint64 CpuinfoTransitionLatency *uint64 @@ -269,6 +270,7 @@ func (fs FS) SystemCpufreq() ([]SystemCPUCpufreqStats, error) { func parseCpufreqCpuinfo(cpuPath string) (*SystemCPUCpufreqStats, error) { uintFiles := []string{ "cpuinfo_cur_freq", + "cpuinfo_avg_freq", "cpuinfo_max_freq", "cpuinfo_min_freq", "cpuinfo_transition_latency", @@ -380,12 +382,13 @@ func parseCpufreqCpuinfo(cpuPath string) (*SystemCPUCpufreqStats, error) { return &SystemCPUCpufreqStats{ CpuinfoCurrentFrequency: uintOut[0], - CpuinfoMaximumFrequency: uintOut[1], - CpuinfoMinimumFrequency: uintOut[2], - CpuinfoTransitionLatency: uintOut[3], - ScalingCurrentFrequency: uintOut[4], - ScalingMaximumFrequency: uintOut[5], - ScalingMinimumFrequency: uintOut[6], + CpuinfoAverageFrequency: uintOut[1], + CpuinfoMaximumFrequency: uintOut[2], + CpuinfoMinimumFrequency: uintOut[3], + CpuinfoTransitionLatency: uintOut[4], + ScalingCurrentFrequency: uintOut[5], + ScalingMaximumFrequency: uintOut[6], + ScalingMinimumFrequency: uintOut[7], AvailableGovernors: stringOut[0], Driver: stringOut[1], Governor: stringOut[2], diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go index f69fd75..c261a8e 100644 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -109,7 +109,7 @@ func (g *Group) TryGo(f func() error) bool { if g.sem != nil { select { case g.sem <- token{}: - // Note: this allows barging iff channels in general allow barging. + // Note: this allows barging if and only if channels in general allow barging. default: return false } diff --git a/vendor/modules.txt b/vendor/modules.txt index b5d8cf4..f95cadc 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -92,7 +92,7 @@ github.com/prometheus/common/version ## explicit; go 1.25.0 github.com/prometheus/exporter-toolkit/web github.com/prometheus/exporter-toolkit/web/kingpinflag -# github.com/prometheus/procfs v0.20.1 +# github.com/prometheus/procfs v0.21.1 ## explicit; go 1.25.0 github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs @@ -150,7 +150,7 @@ golang.org/x/net/trace golang.org/x/oauth2 golang.org/x/oauth2/clientcredentials golang.org/x/oauth2/internal -# golang.org/x/sync v0.20.0 +# golang.org/x/sync v0.21.0 ## explicit; go 1.25.0 golang.org/x/sync/errgroup # golang.org/x/sys v0.46.0