Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions disk/disk_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,14 +374,21 @@ func parseFieldsOnMountinfo(ctx context.Context, lines []string, all bool, filen
device = mntSrc
}

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

seenDevIDs[blockDeviceID] = mountPoint
if _, ok := seenDevIDs[blockDeviceID]; !ok {
seenDevIDs[blockDeviceID] = device
}

if !all && isBind {
continue
Expand Down
25 changes: 24 additions & 1 deletion disk/disk_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func Test_parseFieldsOnMountinfo(t *testing.T) {
expect: []PartitionStat{
{Device: "/dev/sda1", Mountpoint: "/", Fstype: "ext4", Opts: []string{"rw", "noatime"}},
{Device: "/dev/sda2", Mountpoint: "/foo", Fstype: "ext4", Opts: []string{"rw", "noatime"}},
{Device: "/foo", Mountpoint: "/foo/bar", Fstype: "ext4", Opts: []string{"rw", "noatime", "bind"}},
{Device: "/dev/sda2", Mountpoint: "/foo/bar", Fstype: "ext4", Opts: []string{"rw", "noatime", "bind"}},
{Device: "-", Mountpoint: "/dev/shm", Fstype: "tmpfs", Opts: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}},
{Device: "net:[12345]", Mountpoint: "/run/netns/foo", Fstype: "nsfs", Opts: []string{"rw"}},
{Device: "sysfs", Mountpoint: "/sys", Fstype: "sysfs", Opts: []string{"rw", "nosuid", "nodev", "noexec", "noatime"}},
Expand All @@ -56,6 +56,29 @@ func Test_parseFieldsOnMountinfo(t *testing.T) {
}
}

func Test_parseFieldsOnMountinfo_multiMount(t *testing.T) {
// Reproduces issue #2005: same block device (259:4) mounted multiple times
// with different rootDirs. Bind mounts should be detected by rootDir != "/",
// not by whether the device ID was seen before.
lines := []string{
"1204 1184 259:4 /var/lib/kubelet/pods/abc/volumes/tmp /tmp rw,relatime shared:1 - ext4 /dev/nvme0n1p3 rw",
"1205 1184 259:4 /var/lib/kubelet/pods/abc/volumes/config /etc/datadog-agent rw,relatime shared:1 - ext4 /dev/nvme0n1p3 rw",
"1209 1184 259:4 /etc/passwd /etc/passwd ro,relatime shared:1 - ext4 /dev/nvme0n1p3 rw",
"1210 1184 259:4 / /host/root ro,relatime shared:1 - ext4 /dev/nvme0n1p3 rw",
}

actual, err := parseFieldsOnMountinfo(context.Background(), lines, true, "")
require.NoError(t, err)

expected := []PartitionStat{
{Device: "/dev/nvme0n1p3", Mountpoint: "/tmp", Fstype: "ext4", Opts: []string{"rw", "relatime", "bind"}},
{Device: "/dev/nvme0n1p3", Mountpoint: "/etc/datadog-agent", Fstype: "ext4", Opts: []string{"rw", "relatime", "bind"}},
{Device: "/dev/nvme0n1p3", Mountpoint: "/etc/passwd", Fstype: "ext4", Opts: []string{"ro", "relatime", "bind"}},
{Device: "/dev/nvme0n1p3", Mountpoint: "/host/root", Fstype: "ext4", Opts: []string{"ro", "relatime"}},
}
assert.Equal(t, expected, actual)
}

func Test_parseFieldsOnMounts(t *testing.T) {
fs := []string{"sysfs", "tmpfs"}

Expand Down