| Copyright 2020 The Monogon Project Authors. | 
 |  | 
 | Licensed under the Apache License, Version 2.0 (the "License"); | 
 | you may not use this file except in compliance with the License. | 
 | You may obtain a copy of the License at | 
 |  | 
 |   http://www.apache.org/licenses/LICENSE-2.0 | 
 |  | 
 | Unless required by applicable law or agreed to in writing, software | 
 | distributed under the License is distributed on an "AS IS" BASIS, | 
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | See the License for the specific language governing permissions and | 
 | limitations under the License. | 
 |  | 
 |  | 
 | This rips out ZFS support from cadvisor. This should be turned into an upstream change for allowing zfs to be disabled via a build tag. | 
 |  | 
 | diff -ur com_github_google_cadvisor.orig/container/docker/factory.go com_github_google_cadvisor/container/docker/factory.go | 
 | --- com_github_google_cadvisor.orig/container/docker/factory.go	2020-04-15 17:54:23.082143453 +0200 | 
 | +++ com_github_google_cadvisor/container/docker/factory.go	2020-04-16 15:08:47.394501543 +0200 | 
 | @@ -34,7 +34,6 @@ | 
 |  	info "github.com/google/cadvisor/info/v1" | 
 |  	"github.com/google/cadvisor/machine" | 
 |  	"github.com/google/cadvisor/watcher" | 
 | -	"github.com/google/cadvisor/zfs" | 
 |   | 
 |  	docker "github.com/docker/docker/client" | 
 |  	"golang.org/x/net/context" | 
 | @@ -102,7 +101,6 @@ | 
 |  	aufsStorageDriver         storageDriver = "aufs" | 
 |  	overlayStorageDriver      storageDriver = "overlay" | 
 |  	overlay2StorageDriver     storageDriver = "overlay2" | 
 | -	zfsStorageDriver          storageDriver = "zfs" | 
 |  ) | 
 |   | 
 |  type dockerFactory struct { | 
 | @@ -127,8 +125,6 @@ | 
 |   | 
 |  	thinPoolName    string | 
 |  	thinPoolWatcher *devicemapper.ThinPoolWatcher | 
 | - | 
 | -	zfsWatcher *zfs.ZfsWatcher | 
 |  } | 
 |   | 
 |  func (self *dockerFactory) String() string { | 
 | @@ -157,7 +153,6 @@ | 
 |  		self.includedMetrics, | 
 |  		self.thinPoolName, | 
 |  		self.thinPoolWatcher, | 
 | -		self.zfsWatcher, | 
 |  	) | 
 |  	return | 
 |  } | 
 | @@ -246,21 +241,6 @@ | 
 |  	return thinPoolWatcher, nil | 
 |  } | 
 |   | 
 | -func startZfsWatcher(dockerInfo *dockertypes.Info) (*zfs.ZfsWatcher, error) { | 
 | -	filesystem, err := dockerutil.DockerZfsFilesystem(*dockerInfo) | 
 | -	if err != nil { | 
 | -		return nil, err | 
 | -	} | 
 | - | 
 | -	zfsWatcher, err := zfs.NewZfsWatcher(filesystem) | 
 | -	if err != nil { | 
 | -		return nil, err | 
 | -	} | 
 | - | 
 | -	go zfsWatcher.Start() | 
 | -	return zfsWatcher, nil | 
 | -} | 
 | - | 
 |  func ensureThinLsKernelVersion(kernelVersion string) error { | 
 |  	// kernel 4.4.0 has the proper bug fixes to allow thin_ls to work without corrupting the thin pool | 
 |  	minKernelVersion := semver.MustParse("4.4.0") | 
 | @@ -358,14 +338,6 @@ | 
 |  		thinPoolName = status.DriverStatus[dockerutil.DriverStatusPoolName] | 
 |  	} | 
 |   | 
 | -	var zfsWatcher *zfs.ZfsWatcher | 
 | -	if storageDriver(dockerInfo.Driver) == zfsStorageDriver { | 
 | -		zfsWatcher, err = startZfsWatcher(dockerInfo) | 
 | -		if err != nil { | 
 | -			klog.Errorf("zfs filesystem stats will not be reported: %v", err) | 
 | -		} | 
 | -	} | 
 | - | 
 |  	klog.V(1).Infof("Registering Docker factory") | 
 |  	f := &dockerFactory{ | 
 |  		cgroupSubsystems:   cgroupSubsystems, | 
 | @@ -379,7 +351,6 @@ | 
 |  		includedMetrics:    includedMetrics, | 
 |  		thinPoolName:       thinPoolName, | 
 |  		thinPoolWatcher:    thinPoolWatcher, | 
 | -		zfsWatcher:         zfsWatcher, | 
 |  	} | 
 |   | 
 |  	container.RegisterContainerHandlerFactory(f, []watcher.ContainerWatchSource{watcher.Raw}) | 
 | diff -ur com_github_google_cadvisor.orig/container/docker/handler.go com_github_google_cadvisor/container/docker/handler.go | 
 | --- com_github_google_cadvisor.orig/container/docker/handler.go	2020-04-15 17:54:23.082143453 +0200 | 
 | +++ com_github_google_cadvisor/container/docker/handler.go	2020-04-16 15:45:56.432489633 +0200 | 
 | @@ -25,12 +25,10 @@ | 
 |   | 
 |  	"github.com/google/cadvisor/container" | 
 |  	"github.com/google/cadvisor/container/common" | 
 | -	dockerutil "github.com/google/cadvisor/container/docker/utils" | 
 |  	containerlibcontainer "github.com/google/cadvisor/container/libcontainer" | 
 |  	"github.com/google/cadvisor/devicemapper" | 
 |  	"github.com/google/cadvisor/fs" | 
 |  	info "github.com/google/cadvisor/info/v1" | 
 | -	"github.com/google/cadvisor/zfs" | 
 |   | 
 |  	dockercontainer "github.com/docker/docker/api/types/container" | 
 |  	docker "github.com/docker/docker/client" | 
 | @@ -87,9 +85,6 @@ | 
 |  	// the devicemapper poolname | 
 |  	poolName string | 
 |   | 
 | -	// zfsParent is the parent for docker zfs | 
 | -	zfsParent string | 
 | - | 
 |  	// Reference to the container | 
 |  	reference info.ContainerReference | 
 |   | 
 | @@ -130,7 +125,6 @@ | 
 |  	includedMetrics container.MetricSet, | 
 |  	thinPoolName string, | 
 |  	thinPoolWatcher *devicemapper.ThinPoolWatcher, | 
 | -	zfsWatcher *zfs.ZfsWatcher, | 
 |  ) (container.ContainerHandler, error) { | 
 |  	// Create the cgroup paths. | 
 |  	cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name) | 
 | @@ -164,8 +158,6 @@ | 
 |  	// For devicemapper, we only need the thin pool name, and that is passed in to this call | 
 |  	var ( | 
 |  		rootfsStorageDir string | 
 | -		zfsFilesystem    string | 
 | -		zfsParent        string | 
 |  	) | 
 |  	switch storageDriver { | 
 |  	case aufsStorageDriver: | 
 | @@ -174,13 +166,6 @@ | 
 |  		rootfsStorageDir = path.Join(storageDir, string(storageDriver), rwLayerID, overlayRWLayer) | 
 |  	case overlay2StorageDriver: | 
 |  		rootfsStorageDir = path.Join(storageDir, string(storageDriver), rwLayerID, overlay2RWLayer) | 
 | -	case zfsStorageDriver: | 
 | -		status, err := Status() | 
 | -		if err != nil { | 
 | -			return nil, fmt.Errorf("unable to determine docker status: %v", err) | 
 | -		} | 
 | -		zfsParent = status.DriverStatus[dockerutil.DriverStatusParentDataset] | 
 | -		zfsFilesystem = path.Join(zfsParent, rwLayerID) | 
 |  	} | 
 |   | 
 |  	// We assume that if Inspect fails then the container is not known to docker. | 
 | @@ -200,7 +185,6 @@ | 
 |  		envs:               make(map[string]string), | 
 |  		labels:             ctnr.Config.Labels, | 
 |  		includedMetrics:    includedMetrics, | 
 | -		zfsParent:          zfsParent, | 
 |  	} | 
 |  	// Timestamp returned by Docker is in time.RFC3339Nano format. | 
 |  	handler.creationTime, err = time.Parse(time.RFC3339Nano, ctnr.Created) | 
 | @@ -244,9 +228,6 @@ | 
 |  		handler.fsHandler = &dockerFsHandler{ | 
 |  			fsHandler:       common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, otherStorageDir, fsInfo), | 
 |  			thinPoolWatcher: thinPoolWatcher, | 
 | -			zfsWatcher:      zfsWatcher, | 
 | -			deviceID:        ctnr.GraphDriver.Data["DeviceId"], | 
 | -			zfsFilesystem:   zfsFilesystem, | 
 |  		} | 
 |  	} | 
 |   | 
 | @@ -271,7 +252,7 @@ | 
 |  } | 
 |   | 
 |  // dockerFsHandler is a composite FsHandler implementation the incorporates | 
 | -// the common fs handler, a devicemapper ThinPoolWatcher, and a zfsWatcher | 
 | +// the common fs handler and a devicemapper ThinPoolWatcher | 
 |  type dockerFsHandler struct { | 
 |  	fsHandler common.FsHandler | 
 |   | 
 | @@ -279,11 +260,6 @@ | 
 |  	thinPoolWatcher *devicemapper.ThinPoolWatcher | 
 |  	// deviceID is the id of the container's fs device | 
 |  	deviceID string | 
 | - | 
 | -	// zfsWatcher is the zfs filesystem watcher | 
 | -	zfsWatcher *zfs.ZfsWatcher | 
 | -	// zfsFilesystem is the docker zfs filesystem | 
 | -	zfsFilesystem string | 
 |  } | 
 |   | 
 |  var _ common.FsHandler = &dockerFsHandler{} | 
 | @@ -316,16 +292,6 @@ | 
 |  			usage.TotalUsageBytes += thinPoolUsage | 
 |  		} | 
 |  	} | 
 | - | 
 | -	if h.zfsWatcher != nil { | 
 | -		zfsUsage, err := h.zfsWatcher.GetUsage(h.zfsFilesystem) | 
 | -		if err != nil { | 
 | -			klog.V(5).Infof("unable to get fs usage from zfs for filesystem %s: %v", h.zfsFilesystem, err) | 
 | -		} else { | 
 | -			usage.BaseUsageBytes = zfsUsage | 
 | -			usage.TotalUsageBytes += zfsUsage | 
 | -		} | 
 | -	} | 
 |  	return usage | 
 |  } | 
 |   | 
 | @@ -389,8 +355,6 @@ | 
 |  			return fmt.Errorf("unable to determine device info for dir: %v: %v", self.rootfsStorageDir, err) | 
 |  		} | 
 |  		device = deviceInfo.Device | 
 | -	case zfsStorageDriver: | 
 | -		device = self.zfsParent | 
 |  	default: | 
 |  		return nil | 
 |  	} | 
 | diff -ur com_github_google_cadvisor.orig/container/docker/utils/docker.go com_github_google_cadvisor/container/docker/utils/docker.go | 
 | --- com_github_google_cadvisor.orig/container/docker/utils/docker.go	2020-04-15 17:54:23.082143453 +0200 | 
 | +++ com_github_google_cadvisor/container/docker/utils/docker.go	2020-04-16 15:10:30.379817831 +0200 | 
 | @@ -69,12 +69,3 @@ | 
 |   | 
 |  	return metadataDevice, nil | 
 |  } | 
 | - | 
 | -func DockerZfsFilesystem(info dockertypes.Info) (string, error) { | 
 | -	filesystem := DriverStatusValue(info.DriverStatus, DriverStatusParentDataset) | 
 | -	if len(filesystem) == 0 { | 
 | -		return "", fmt.Errorf("Could not get zfs filesystem") | 
 | -	} | 
 | - | 
 | -	return filesystem, nil | 
 | -} | 
 | diff -ur com_github_google_cadvisor.orig/fs/fs.go com_github_google_cadvisor/fs/fs.go | 
 | --- com_github_google_cadvisor.orig/fs/fs.go	2020-04-15 17:54:23.086143468 +0200 | 
 | +++ com_github_google_cadvisor/fs/fs.go	2020-04-16 15:39:57.294333566 +0200 | 
 | @@ -32,7 +32,6 @@ | 
 |   | 
 |  	"github.com/google/cadvisor/devicemapper" | 
 |  	"github.com/google/cadvisor/utils" | 
 | -	zfs "github.com/mistifyio/go-zfs" | 
 |   | 
 |  	"k8s.io/klog" | 
 |  	"k8s.io/utils/mount" | 
 | @@ -167,11 +166,9 @@ | 
 |   | 
 |  	supportedFsType := map[string]bool{ | 
 |  		// all ext systems are checked through prefix. | 
 | -		"btrfs":   true, | 
 |  		"overlay": true, | 
 |  		"tmpfs":   true, | 
 |  		"xfs":     true, | 
 | -		"zfs":     true, | 
 |  	} | 
 |   | 
 |  	for _, mount := range mounts { | 
 | @@ -200,17 +197,6 @@ | 
 |  		if mount.FsType == "tmpfs" { | 
 |  			mount.Source = mount.MountPoint | 
 |  		} | 
 | -		// 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/") { | 
 | -			major, minor, err := getBtrfsMajorMinorIds(&mount) | 
 | -			if err != nil { | 
 | -				klog.Warningf("%s", err) | 
 | -			} else { | 
 | -				mount.Major = major | 
 | -				mount.Minor = minor | 
 | -			} | 
 | -		} | 
 |   | 
 |  		// overlay fix: Making mount source unique for all overlay mounts, using the mount's major and minor ids. | 
 |  		if mount.FsType == "overlay" { | 
 | @@ -312,7 +298,7 @@ | 
 |   | 
 |  	// TODO(rjnagal): Detect docker root and graphdriver directories from docker info. | 
 |  	dockerRoot := context.Docker.Root | 
 | -	for _, dir := range []string{"devicemapper", "btrfs", "aufs", "overlay", "overlay2", "zfs"} { | 
 | +	for _, dir := range []string{"devicemapper", "overlay", "overlay2"} { | 
 |  		dockerImagePaths[path.Join(dockerRoot, dir)] = struct{}{} | 
 |  	} | 
 |  	for dockerRoot != "/" && dockerRoot != "." { | 
 | @@ -390,14 +376,6 @@ | 
 |  				fs.Capacity, fs.Free, fs.Available, err = getDMStats(device, partition.blockSize) | 
 |  				klog.V(5).Infof("got devicemapper fs capacity stats: capacity: %v free: %v available: %v:", fs.Capacity, fs.Free, fs.Available) | 
 |  				fs.Type = DeviceMapper | 
 | -			case ZFS.String(): | 
 | -				if _, devzfs := os.Stat("/dev/zfs"); os.IsExist(devzfs) { | 
 | -					fs.Capacity, fs.Free, fs.Available, err = getZfstats(device) | 
 | -					fs.Type = ZFS | 
 | -					break | 
 | -				} | 
 | -				// if /dev/zfs is not present default to VFS | 
 | -				fallthrough | 
 |  			default: | 
 |  				var inodes, inodesFree uint64 | 
 |  				if utils.FileExists(partition.mountpoint) { | 
 | @@ -521,30 +499,6 @@ | 
 |  		} | 
 |  	} | 
 |   | 
 | -	mount, found := self.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 | 
 | -	// the subvolume | 
 | -	for !found { | 
 | -		pathdir, _ := filepath.Split(dir) | 
 | -		// break when we reach root | 
 | -		if pathdir == "/" { | 
 | -			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 = self.mounts[dir] | 
 | -	} | 
 | - | 
 | -	if found && mount.FsType == "btrfs" && mount.Major == 0 && strings.HasPrefix(mount.Source, "/dev/") { | 
 | -		major, minor, err := getBtrfsMajorMinorIds(&mount) | 
 | -		if err != nil { | 
 | -			klog.Warningf("%s", err) | 
 | -		} else { | 
 | -			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) | 
 |  } | 
 |   | 
 | @@ -715,18 +669,6 @@ | 
 |  	return used, total, nil | 
 |  } | 
 |   | 
 | -// getZfstats returns ZFS mount stats using zfsutils | 
 | -func getZfstats(poolName string) (uint64, uint64, uint64, error) { | 
 | -	dataset, err := zfs.GetDataset(poolName) | 
 | -	if err != nil { | 
 | -		return 0, 0, 0, err | 
 | -	} | 
 | - | 
 | -	total := dataset.Used + dataset.Avail + dataset.Usedbydataset | 
 | - | 
 | -	return total, dataset.Avail, dataset.Avail, nil | 
 | -} | 
 | - | 
 |  // Simple io.Writer implementation that counts how many bytes were written. | 
 |  type byteCounter struct{ bytesWritten uint64 } | 
 |   | 
 | @@ -734,33 +676,3 @@ | 
 |  	b.bytesWritten += uint64(len(p)) | 
 |  	return len(p), nil | 
 |  } | 
 | - | 
 | -// Get major and minor Ids for a mount point using btrfs as filesystem. | 
 | -func getBtrfsMajorMinorIds(mount *mount.MountInfo) (int, int, error) { | 
 | -	// 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 { | 
 | -		err = fmt.Errorf("stat failed on %s with error: %s", mount.Source, err) | 
 | -		return 0, 0, err | 
 | -	} | 
 | - | 
 | -	klog.V(4).Infof("btrfs mount %#v", mount) | 
 | -	if buf.Mode&syscall.S_IFMT == syscall.S_IFBLK { | 
 | -		err := syscall.Stat(mount.MountPoint, buf) | 
 | -		if err != nil { | 
 | -			err = fmt.Errorf("stat failed on %s with error: %s", mount.MountPoint, err) | 
 | -			return 0, 0, err | 
 | -		} | 
 | - | 
 | -		// The type Dev and Rdev in Stat_t are 32bit on mips. | 
 | -		klog.V(4).Infof("btrfs dev major:minor %d:%d\n", int(major(uint64(buf.Dev))), int(minor(uint64(buf.Dev))))    // nolint: unconvert | 
 | -		klog.V(4).Infof("btrfs rdev major:minor %d:%d\n", int(major(uint64(buf.Rdev))), int(minor(uint64(buf.Rdev)))) // nolint: unconvert | 
 | - | 
 | -		return int(major(uint64(buf.Dev))), int(minor(uint64(buf.Dev))), nil // nolint: unconvert | 
 | -	} else { | 
 | -		return 0, 0, fmt.Errorf("%s is not a block device", mount.Source) | 
 | -	} | 
 | -} | 
 | diff -ur com_github_google_cadvisor.orig/fs/fs_test.go com_github_google_cadvisor/fs/fs_test.go | 
 | --- com_github_google_cadvisor.orig/fs/fs_test.go	2020-04-15 17:54:23.086143468 +0200 | 
 | +++ com_github_google_cadvisor/fs/fs_test.go	2020-04-16 15:10:42.829856068 +0200 | 
 | @@ -516,7 +516,6 @@ | 
 |  				{Root: "/", MountPoint: "/b", Source: "/dev/sdb", FsType: "ext4", Major: 253, Minor: 1}, | 
 |  				{Root: "/", MountPoint: "/c", Source: "/dev/sdc", FsType: "btrfs", Major: 253, Minor: 2}, | 
 |  				{Root: "/", MountPoint: "/d", Source: "/dev/sdd", FsType: "xfs", Major: 253, Minor: 3}, | 
 | -				{Root: "/", MountPoint: "/e", Source: "/dev/sde", FsType: "zfs", Major: 253, Minor: 4}, | 
 |  				{Root: "/", MountPoint: "/f", Source: "overlay", FsType: "overlay", Major: 253, Minor: 5}, | 
 |  				{Root: "/", MountPoint: "/test1", Source: "tmpfs", FsType: "tmpfs", Major: 253, Minor: 4}, | 
 |  				{Root: "/", MountPoint: "/test2", Source: "tmpfs", FsType: "tmpfs", Major: 253, Minor: 4}, | 
 | @@ -526,7 +525,6 @@ | 
 |  				"/dev/sdb":      {fsType: "ext4", mountpoint: "/b", major: 253, minor: 1}, | 
 |  				"/dev/sdc":      {fsType: "btrfs", mountpoint: "/c", major: 253, minor: 2}, | 
 |  				"/dev/sdd":      {fsType: "xfs", mountpoint: "/d", major: 253, minor: 3}, | 
 | -				"/dev/sde":      {fsType: "zfs", mountpoint: "/e", major: 253, minor: 4}, | 
 |  				"overlay_253-5": {fsType: "overlay", mountpoint: "/f", major: 253, minor: 5}, | 
 |  				"/test1":        {fsType: "tmpfs", mountpoint: "/test1", major: 253, minor: 4}, | 
 |  				"/test2":        {fsType: "tmpfs", mountpoint: "/test2", major: 253, minor: 4}, | 
 | diff -ur com_github_google_cadvisor.orig/fs/types.go com_github_google_cadvisor/fs/types.go | 
 | --- com_github_google_cadvisor.orig/fs/types.go	2020-04-15 17:54:23.086143468 +0200 | 
 | +++ com_github_google_cadvisor/fs/types.go	2020-04-16 15:10:48.264872763 +0200 | 
 | @@ -47,7 +47,6 @@ | 
 |  } | 
 |   | 
 |  const ( | 
 | -	ZFS          FsType = "zfs" | 
 |  	DeviceMapper FsType = "devicemapper" | 
 |  	VFS          FsType = "vfs" | 
 |  ) |