fs: evaluate labels from all mount points

This commit is contained in:
Aaron Levy 2016-03-01 09:20:57 +00:00
parent 8b2e8bd9ad
commit b1e4bc7d11
2 changed files with 101 additions and 63 deletions

View File

@ -76,6 +76,10 @@ func NewFsInfo(context Context) (FsInfo, error) {
labels: make(map[string]string, 0),
dmsetup: &defaultDmsetupClient{},
}
fsInfo.addSystemRootLabel(mounts)
fsInfo.addDockerImagesLabel(context, mounts)
supportedFsType := map[string]bool{
// all ext systems are checked through prefix.
"btrfs": true,
@ -102,12 +106,7 @@ func NewFsInfo(context Context) (FsInfo, error) {
}
}
// 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
fsInfo.addDockerImagesLabel(context)
glog.Infof("Filesystem partitions: %+v", fsInfo.partitions)
fsInfo.addSystemRootLabel()
return fsInfo, nil
}
@ -144,18 +143,23 @@ func (self *RealFsInfo) getDockerDeviceMapperInfo(dockerInfo map[string]string)
}
// addSystemRootLabel attempts to determine which device contains the mount for /.
func (self *RealFsInfo) addSystemRootLabel() {
for src, p := range self.partitions {
if p.mountpoint == "/" {
if _, ok := self.labels[LabelSystemRoot]; !ok {
self.labels[LabelSystemRoot] = src
func (self *RealFsInfo) addSystemRootLabel(mounts []*mount.Info) {
for _, m := range mounts {
if m.Mountpoint == "/" {
self.partitions[m.Source] = partition{
fsType: m.Fstype,
mountpoint: m.Mountpoint,
major: uint(m.Major),
minor: uint(m.Minor),
}
self.labels[LabelSystemRoot] = m.Source
return
}
}
}
// addDockerImagesLabel attempts to determine which device contains the mount for docker images.
func (self *RealFsInfo) addDockerImagesLabel(context Context) {
func (self *RealFsInfo) addDockerImagesLabel(context Context, mounts []*mount.Info) {
dockerDev, dockerPartition, err := self.getDockerDeviceMapperInfo(context.DockerInfo)
if err != nil {
glog.Warningf("Could not get Docker devicemapper device: %v", err)
@ -164,11 +168,7 @@ func (self *RealFsInfo) addDockerImagesLabel(context Context) {
self.partitions[dockerDev] = *dockerPartition
self.labels[LabelDockerImages] = dockerDev
} else {
dockerPaths := getDockerImagePaths(context)
for src, p := range self.partitions {
self.updateDockerImagesPath(src, p.mountpoint, dockerPaths)
}
self.updateDockerImagesPath(mounts, getDockerImagePaths(context))
}
}
@ -190,22 +190,30 @@ func getDockerImagePaths(context Context) []string {
return dockerImagePaths
}
// This method compares the mountpoint with possible docker image mount points. If a match is found,
// This method compares the mountpoints with possible docker image mount points. If a match is found,
// docker images label is added to the partition.
func (self *RealFsInfo) updateDockerImagesPath(source string, mountpoint string, dockerImagePaths []string) {
for _, v := range dockerImagePaths {
if v == mountpoint {
if i, ok := self.labels[LabelDockerImages]; ok {
// pick the innermost mountpoint.
mnt := self.partitions[i].mountpoint
if len(mnt) < len(mountpoint) {
self.labels[LabelDockerImages] = source
}
} else {
self.labels[LabelDockerImages] = source
func (self *RealFsInfo) updateDockerImagesPath(mounts []*mount.Info, dockerImagePaths []string) {
var useMount *mount.Info
for _, m := range mounts {
for _, p := range dockerImagePaths {
if p != m.Mountpoint {
continue
}
// pick the innermost mountpoint
if useMount == nil || (len(useMount.Mountpoint) < len(m.Mountpoint)) {
useMount = m
}
}
}
if useMount != nil {
self.partitions[useMount.Source] = partition{
fsType: useMount.Fstype,
mountpoint: useMount.Mountpoint,
major: uint(useMount.Major),
minor: uint(useMount.Minor),
}
self.labels[LabelDockerImages] = useMount.Source
}
}
func (self *RealFsInfo) GetDeviceForLabel(label string) (string, error) {

View File

@ -22,6 +22,7 @@ import (
"testing"
"time"
"github.com/docker/docker/pkg/mount"
"github.com/stretchr/testify/assert"
)
@ -161,22 +162,29 @@ func TestParseDMTable(t *testing.T) {
}
func TestAddSystemRootLabel(t *testing.T) {
fsInfo := &RealFsInfo{
labels: map[string]string{},
partitions: map[string]partition{
"/dev/mapper/vg_vagrant-lv_root": {
mountpoint: "/",
},
"vg_vagrant-docker--pool": {
mountpoint: "",
fsType: "devicemapper",
tests := []struct {
mounts []*mount.Info
expected string
}{
{
mounts: []*mount.Info{
{Source: "/dev/sda1", Mountpoint: "/foo"},
{Source: "/dev/sdb1", Mountpoint: "/"},
},
expected: "/dev/sdb1",
},
}
fsInfo.addSystemRootLabel()
if e, a := "/dev/mapper/vg_vagrant-lv_root", fsInfo.labels[LabelSystemRoot]; e != a {
t.Errorf("expected %q, got %q", e, a)
for i, tt := range tests {
fsInfo := &RealFsInfo{
labels: map[string]string{},
partitions: map[string]partition{},
}
fsInfo.addSystemRootLabel(tt.mounts)
if source, ok := fsInfo.labels[LabelSystemRoot]; !ok || source != tt.expected {
t.Errorf("case %d: expected mount source '%s', got '%s'", i, tt.expected, source)
}
}
}
@ -305,7 +313,7 @@ func TestAddDockerImagesLabel(t *testing.T) {
driverStatus string
dmsetupTable string
getDockerDeviceMapperInfoError error
partitions map[string]partition
mounts []*mount.Info
expectedDockerDevice string
expectedPartition *partition
}{
@ -314,10 +322,11 @@ func TestAddDockerImagesLabel(t *testing.T) {
driver: "devicemapper",
driverStatus: `[["Pool Name", "vg_vagrant-docker--pool"]]`,
dmsetupTable: "0 53870592 thin-pool 253:2 253:3 1024 0 1 skip_block_zeroing",
partitions: map[string]partition{
"/dev/mapper/vg_vagrant-lv_root": {
mountpoint: "/",
fsType: "devicemapper",
mounts: []*mount.Info{
{
Source: "/dev/mapper/vg_vagrant-lv_root",
Mountpoint: "/",
Fstype: "devicemapper",
},
},
expectedDockerDevice: "vg_vagrant-docker--pool",
@ -332,41 +341,62 @@ func TestAddDockerImagesLabel(t *testing.T) {
name: "devicemapper, loopback on non-root partition",
driver: "devicemapper",
driverStatus: `[["Data loop file","/var/lib/docker/devicemapper/devicemapper/data"]]`,
partitions: map[string]partition{
"/dev/mapper/vg_vagrant-lv_root": {
mountpoint: "/",
fsType: "devicemapper",
mounts: []*mount.Info{
{
Source: "/dev/mapper/vg_vagrant-lv_root",
Mountpoint: "/",
Fstype: "devicemapper",
},
"/dev/sdb1": {
mountpoint: "/var/lib/docker/devicemapper",
{
Source: "/dev/sdb1",
Mountpoint: "/var/lib/docker/devicemapper",
},
},
expectedDockerDevice: "/dev/sdb1",
},
{
name: "multiple mounts - innermost check",
partitions: map[string]partition{
"/dev/sda1": {
mountpoint: "/",
fsType: "ext4",
mounts: []*mount.Info{
{
Source: "/dev/sda1",
Mountpoint: "/",
Fstype: "ext4",
},
"/dev/sdb1": {
mountpoint: "/var/lib/docker",
fsType: "ext4",
{
Source: "/dev/sdb1",
Mountpoint: "/var/lib/docker",
Fstype: "ext4",
},
"/dev/sdb2": {
mountpoint: "/var/lib/docker/btrfs",
fsType: "btrfs",
{
Source: "/dev/sdb2",
Mountpoint: "/var/lib/docker/btrfs",
Fstype: "btrfs",
},
},
expectedDockerDevice: "/dev/sdb2",
},
{
name: "root fs inside container, docker-images bindmount",
mounts: []*mount.Info{
{
Source: "overlay",
Mountpoint: "/",
Fstype: "overlay",
},
{
Source: "/dev/sda1",
Mountpoint: "/var/lib/docker",
Fstype: "ext4",
},
},
expectedDockerDevice: "/dev/sda1",
},
}
for _, tt := range tests {
fsInfo := &RealFsInfo{
labels: map[string]string{},
partitions: tt.partitions,
partitions: map[string]partition{},
dmsetup: &testDmsetup{
data: []byte(tt.dmsetupTable),
},
@ -380,7 +410,7 @@ func TestAddDockerImagesLabel(t *testing.T) {
},
}
fsInfo.addDockerImagesLabel(context)
fsInfo.addDockerImagesLabel(context, tt.mounts)
if e, a := tt.expectedDockerDevice, fsInfo.labels[LabelDockerImages]; e != a {
t.Errorf("%s: docker device: expected %q, got %q", tt.name, e, a)