cgroup2: implement `runc ps`
Implemented `runc ps` for cgroup v2 , using a newly added method `m.GetUnifiedPath()`. Unlike the v1 implementation that checks `m.GetPaths()["devices"]`, the v2 implementation does not require the device controller to be available. Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
parent
f017e0f9e1
commit
dbd771e475
|
@ -37,6 +37,13 @@ type Manager interface {
|
||||||
// restore the object later.
|
// restore the object later.
|
||||||
GetPaths() map[string]string
|
GetPaths() map[string]string
|
||||||
|
|
||||||
|
// GetUnifiedPath returns the unified path when running in unified mode.
|
||||||
|
// The value corresponds to the all values of GetPaths() map.
|
||||||
|
//
|
||||||
|
// GetUnifiedPath returns error when running in hybrid mode as well as
|
||||||
|
// in legacy mode.
|
||||||
|
GetUnifiedPath() (string, error)
|
||||||
|
|
||||||
// Sets the cgroup as configured.
|
// Sets the cgroup as configured.
|
||||||
Set(container *configs.Config) error
|
Set(container *configs.Config) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,6 +224,28 @@ func (m *Manager) GetPaths() map[string]string {
|
||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Manager) GetUnifiedPath() (string, error) {
|
||||||
|
if !cgroups.IsCgroup2UnifiedMode() {
|
||||||
|
return "", errors.New("unified path is only supported when running in unified mode")
|
||||||
|
}
|
||||||
|
unifiedPath := ""
|
||||||
|
m.mu.Lock()
|
||||||
|
defer m.mu.Unlock()
|
||||||
|
for k, v := range m.Paths {
|
||||||
|
if unifiedPath == "" {
|
||||||
|
unifiedPath = v
|
||||||
|
} else if v != unifiedPath {
|
||||||
|
return unifiedPath,
|
||||||
|
errors.Errorf("expected %q path to be unified path %q, got %q", k, unifiedPath, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if unifiedPath == "" {
|
||||||
|
// FIXME: unified path could be detected even when no controller is available
|
||||||
|
return unifiedPath, errors.New("cannot detect unified path")
|
||||||
|
}
|
||||||
|
return unifiedPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Manager) GetStats() (*cgroups.Stats, error) {
|
func (m *Manager) GetStats() (*cgroups.Stats, error) {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
|
@ -302,11 +324,25 @@ func (m *Manager) Freeze(state configs.FreezerState) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) GetPids() ([]int, error) {
|
func (m *Manager) GetPids() ([]int, error) {
|
||||||
|
if cgroups.IsCgroup2UnifiedMode() {
|
||||||
|
path, err := m.GetUnifiedPath()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return cgroups.GetPids(path)
|
||||||
|
}
|
||||||
paths := m.GetPaths()
|
paths := m.GetPaths()
|
||||||
return cgroups.GetPids(paths["devices"])
|
return cgroups.GetPids(paths["devices"])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) GetAllPids() ([]int, error) {
|
func (m *Manager) GetAllPids() ([]int, error) {
|
||||||
|
if cgroups.IsCgroup2UnifiedMode() {
|
||||||
|
path, err := m.GetUnifiedPath()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return cgroups.GetAllPids(path)
|
||||||
|
}
|
||||||
paths := m.GetPaths()
|
paths := m.GetPaths()
|
||||||
return cgroups.GetAllPids(paths["devices"])
|
return cgroups.GetAllPids(paths["devices"])
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,10 @@ func (m *Manager) GetPaths() map[string]string {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Manager) GetUnifiedPath() (string, error) {
|
||||||
|
return "", fmt.Errorf("Systemd not supported")
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Manager) GetStats() (*cgroups.Stats, error) {
|
func (m *Manager) GetStats() (*cgroups.Stats, error) {
|
||||||
return nil, fmt.Errorf("Systemd not supported")
|
return nil, fmt.Errorf("Systemd not supported")
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,6 +297,10 @@ func (m *LegacyManager) GetPaths() map[string]string {
|
||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *LegacyManager) GetUnifiedPath() (string, error) {
|
||||||
|
return "", errors.New("unified path is only supported when running in unified mode")
|
||||||
|
}
|
||||||
|
|
||||||
func join(c *configs.Cgroup, subsystem string, pid int) (string, error) {
|
func join(c *configs.Cgroup, subsystem string, pid int) (string, error) {
|
||||||
path, err := getSubsystemPath(c, subsystem)
|
path, err := getSubsystemPath(c, subsystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||||
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
|
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
|
||||||
"github.com/opencontainers/runc/libcontainer/configs"
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -195,7 +196,24 @@ func (m *UnifiedManager) GetPaths() map[string]string {
|
||||||
m.mu.Unlock()
|
m.mu.Unlock()
|
||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
|
func (m *UnifiedManager) GetUnifiedPath() (string, error) {
|
||||||
|
unifiedPath := ""
|
||||||
|
m.mu.Lock()
|
||||||
|
defer m.mu.Unlock()
|
||||||
|
for k, v := range m.Paths {
|
||||||
|
if unifiedPath == "" {
|
||||||
|
unifiedPath = v
|
||||||
|
} else if v != unifiedPath {
|
||||||
|
return unifiedPath,
|
||||||
|
errors.Errorf("expected %q path to be unified path %q, got %q", k, unifiedPath, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if unifiedPath == "" {
|
||||||
|
// FIXME: unified path could be detected even when no controller is available
|
||||||
|
return unifiedPath, errors.New("cannot detect unified path")
|
||||||
|
}
|
||||||
|
return unifiedPath, nil
|
||||||
|
}
|
||||||
func createCgroupsv2Path(path string) (Err error) {
|
func createCgroupsv2Path(path string) (Err error) {
|
||||||
content, err := ioutil.ReadFile("/sys/fs/cgroup/cgroup.controllers")
|
content, err := ioutil.ReadFile("/sys/fs/cgroup/cgroup.controllers")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -270,7 +288,7 @@ func (m *UnifiedManager) Freeze(state configs.FreezerState) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *UnifiedManager) GetPids() ([]int, error) {
|
func (m *UnifiedManager) GetPids() ([]int, error) {
|
||||||
path, err := getSubsystemPath(m.Cgroups, "devices")
|
path, err := m.GetUnifiedPath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -278,7 +296,7 @@ func (m *UnifiedManager) GetPids() ([]int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *UnifiedManager) GetAllPids() ([]int, error) {
|
func (m *UnifiedManager) GetAllPids() ([]int, error) {
|
||||||
path, err := getSubsystemPath(m.Cgroups, "devices")
|
path, err := m.GetUnifiedPath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,10 @@ func (m *mockCgroupManager) GetPaths() map[string]string {
|
||||||
return m.paths
|
return m.paths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *mockCgroupManager) GetUnifiedPath() (string, error) {
|
||||||
|
return "", fmt.Errorf("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
func (m *mockCgroupManager) Freeze(state configs.FreezerState) error {
|
func (m *mockCgroupManager) Freeze(state configs.FreezerState) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue