Skip to content

Commit 2ef7eb7

Browse files
committed
[linux][disk]: fix disk mountinfo parsing bug
1 parent 962bfd8 commit 2ef7eb7

2 files changed

Lines changed: 36 additions & 6 deletions

File tree

disk/disk_linux.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,14 +374,21 @@ func parseFieldsOnMountinfo(ctx context.Context, lines []string, all bool, filen
374374
device = mntSrc
375375
}
376376

377-
if _, ok := seenDevIDs[blockDeviceID]; ok {
378-
// Bind mount; set the underlying mount path as the device.
379-
device = seenDevIDs[blockDeviceID]
377+
// Track device paths by block device ID to resolve bind mounts.
378+
// A bind mount is identified by rootDir != "/" (mounting a subdirectory of a filesystem).
379+
// Only apply bind detection for storage-backed filesystems (mntSrc starts with "/"),
380+
// since virtual filesystems (e.g. nsfs) use rootDir for non-path identifiers.
381+
if firstDev, ok := seenDevIDs[blockDeviceID]; ok {
382+
// Same block device seen before - use the original device path.
383+
device = firstDev
384+
}
385+
if strings.HasPrefix(mntSrc, "/") && rootDir != "/" {
380386
isBind = true
381387
mountOpts = append(mountOpts, "bind")
382388
}
383-
384-
seenDevIDs[blockDeviceID] = mountPoint
389+
if _, ok := seenDevIDs[blockDeviceID]; !ok {
390+
seenDevIDs[blockDeviceID] = device
391+
}
385392

386393
if !all && isBind {
387394
continue

disk/disk_linux_test.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func Test_parseFieldsOnMountinfo(t *testing.T) {
3131
expect: []PartitionStat{
3232
{Device: "/dev/sda1", Mountpoint: "/", Fstype: "ext4", Opts: []string{"rw", "noatime"}},
3333
{Device: "/dev/sda2", Mountpoint: "/foo", Fstype: "ext4", Opts: []string{"rw", "noatime"}},
34-
{Device: "/foo", Mountpoint: "/foo/bar", Fstype: "ext4", Opts: []string{"rw", "noatime", "bind"}},
34+
{Device: "/dev/sda2", Mountpoint: "/foo/bar", Fstype: "ext4", Opts: []string{"rw", "noatime", "bind"}},
3535
{Device: "-", Mountpoint: "/dev/shm", Fstype: "tmpfs", Opts: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}},
3636
{Device: "net:[12345]", Mountpoint: "/run/netns/foo", Fstype: "nsfs", Opts: []string{"rw"}},
3737
{Device: "sysfs", Mountpoint: "/sys", Fstype: "sysfs", Opts: []string{"rw", "nosuid", "nodev", "noexec", "noatime"}},
@@ -56,6 +56,29 @@ func Test_parseFieldsOnMountinfo(t *testing.T) {
5656
}
5757
}
5858

59+
func Test_parseFieldsOnMountinfo_multiMount(t *testing.T) {
60+
// Reproduces issue #2005: same block device (259:4) mounted multiple times
61+
// with different rootDirs. Bind mounts should be detected by rootDir != "/",
62+
// not by whether the device ID was seen before.
63+
lines := []string{
64+
"1204 1184 259:4 /var/lib/kubelet/pods/abc/volumes/tmp /tmp rw,relatime shared:1 - ext4 /dev/nvme0n1p3 rw",
65+
"1205 1184 259:4 /var/lib/kubelet/pods/abc/volumes/config /etc/datadog-agent rw,relatime shared:1 - ext4 /dev/nvme0n1p3 rw",
66+
"1209 1184 259:4 /etc/passwd /etc/passwd ro,relatime shared:1 - ext4 /dev/nvme0n1p3 rw",
67+
"1210 1184 259:4 / /host/root ro,relatime shared:1 - ext4 /dev/nvme0n1p3 rw",
68+
}
69+
70+
actual, err := parseFieldsOnMountinfo(context.Background(), lines, true, "")
71+
require.NoError(t, err)
72+
73+
expected := []PartitionStat{
74+
{Device: "/dev/nvme0n1p3", Mountpoint: "/tmp", Fstype: "ext4", Opts: []string{"rw", "relatime", "bind"}},
75+
{Device: "/dev/nvme0n1p3", Mountpoint: "/etc/datadog-agent", Fstype: "ext4", Opts: []string{"rw", "relatime", "bind"}},
76+
{Device: "/dev/nvme0n1p3", Mountpoint: "/etc/passwd", Fstype: "ext4", Opts: []string{"ro", "relatime", "bind"}},
77+
{Device: "/dev/nvme0n1p3", Mountpoint: "/host/root", Fstype: "ext4", Opts: []string{"ro", "relatime"}},
78+
}
79+
assert.Equal(t, expected, actual)
80+
}
81+
5982
func Test_parseFieldsOnMounts(t *testing.T) {
6083
fs := []string{"sysfs", "tmpfs"}
6184

0 commit comments

Comments
 (0)