The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/1276

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Currently containers inherit the resource limits of the process starting them, but it can be useful to configure them explicitly.
If for instance a container can be started via a system service or manually via `lxc-start` or some wrapper, these 2 ways of starting the container can end up giving it different limits. Both have the option to change the limits before starting, but if they do not have `CAP_SYS_RESOURCE` or are unprivileged they won't be able to raise them back up if they lowered them and would have to resort to forking first.

Limits which aren't explicitly specified will be inherited as before, so the default behavior stays the same.
As usual the last specified value for a limit takes precedence, specifying an empty value deletes it (iow. declares it as to be inherited as before).
From b83d686ba16afdff778a7a2ad092ca8545b1d1c3 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <[email protected]>
Date: Fri, 4 Nov 2016 10:19:07 +0100
Subject: [PATCH 1/3] conf: implement resource limits

Signed-off-by: Wolfgang Bumiller <[email protected]>
---
 configure.ac      |   2 +-
 src/lxc/conf.c    | 132 ++++++++++++++++++++++++++++++++++++++++++
 src/lxc/conf.h    |  24 ++++++++
 src/lxc/confile.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 326 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index dcb33ee..7d83382 100644
--- a/configure.ac
+++ b/configure.ac
@@ -617,7 +617,7 @@ AC_CHECK_DECLS([PR_SET_NO_NEW_PRIVS], [], [], [#include 
<sys/prctl.h>])
 AC_CHECK_DECLS([PR_GET_NO_NEW_PRIVS], [], [], [#include <sys/prctl.h>])
 
 # Check for some headers
-AC_CHECK_HEADERS([sys/signalfd.h pty.h ifaddrs.h sys/capability.h 
sys/personality.h utmpx.h sys/timerfd.h])
+AC_CHECK_HEADERS([sys/signalfd.h pty.h ifaddrs.h sys/capability.h 
sys/personality.h utmpx.h sys/timerfd.h sys/resource.h])
 
 # Check for some syscalls functions
 AC_CHECK_FUNCS([setns pivot_root sethostname unshare rand_r confstr faccessat])
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index b2e0fd9..9f5f978 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -183,6 +183,11 @@ struct caps_opt {
        int value;
 };
 
+struct limit_opt {
+       char *name;
+       int value;
+};
+
 /*
  * The lxc_conf of the container currently being worked on in an
  * API call
@@ -315,6 +320,57 @@ static struct caps_opt caps_opt[] = {
 static struct caps_opt caps_opt[] = {};
 #endif
 
+static struct limit_opt limit_opt[] = {
+#ifdef RLIMIT_AS
+       { "as",          RLIMIT_AS          },
+#endif
+#ifdef RLIMIT_CORE
+       { "core",        RLIMIT_CORE        },
+#endif
+#ifdef RLIMIT_CPU
+       { "cpu",         RLIMIT_CPU         },
+#endif
+#ifdef RLIMIT_DATA
+       { "data",        RLIMIT_DATA        },
+#endif
+#ifdef RLIMIT_FSIZE
+       { "fsize",       RLIMIT_FSIZE       },
+#endif
+#ifdef RLIMIT_LOCKS
+       { "locks",       RLIMIT_LOCKS       },
+#endif
+#ifdef RLIMIT_MEMLOCK
+       { "memlock",     RLIMIT_MEMLOCK     },
+#endif
+#ifdef RLIMIT_MSGQUEUE
+       { "msgqueue",    RLIMIT_MSGQUEUE    },
+#endif
+#ifdef RLIMIT_NICE
+       { "nice",        RLIMIT_NICE        },
+#endif
+#ifdef RLIMIT_NOFILE
+       { "nofile",      RLIMIT_NOFILE      },
+#endif
+#ifdef RLIMIT_NPROC
+       { "nproc",       RLIMIT_NPROC       },
+#endif
+#ifdef RLIMIT_RSS
+       { "rss",         RLIMIT_RSS         },
+#endif
+#ifdef RLIMIT_RTPRIO
+       { "rtprio",      RLIMIT_RTPRIO      },
+#endif
+#ifdef RLIMIT_RTTIME
+       { "rttime",      RLIMIT_RTTIME      },
+#endif
+#ifdef RLIMIT_SIGPENDING
+       { "sigpending",  RLIMIT_SIGPENDING  },
+#endif
+#ifdef RLIMIT_STACK
+       { "stack",       RLIMIT_STACK       },
+#endif
+};
+
 static int run_buffer(char *buffer)
 {
        struct lxc_popen_FILE *f;
@@ -2396,6 +2452,54 @@ static int setup_network(struct lxc_list *network)
        return 0;
 }
 
+static int parse_resource(const char *res) {
+       char *ptr = NULL;
+       size_t i;
+       int resid = -1;
+
+       for (i = 0; i < sizeof(limit_opt)/sizeof(limit_opt[0]); ++i) {
+               if (strcmp(res, limit_opt[i].name))
+                       continue;
+
+               resid = limit_opt[i].value;
+               break;
+       }
+
+       if (resid < 0) {
+               /* try to see if it's numeric, so the user may specify
+                * resources that the running kernel knows about but
+                * we don't */
+               errno = 0;
+               resid = strtol(res, &ptr, 10);
+               if (!ptr || *ptr != '\0' || errno != 0)
+                       resid = -1;
+       }
+
+       return resid;
+}
+
+static int setup_resource_limits(struct lxc_list *limits) {
+       struct lxc_list *it;
+       struct lxc_limit *lim;
+       int resid;
+
+       lxc_list_for_each(it, limits) {
+               lim = it->elem;
+
+               resid = parse_resource(lim->resource);
+               if (resid < 0) {
+                       ERROR("unknown resource %s", lim->resource);
+                       return -1;
+               }
+
+               if (setrlimit(resid, &lim->limit) != 0) {
+                       ERROR("failed to set limit %s: %s", lim->resource, 
strerror(errno));
+                       return -1;
+               }
+       }
+       return 0;
+}
+
 /* try to move physical nics to the init netns */
 void lxc_restore_phys_nics_to_netns(int netnsfd, struct lxc_conf *conf)
 {
@@ -2486,6 +2590,7 @@ struct lxc_conf *lxc_conf_init(void)
        lxc_list_init(&new->includes);
        lxc_list_init(&new->aliens);
        lxc_list_init(&new->environment);
+       lxc_list_init(&new->limits);
        for (i=0; i<NUM_LXC_HOOKS; i++)
                lxc_list_init(&new->hooks[i]);
        lxc_list_init(&new->groups);
@@ -3828,6 +3933,11 @@ int lxc_setup(struct lxc_handler *handler)
                return -1;
        }
 
+       if (!lxc_list_empty(&lxc_conf->limits) && 
setup_resource_limits(&lxc_conf->limits)) {
+               ERROR("failed to setup resource limits for '%s'", name);
+               return -1;
+       }
+
        if (!lxc_list_empty(&lxc_conf->keepcaps)) {
                if (!lxc_list_empty(&lxc_conf->caps)) {
                        ERROR("Simultaneously requested dropping and keeping 
caps");
@@ -4037,6 +4147,27 @@ int lxc_clear_cgroups(struct lxc_conf *c, const char 
*key)
        return 0;
 }
 
+int lxc_clear_limits(struct lxc_conf *c, const char *key)
+{
+       struct lxc_list *it, *next;
+       bool all = false;
+       const char *k = key + 10;
+
+       if (strcmp(key, "lxc.limit") == 0)
+               all = true;
+
+       lxc_list_for_each_safe(it, &c->limits, next) {
+               struct lxc_limit *lim = it->elem;
+               if (!all && strcmp(lim->resource, k) != 0)
+                       continue;
+               lxc_list_del(it);
+               free(lim->resource);
+               free(lim);
+               free(it);
+       }
+       return 0;
+}
+
 int lxc_clear_groups(struct lxc_conf *c)
 {
        struct lxc_list *it,*next;
@@ -4179,6 +4310,7 @@ void lxc_conf_free(struct lxc_conf *conf)
        lxc_clear_includes(conf);
        lxc_clear_aliens(conf);
        lxc_clear_environment(conf);
+       lxc_clear_limits(conf, "lxc.limit");
        free(conf);
 }
 
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 842e4dc..a01617c 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -30,6 +30,9 @@
 #include <net/if.h>
 #include <sys/param.h>
 #include <sys/types.h>
+#if HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
 #include <stdbool.h>
 
 #include "list.h"
@@ -149,6 +152,23 @@ struct lxc_cgroup {
        char *value;
 };
 
+#if !HAVE_SYS_RESOURCE_H
+# define RLIM_INFINITY ((unsigned long)-1)
+struct rlimit {
+       unsigned long rlim_cur;
+       unsigned long rlim_max;
+};
+#endif
+/*
+ * Defines a structure to configure resource limits to set via setrlimit().
+ * @resource : the resource name in lowercase without the RLIMIT_ prefix
+ * @limit    : the limit to set
+ */
+struct lxc_limit {
+       char *resource;
+       struct rlimit limit;
+};
+
 enum idtype {
        ID_TYPE_UID,
        ID_TYPE_GID
@@ -385,6 +405,9 @@ struct lxc_conf {
 
        /* Whether PR_SET_NO_NEW_PRIVS will be set for the container. */
        bool no_new_privs;
+
+       /* RLIMIT_* limits */
+       struct lxc_list limits;
 };
 
 #ifdef HAVE_TLS
@@ -428,6 +451,7 @@ extern int lxc_clear_hooks(struct lxc_conf *c, const char 
*key);
 extern int lxc_clear_idmaps(struct lxc_conf *c);
 extern int lxc_clear_groups(struct lxc_conf *c);
 extern int lxc_clear_environment(struct lxc_conf *c);
+extern int lxc_clear_limits(struct lxc_conf *c, const char *key);
 extern int lxc_delete_autodev(struct lxc_handler *handler);
 
 extern int do_rootfs_setup(struct lxc_conf *conf, const char *name,
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 8f370f6..c7870e3 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -115,6 +115,7 @@ static int config_init_uid(const char *, const char *, 
struct lxc_conf *);
 static int config_init_gid(const char *, const char *, struct lxc_conf *);
 static int config_ephemeral(const char *, const char *, struct lxc_conf *);
 static int config_no_new_privs(const char *, const char *, struct lxc_conf *);
+static int config_limit(const char *, const char *, struct lxc_conf *);
 
 static struct lxc_config_t config[] = {
 
@@ -189,6 +190,7 @@ static struct lxc_config_t config[] = {
        { "lxc.ephemeral",            config_ephemeral            },
        { "lxc.syslog",               config_syslog               },
        { "lxc.no_new_privs",         config_no_new_privs         },
+       { "lxc.limit",                config_limit                },
 };
 
 struct signame {
@@ -1468,6 +1470,110 @@ static int config_cgroup(const char *key, const char 
*value,
        return -1;
 }
 
+static bool parse_limit_value(const char **value, unsigned long *res) {
+       char *endptr = NULL;
+
+       if (strncmp(*value, "unlimited", sizeof("unlimited")-1) == 0) {
+               *res = RLIM_INFINITY;
+               *value += sizeof("unlimited")-1;
+               return true;
+       }
+
+       errno = 0;
+       *res = strtoul(*value, &endptr, 10);
+       if (errno || !endptr)
+               return false;
+       *value = endptr;
+
+       return true;
+}
+
+static int config_limit(const char *key, const char *value,
+                        struct lxc_conf *lxc_conf)
+{
+       struct lxc_list *limlist = NULL;
+       struct lxc_limit *limelem = NULL;
+       struct lxc_list *iter;
+       struct rlimit limit;
+       unsigned long limit_value;
+
+       if (!value || strlen(value) == 0)
+               return lxc_clear_limits(lxc_conf, key);
+
+       if (strncmp(key, "lxc.limit.", sizeof("lxc.limit.")-1) != 0)
+               return -1;
+
+       key += sizeof("lxc.limit.")-1;
+
+       /* soft limit comes first in the value */
+       if (!parse_limit_value(&value, &limit_value))
+               return -1;
+       limit.rlim_cur = limit_value;
+
+       /* skip spaces and a colon */
+       while (isspace(*value))
+               ++value;
+       if (*value == ':')
+               ++value;
+       else if (*value) /* any other character is an error here */
+               return -1;
+       while (isspace(*value))
+               ++value;
+
+       /* optional hard limit */
+       if (*value) {
+               if (!parse_limit_value(&value, &limit_value))
+                       return -1;
+               limit.rlim_max = limit_value;
+               /* check for trailing garbage */
+               while (isspace(*value))
+                       ++value;
+               if (*value)
+                       return -1;
+       } else {
+               /* a single value sets both hard and soft limit */
+               limit.rlim_max = limit.rlim_cur;
+       }
+
+       /* find existing list element */
+       lxc_list_for_each(iter, &lxc_conf->limits) {
+               limelem = iter->elem;
+               if (!strcmp(key, limelem->resource)) {
+                       limelem->limit = limit;
+                       return 0;
+               }
+       }
+
+       /* allocate list element */
+       limlist = malloc(sizeof(*limlist));
+       if (!limlist)
+               goto out;
+       
+       limelem = malloc(sizeof(*limelem));
+       if (!limelem)
+               goto out;
+       memset(limelem, 0, sizeof(*limelem));
+
+       limelem->resource = strdup(key);
+       if (!limelem->resource)
+               goto out;
+       limelem->limit = limit;
+
+       limlist->elem = limelem;
+
+       lxc_list_add_tail(&lxc_conf->limits, limlist);
+
+       return 0;
+
+out:
+       free(limlist);
+       if (limelem) {
+               free(limelem->resource);
+               free(limelem);
+       }
+       return -1;
+}
+
 static int config_idmap(const char *key, const char *value, struct lxc_conf 
*lxc_conf)
 {
        char *token = "lxc.id_map";
@@ -2201,6 +2307,63 @@ static int lxc_get_cgroup_entry(struct lxc_conf *c, char 
*retv, int inlen,
        return fulllen;
 }
 
+/*
+ * If you ask for a specific value, i.e. lxc.limit.nofile, then just the value
+ * will be printed. If you ask for 'lxc.limit', then all limit entries will be
+ * printed, in 'lxc.limit.resource = value' format.
+ */
+static int lxc_get_limit_entry(struct lxc_conf *c, char *retv, int inlen,
+                               const char *key)
+{
+       int fulllen = 0, len;
+       int all = 0;
+       struct lxc_list *it;
+
+       if (!retv)
+               inlen = 0;
+       else
+               memset(retv, 0, inlen);
+
+       if (strcmp(key, "all") == 0)
+               all = 1;
+
+       lxc_list_for_each(it, &c->limits) {
+               char buf[64]; /* 2 64 bit integers or the word 'unlimited' 
twice */
+               int partlen;
+               struct lxc_limit *lim = it->elem;
+
+               if (lim->limit.rlim_cur == lim->limit.rlim_max) {
+                       if (lim->limit.rlim_cur == RLIM_INFINITY) {
+                               memcpy(buf, "unlimited", sizeof("unlimited"));
+                               partlen = sizeof("unlimited")-1;
+                       } else {
+                               partlen = sprintf(buf, "%lu", 
lim->limit.rlim_cur);
+                       }
+               } else {
+                       if (lim->limit.rlim_cur == RLIM_INFINITY) {
+                               memcpy(buf, "unlimited:", 
sizeof("unlimited:")-1);
+                               partlen = sizeof("unlimited:")-1;
+                       } else {
+                               partlen = sprintf(buf, "%lu:", 
lim->limit.rlim_cur);
+                       }
+
+                       if (lim->limit.rlim_max == RLIM_INFINITY) {
+                               memcpy(buf+partlen, "unlimited", 
sizeof("unlimited"));
+                       } else {
+                               sprintf(buf+partlen, "%lu", 
lim->limit.rlim_max);
+                       }
+               }
+
+               if (all) {
+                       strprint(retv, inlen, "lxc.limit.%s = %s\n", 
lim->resource, buf);
+               } else if (strcmp(lim->resource, key) == 0) {
+                       strprint(retv, inlen, "%s", buf);
+               }
+       }
+
+       return fulllen;
+}
+
 static int lxc_get_item_hooks(struct lxc_conf *c, char *retv, int inlen,
                              const char *key)
 {
@@ -2566,6 +2729,10 @@ int lxc_get_config_item(struct lxc_conf *c, const char 
*key, char *retv,
                v = c->syslog;
        else if (strcmp(key, "lxc.no_new_privs") == 0)
                return lxc_get_conf_int(c, retv, inlen, c->no_new_privs);
+       else if (strcmp(key, "lxc.limit") == 0) // all limits
+               return lxc_get_limit_entry(c, retv, inlen, "all");
+       else if (strncmp(key, "lxc.limit.", 10) == 0) // specific limit
+               return lxc_get_limit_entry(c, retv, inlen, key + 10);
        else return -1;
 
        if (!v)
@@ -2599,6 +2766,8 @@ int lxc_clear_config_item(struct lxc_conf *c, const char 
*key)
                return lxc_clear_environment(c);
        else if (strncmp(key, "lxc.id_map", 10) == 0)
                return lxc_clear_idmaps(c);
+       else if (strncmp(key, "lxc.limit", 9) == 0)
+               return lxc_clear_limits(c, key);
        return -1;
 }
 

From 8aea67e2dcc8edccd6e2a86edda77715a2c82bd7 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <[email protected]>
Date: Fri, 4 Nov 2016 12:03:28 +0100
Subject: [PATCH 2/3] doc: add lxc.limit to lxc.container.conf

Signed-off-by: Wolfgang Bumiller <[email protected]>
---
 doc/lxc.container.conf.sgml.in | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in
index fcccd8b..43f3139 100644
--- a/doc/lxc.container.conf.sgml.in
+++ b/doc/lxc.container.conf.sgml.in
@@ -1184,6 +1184,40 @@ proc proc proc nodev,noexec,nosuid 0 0
     </refsect2>
 
     <refsect2>
+      <title>Resource limits</title>
+      <para>
+        The soft and hard resource limits for the container can be changed.
+        Unprivileged containers can only lower them. Resources which are not
+        explicitly specified will be inherited.
+      </para>
+      <variablelist>
+        <varlistentry>
+          <term>
+            <option>lxc.limit.[limit name]</option>
+          </term>
+          <listitem>
+            <para>
+              Specify the resource limit to be set. A limit is specified as two
+              colon separated values which are either numeric or the word
+              'unlimited'. A single value can be used as a shortcut to set both
+              soft and hard limit to the same value. The permitted names the
+              "RLIMIT_" resource names in lowercase without the "RLIMIT_"
+              prefix, eg. RLIMIT_NOFILE should be specified as "nofile". See
+              <citerefentry>
+                <refentrytitle><command>setrlimit</command></refentrytitle>
+                <manvolnum>2</manvolnum>
+              </citerefentry>.
+              If used with no value, lxc will clear the resource limit
+              specified up to this point. A resource with no explicitly
+              configured limitation will be inherited from the process starting
+              up the container.
+            </para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
       <title>Apparmor profile</title>
       <para>
         If lxc was compiled and installed with apparmor support, and the host

From 3a82465d95179b7240b364d7273f3761d2e180d0 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <[email protected]>
Date: Fri, 4 Nov 2016 11:45:47 +0100
Subject: [PATCH 3/3] test: resource limit config entries

Signed-off-by: Wolfgang Bumiller <[email protected]>
---
 src/tests/get_item.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/src/tests/get_item.c b/src/tests/get_item.c
index eb2274e..cb4ba42 100644
--- a/src/tests/get_item.c
+++ b/src/tests/get_item.c
@@ -174,6 +174,70 @@ int main(int argc, char *argv[])
        }
        printf("lxc.mount.entry returned %d %s\n", ret, v2);
 
+       ret = c->get_config_item(c, "lxc.limit", v3, 2047);
+       if (ret != 0) {
+               fprintf(stderr, "%d: get_config_item(limit) returned %d\n", 
__LINE__, ret);
+               goto out;
+       }
+
+       if (!c->set_config_item(c, "lxc.limit.nofile", "1234:unlimited")) {
+               fprintf(stderr, "%d: failed to set limit.nofile\n", __LINE__);
+               goto out;
+       }
+       ret = c->get_config_item(c, "lxc.limit.nofile", v2, 255);
+       if (ret < 0) {
+               fprintf(stderr, "%d: get_config_item(lxc.limit.nofile) returned 
%d\n", __LINE__, ret);
+               goto out;
+       }
+       if (strcmp(v2, "1234:unlimited")) {
+               fprintf(stderr, "%d: lxc.limit.nofile returned wrong value: %d 
%s not 14 1234:unlimited\n", __LINE__, ret, v2);
+               goto out;
+       }
+       printf("lxc.limit.nofile returned %d %s\n", ret, v2);
+
+       if (!c->set_config_item(c, "lxc.limit.stack", "unlimited")) {
+               fprintf(stderr, "%d: failed to set limit.stack\n", __LINE__);
+               goto out;
+       }
+       ret = c->get_config_item(c, "lxc.limit.stack", v2, 255);
+       if (ret < 0) {
+               fprintf(stderr, "%d: get_config_item(lxc.limit.stack) returned 
%d\n", __LINE__, ret);
+               goto out;
+       }
+       if (strcmp(v2, "unlimited")) {
+               fprintf(stderr, "%d: lxc.limit.stack returned wrong value: %d 
%s not 9 unlimited\n", __LINE__, ret, v2);
+               goto out;
+       }
+       printf("lxc.limit.stack returned %d %s\n", ret, v2);
+
+#define LIMIT_STACK "lxc.limit.stack = unlimited\n"
+#define ALL_LIMITS "lxc.limit.nofile = 1234:unlimited\n" LIMIT_STACK
+       ret = c->get_config_item(c, "lxc.limit", v3, 2047);
+       if (ret != sizeof(ALL_LIMITS)-1) {
+               fprintf(stderr, "%d: get_config_item(limit) returned %d\n", 
__LINE__, ret);
+               goto out;
+       }
+       if (strcmp(v3, ALL_LIMITS)) {
+               fprintf(stderr, "%d: lxc.limit returned wrong value: %d %s not 
%d %s\n", __LINE__, ret, v3, (int)sizeof(ALL_LIMITS)-1, ALL_LIMITS);
+               goto out;
+       }
+       printf("lxc.limit returned %d %s\n", ret, v3);
+
+       if (!c->clear_config_item(c, "lxc.limit.nofile")) {
+               fprintf(stderr, "%d: failed clearing limit.nofile\n", __LINE__);
+               goto out;
+       }
+       ret = c->get_config_item(c, "lxc.limit", v3, 2047);
+       if (ret != sizeof(LIMIT_STACK)-1) {
+               fprintf(stderr, "%d: get_config_item(limit) returned %d\n", 
__LINE__, ret);
+               goto out;
+       }
+       if (strcmp(v3, LIMIT_STACK)) {
+               fprintf(stderr, "%d: lxc.limit returned wrong value: %d %s not 
%d %s\n", __LINE__, ret, v3, (int)sizeof(LIMIT_STACK)-1, LIMIT_STACK);
+               goto out;
+       }
+       printf("lxc.limit returned %d %s\n", ret, v3);
+
        if (!c->set_config_item(c, "lxc.aa_profile", "unconfined")) {
                fprintf(stderr, "%d: failed to set aa_profile\n", __LINE__);
                goto out;
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to