Skip to content

Commit

Permalink
Add SkipOpts for handling how subsystems are registered
Browse files Browse the repository at this point in the history
This adds a flexible way for subsystems to be skipped or required within
the cgroups package.

Signed-off-by: Michael Crosby <[email protected]>
  • Loading branch information
crosbymichael committed Feb 26, 2019
1 parent 4dacf2b commit 4a9f0f7
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 3 deletions.
30 changes: 28 additions & 2 deletions cgroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ import (
)

// New returns a new control via the cgroup cgroups interface
func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources) (Cgroup, error) {
func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources, opts ...InitOpts) (Cgroup, error) {
config := newInitConfig()
for _, o := range opts {
if err := o(config); err != nil {
return nil, err
}
}
subsystems, err := hierarchy()
if err != nil {
return nil, err
Expand All @@ -40,6 +46,13 @@ func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources) (Cgrou
// check if subsystem exists
if err := initializeSubsystem(s, path, resources); err != nil {
if err == ErrControllerNotActive {
if config.InitCheck != nil {
if skerr := config.InitCheck(s, path, err); skerr != nil {
if skerr != ErrIgnoreSubsystem {
return nil, skerr
}
}
}
continue
}
return nil, err
Expand All @@ -53,7 +66,13 @@ func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources) (Cgrou
}

// Load will load an existing cgroup and allow it to be controlled
func Load(hierarchy Hierarchy, path Path) (Cgroup, error) {
func Load(hierarchy Hierarchy, path Path, opts ...InitOpts) (Cgroup, error) {
config := newInitConfig()
for _, o := range opts {
if err := o(config); err != nil {
return nil, err
}
}
var activeSubsystems []Subsystem
subsystems, err := hierarchy()
if err != nil {
Expand All @@ -67,6 +86,13 @@ func Load(hierarchy Hierarchy, path Path) (Cgroup, error) {
return nil, ErrCgroupDeleted
}
if err == ErrControllerNotActive {
if config.InitCheck != nil {
if skerr := config.InitCheck(s, path, err); skerr != nil {
if skerr != ErrIgnoreSubsystem {
return nil, skerr
}
}
}
continue
}
return nil, err
Expand Down
61 changes: 61 additions & 0 deletions opts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cgroups

import (
"github.com/pkg/errors"
)

var (
// ErrIgnoreSubsystem allows the specific subsystem to be skipped
ErrIgnoreSubsystem = errors.New("skip subsystem")
// ErrDevicesRequired is returned when the devices subsystem is required but
// does not exist or is not active
ErrDevicesRequired = errors.New("devices subsystem is required")
)

// InitOpts allows configuration for the creation or loading of a cgroup
type InitOpts func(*InitConfig) error

// InitConfig provides configuration options for the creation
// or loading of a cgroup and its subsystems
type InitConfig struct {
// InitCheck can be used to check initialization errors from the subsystem
InitCheck InitCheck
}

func newInitConfig() *InitConfig {
return &InitConfig{
InitCheck: RequireDevices,
}
}

// InitCheck allows subsystems errors to be checked when initialized or loaded
type InitCheck func(Subsystem, Path, error) error

// AllowAny allows any subsystem errors to be skipped
func AllowAny(s Subsystem, p Path, err error) error {
return ErrIgnoreSubsystem
}

// RequireDevices requires the device subsystem but no others
func RequireDevices(s Subsystem, p Path, err error) error {
if s.Name() == Devices {
return ErrDevicesRequired
}
return ErrIgnoreSubsystem
}
2 changes: 1 addition & 1 deletion paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func PidPath(pid int) Path {
return existingPath(paths, "")
}

// ErrControllerNotActive is returned when a controller is not supported or enalbed
// ErrControllerNotActive is returned when a controller is not supported or enabled
var ErrControllerNotActive = errors.New("controller is not supported")

func existingPath(paths map[string]string, suffix string) Path {
Expand Down

0 comments on commit 4a9f0f7

Please sign in to comment.