Merge pull request #274 from ashahab-altiscale/raw-disk-space
Mounted partitions space usage metrics per container
This commit is contained in:
commit
bc3b01665f
@ -32,8 +32,14 @@ type containerHints struct {
|
||||
}
|
||||
|
||||
type containerHint struct {
|
||||
FullName string `json:"full_path,omitempty"`
|
||||
NetworkInterface *networkInterface `json:"network_interface,omitempty"`
|
||||
FullName string `json:"full_path,omitempty"`
|
||||
NetworkInterface *networkInterface `json:"network_interface,omitempty"`
|
||||
Mounts []mount `json:"mounts,omitempty"`
|
||||
}
|
||||
|
||||
type mount struct {
|
||||
HostDir string `json:"host_dir,omitempty"`
|
||||
ContainerDir string `json:"container_dir,omitempty"`
|
||||
}
|
||||
|
||||
type networkInterface struct {
|
||||
|
@ -15,6 +15,24 @@ func TestGetContainerHintsFromFile(t *testing.T) {
|
||||
cHints.AllHosts[0].NetworkInterface.VethChild != "eth1" {
|
||||
t.Errorf("Cannot find network interface in %s", cHints)
|
||||
}
|
||||
|
||||
correctMountDirs := [...]string{
|
||||
"/var/run/nm-sdc1",
|
||||
"/var/run/nm-sdb3",
|
||||
"/var/run/nm-sda3",
|
||||
"/var/run/netns/root",
|
||||
"/var/run/openvswitch/db.sock",
|
||||
}
|
||||
|
||||
if len(cHints.AllHosts[0].Mounts) == 0 {
|
||||
t.Errorf("Cannot find any mounts")
|
||||
}
|
||||
|
||||
for i, mountDir := range cHints.AllHosts[0].Mounts {
|
||||
if correctMountDirs[i] != mountDir.HostDir {
|
||||
t.Errorf("Cannot find mount %s in %s", mountDir.HostDir, cHints)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileNotExist(t *testing.T) {
|
||||
|
@ -44,7 +44,8 @@ type rawContainerHandler struct {
|
||||
stopWatcher chan error
|
||||
watches map[string]struct{}
|
||||
fsInfo fs.FsInfo
|
||||
networkInterface *networkInterface
|
||||
networkInterface *networkInterface
|
||||
externalMounts []mount
|
||||
}
|
||||
|
||||
func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, machineInfoFactory info.MachineInfoFactory) (container.ContainerHandler, error) {
|
||||
@ -57,9 +58,11 @@ func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, mac
|
||||
return nil, err
|
||||
}
|
||||
var networkInterface *networkInterface
|
||||
var externalMounts []mount
|
||||
for _, container := range cHints.AllHosts {
|
||||
if name == container.FullName {
|
||||
networkInterface = container.NetworkInterface
|
||||
externalMounts = container.Mounts
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -74,7 +77,8 @@ func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, mac
|
||||
stopWatcher: make(chan error),
|
||||
watches: make(map[string]struct{}),
|
||||
fsInfo: fsInfo,
|
||||
networkInterface: networkInterface,
|
||||
networkInterface: networkInterface,
|
||||
externalMounts: externalMounts,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -164,7 +168,7 @@ func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
||||
}
|
||||
|
||||
// Fs.
|
||||
if self.name == "/" {
|
||||
if self.name == "/" || self.externalMounts != nil {
|
||||
spec.HasFilesystem = true
|
||||
}
|
||||
|
||||
@ -175,6 +179,34 @@ func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
||||
return spec, nil
|
||||
}
|
||||
|
||||
func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
|
||||
|
||||
// Get Filesystem information only for the root cgroup.
|
||||
if self.name == "/" {
|
||||
filesystems, err := self.fsInfo.GetGlobalFsInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, fs := range filesystems {
|
||||
stats.Filesystem = append(stats.Filesystem, info.FsStats{fs.Device, fs.Capacity, fs.Capacity - fs.Free})
|
||||
}
|
||||
} else if len(self.externalMounts) > 0 {
|
||||
var mountSet map[string]struct{}
|
||||
mountSet = make(map[string]struct{})
|
||||
for _, mount := range self.externalMounts {
|
||||
mountSet[mount.HostDir] = struct{}{}
|
||||
}
|
||||
filesystems, err := self.fsInfo.GetFsInfoForPath(mountSet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, fs := range filesystems {
|
||||
stats.Filesystem = append(stats.Filesystem, info.FsStats{fs.Device, fs.Capacity, fs.Capacity - fs.Free})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *rawContainerHandler) GetStats() (*info.ContainerStats, error) {
|
||||
state := dockerlibcontainer.State{}
|
||||
if self.networkInterface != nil {
|
||||
@ -191,15 +223,10 @@ func (self *rawContainerHandler) GetStats() (*info.ContainerStats, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get Filesystem information only for the root cgroup.
|
||||
if self.name == "/" {
|
||||
filesystems, err := self.fsInfo.GetGlobalFsInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, fs := range filesystems {
|
||||
stats.Filesystem = append(stats.Filesystem, info.FsStats{fs.Device, fs.Capacity, fs.Capacity - fs.Free})
|
||||
}
|
||||
|
||||
err = self.getFsStats(stats)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
|
@ -9,28 +9,28 @@
|
||||
},
|
||||
"mounts": [
|
||||
{
|
||||
"host-dir": "/var/run/nm-sdc1",
|
||||
"container-dir": "/var/run/nm-sdc1",
|
||||
"host_dir": "/var/run/nm-sdc1",
|
||||
"container_dir": "/var/run/nm-sdc1",
|
||||
"permission": "rw"
|
||||
},
|
||||
{
|
||||
"host-dir": "/var/run/nm-sdb3",
|
||||
"container-dir": "/var/run/nm-sdb3",
|
||||
"host_dir": "/var/run/nm-sdb3",
|
||||
"container_dir": "/var/run/nm-sdb3",
|
||||
"permission": "rw"
|
||||
},
|
||||
{
|
||||
"host-dir": "/var/run/nm-sda3",
|
||||
"container-dir": "/var/run/nm-sda3",
|
||||
"host_dir": "/var/run/nm-sda3",
|
||||
"container_dir": "/var/run/nm-sda3",
|
||||
"permission": "rw"
|
||||
},
|
||||
{
|
||||
"host-dir": "/var/run/netns/root",
|
||||
"container-dir": "/var/run/netns/root",
|
||||
"host_dir": "/var/run/netns/root",
|
||||
"container_dir": "/var/run/netns/root",
|
||||
"permission": "ro"
|
||||
},
|
||||
{
|
||||
"host-dir": "/var/run/openvswitch/db.sock",
|
||||
"container-dir": "/var/run/openvswitch/db.sock",
|
||||
"host_dir": "/var/run/openvswitch/db.sock",
|
||||
"container_dir": "/var/run/openvswitch/db.sock",
|
||||
"permission": "rw"
|
||||
}
|
||||
],
|
||||
|
32
fs/fs.go
32
fs/fs.go
@ -50,25 +50,35 @@ func NewFsInfo() (FsInfo, error) {
|
||||
return &RealFsInfo{partitions}, nil
|
||||
}
|
||||
|
||||
func (self *RealFsInfo) GetGlobalFsInfo() ([]Fs, error) {
|
||||
func (self *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error) {
|
||||
filesystems := make([]Fs, 0)
|
||||
deviceSet := make(map[string]struct{})
|
||||
for device, partition := range self.partitions {
|
||||
total, free, err := getVfsStats(partition.mountpoint)
|
||||
if err != nil {
|
||||
glog.Errorf("Statvfs failed. Error: %v", err)
|
||||
} else {
|
||||
deviceInfo := DeviceInfo{
|
||||
Device: device,
|
||||
Major: uint(partition.major),
|
||||
Minor: uint(partition.minor),
|
||||
_, hasMount := mountSet[partition.mountpoint]
|
||||
_, hasDevice := deviceSet[device]
|
||||
if mountSet == nil || hasMount && !hasDevice {
|
||||
total, free, err := getVfsStats(partition.mountpoint)
|
||||
if err != nil {
|
||||
glog.Errorf("Statvfs failed. Error: %v", err)
|
||||
} else {
|
||||
deviceSet[device] = struct{}{}
|
||||
deviceInfo := DeviceInfo{
|
||||
Device: device,
|
||||
Major: uint(partition.major),
|
||||
Minor: uint(partition.minor),
|
||||
}
|
||||
fs := Fs{deviceInfo, total, free}
|
||||
filesystems = append(filesystems, fs)
|
||||
}
|
||||
fs := Fs{deviceInfo, total, free}
|
||||
filesystems = append(filesystems, fs)
|
||||
}
|
||||
}
|
||||
return filesystems, nil
|
||||
}
|
||||
|
||||
func (self *RealFsInfo) GetGlobalFsInfo() ([]Fs, error) {
|
||||
return self.GetFsInfoForPath(nil)
|
||||
}
|
||||
|
||||
func major(devNumber uint64) uint {
|
||||
return uint((devNumber >> 8) & 0xfff)
|
||||
}
|
||||
|
@ -16,6 +16,9 @@ type FsInfo interface {
|
||||
// Returns capacity and free space, in bytes, of all the ext2, ext3, ext4 filesystems on the host.
|
||||
GetGlobalFsInfo() ([]Fs, error)
|
||||
|
||||
// Returns capacity and free space, in bytes, of the set of mounts passed.
|
||||
GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error)
|
||||
|
||||
// Returns number of bytes occupied by 'dir'.
|
||||
GetDirUsage(dir string) (uint64, error)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user