[lxc-devel] [PATCH 2/3] python: Add binding for {get|set}_cgroup_item

Stéphane Graber stgraber at ubuntu.com
Fri Dec 7 20:47:11 UTC 2012


Updates the binding for the two new functions.

This also fixes some problems with the argument checking of
get_config_item that'd otherwise lead to a segfault.

The python binding for set_cgroup_item and get_cgroup_item are pretty
raw as lxc has little control over the cgroup entries.
That means that we don't try to interpret lists as we do for the config
entries.

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 src/python-lxc/examples/api_test.py.in |  7 +++++
 src/python-lxc/lxc.c                   | 55 +++++++++++++++++++++++++++++++++-
 src/python-lxc/lxc/__init__.py.in      | 12 ++++++++
 3 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/src/python-lxc/examples/api_test.py.in b/src/python-lxc/examples/api_test.py.in
index 0b17bd6..7711291 100644
--- a/src/python-lxc/examples/api_test.py.in
+++ b/src/python-lxc/examples/api_test.py.in
@@ -97,6 +97,13 @@ container.attach("NETWORK|UTSNAME", "/sbin/ifconfig", "eth0")
 # A few basic checks of the current state
 assert(len(ips) > 0)
 
+## Testing cgroups a bit
+print("Testing cgroup API")
+max_mem = container.get_cgroup_item("memory.max_usage_in_bytes")
+current_limit = container.get_cgroup_item("memory.limit_in_bytes")
+assert(container.set_cgroup_item("memory.limit_in_bytes", max_mem))
+assert(container.get_cgroup_item("memory.limit_in_bytes") != current_limit)
+
 ## Freezing the container
 print("Freezing the container")
 container.freeze()
diff --git a/src/python-lxc/lxc.c b/src/python-lxc/lxc.c
index b489079..83e2659 100644
--- a/src/python-lxc/lxc.c
+++ b/src/python-lxc/lxc.c
@@ -204,13 +204,38 @@ Container_freeze(Container *self, PyObject *args, PyObject *kwds)
 }
 
 static PyObject *
+Container_get_cgroup_item(Container *self, PyObject *args, PyObject *kwds)
+{
+    static char *kwlist[] = {"key", NULL};
+    char* key = NULL;
+    int len = 0;
+
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist,
+                                      &key))
+        Py_RETURN_FALSE;
+
+    len = self->container->get_cgroup_item(self->container, key, NULL, 0);
+
+    if (len <= 0) {
+        Py_RETURN_FALSE;
+    }
+
+    char* value = (char*) malloc(sizeof(char)*len + 1);
+    if (self->container->get_cgroup_item(self->container, key, value, len + 1) != len) {
+        Py_RETURN_FALSE;
+    }
+
+    return PyUnicode_FromString(value);
+}
+
+static PyObject *
 Container_get_config_item(Container *self, PyObject *args, PyObject *kwds)
 {
     static char *kwlist[] = {"key", NULL};
     char* key = NULL;
     int len = 0;
 
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist,
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist,
                                       &key))
         Py_RETURN_FALSE;
 
@@ -288,6 +313,24 @@ Container_save_config(Container *self, PyObject *args, PyObject *kwds)
 }
 
 static PyObject *
+Container_set_cgroup_item(Container *self, PyObject *args, PyObject *kwds)
+{
+    static char *kwlist[] = {"key", "value", NULL};
+    char *key = NULL;
+    char *value = NULL;
+
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "ss|", kwlist,
+                                      &key, &value))
+        Py_RETURN_FALSE;
+
+    if (self->container->set_cgroup_item(self->container, key, value)) {
+        Py_RETURN_TRUE;
+    }
+
+    Py_RETURN_FALSE;
+}
+
+static PyObject *
 Container_set_config_item(Container *self, PyObject *args, PyObject *kwds)
 {
     static char *kwlist[] = {"key", "value", NULL};
@@ -441,6 +484,11 @@ static PyMethodDef Container_methods[] = {
      "\n"
      "Freezes the container and returns its return code."
     },
+    {"get_cgroup_item", (PyCFunction)Container_get_cgroup_item, METH_VARARGS | METH_KEYWORDS,
+     "get_cgroup_item(key) -> string\n"
+     "\n"
+     "Get the current value of a cgroup entry."
+    },
     {"get_config_item", (PyCFunction)Container_get_config_item, METH_VARARGS | METH_KEYWORDS,
      "get_config_item(key) -> string\n"
      "\n"
@@ -463,6 +511,11 @@ static PyMethodDef Container_methods[] = {
      "Save the container configuration to its default "
      "location or to an alternative location if provided."
     },
+    {"set_cgroup_item", (PyCFunction)Container_set_cgroup_item, METH_VARARGS | METH_KEYWORDS,
+     "set_cgroup_item(key, value) -> boolean\n"
+     "\n"
+     "Set a cgroup entry to the provided value."
+    },
     {"set_config_item", (PyCFunction)Container_set_config_item, METH_VARARGS | METH_KEYWORDS,
      "set_config_item(key, value) -> boolean\n"
      "\n"
diff --git a/src/python-lxc/lxc/__init__.py.in b/src/python-lxc/lxc/__init__.py.in
index 9ef3459..91a59ed 100644
--- a/src/python-lxc/lxc/__init__.py.in
+++ b/src/python-lxc/lxc/__init__.py.in
@@ -318,6 +318,18 @@ class Container(_lxc.Container):
             return False
         return True
 
+    def get_cgroup_item(self, key):
+        """
+            Returns the value for a given cgroup entry.
+            A list is returned when multiple values are set.
+        """
+        value = _lxc.Container.get_cgroup_item(self, key)
+
+        if value is False:
+            return False
+        else:
+            return value.rstrip("\n")
+
     def get_config_item(self, key):
         """
             Returns the value for a given config key.
-- 
1.8.0





More information about the lxc-devel mailing list