fs: evaluate labels from all mount points
This commit is contained in:
parent
8b2e8bd9ad
commit
b1e4bc7d11
62
fs/fs.go
62
fs/fs.go
@ -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
|
||||
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
|
||||
}
|
||||
} else {
|
||||
self.labels[LabelDockerImages] = source
|
||||
// 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) {
|
||||
|
100
fs/fs_test.go
100
fs/fs_test.go
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user