Add support for setting rlimit for contianer
Adds a new item to the config struct []*Rlimit Rlimit takes a type (ie, syscall.RLIMIT_NOFILE) and the hard/soft limit (As max/cur) Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
parent
72942137ef
commit
e6cc8fc713
10
config.go
10
config.go
|
@ -68,6 +68,10 @@ type Config struct {
|
||||||
// RestrictSys will remount /proc/sys, /sys, and mask over sysrq-trigger as well as /proc/irq and
|
// RestrictSys will remount /proc/sys, /sys, and mask over sysrq-trigger as well as /proc/irq and
|
||||||
// /proc/bus
|
// /proc/bus
|
||||||
RestrictSys bool `json:"restrict_sys,omitempty"`
|
RestrictSys bool `json:"restrict_sys,omitempty"`
|
||||||
|
|
||||||
|
// 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,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routes can be specified to create entries in the route table as the container is started
|
// Routes can be specified to create entries in the route table as the container is started
|
||||||
|
@ -90,3 +94,9 @@ type Route struct {
|
||||||
// The device to set this route up for, for example: eth0
|
// The device to set this route up for, for example: eth0
|
||||||
InterfaceName string `json:"interface_name,omitempty"`
|
InterfaceName string `json:"interface_name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Rlimit struct {
|
||||||
|
Type int `json:"type,omitempty"`
|
||||||
|
Hard uint64 `json:"hard,omitempty"`
|
||||||
|
Soft uint64 `json:"soft,omitempty"`
|
||||||
|
}
|
||||||
|
|
|
@ -156,3 +156,24 @@ func TestIPCBadPath(t *testing.T) {
|
||||||
t.Fatal("container succeded with bad ipc path")
|
t.Fatal("container succeded with bad ipc path")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRlimit(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rootfs, err := newRootFs()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer remove(rootfs)
|
||||||
|
|
||||||
|
config := newTemplateConfig(rootfs)
|
||||||
|
out, _, err := runContainer(config, "", "/bin/sh", "-c", "ulimit -n")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if limit := strings.TrimSpace(out.Stdout.String()); limit != "1024" {
|
||||||
|
t.Fatalf("expected rlimit to be 1024, got %s", limit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package integration
|
package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/docker/libcontainer"
|
"github.com/docker/libcontainer"
|
||||||
"github.com/docker/libcontainer/cgroups"
|
"github.com/docker/libcontainer/cgroups"
|
||||||
"github.com/docker/libcontainer/devices"
|
"github.com/docker/libcontainer/devices"
|
||||||
|
@ -60,5 +62,12 @@ func newTemplateConfig(rootfs string) *libcontainer.Config {
|
||||||
Gateway: "localhost",
|
Gateway: "localhost",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Rlimits: []libcontainer.Rlimit{
|
||||||
|
{
|
||||||
|
Type: syscall.RLIMIT_NOFILE,
|
||||||
|
Hard: uint64(1024),
|
||||||
|
Soft: uint64(1024),
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,10 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, pip
|
||||||
return fmt.Errorf("setup route %s", err)
|
return fmt.Errorf("setup route %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := setupRlimits(container); err != nil {
|
||||||
|
return fmt.Errorf("setup rlimits %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
label.Init()
|
label.Init()
|
||||||
|
|
||||||
if err := mount.InitializeMountNamespace(rootfs,
|
if err := mount.InitializeMountNamespace(rootfs,
|
||||||
|
@ -238,6 +242,16 @@ func setupRoute(container *libcontainer.Config) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupRlimits(container *libcontainer.Config) error {
|
||||||
|
for _, rlimit := range container.Rlimits {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// FinalizeNamespace drops the caps, sets the correct user
|
// FinalizeNamespace drops the caps, sets the correct user
|
||||||
// and working dir, and closes any leaky file descriptors
|
// and working dir, and closes any leaky file descriptors
|
||||||
// before execing the command inside the namespace
|
// before execing the command inside the namespace
|
||||||
|
|
Loading…
Reference in New Issue