| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- package manager
- import (
- "errors"
- "fmt"
- "path/filepath"
- "github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/cgroups/fs"
- "github.com/opencontainers/runc/libcontainer/cgroups/fs2"
- "github.com/opencontainers/runc/libcontainer/cgroups/systemd"
- "github.com/opencontainers/runc/libcontainer/configs"
- )
- // New returns the instance of a cgroup manager, which is chosen
- // based on the local environment (whether cgroup v1 or v2 is used)
- // and the config (whether config.Systemd is set or not).
- func New(config *configs.Cgroup) (cgroups.Manager, error) {
- return NewWithPaths(config, nil)
- }
- // NewWithPaths is similar to New, and can be used in case cgroup paths
- // are already well known, which can save some resources.
- //
- // For cgroup v1, the keys are controller/subsystem name, and the values
- // are absolute filesystem paths to the appropriate cgroups.
- //
- // For cgroup v2, the only key allowed is "" (empty string), and the value
- // is the unified cgroup path.
- func NewWithPaths(config *configs.Cgroup, paths map[string]string) (cgroups.Manager, error) {
- if config == nil {
- return nil, errors.New("cgroups/manager.New: config must not be nil")
- }
- if config.Systemd && !systemd.IsRunningSystemd() {
- return nil, errors.New("systemd not running on this host, cannot use systemd cgroups manager")
- }
- // Cgroup v2 aka unified hierarchy.
- if cgroups.IsCgroup2UnifiedMode() {
- path, err := getUnifiedPath(paths)
- if err != nil {
- return nil, fmt.Errorf("manager.NewWithPaths: inconsistent paths: %w", err)
- }
- if config.Systemd {
- return systemd.NewUnifiedManager(config, path)
- }
- return fs2.NewManager(config, path)
- }
- // Cgroup v1.
- if config.Systemd {
- return systemd.NewLegacyManager(config, paths)
- }
- return fs.NewManager(config, paths)
- }
- // getUnifiedPath is an implementation detail of libcontainer factory.
- // Historically, it saves cgroup paths as per-subsystem path map (as returned
- // by cm.GetPaths(""), but with v2 we only have one single unified path
- // (with "" as a key).
- //
- // This function converts from that map to string (using "" as a key),
- // and also checks that the map itself is sane.
- func getUnifiedPath(paths map[string]string) (string, error) {
- if len(paths) > 1 {
- return "", fmt.Errorf("expected a single path, got %+v", paths)
- }
- path := paths[""]
- // can be empty
- if path != "" {
- if filepath.Clean(path) != path || !filepath.IsAbs(path) {
- return "", fmt.Errorf("invalid path: %q", path)
- }
- }
- return path, nil
- }
|