diff --git a/cgroups.go b/cgroups.go index 5a97bd3..473877b 100644 --- a/cgroups.go +++ b/cgroups.go @@ -44,6 +44,27 @@ type Manager interface { // GetStats returns cgroups statistics. GetStats() (*Stats, error) + // GetCpuStats returns cgroups cpu statistics + GetCpuStats() (*Stats, error) + + // GetMemoryStats returns cgroups memory statistics + GetMemoryStats() (*Stats, error) + + // GetPidsStats returns cgroups pids statistics + GetPidsStats() (*Stats, error) + + // GetIoStats returns cgroups io statistics + GetIoStats() (*Stats, error) + + // GetHugetlbStats returns cgroups hugetlb statistics + GetHugetlbStats() (*Stats, error) + + // GetRdmaStats returns cgroups rdma statistics + GetRdmaStats() (*Stats, error) + + // GetMiscStats returns cgroups misc statistics + GetMiscStats() (*Stats, error) + // Freeze sets the freezer cgroup to the specified state. Freeze(state FreezerState) error diff --git a/fs/fs.go b/fs/fs.go index 6259311..18f6434 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -196,6 +196,111 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) { return stats, nil } +func (m *Manager) GetCpuStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + cpuGroup := &CpuGroup{} + if path := m.paths["cpu"]; path != "" { + if err := cpuGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + cpuacctGroup := &CpuacctGroup{} + if path := m.paths["cpuacct"]; path != "" { + if err := cpuacctGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + return stats, nil +} + +func (m *Manager) GetMemoryStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + memoryGroup := &MemoryGroup{} + if path := m.paths["memory"]; path != "" { + if err := memoryGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + return stats, nil +} + +func (m *Manager) GetPidsStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + pidsGroup := &PidsGroup{} + if path := m.paths["pids"]; path != "" { + if err := pidsGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + return stats, nil +} + +func (m *Manager) GetIoStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + blkioGroup := &BlkioGroup{} + if path := m.paths["blkio"]; path != "" { + if err := blkioGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + return stats, nil +} + +func (m *Manager) GetHugetlbStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + hugetlbGroup := &HugetlbGroup{} + if path := m.paths["hugetlb"]; path != "" { + if err := hugetlbGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + return stats, nil +} + +func (m *Manager) GetRdmaStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + rdmaGroup := &RdmaGroup{} + if path := m.paths["rdma"]; path != "" { + if err := rdmaGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + return stats, nil +} + +func (m *Manager) GetMiscStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + return stats, nil +} + func (m *Manager) Set(r *cgroups.Resources) error { if r == nil { return nil diff --git a/fs2/fs2.go b/fs2/fs2.go index 356d087..3ea8e48 100644 --- a/fs2/fs2.go +++ b/fs2/fs2.go @@ -155,6 +155,84 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) { return st, nil } +func (m *Manager) GetCpuStats() (*cgroups.Stats, error) { + st := cgroups.NewStats() + + if err := statCpu(m.dirPath, st); err != nil && !os.IsNotExist(err) { + return st, err + } + + var err error + if st.CpuStats.PSI, err = statPSI(m.dirPath, "cpu.pressure"); err != nil { + return st, err + } + + return st, nil +} + +func (m *Manager) GetMemoryStats() (*cgroups.Stats, error) { + st := cgroups.NewStats() + + if err := statMemory(m.dirPath, st); err != nil && !os.IsNotExist(err) { + return st, err + } + + var err error + if st.MemoryStats.PSI, err = statPSI(m.dirPath, "memory.pressure"); err != nil { + return st, err + } + + return st, nil +} + +func (m *Manager) GetPidsStats() (*cgroups.Stats, error) { + st := cgroups.NewStats() + err := statPids(m.dirPath, st) + return st, err +} + +func (m *Manager) GetIoStats() (*cgroups.Stats, error) { + st := cgroups.NewStats() + + if err := statIo(m.dirPath, st); err != nil && !os.IsNotExist(err) { + return st, err + } + + var err error + if st.BlkioStats.PSI, err = statPSI(m.dirPath, "io.pressure"); err != nil { + return st, err + } + + return st, nil +} + +func (m *Manager) GetHugetlbStats() (*cgroups.Stats, error) { + st := cgroups.NewStats() + err := statHugeTlb(m.dirPath, st) + if err != nil && !os.IsNotExist(err) { + return st, err + } + return st, nil +} + +func (m *Manager) GetRdmaStats() (*cgroups.Stats, error) { + st := cgroups.NewStats() + err := fscommon.RdmaGetStats(m.dirPath, st) + if err != nil && !os.IsNotExist(err) { + return st, err + } + return st, nil +} + +func (m *Manager) GetMiscStats() (*cgroups.Stats, error) { + st := cgroups.NewStats() + err := statMisc(m.dirPath, st) + if err != nil && !os.IsNotExist(err) { + return st, err + } + return st, nil +} + func (m *Manager) Freeze(state cgroups.FreezerState) error { if m.config.Resources == nil { return errors.New("cannot toggle freezer: cgroups not configured for container") diff --git a/systemd/v1.go b/systemd/v1.go index 96e69bb..966762d 100644 --- a/systemd/v1.go +++ b/systemd/v1.go @@ -355,6 +355,111 @@ func (m *LegacyManager) GetStats() (*cgroups.Stats, error) { return stats, nil } +func (m *LegacyManager) GetCpuStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + cpuGroup := &fs.CpuGroup{} + if path := m.paths["cpu"]; path != "" { + if err := cpuGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + cpuacctGroup := &fs.CpuacctGroup{} + if path := m.paths["cpuacct"]; path != "" { + if err := cpuacctGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + return stats, nil +} + +func (m *LegacyManager) GetMemoryStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + memoryGroup := &fs.MemoryGroup{} + if path := m.paths["memory"]; path != "" { + if err := memoryGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + return stats, nil +} + +func (m *LegacyManager) GetPidsStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + pidsGroup := &fs.PidsGroup{} + if path := m.paths["pids"]; path != "" { + if err := pidsGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + return stats, nil +} + +func (m *LegacyManager) GetIoStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + blkioGroup := &fs.BlkioGroup{} + if path := m.paths["blkio"]; path != "" { + if err := blkioGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + return stats, nil +} + +func (m *LegacyManager) GetHugetlbStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + hugetlbGroup := &fs.HugetlbGroup{} + if path := m.paths["hugetlb"]; path != "" { + if err := hugetlbGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + return stats, nil +} + +func (m *LegacyManager) GetRdmaStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + rdmaGroup := &fs.RdmaGroup{} + if path := m.paths["rdma"]; path != "" { + if err := rdmaGroup.GetStats(path, stats); err != nil { + return nil, err + } + } + + return stats, nil +} + +func (m *LegacyManager) GetMiscStats() (*cgroups.Stats, error) { + m.mu.Lock() + defer m.mu.Unlock() + stats := cgroups.NewStats() + + return stats, nil +} + func (m *LegacyManager) Set(r *cgroups.Resources) error { if r == nil { return nil diff --git a/systemd/v2.go b/systemd/v2.go index f76c93e..4c7e763 100644 --- a/systemd/v2.go +++ b/systemd/v2.go @@ -497,6 +497,34 @@ func (m *UnifiedManager) GetStats() (*cgroups.Stats, error) { return m.fsMgr.GetStats() } +func (m *UnifiedManager) GetCpuStats() (*cgroups.Stats, error) { + return m.fsMgr.GetCpuStats() +} + +func (m *UnifiedManager) GetMemoryStats() (*cgroups.Stats, error) { + return m.fsMgr.GetMemoryStats() +} + +func (m *UnifiedManager) GetPidsStats() (*cgroups.Stats, error) { + return m.fsMgr.GetPidsStats() +} + +func (m *UnifiedManager) GetIoStats() (*cgroups.Stats, error) { + return m.fsMgr.GetIoStats() +} + +func (m *UnifiedManager) GetHugetlbStats() (*cgroups.Stats, error) { + return m.fsMgr.GetHugetlbStats() +} + +func (m *UnifiedManager) GetRdmaStats() (*cgroups.Stats, error) { + return m.fsMgr.GetRdmaStats() +} + +func (m *UnifiedManager) GetMiscStats() (*cgroups.Stats, error) { + return m.fsMgr.GetMiscStats() +} + func (m *UnifiedManager) Set(r *cgroups.Resources) error { if r == nil { return nil