Skip to content

Commit 57a2c80

Browse files
authored
Merge pull request #2775 from gjkim42/0.38-backport-2752
Cherrypick to v0.38: Return correct DeviceInfo from GetDirFsDevice on / path for Btrfs - Fix kubernetes issue #94335
2 parents 0d75c01 + d3d4900 commit 57a2c80

File tree

2 files changed

+36
-17
lines changed

2 files changed

+36
-17
lines changed

fs/fs.go

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -527,22 +527,7 @@ func (i *RealFsInfo) GetDeviceInfoByFsUUID(uuid string) (*DeviceInfo, error) {
527527
return &DeviceInfo{deviceName, p.major, p.minor}, nil
528528
}
529529

530-
func (i *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
531-
buf := new(syscall.Stat_t)
532-
err := syscall.Stat(dir, buf)
533-
if err != nil {
534-
return nil, fmt.Errorf("stat failed on %s with error: %s", dir, err)
535-
}
536-
537-
// The type Dev in Stat_t is 32bit on mips.
538-
major := major(uint64(buf.Dev)) // nolint: unconvert
539-
minor := minor(uint64(buf.Dev)) // nolint: unconvert
540-
for device, partition := range i.partitions {
541-
if partition.major == major && partition.minor == minor {
542-
return &DeviceInfo{device, major, minor}, nil
543-
}
544-
}
545-
530+
func (i *RealFsInfo) mountInfoFromDir(dir string) (*mount.MountInfo, bool) {
546531
mount, found := i.mounts[dir]
547532
// try the parent dir if not found until we reach the root dir
548533
// this is an issue on btrfs systems where the directory is not
@@ -551,16 +536,36 @@ func (i *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
551536
pathdir, _ := filepath.Split(dir)
552537
// break when we reach root
553538
if pathdir == "/" {
539+
mount, found = i.mounts["/"]
554540
break
555541
}
556542
// trim "/" from the new parent path otherwise the next possible
557543
// filepath.Split in the loop will not split the string any further
558544
dir = strings.TrimSuffix(pathdir, "/")
559545
mount, found = i.mounts[dir]
560546
}
547+
return &mount, found
548+
}
549+
550+
func (i *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
551+
buf := new(syscall.Stat_t)
552+
err := syscall.Stat(dir, buf)
553+
if err != nil {
554+
return nil, fmt.Errorf("stat failed on %s with error: %s", dir, err)
555+
}
556+
557+
// The type Dev in Stat_t is 32bit on mips.
558+
major := major(uint64(buf.Dev)) // nolint: unconvert
559+
minor := minor(uint64(buf.Dev)) // nolint: unconvert
560+
for device, partition := range i.partitions {
561+
if partition.major == major && partition.minor == minor {
562+
return &DeviceInfo{device, major, minor}, nil
563+
}
564+
}
561565

566+
mount, found := i.mountInfoFromDir(dir)
562567
if found && mount.FsType == "btrfs" && mount.Major == 0 && strings.HasPrefix(mount.Source, "/dev/") {
563-
major, minor, err := getBtrfsMajorMinorIds(&mount)
568+
major, minor, err := getBtrfsMajorMinorIds(mount)
564569
if err != nil {
565570
klog.Warningf("%s", err)
566571
} else {

fs/fs_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,20 @@ import (
2727
"k8s.io/utils/mount"
2828
)
2929

30+
func TestMountInfoFromDir(t *testing.T) {
31+
as := assert.New(t)
32+
fsInfo := &RealFsInfo{
33+
mounts: map[string]mount.MountInfo{
34+
"/": {},
35+
},
36+
}
37+
testDirs := []string{"/var/lib/kubelet", "/var/lib/rancher"}
38+
for _, testDir := range testDirs {
39+
_, found := fsInfo.mountInfoFromDir(testDir)
40+
as.True(found, "failed to find MountInfo %s from FsInfo %s", testDir, fsInfo)
41+
}
42+
}
43+
3044
func TestGetDiskStatsMap(t *testing.T) {
3145
diskStatsMap, err := getDiskStatsMap("test_resources/diskstats")
3246
if err != nil {

0 commit comments

Comments
 (0)