File kubelet-support-btrfs-fixes-bsc-1042383.patch of Package kubernetes

From 434c8c0aa319e3b3da8d64d833fb03dda906d050 Mon Sep 17 00:00:00 2001
From: Flavio Castelli <fcastelli@suse.com>
Date: Tue, 6 Jun 2017 16:48:57 +0200
Subject: [PATCH] kubelet: fix disk space check on btrfs (issue 47046)

This commit fixes the warning messages reported by kubelet when
checking for the disk space on a btrfs `/` which has `/var/lib/kubelet`
inside of a btrfs sub-volume.

This fix follows the same principle adopted to fix issue #38337 with
commit dc8b6cc.

This commit fixes issue 47046.

Signed-off-by: Flavio Castelli <fcastelli@suse.com>
---
 vendor/github.com/google/cadvisor/fs/fs.go | 55 ++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

Index: kubernetes-1.7.0/vendor/github.com/google/cadvisor/fs/fs.go
===================================================================
--- kubernetes-1.7.0.orig/vendor/github.com/google/cadvisor/fs/fs.go
+++ kubernetes-1.7.0/vendor/github.com/google/cadvisor/fs/fs.go
@@ -79,6 +79,8 @@ type RealFsInfo struct {
 	// Map from label to block device path.
 	// Labels are intent-specific tags that are auto-detected.
 	labels map[string]string
+	// Map from mountpoint to mount information.
+	mounts map[string]*mount.Info
 	// devicemapper client
 	dmsetup devicemapper.DmsetupClient
 }
@@ -106,9 +108,14 @@ func NewFsInfo(context Context) (FsInfo,
 	fsInfo := &RealFsInfo{
 		partitions: processMounts(mounts, excluded),
 		labels:     make(map[string]string, 0),
+		mounts:     make(map[string]*mount.Info, 0),
 		dmsetup:    devicemapper.NewDmsetupClient(),
 	}
 
+	for _, mount := range mounts {
+		fsInfo.mounts[mount.Mountpoint] = mount
+	}
+
 	fsInfo.addRktImagesLabel(context, mounts)
 	// need to call this before the log line below printing out the partitions, as this function may
 	// add a "partition" for devicemapper to fsInfo.partitions
@@ -152,25 +159,10 @@ func processMounts(mounts []*mount.Info,
 		// btrfs fix: following workaround fixes wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo.
 		// instead of using values from /proc/self/mountinfo we use stat to get Ids from btrfs mount point
 		if mount.Fstype == "btrfs" && mount.Major == 0 && strings.HasPrefix(mount.Source, "/dev/") {
-
-			buf := new(syscall.Stat_t)
-			err := syscall.Stat(mount.Source, buf)
-			if err != nil {
-				glog.Warningf("stat failed on %s with error: %s", mount.Source, err)
-			} else {
-				glog.Infof("btrfs mount %#v", mount)
-				if buf.Mode&syscall.S_IFMT == syscall.S_IFBLK {
-					err := syscall.Stat(mount.Mountpoint, buf)
-					if err != nil {
-						glog.Warningf("stat failed on %s with error: %s", mount.Mountpoint, err)
-					} else {
-						glog.Infof("btrfs dev major:minor %d:%d\n", int(major(buf.Dev)), int(minor(buf.Dev)))
-						glog.Infof("btrfs rdev major:minor %d:%d\n", int(major(buf.Rdev)), int(minor(buf.Rdev)))
-
-						mount.Major = int(major(buf.Dev))
-						mount.Minor = int(minor(buf.Dev))
-					}
-				}
+			major, minor, ok := getBtrfsMajorMinorIds(mount)
+			if ok {
+				mount.Major = major
+				mount.Minor = minor
 			}
 		}
 
@@ -444,6 +436,7 @@ func (self *RealFsInfo) GetDirFsDevice(d
 	if err != nil {
 		return nil, fmt.Errorf("stat failed on %s with error: %s", dir, err)
 	}
+
 	major := major(buf.Dev)
 	minor := minor(buf.Dev)
 	for device, partition := range self.partitions {
@@ -451,6 +444,14 @@ func (self *RealFsInfo) GetDirFsDevice(d
 			return &DeviceInfo{device, major, minor}, nil
 		}
 	}
+
+	mount, ok := self.mounts[dir]
+	if ok && mount.Fstype == "btrfs" && mount.Major == 0 && strings.HasPrefix(mount.Source, "/dev/") {
+		major, minor, ok := getBtrfsMajorMinorIds(mount)
+		if ok {
+			return &DeviceInfo{mount.Source, uint(major), uint(minor)}, nil
+		}
+	}
 	return nil, fmt.Errorf("could not find device with major: %d, minor: %d in cached partitions map", major, minor)
 }
 
@@ -637,6 +638,35 @@ func getZfstats(poolName string) (uint64
 	return total, dataset.Avail, dataset.Avail, nil
 }
 
+// Get major and minor Ids for a mount point using btrfs as filesystem.
+// The boolean is set to true when both the values are successfully retrieved.
+func getBtrfsMajorMinorIds(mount *mount.Info) (int, int, bool) {
+	// btrfs fix: following workaround fixes wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo.
+	// instead of using values from /proc/self/mountinfo we use stat to get Ids from btrfs mount point
+
+	buf := new(syscall.Stat_t)
+	err := syscall.Stat(mount.Source, buf)
+	if err != nil {
+		glog.Warningf("stat failed on %s with error: %s", mount.Source, err)
+		return 0, 0, false
+	}
+
+	glog.Infof("btrfs mount %#v", mount)
+	if buf.Mode&syscall.S_IFMT == syscall.S_IFBLK {
+		err := syscall.Stat(mount.Mountpoint, buf)
+		if err != nil {
+			glog.Warningf("stat failed on %s with error: %s", mount.Mountpoint, err)
+			return 0, 0, false
+		}
+
+		glog.Infof("btrfs dev major:minor %d:%d\n", int(major(buf.Dev)), int(minor(buf.Dev)))
+		glog.Infof("btrfs rdev major:minor %d:%d\n", int(major(buf.Rdev)), int(minor(buf.Rdev)))
+
+		return int(major(buf.Dev)), int(minor(buf.Dev)), true
+	}
+	return 0, 0, false
+}
+
 // Simple io.Writer implementation that counts how many bytes were written.
 type byteCounter struct{ bytesWritten uint64 }
 
openSUSE Build Service is sponsored by