Skip to content

PMM-14832 make mount path configurable#208

Open
nmarukovich wants to merge 1 commit intopercona:mainfrom
nmarukovich:PMM-14832
Open

PMM-14832 make mount path configurable#208
nmarukovich wants to merge 1 commit intopercona:mainfrom
nmarukovich:PMM-14832

Conversation

@nmarukovich
Copy link

By design, node_exporter first tries to read /proc/1/mounts and only falls back to /proc/self/mounts if /proc/1/mounts is not accessible.

However, with shareProcessNamespace enabled (like we have in postgres operator):

PID 1 inside the Pod belongs to the /pause container.

The /pause container runs in a restricted mount namespace.

As a result, /proc/1/mounts only reflects the limited mount view of the /pause container.

It does not expose the full set of actual node mounts.

Because /proc/1/mounts is technically accessible, node_exporter does not fall back to /proc/self/mounts.

This leads to incomplete or incorrect mount metrics being collected by node_exporter

@nmarukovich nmarukovich requested a review from a team as a code owner February 26, 2026 08:33
@nmarukovich nmarukovich requested review from ademidoff and maxkondr and removed request for a team February 26, 2026 08:33
@it-percona-cla
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes the filesystem collector’s mount-info source configurable so deployments affected by shareProcessNamespace (where /proc/1/mounts reflects the pause container’s restricted mount namespace) can point the collector at a more accurate mounts file.

Changes:

  • Add --collector.filesystem.mount-info-path to override the mounts file used by the filesystem collector.
  • Update mountPointDetails to read the override path when provided and limit fallback behavior to the default mode.
  • Add a unit test validating that the override path takes precedence over --path.procfs.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
collector/filesystem_linux.go Introduces a new CLI flag and uses it to select the mounts file path in mountPointDetails.
collector/filesystem_linux_test.go Adds coverage for the new override flag behavior using fixtures.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +146 to +154
func TestMountInfoPathOverride(t *testing.T) {
// --path.procfs points to fixtures with 25+ mount points,
// but --collector.filesystem.mount-info-path overrides to a file with only 1 mount.
if _, err := kingpin.CommandLine.Parse([]string{
"--path.procfs", "./fixtures/proc",
"--collector.filesystem.mount-info-path", "./fixtures_hidepid/proc/mounts",
}); err != nil {
t.Fatal(err)
}
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test sets the global --collector.filesystem.mount-info-path via kingpin.CommandLine.Parse but never restores it. Because kingpin flag values persist across parses and Go test order is not guaranteed, this can make other tests in this package order-dependent/flaky (they don’t pass the flag, so they may inherit the previous value). Consider saving the prior *mountInfoPath and restoring it in t.Cleanup, or explicitly setting the flag back to empty in other tests that call mountPointDetails.

Copilot uses AI. Check for mistakes.
"how many stat calls to process simultaneously").
Hidden().Default("4").Int()
var mountInfoPath = kingpin.Flag("collector.filesystem.mount-info-path",
"Override path to mounts file. If set, disables the default /proc/1/mounts fallback logic.").
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--collector.filesystem.mount-info-path is treated as an exact filesystem path and bypasses --path.procfs entirely. That can be surprising for users who expect a value like mounts or self/mounts to be resolved under the configured procfs mountpoint (similar to other proc-based reads in this package). Either document that the flag must be an absolute/fully-qualified path, or resolve relative values against procFilePath(...) for consistency.

Suggested change
"Override path to mounts file. If set, disables the default /proc/1/mounts fallback logic.").
"Override absolute path to mounts file. This must be a fully-qualified filesystem path; relative paths are not resolved against --path.procfs. If set, disables the default /proc/1/mounts fallback logic.").

Copilot uses AI. Check for mistakes.
Comment on lines +190 to 191
if errors.Is(err, os.ErrNotExist) && *mountInfoPath == "" {
// Fallback to `/proc/mounts` if `/proc/1/mounts` is missing due hidepid.
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fallback to procFilePath("mounts") is only triggered on os.ErrNotExist. In common hidepid/permission-restricted setups, opening /proc/1/mounts often fails with EACCES (permission denied) rather than being missing, which would currently return an error and skip the intended fallback. Consider broadening the fallback condition (e.g., also on os.ErrPermission or on any open error when mountInfoPath is unset), and update the comment accordingly.

Suggested change
if errors.Is(err, os.ErrNotExist) && *mountInfoPath == "" {
// Fallback to `/proc/mounts` if `/proc/1/mounts` is missing due hidepid.
if err != nil && *mountInfoPath == "" {
// Fallback to `/proc/mounts` if `/proc/1/mounts` is missing or inaccessible (e.g. hidepid/permission restrictions).

Copilot uses AI. Check for mistakes.
@ademidoff
Copy link
Member

@nmarukovich Could you please sign the CLA?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants