[lxc-devel] [PATCH 2/3] python: Add binding for {get|set}_cgroup_item
Serge Hallyn
serge.hallyn at canonical.com
Mon Dec 10 05:08:34 UTC 2012
Quoting Stéphane Graber (stgraber at ubuntu.com):
> 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>
Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>
(if it wasn't a testcase i'd say something about the malloc return value
not being checked...)
> ---
> 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
>
>
> ------------------------------------------------------------------------------
> LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial
> Remotely access PCs and mobile devices and provide instant support
> Improve your efficiency, and focus on delivering more value-add services
> Discover what IT Professionals Know. Rescue delivers
> http://p.sf.net/sfu/logmein_12329d2d
> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel
More information about the lxc-devel
mailing list