Allow clients to know if inodes are supported on a filesystem

This commit is contained in:
derekwaynecarr 2016-07-26 11:15:07 -04:00
parent 04f73fefa5
commit cccf9d5fec
9 changed files with 76 additions and 60 deletions

View File

@ -165,22 +165,20 @@ func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {
return spec, nil return spec, nil
} }
func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error { func fsToFsStats(fs *fs.Fs) info.FsStats {
// Get Filesystem information only for the root cgroup. inodesFree := uint64(0)
if isRootCgroup(self.name) { hasInodes := fs.InodesFree != nil
filesystems, err := self.fsInfo.GetGlobalFsInfo() if hasInodes {
if err != nil { inodesFree = *fs.InodesFree
return err
} }
for _, fs := range filesystems { return info.FsStats{
stats.Filesystem = append(stats.Filesystem,
info.FsStats{
Device: fs.Device, Device: fs.Device,
Type: fs.Type.String(), Type: fs.Type.String(),
Limit: fs.Capacity, Limit: fs.Capacity,
Usage: fs.Capacity - fs.Free, Usage: fs.Capacity - fs.Free,
HasInodes: hasInodes,
InodesFree: inodesFree,
Available: fs.Available, Available: fs.Available,
InodesFree: fs.InodesFree,
ReadsCompleted: fs.DiskStats.ReadsCompleted, ReadsCompleted: fs.DiskStats.ReadsCompleted,
ReadsMerged: fs.DiskStats.ReadsMerged, ReadsMerged: fs.DiskStats.ReadsMerged,
SectorsRead: fs.DiskStats.SectorsRead, SectorsRead: fs.DiskStats.SectorsRead,
@ -192,7 +190,19 @@ func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
IoInProgress: fs.DiskStats.IoInProgress, IoInProgress: fs.DiskStats.IoInProgress,
IoTime: fs.DiskStats.IoTime, IoTime: fs.DiskStats.IoTime,
WeightedIoTime: fs.DiskStats.WeightedIoTime, WeightedIoTime: fs.DiskStats.WeightedIoTime,
}) }
}
func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
// Get Filesystem information only for the root cgroup.
if isRootCgroup(self.name) {
filesystems, err := self.fsInfo.GetGlobalFsInfo()
if err != nil {
return err
}
for i := range filesystems {
fs := filesystems[i]
stats.Filesystem = append(stats.Filesystem, fsToFsStats(&fs))
} }
} else if len(self.externalMounts) > 0 { } else if len(self.externalMounts) > 0 {
var mountSet map[string]struct{} var mountSet map[string]struct{}
@ -204,26 +214,9 @@ func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
if err != nil { if err != nil {
return err return err
} }
for _, fs := range filesystems { for i := range filesystems {
stats.Filesystem = append(stats.Filesystem, fs := filesystems[i]
info.FsStats{ stats.Filesystem = append(stats.Filesystem, fsToFsStats(&fs))
Device: fs.Device,
Type: fs.Type.String(),
Limit: fs.Capacity,
Usage: fs.Capacity - fs.Free,
InodesFree: fs.InodesFree,
ReadsCompleted: fs.DiskStats.ReadsCompleted,
ReadsMerged: fs.DiskStats.ReadsMerged,
SectorsRead: fs.DiskStats.SectorsRead,
ReadTime: fs.DiskStats.ReadTime,
WritesCompleted: fs.DiskStats.WritesCompleted,
WritesMerged: fs.DiskStats.WritesMerged,
SectorsWritten: fs.DiskStats.SectorsWritten,
WriteTime: fs.DiskStats.WriteTime,
IoInProgress: fs.DiskStats.IoInProgress,
IoTime: fs.DiskStats.IoTime,
WeightedIoTime: fs.DiskStats.WeightedIoTime,
})
} }
} }
return nil return nil

View File

@ -322,7 +322,10 @@ func (self *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, er
fs.Capacity, fs.Free, fs.Available, err = getZfstats(device) fs.Capacity, fs.Free, fs.Available, err = getZfstats(device)
fs.Type = ZFS fs.Type = ZFS
default: default:
fs.Capacity, fs.Free, fs.Available, fs.Inodes, fs.InodesFree, err = getVfsStats(partition.mountpoint) var inodes, inodesFree uint64
fs.Capacity, fs.Free, fs.Available, inodes, inodesFree, err = getVfsStats(partition.mountpoint)
fs.Inodes = &inodes
fs.InodesFree = &inodesFree
fs.Type = VFS fs.Type = VFS
} }
if err != nil { if err != nil {

View File

@ -40,8 +40,8 @@ type Fs struct {
Capacity uint64 Capacity uint64
Free uint64 Free uint64
Available uint64 Available uint64
Inodes uint64 Inodes *uint64
InodesFree uint64 InodesFree *uint64
DiskStats DiskStats DiskStats DiskStats
} }

View File

@ -415,6 +415,9 @@ type FsStats struct {
// Number of bytes available for non-root user. // Number of bytes available for non-root user.
Available uint64 `json:"available"` Available uint64 `json:"available"`
// HasInodes when true, indicates that Inodes info will be available.
HasInodes bool `json:"has_inodes"`
// Number of available Inodes // Number of available Inodes
InodesFree uint64 `json:"inodes_free"` InodesFree uint64 `json:"inodes_free"`

View File

@ -26,6 +26,9 @@ type FsInfo struct {
// Total number of inodes available on the filesystem. // Total number of inodes available on the filesystem.
Inodes uint64 `json:"inodes"` Inodes uint64 `json:"inodes"`
// HasInodes when true, indicates that Inodes info will be available.
HasInodes bool `json:"has_inodes"`
} }
type Node struct { type Node struct {

View File

@ -217,8 +217,8 @@ type FsInfo struct {
// Labels associated with this filesystem. // Labels associated with this filesystem.
Labels []string `json:"labels"` Labels []string `json:"labels"`
// Number of available Inodes. // Number of available Inodes (if known)
InodesFree uint64 `json:"inodes_free"` InodesFree *uint64 `json:"inodes_free,omitempty"`
} }
type RequestOptions struct { type RequestOptions struct {

View File

@ -30,13 +30,12 @@ func machineFsStatsFromV1(fsStats []v1.FsStats) []MachineFsStats {
writeDuration := time.Millisecond * time.Duration(stat.WriteTime) writeDuration := time.Millisecond * time.Duration(stat.WriteTime)
ioDuration := time.Millisecond * time.Duration(stat.IoTime) ioDuration := time.Millisecond * time.Duration(stat.IoTime)
weightedDuration := time.Millisecond * time.Duration(stat.WeightedIoTime) weightedDuration := time.Millisecond * time.Duration(stat.WeightedIoTime)
result = append(result, MachineFsStats{ machineFsStat := MachineFsStats{
Device: stat.Device, Device: stat.Device,
Type: stat.Type, Type: stat.Type,
Capacity: &stat.Limit, Capacity: &stat.Limit,
Usage: &stat.Usage, Usage: &stat.Usage,
Available: &stat.Available, Available: &stat.Available,
InodesFree: &stat.InodesFree,
DiskStats: DiskStats{ DiskStats: DiskStats{
ReadsCompleted: &stat.ReadsCompleted, ReadsCompleted: &stat.ReadsCompleted,
ReadsMerged: &stat.ReadsMerged, ReadsMerged: &stat.ReadsMerged,
@ -50,7 +49,11 @@ func machineFsStatsFromV1(fsStats []v1.FsStats) []MachineFsStats {
IoDuration: &ioDuration, IoDuration: &ioDuration,
WeightedIoDuration: &weightedDuration, WeightedIoDuration: &weightedDuration,
}, },
}) }
if stat.HasInodes {
machineFsStat.InodesFree = &stat.InodesFree
}
result = append(result, machineFsStat)
} }
return result return result
} }
@ -58,7 +61,8 @@ func machineFsStatsFromV1(fsStats []v1.FsStats) []MachineFsStats {
func MachineStatsFromV1(cont *v1.ContainerInfo) []MachineStats { func MachineStatsFromV1(cont *v1.ContainerInfo) []MachineStats {
var stats []MachineStats var stats []MachineStats
var last *v1.ContainerStats var last *v1.ContainerStats
for _, val := range cont.Stats { for i := range cont.Stats {
val := cont.Stats[i]
stat := MachineStats{ stat := MachineStats{
Timestamp: val.Timestamp, Timestamp: val.Timestamp,
} }

View File

@ -110,8 +110,13 @@ func Info(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (*info.Mach
InstanceID: instanceID, InstanceID: instanceID,
} }
for _, fs := range filesystems { for i := range filesystems {
machineInfo.Filesystems = append(machineInfo.Filesystems, info.FsInfo{Device: fs.Device, Type: fs.Type.String(), Capacity: fs.Capacity, Inodes: fs.Inodes}) fs := filesystems[i]
inodes := uint64(0)
if fs.Inodes != nil {
inodes = *fs.Inodes
}
machineInfo.Filesystems = append(machineInfo.Filesystems, info.FsInfo{Device: fs.Device, Type: fs.Type.String(), Capacity: fs.Capacity, Inodes: inodes, HasInodes: fs.Inodes != nil})
} }
return machineInfo, nil return machineInfo, nil

View File

@ -44,9 +44,10 @@ import (
"github.com/google/cadvisor/utils/sysfs" "github.com/google/cadvisor/utils/sysfs"
"github.com/google/cadvisor/version" "github.com/google/cadvisor/version"
"net/http"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
"net/http"
) )
var globalHousekeepingInterval = flag.Duration("global_housekeeping_interval", 1*time.Minute, "Interval between global housekeepings") var globalHousekeepingInterval = flag.Duration("global_housekeeping_interval", 1*time.Minute, "Interval between global housekeepings")
@ -671,7 +672,8 @@ func (self *manager) GetFsInfo(label string) ([]v2.FsInfo, error) {
} }
} }
fsInfo := []v2.FsInfo{} fsInfo := []v2.FsInfo{}
for _, fs := range stats[0].Filesystem { for i := range stats[0].Filesystem {
fs := stats[0].Filesystem[i]
if len(label) != 0 && fs.Device != dev { if len(label) != 0 && fs.Device != dev {
continue continue
} }
@ -683,6 +685,7 @@ func (self *manager) GetFsInfo(label string) ([]v2.FsInfo, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
fi := v2.FsInfo{ fi := v2.FsInfo{
Device: fs.Device, Device: fs.Device,
Mountpoint: mountpoint, Mountpoint: mountpoint,
@ -690,7 +693,9 @@ func (self *manager) GetFsInfo(label string) ([]v2.FsInfo, error) {
Usage: fs.Usage, Usage: fs.Usage,
Available: fs.Available, Available: fs.Available,
Labels: labels, Labels: labels,
InodesFree: fs.InodesFree, }
if fs.HasInodes {
fi.InodesFree = &fs.InodesFree
} }
fsInfo = append(fsInfo, fi) fsInfo = append(fsInfo, fi)
} }