Merge pull request #1358 from ncdc/ignore-devicemapper-container-mounts

Exclude Docker devicemapper mounts from fs info
This commit is contained in:
Tim St. Clair 2016-07-07 13:17:52 -07:00 committed by GitHub
commit 40fd72ef26
2 changed files with 109 additions and 27 deletions

View File

@ -99,38 +99,15 @@ func NewFsInfo(context Context) (FsInfo, error) {
if err != nil {
return nil, err
}
// Avoid devicemapper container mounts - these are tracked by the ThinPoolWatcher
excluded := []string{fmt.Sprintf("%s/devicemapper/mnt", context.Docker.Root)}
fsInfo := &RealFsInfo{
partitions: make(map[string]partition, 0),
partitions: processMounts(mounts, excluded),
labels: make(map[string]string, 0),
dmsetup: devicemapper.NewDmsetupClient(),
}
supportedFsType := map[string]bool{
// all ext systems are checked through prefix.
"btrfs": true,
"xfs": true,
"zfs": true,
}
for _, mount := range mounts {
var Fstype string
if !strings.HasPrefix(mount.Fstype, "ext") && !supportedFsType[mount.Fstype] {
continue
}
// Avoid bind mounts.
if _, ok := fsInfo.partitions[mount.Source]; ok {
continue
}
if mount.Fstype == "zfs" {
Fstype = mount.Fstype
}
fsInfo.partitions[mount.Source] = partition{
fsType: Fstype,
mountpoint: mount.Mountpoint,
major: uint(mount.Major),
minor: uint(mount.Minor),
}
}
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
@ -141,6 +118,47 @@ func NewFsInfo(context Context) (FsInfo, error) {
return fsInfo, nil
}
func processMounts(mounts []*mount.Info, excludedMountpointPrefixes []string) map[string]partition {
partitions := make(map[string]partition, 0)
supportedFsType := map[string]bool{
// all ext systems are checked through prefix.
"btrfs": true,
"xfs": true,
"zfs": true,
}
for _, mount := range mounts {
if !strings.HasPrefix(mount.Fstype, "ext") && !supportedFsType[mount.Fstype] {
continue
}
// Avoid bind mounts.
if _, ok := partitions[mount.Source]; ok {
continue
}
hasPrefix := false
for _, prefix := range excludedMountpointPrefixes {
if strings.HasPrefix(mount.Mountpoint, prefix) {
hasPrefix = true
break
}
}
if hasPrefix {
continue
}
partitions[mount.Source] = partition{
fsType: mount.Fstype,
mountpoint: mount.Mountpoint,
major: uint(mount.Major),
minor: uint(mount.Minor),
}
}
return partitions
}
// getDockerDeviceMapperInfo returns information about the devicemapper device and "partition" if
// docker is using devicemapper for its storage driver. If a loopback device is being used, don't
// return any information or error, as we want to report based on the actual partition where the

View File

@ -432,3 +432,67 @@ func TestAddDockerImagesLabel(t *testing.T) {
}
}
}
func TestProcessMounts(t *testing.T) {
tests := []struct {
name string
mounts []*mount.Info
excludedPrefixes []string
expected map[string]partition
}{
{
name: "unsupported fs types",
mounts: []*mount.Info{
{Fstype: "overlay"},
{Fstype: "somethingelse"},
},
expected: map[string]partition{},
},
{
name: "avoid bind mounts",
mounts: []*mount.Info{
{Root: "/", Mountpoint: "/", Source: "/dev/sda1", Fstype: "xfs", Major: 253, Minor: 0},
{Root: "/foo", Mountpoint: "/bar", Source: "/dev/sda1", Fstype: "xfs", Major: 253, Minor: 0},
},
expected: map[string]partition{
"/dev/sda1": {fsType: "xfs", mountpoint: "/", major: 253, minor: 0},
},
},
{
name: "exclude prefixes",
mounts: []*mount.Info{
{Root: "/", Mountpoint: "/someother", Source: "/dev/sda1", Fstype: "xfs", Major: 253, Minor: 2},
{Root: "/", Mountpoint: "/", Source: "/dev/sda2", Fstype: "xfs", Major: 253, Minor: 0},
{Root: "/", Mountpoint: "/excludeme", Source: "/dev/sda3", Fstype: "xfs", Major: 253, Minor: 1},
},
excludedPrefixes: []string{"/exclude", "/some"},
expected: map[string]partition{
"/dev/sda2": {fsType: "xfs", mountpoint: "/", major: 253, minor: 0},
},
},
{
name: "supported fs types",
mounts: []*mount.Info{
{Root: "/", Mountpoint: "/a", Source: "/dev/sda", Fstype: "ext3", Major: 253, Minor: 0},
{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},
},
expected: map[string]partition{
"/dev/sda": {fsType: "ext3", mountpoint: "/a", major: 253, minor: 0},
"/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},
},
},
}
for _, test := range tests {
actual := processMounts(test.mounts, test.excludedPrefixes)
if !reflect.DeepEqual(test.expected, actual) {
t.Errorf("%s: expected %#v, got %#v", test.name, test.expected, actual)
}
}
}