Skip to content

Commit

Permalink
Merge pull request #2775 from gjkim42/0.38-backport-2752
Browse files Browse the repository at this point in the history
Cherrypick to v0.38: Return correct DeviceInfo from GetDirFsDevice on / path for Btrfs - Fix kubernetes issue #94335
  • Loading branch information
bobbypage committed Jan 12, 2021
2 parents 0d75c01 + d3d4900 commit 57a2c80
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 17 deletions.
39 changes: 22 additions & 17 deletions fs/fs.go
Expand Up @@ -527,22 +527,7 @@ func (i *RealFsInfo) GetDeviceInfoByFsUUID(uuid string) (*DeviceInfo, error) {
return &DeviceInfo{deviceName, p.major, p.minor}, nil
}

func (i *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
buf := new(syscall.Stat_t)
err := syscall.Stat(dir, buf)
if err != nil {
return nil, fmt.Errorf("stat failed on %s with error: %s", dir, err)
}

// The type Dev in Stat_t is 32bit on mips.
major := major(uint64(buf.Dev)) // nolint: unconvert
minor := minor(uint64(buf.Dev)) // nolint: unconvert
for device, partition := range i.partitions {
if partition.major == major && partition.minor == minor {
return &DeviceInfo{device, major, minor}, nil
}
}

func (i *RealFsInfo) mountInfoFromDir(dir string) (*mount.MountInfo, bool) {
mount, found := i.mounts[dir]
// try the parent dir if not found until we reach the root dir
// this is an issue on btrfs systems where the directory is not
Expand All @@ -551,16 +536,36 @@ func (i *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
pathdir, _ := filepath.Split(dir)
// break when we reach root
if pathdir == "/" {
mount, found = i.mounts["/"]
break
}
// trim "/" from the new parent path otherwise the next possible
// filepath.Split in the loop will not split the string any further
dir = strings.TrimSuffix(pathdir, "/")
mount, found = i.mounts[dir]
}
return &mount, found
}

func (i *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
buf := new(syscall.Stat_t)
err := syscall.Stat(dir, buf)
if err != nil {
return nil, fmt.Errorf("stat failed on %s with error: %s", dir, err)
}

// The type Dev in Stat_t is 32bit on mips.
major := major(uint64(buf.Dev)) // nolint: unconvert
minor := minor(uint64(buf.Dev)) // nolint: unconvert
for device, partition := range i.partitions {
if partition.major == major && partition.minor == minor {
return &DeviceInfo{device, major, minor}, nil
}
}

mount, found := i.mountInfoFromDir(dir)
if found && mount.FsType == "btrfs" && mount.Major == 0 && strings.HasPrefix(mount.Source, "/dev/") {
major, minor, err := getBtrfsMajorMinorIds(&mount)
major, minor, err := getBtrfsMajorMinorIds(mount)
if err != nil {
klog.Warningf("%s", err)
} else {
Expand Down
14 changes: 14 additions & 0 deletions fs/fs_test.go
Expand Up @@ -27,6 +27,20 @@ import (
"k8s.io/utils/mount"
)

func TestMountInfoFromDir(t *testing.T) {
as := assert.New(t)
fsInfo := &RealFsInfo{
mounts: map[string]mount.MountInfo{
"/": {},
},
}
testDirs := []string{"/var/lib/kubelet", "/var/lib/rancher"}
for _, testDir := range testDirs {
_, found := fsInfo.mountInfoFromDir(testDir)
as.True(found, "failed to find MountInfo %s from FsInfo %s", testDir, fsInfo)
}
}

func TestGetDiskStatsMap(t *testing.T) {
diskStatsMap, err := getDiskStatsMap("test_resources/diskstats")
if err != nil {
Expand Down

0 comments on commit 57a2c80

Please sign in to comment.