[lxc-devel] [lxd/master] Implement support for pid cgroup
stgraber on Github
lxc-bot at linuxcontainers.org
Tue Feb 23 02:38:13 UTC 2016
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160223/110b87fc/attachment.bin>
-------------- next part --------------
From 7cc21c04807b92a4bcfe2caee4dbe2f480035f16 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 22 Feb 2016 21:27:52 -0500
Subject: [PATCH 1/2] Add process limit (pids cgroup)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/container.go | 2 ++
lxd/container_lxc.go | 40 ++++++++++++++++++++++++++++++++++++++++
lxd/daemon.go | 6 ++++++
specs/configuration.md | 1 +
4 files changed, 49 insertions(+)
diff --git a/lxd/container.go b/lxd/container.go
index 0792c17..4ded43f 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -63,6 +63,8 @@ func containerValidConfigKey(k string) bool {
return true
case "limits.network.priority":
return true
+ case "limits.processes":
+ return true
case "linux.kernel_modules":
return true
case "security.privileged":
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index c3afead..a09ee56 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -616,6 +616,22 @@ func (c *containerLXC) initLXC() error {
}
}
+ // Processes
+ if cgPidsController {
+ processes := c.expandedConfig["limits.processes"]
+ if processes != "" {
+ valueInt, err := strconv.ParseInt(processes, 10, 64)
+ if err != nil {
+ return err
+ }
+
+ err = lxcSetConfigItem(cc, "lxc.cgroup.pids.max", fmt.Sprintf("%d", valueInt))
+ if err != nil {
+ return err
+ }
+ }
+ }
+
// Setup devices
for k, m := range c.expandedDevices {
if shared.StringInSlice(m["type"], []string{"unix-char", "unix-block"}) {
@@ -2065,6 +2081,30 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
undoChanges()
return err
}
+ } else if key == "limits.processes" {
+ if !cgPidsController {
+ continue
+ }
+
+ if value == "" {
+ err = c.CGroupSet("pids.max", "max")
+ if err != nil {
+ undoChanges()
+ return err
+ }
+ } else {
+ valueInt, err := strconv.ParseInt(value, 10, 64)
+ if err != nil {
+ undoChanges()
+ return err
+ }
+
+ err = c.CGroupSet("pids.max", fmt.Sprintf("%d", valueInt))
+ if err != nil {
+ undoChanges()
+ return err
+ }
+ }
}
}
diff --git a/lxd/daemon.go b/lxd/daemon.go
index 5b1546c..bbb34a8 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -48,6 +48,7 @@ var cgCpusetController = false
var cgDevicesController = false
var cgMemoryController = false
var cgNetPrioController = false
+var cgPidsController = false
var cgSwapAccounting = false
// UserNS
@@ -744,6 +745,11 @@ func (d *Daemon) Init() error {
shared.Log.Warn("Couldn't find the CGroup network class controller, network limits will be ignored.")
}
+ cgPidsController = shared.PathExists("/sys/fs/cgroup/pids/")
+ if !cgPidsController {
+ shared.Log.Warn("Couldn't find the CGroup pids controller, process limits will be ignored.")
+ }
+
cgSwapAccounting = shared.PathExists("/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes")
if !cgSwapAccounting {
shared.Log.Warn("CGroup memory swap accounting is disabled, swap limits will be ignored.")
diff --git a/specs/configuration.md b/specs/configuration.md
index fe6d7f0..fe7e6f7 100644
--- a/specs/configuration.md
+++ b/specs/configuration.md
@@ -70,6 +70,7 @@ limits.memory.enforce | string | hard | yes | If har
limits.memory.swap | boolean | true | yes | Whether to allow some of the container's memory to be swapped out to disk
limits.memory.swap.priority | integer | 10 (maximum) | yes | The higher this is set, the least likely the container is to be swapped to disk
limits.network.priority | integer | 0 (minimum) | yes | When under load, how much priority to give to the container's network requests
+limits.processes | integer | - (max) | yes | Maximum number of processes that can run in the container
linux.kernel\_modules | string | - | yes | Comma separated list of kernel modules to load before starting the container
raw.apparmor | blob | - | yes | Apparmor profile entries to be appended to the generated profile
raw.lxc | blob | - | no | Raw LXC configuration to be appended to the generated one
From eef45154892ab079dbc9748710bbf450a8b1b4db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 22 Feb 2016 21:37:29 -0500
Subject: [PATCH 2/2] Optimize container process count (use pid cgroup)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/container.go | 1 +
lxd/container_lxc.go | 26 ++++++++++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/lxd/container.go b/lxd/container.go
index 4ded43f..9dc714e 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -329,6 +329,7 @@ type container interface {
Export(w io.Writer) error
// Live configuration
+ CGroupGet(key string) (string, error)
CGroupSet(key string, value string) error
ConfigKeySet(key string, value string) error
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index a09ee56..bcff879 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -1617,6 +1617,22 @@ func (c *containerLXC) Rename(newName string) error {
return nil
}
+func (c *containerLXC) CGroupGet(key string) (string, error) {
+ // Load the go-lxc struct
+ err := c.initLXC()
+ if err != nil {
+ return "", err
+ }
+
+ // Make sure the container is running
+ if !c.IsRunning() {
+ return "", fmt.Errorf("Can't get cgroups on a stopped container")
+ }
+
+ value := c.c.CgroupItem(key)
+ return strings.Join(value, "\n"), nil
+}
+
func (c *containerLXC) CGroupSet(key string, value string) error {
// Load the go-lxc struct
err := c.initLXC()
@@ -2703,6 +2719,16 @@ func (c *containerLXC) processcountGet() int {
return 0
}
+ if cgPidsController {
+ value, err := c.CGroupGet("pids.current")
+ valueInt, err := strconv.Atoi(value)
+ if err != nil {
+ return 0
+ }
+
+ return valueInt
+ }
+
pids := []int{pid}
// Go through the pid list, adding new pids at the end so we go through them all
More information about the lxc-devel
mailing list