Merge pull request #280 from cpuguy83/add_rlimit_support

Add support for setting rlimit for contianer
This commit is contained in:
Michael Crosby 2014-11-26 11:14:49 -08:00
commit 7ce34f58cb
4 changed files with 54 additions and 0 deletions

View File

@ -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"`
}

View File

@ -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)
}
}

View File

@ -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),
},
},
} }
} }

View File

@ -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