mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
6a3fe1618f
Since LinuxFactory has become the means to specify containers state top directory (aka --root), and is only used by two methods (Create and Load), it is easier to pass root to them directly. Modify all the users and the docs accordingly. While at it, fix Create and Load docs (those that were originally moved from the Factory interface docs). Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
79 lines
2.5 KiB
Go
79 lines
2.5 KiB
Go
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.
|
|
// Historically, libcontainer.Create 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
|
|
}
|