fs: evaluate labels from all mount points
This commit is contained in:
parent
8b2e8bd9ad
commit
b1e4bc7d11
64
fs/fs.go
64
fs/fs.go
@ -76,6 +76,10 @@ func NewFsInfo(context Context) (FsInfo, error) {
|
|||||||
labels: make(map[string]string, 0),
|
labels: make(map[string]string, 0),
|
||||||
dmsetup: &defaultDmsetupClient{},
|
dmsetup: &defaultDmsetupClient{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fsInfo.addSystemRootLabel(mounts)
|
||||||
|
fsInfo.addDockerImagesLabel(context, mounts)
|
||||||
|
|
||||||
supportedFsType := map[string]bool{
|
supportedFsType := map[string]bool{
|
||||||
// all ext systems are checked through prefix.
|
// all ext systems are checked through prefix.
|
||||||
"btrfs": true,
|
"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)
|
glog.Infof("Filesystem partitions: %+v", fsInfo.partitions)
|
||||||
fsInfo.addSystemRootLabel()
|
|
||||||
return fsInfo, nil
|
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 /.
|
// addSystemRootLabel attempts to determine which device contains the mount for /.
|
||||||
func (self *RealFsInfo) addSystemRootLabel() {
|
func (self *RealFsInfo) addSystemRootLabel(mounts []*mount.Info) {
|
||||||
for src, p := range self.partitions {
|
for _, m := range mounts {
|
||||||
if p.mountpoint == "/" {
|
if m.Mountpoint == "/" {
|
||||||
if _, ok := self.labels[LabelSystemRoot]; !ok {
|
self.partitions[m.Source] = partition{
|
||||||
self.labels[LabelSystemRoot] = src
|
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.
|
// 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)
|
dockerDev, dockerPartition, err := self.getDockerDeviceMapperInfo(context.DockerInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Warningf("Could not get Docker devicemapper device: %v", err)
|
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.partitions[dockerDev] = *dockerPartition
|
||||||
self.labels[LabelDockerImages] = dockerDev
|
self.labels[LabelDockerImages] = dockerDev
|
||||||
} else {
|
} else {
|
||||||
dockerPaths := getDockerImagePaths(context)
|
self.updateDockerImagesPath(mounts, getDockerImagePaths(context))
|
||||||
|
|
||||||
for src, p := range self.partitions {
|
|
||||||
self.updateDockerImagesPath(src, p.mountpoint, dockerPaths)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,22 +190,30 @@ func getDockerImagePaths(context Context) []string {
|
|||||||
return dockerImagePaths
|
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.
|
// docker images label is added to the partition.
|
||||||
func (self *RealFsInfo) updateDockerImagesPath(source string, mountpoint string, dockerImagePaths []string) {
|
func (self *RealFsInfo) updateDockerImagesPath(mounts []*mount.Info, dockerImagePaths []string) {
|
||||||
for _, v := range dockerImagePaths {
|
var useMount *mount.Info
|
||||||
if v == mountpoint {
|
for _, m := range mounts {
|
||||||
if i, ok := self.labels[LabelDockerImages]; ok {
|
for _, p := range dockerImagePaths {
|
||||||
// pick the innermost mountpoint.
|
if p != m.Mountpoint {
|
||||||
mnt := self.partitions[i].mountpoint
|
continue
|
||||||
if len(mnt) < len(mountpoint) {
|
}
|
||||||
self.labels[LabelDockerImages] = source
|
// pick the innermost mountpoint
|
||||||
}
|
if useMount == nil || (len(useMount.Mountpoint) < len(m.Mountpoint)) {
|
||||||
} else {
|
useMount = m
|
||||||
self.labels[LabelDockerImages] = source
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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) {
|
func (self *RealFsInfo) GetDeviceForLabel(label string) (string, error) {
|
||||||
|
100
fs/fs_test.go
100
fs/fs_test.go
@ -22,6 +22,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/docker/docker/pkg/mount"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -161,22 +162,29 @@ func TestParseDMTable(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAddSystemRootLabel(t *testing.T) {
|
func TestAddSystemRootLabel(t *testing.T) {
|
||||||
fsInfo := &RealFsInfo{
|
tests := []struct {
|
||||||
labels: map[string]string{},
|
mounts []*mount.Info
|
||||||
partitions: map[string]partition{
|
expected string
|
||||||
"/dev/mapper/vg_vagrant-lv_root": {
|
}{
|
||||||
mountpoint: "/",
|
{
|
||||||
},
|
mounts: []*mount.Info{
|
||||||
"vg_vagrant-docker--pool": {
|
{Source: "/dev/sda1", Mountpoint: "/foo"},
|
||||||
mountpoint: "",
|
{Source: "/dev/sdb1", Mountpoint: "/"},
|
||||||
fsType: "devicemapper",
|
|
||||||
},
|
},
|
||||||
|
expected: "/dev/sdb1",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fsInfo.addSystemRootLabel()
|
for i, tt := range tests {
|
||||||
if e, a := "/dev/mapper/vg_vagrant-lv_root", fsInfo.labels[LabelSystemRoot]; e != a {
|
fsInfo := &RealFsInfo{
|
||||||
t.Errorf("expected %q, got %q", e, a)
|
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
|
driverStatus string
|
||||||
dmsetupTable string
|
dmsetupTable string
|
||||||
getDockerDeviceMapperInfoError error
|
getDockerDeviceMapperInfoError error
|
||||||
partitions map[string]partition
|
mounts []*mount.Info
|
||||||
expectedDockerDevice string
|
expectedDockerDevice string
|
||||||
expectedPartition *partition
|
expectedPartition *partition
|
||||||
}{
|
}{
|
||||||
@ -314,10 +322,11 @@ func TestAddDockerImagesLabel(t *testing.T) {
|
|||||||
driver: "devicemapper",
|
driver: "devicemapper",
|
||||||
driverStatus: `[["Pool Name", "vg_vagrant-docker--pool"]]`,
|
driverStatus: `[["Pool Name", "vg_vagrant-docker--pool"]]`,
|
||||||
dmsetupTable: "0 53870592 thin-pool 253:2 253:3 1024 0 1 skip_block_zeroing",
|
dmsetupTable: "0 53870592 thin-pool 253:2 253:3 1024 0 1 skip_block_zeroing",
|
||||||
partitions: map[string]partition{
|
mounts: []*mount.Info{
|
||||||
"/dev/mapper/vg_vagrant-lv_root": {
|
{
|
||||||
mountpoint: "/",
|
Source: "/dev/mapper/vg_vagrant-lv_root",
|
||||||
fsType: "devicemapper",
|
Mountpoint: "/",
|
||||||
|
Fstype: "devicemapper",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedDockerDevice: "vg_vagrant-docker--pool",
|
expectedDockerDevice: "vg_vagrant-docker--pool",
|
||||||
@ -332,41 +341,62 @@ func TestAddDockerImagesLabel(t *testing.T) {
|
|||||||
name: "devicemapper, loopback on non-root partition",
|
name: "devicemapper, loopback on non-root partition",
|
||||||
driver: "devicemapper",
|
driver: "devicemapper",
|
||||||
driverStatus: `[["Data loop file","/var/lib/docker/devicemapper/devicemapper/data"]]`,
|
driverStatus: `[["Data loop file","/var/lib/docker/devicemapper/devicemapper/data"]]`,
|
||||||
partitions: map[string]partition{
|
mounts: []*mount.Info{
|
||||||
"/dev/mapper/vg_vagrant-lv_root": {
|
{
|
||||||
mountpoint: "/",
|
Source: "/dev/mapper/vg_vagrant-lv_root",
|
||||||
fsType: "devicemapper",
|
Mountpoint: "/",
|
||||||
|
Fstype: "devicemapper",
|
||||||
},
|
},
|
||||||
"/dev/sdb1": {
|
{
|
||||||
mountpoint: "/var/lib/docker/devicemapper",
|
Source: "/dev/sdb1",
|
||||||
|
Mountpoint: "/var/lib/docker/devicemapper",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedDockerDevice: "/dev/sdb1",
|
expectedDockerDevice: "/dev/sdb1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "multiple mounts - innermost check",
|
name: "multiple mounts - innermost check",
|
||||||
partitions: map[string]partition{
|
mounts: []*mount.Info{
|
||||||
"/dev/sda1": {
|
{
|
||||||
mountpoint: "/",
|
Source: "/dev/sda1",
|
||||||
fsType: "ext4",
|
Mountpoint: "/",
|
||||||
|
Fstype: "ext4",
|
||||||
},
|
},
|
||||||
"/dev/sdb1": {
|
{
|
||||||
mountpoint: "/var/lib/docker",
|
Source: "/dev/sdb1",
|
||||||
fsType: "ext4",
|
Mountpoint: "/var/lib/docker",
|
||||||
|
Fstype: "ext4",
|
||||||
},
|
},
|
||||||
"/dev/sdb2": {
|
{
|
||||||
mountpoint: "/var/lib/docker/btrfs",
|
Source: "/dev/sdb2",
|
||||||
fsType: "btrfs",
|
Mountpoint: "/var/lib/docker/btrfs",
|
||||||
|
Fstype: "btrfs",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedDockerDevice: "/dev/sdb2",
|
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 {
|
for _, tt := range tests {
|
||||||
fsInfo := &RealFsInfo{
|
fsInfo := &RealFsInfo{
|
||||||
labels: map[string]string{},
|
labels: map[string]string{},
|
||||||
partitions: tt.partitions,
|
partitions: map[string]partition{},
|
||||||
dmsetup: &testDmsetup{
|
dmsetup: &testDmsetup{
|
||||||
data: []byte(tt.dmsetupTable),
|
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 {
|
if e, a := tt.expectedDockerDevice, fsInfo.labels[LabelDockerImages]; e != a {
|
||||||
t.Errorf("%s: docker device: expected %q, got %q", tt.name, e, a)
|
t.Errorf("%s: docker device: expected %q, got %q", tt.name, e, a)
|
||||||
|
Loading…
Reference in New Issue
Block a user