Update libcontainer to support rlimit per process
This updates runc and libcontainer to handle rlimits per process and set them correctly for the container. Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
47eaa08f5a
commit
20422c9bd9
|
@ -138,7 +138,7 @@ type Config struct {
|
|||
|
||||
// Rlimits specifies the resource limits, such as max open files, to set in the container
|
||||
// If Rlimits are not set, the container will inherit rlimits from the parent process
|
||||
Rlimits []Rlimit `json:"rlimits"`
|
||||
Rlimits []Rlimit `json:"rlimits,omitempty"`
|
||||
|
||||
// OomScoreAdj specifies the adjustment to be made by the kernel when calculating oom scores
|
||||
// for a process. Valid values are between the range [-1000, '1000'], where processes with
|
||||
|
|
|
@ -332,6 +332,7 @@ func (c *linuxContainer) newInitConfig(process *Process) *initConfig {
|
|||
NoNewPrivileges: c.config.NoNewPrivileges,
|
||||
AppArmorProfile: c.config.AppArmorProfile,
|
||||
ProcessLabel: c.config.ProcessLabel,
|
||||
Rlimits: c.config.Rlimits,
|
||||
}
|
||||
if process.NoNewPrivileges != nil {
|
||||
cfg.NoNewPrivileges = *process.NoNewPrivileges
|
||||
|
@ -342,6 +343,9 @@ func (c *linuxContainer) newInitConfig(process *Process) *initConfig {
|
|||
if process.Label != "" {
|
||||
cfg.ProcessLabel = process.Label
|
||||
}
|
||||
if len(process.Rlimits) > 0 {
|
||||
cfg.Rlimits = process.Rlimits
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
|
|
|
@ -44,19 +44,20 @@ type network struct {
|
|||
|
||||
// initConfig is used for transferring parameters from Exec() to Init()
|
||||
type initConfig struct {
|
||||
Args []string `json:"args"`
|
||||
Env []string `json:"env"`
|
||||
Cwd string `json:"cwd"`
|
||||
Capabilities []string `json:"capabilities"`
|
||||
ProcessLabel string `json:"process_label"`
|
||||
AppArmorProfile string `json:"apparmor_profile"`
|
||||
NoNewPrivileges bool `json:"no_new_privileges"`
|
||||
User string `json:"user"`
|
||||
Config *configs.Config `json:"config"`
|
||||
Console string `json:"console"`
|
||||
Networks []*network `json:"network"`
|
||||
PassedFilesCount int `json:"passed_files_count"`
|
||||
ContainerId string `json:"containerid"`
|
||||
Args []string `json:"args"`
|
||||
Env []string `json:"env"`
|
||||
Cwd string `json:"cwd"`
|
||||
Capabilities []string `json:"capabilities"`
|
||||
ProcessLabel string `json:"process_label"`
|
||||
AppArmorProfile string `json:"apparmor_profile"`
|
||||
NoNewPrivileges bool `json:"no_new_privileges"`
|
||||
User string `json:"user"`
|
||||
Config *configs.Config `json:"config"`
|
||||
Console string `json:"console"`
|
||||
Networks []*network `json:"network"`
|
||||
PassedFilesCount int `json:"passed_files_count"`
|
||||
ContainerId string `json:"containerid"`
|
||||
Rlimits []configs.Rlimit `json:"rlimits"`
|
||||
}
|
||||
|
||||
type initer interface {
|
||||
|
@ -315,8 +316,8 @@ func setupRoute(config *configs.Config) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func setupRlimits(config *configs.Config) error {
|
||||
for _, rlimit := range config.Rlimits {
|
||||
func setupRlimits(limits []configs.Rlimit) error {
|
||||
for _, rlimit := range limits {
|
||||
l := &syscall.Rlimit{Max: rlimit.Hard, Cur: rlimit.Soft}
|
||||
if err := syscall.Setrlimit(rlimit.Type, l); err != nil {
|
||||
return fmt.Errorf("error setting rlimit type %v: %v", rlimit.Type, err)
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"io"
|
||||
"math"
|
||||
"os"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
type processOperations interface {
|
||||
|
@ -58,6 +60,10 @@ type Process struct {
|
|||
// NoNewPrivileges controls whether processes can gain additional privileges.
|
||||
NoNewPrivileges *bool
|
||||
|
||||
// Rlimits specifies the resource limits, such as max open files, to set in the container
|
||||
// If Rlimits are not set, the container will inherit rlimits from the parent process
|
||||
Rlimits []configs.Rlimit
|
||||
|
||||
ops processOperations
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ func (l *linuxSetnsInit) Init() error {
|
|||
if _, err := keyctl.JoinSessionKeyring(l.getSessionRingName()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setupRlimits(l.config.Config); err != nil {
|
||||
if err := setupRlimits(l.config.Rlimits); err != nil {
|
||||
return err
|
||||
}
|
||||
if l.config.NoNewPrivileges {
|
||||
|
|
|
@ -73,7 +73,7 @@ func (l *linuxStandardInit) Init() error {
|
|||
if err := setupRoute(l.config.Config); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setupRlimits(l.config.Config); err != nil {
|
||||
if err := setupRlimits(l.config.Rlimits); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
7
spec.go
7
spec.go
|
@ -278,13 +278,6 @@ func createLibcontainerConfig(cgroupName string, spec *specs.Spec) (*configs.Con
|
|||
if err := setupUserNamespace(spec, config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, rlimit := range spec.Process.Rlimits {
|
||||
rl, err := createLibContainerRlimit(rlimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.Rlimits = append(config.Rlimits, rl)
|
||||
}
|
||||
c, err := createCgroupConfig(cgroupName, spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
17
utils.go
17
utils.go
|
@ -232,8 +232,8 @@ func getDefaultImagePath(context *cli.Context) string {
|
|||
|
||||
// newProcess returns a new libcontainer Process with the arguments from the
|
||||
// spec and stdio from the current process.
|
||||
func newProcess(p specs.Process) *libcontainer.Process {
|
||||
return &libcontainer.Process{
|
||||
func newProcess(p specs.Process) (*libcontainer.Process, error) {
|
||||
lp := &libcontainer.Process{
|
||||
Args: p.Args,
|
||||
Env: p.Env,
|
||||
// TODO: fix libcontainer's API to better support uid/gid in a typesafe way.
|
||||
|
@ -244,6 +244,14 @@ func newProcess(p specs.Process) *libcontainer.Process {
|
|||
NoNewPrivileges: &p.NoNewPrivileges,
|
||||
AppArmorProfile: p.ApparmorProfile,
|
||||
}
|
||||
for _, rlimit := range p.Rlimits {
|
||||
rl, err := createLibContainerRlimit(rlimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lp.Rlimits = append(lp.Rlimits, rl)
|
||||
}
|
||||
return lp, nil
|
||||
}
|
||||
|
||||
func dupStdio(process *libcontainer.Process, rootuid int) error {
|
||||
|
@ -332,7 +340,10 @@ func createContainer(context *cli.Context, id string, spec *specs.Spec) (libcont
|
|||
// runProcess will create a new process in the specified container
|
||||
// by executing the process specified in the 'config'.
|
||||
func runProcess(container libcontainer.Container, config *specs.Process, listenFDs []*os.File, console string, pidFile string, detach bool) (int, error) {
|
||||
process := newProcess(*config)
|
||||
process, err := newProcess(*config)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
// Add extra file descriptors if needed
|
||||
if len(listenFDs) > 0 {
|
||||
|
|
Loading…
Reference in New Issue