diff --git a/Makefile b/Makefile index 06a80c3..5761f3e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ PACKAGE=lxc-pve -LXCVER=2.0.8 -DEBREL=3 +LXCVER=2.1.0 +DEBREL=1 SRCDIR=lxc SRCTAR=${SRCDIR}.tgz diff --git a/debian/patches/0001-lxc.service-start-after-a-potential-syslog.service.patch b/debian/patches/0001-lxc.service-start-after-a-potential-syslog.service.patch index 849217c..fd56728 100644 --- a/debian/patches/0001-lxc.service-start-after-a-potential-syslog.service.patch +++ b/debian/patches/0001-lxc.service-start-after-a-potential-syslog.service.patch @@ -1,7 +1,7 @@ -From a070120ceba622b1834ad2693376256ba177f249 Mon Sep 17 00:00:00 2001 +From 674c54165393b3ad0059f4a5c5d1e1505eea9114 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Fri, 10 Feb 2017 09:13:40 +0100 -Subject: [PATCH 01/14] lxc.service: start after a potential syslog.service +Subject: [PATCH 1/9] lxc.service: start after a potential syslog.service Signed-off-by: Wolfgang Bumiller --- diff --git a/debian/patches/0002-jessie-systemd-remove-Delegate-flag-to-silence-warni.patch b/debian/patches/0002-jessie-systemd-remove-Delegate-flag-to-silence-warni.patch index 36cadd5..424d475 100644 --- a/debian/patches/0002-jessie-systemd-remove-Delegate-flag-to-silence-warni.patch +++ b/debian/patches/0002-jessie-systemd-remove-Delegate-flag-to-silence-warni.patch @@ -1,8 +1,7 @@ -From de03e2bff16699c10f1c3a80e4c84a44c0a32bc0 Mon Sep 17 00:00:00 2001 +From a5ee14df834c008294b790d96982a1fea36c807a Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Fri, 10 Feb 2017 09:14:55 +0100 -Subject: [PATCH 02/14] jessie/systemd: remove Delegate flag to silence - warnings +Subject: [PATCH 2/9] jessie/systemd: remove Delegate flag to silence warnings Signed-off-by: Wolfgang Bumiller --- @@ -23,11 +22,11 @@ index 77541917..bdd58283 100644 StandardError=syslog diff --git a/config/init/systemd/lxc@.service.in b/config/init/systemd/lxc@.service.in -index 44d11e8e..6b8b5ff1 100644 +index a2aa2211..98d5a3a7 100644 --- a/config/init/systemd/lxc@.service.in +++ b/config/init/systemd/lxc@.service.in -@@ -13,7 +13,6 @@ TimeoutStopSec=120s - ExecStart=@BINDIR@/lxc-start -F -n %i +@@ -13,7 +13,6 @@ ExecStart=@BINDIR@/lxc-start -F -n %i + ExecStop=@BINDIR@/lxc-stop -n %i # Environment=BOOTUP=serial # Environment=CONSOLETYPE=serial -Delegate=yes diff --git a/debian/patches/0003-pve-run-lxcnetaddbr-when-instantiating-veths.patch b/debian/patches/0003-pve-run-lxcnetaddbr-when-instantiating-veths.patch index 2912a1c..5cbc84d 100644 --- a/debian/patches/0003-pve-run-lxcnetaddbr-when-instantiating-veths.patch +++ b/debian/patches/0003-pve-run-lxcnetaddbr-when-instantiating-veths.patch @@ -1,34 +1,31 @@ -From 405bcb676e3eb07e2e2efab45b15cdc8b799b15c Mon Sep 17 00:00:00 2001 +From 84da55875d3a9468957fe0f0012ea2b39b9f7785 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Fri, 10 Feb 2017 09:15:37 +0100 -Subject: [PATCH 03/14] pve: run lxcnetaddbr when instantiating veths +Subject: [PATCH 3/9] pve: run lxcnetaddbr when instantiating veths FIXME: Why aren't we using regular up-scripts? Signed-off-by: Wolfgang Bumiller --- - src/lxc/conf.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) + src/lxc/network.c | 5 +++++ + 1 file changed, 5 insertions(+) -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 923a4d90..3bedcf0f 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -2742,8 +2742,13 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd +diff --git a/src/lxc/network.c b/src/lxc/network.c +index a7f054e7..3c0597c7 100644 +--- a/src/lxc/network.c ++++ b/src/lxc/network.c +@@ -208,6 +208,11 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd "veth", veth1, (char*) NULL); if (err) goto out_delete; -+ } else if (!netdev->link) { ++ } else if (netdev->link[0] == '\0') { + err = run_script(handler->name, "net", "/usr/share/lxc/lxcnetaddbr", "up", + "veth", veth1, (char*) NULL); + if (err) + goto out_delete; } -- -+ - DEBUG("instantiated veth '%s/%s', index is '%d'", - veth1, veth2, netdev->ifindex); + DEBUG("Instantiated veth \"%s/%s\", index is \"%d\"", veth1, veth2, -- 2.11.0 diff --git a/debian/patches/0004-deny-rw-mounting-of-sys-and-proc.patch b/debian/patches/0004-deny-rw-mounting-of-sys-and-proc.patch index 26543f8..3940048 100644 --- a/debian/patches/0004-deny-rw-mounting-of-sys-and-proc.patch +++ b/debian/patches/0004-deny-rw-mounting-of-sys-and-proc.patch @@ -1,7 +1,7 @@ -From 05337fbce533630e978904db57601eedf498b776 Mon Sep 17 00:00:00 2001 +From 2d651f876f4afa97ddd6081d996776c10355732a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Wed, 9 Nov 2016 09:14:26 +0100 -Subject: [PATCH 04/14] deny rw mounting of /sys and /proc +Subject: [PATCH 4/9] deny rw mounting of /sys and /proc this would allow root in a privileged container to change the permissions of /sys on the host, which could lock out diff --git a/debian/patches/0005-separate-the-limiting-from-the-namespaced-cgroup-roo.patch b/debian/patches/0005-separate-the-limiting-from-the-namespaced-cgroup-roo.patch index e89a969..89e92f5 100644 --- a/debian/patches/0005-separate-the-limiting-from-the-namespaced-cgroup-roo.patch +++ b/debian/patches/0005-separate-the-limiting-from-the-namespaced-cgroup-roo.patch @@ -1,7 +1,7 @@ -From 5ceb26ec765edb81aba25b9db4fc5ede0d7a0375 Mon Sep 17 00:00:00 2001 +From 9152a996a7413e1dc7dc3cb6c64af20cdf0389be Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Tue, 15 Nov 2016 09:20:24 +0100 -Subject: [PATCH 05/14] separate the limiting from the namespaced cgroup root +Subject: [PATCH 5/9] separate the limiting from the namespaced cgroup root When cgroup namespaces are enabled a privileged container with mixed cgroups has full write access to its own root @@ -14,22 +14,22 @@ being used in order to combat this. Signed-off-by: Wolfgang Bumiller --- - src/lxc/cgroups/cgfs.c | 19 ++++++-- - src/lxc/cgroups/cgfsng.c | 81 +++++++++++++++++++++++++++----- - src/lxc/cgroups/cgmanager.c | 19 ++++++-- - src/lxc/cgroups/cgroup.c | 16 +++---- - src/lxc/cgroups/cgroup.h | 22 +++++---- - src/lxc/commands.c | 112 ++++++++++++++++++++++++++++++-------------- - src/lxc/commands.h | 2 + - src/lxc/criu.c | 4 +- - src/lxc/start.c | 21 +++++++-- - 9 files changed, 219 insertions(+), 77 deletions(-) + src/lxc/cgroups/cgfs.c | 19 ++++++++--- + src/lxc/cgroups/cgfsng.c | 79 +++++++++++++++++++++++++++++++++++++-------- + src/lxc/cgroups/cgmanager.c | 19 ++++++++--- + src/lxc/cgroups/cgroup.c | 17 +++++----- + src/lxc/cgroups/cgroup.h | 22 ++++++++----- + src/lxc/commands.c | 76 ++++++++++++++++++++++++++++++++++--------- + src/lxc/commands.h | 2 ++ + src/lxc/criu.c | 4 +-- + src/lxc/start.c | 21 ++++++++++-- + 9 files changed, 201 insertions(+), 58 deletions(-) diff --git a/src/lxc/cgroups/cgfs.c b/src/lxc/cgroups/cgfs.c -index 3bfa5239..f305a561 100644 +index bcbd6613..573ccb25 100644 --- a/src/lxc/cgroups/cgfs.c +++ b/src/lxc/cgroups/cgfs.c -@@ -2383,12 +2383,15 @@ static void cgfs_destroy(void *hdata, struct lxc_conf *conf) +@@ -2387,12 +2387,15 @@ static void cgfs_destroy(void *hdata, struct lxc_conf *conf) free(d); } @@ -46,7 +46,7 @@ index 3bfa5239..f305a561 100644 if (!d) return false; md = d->meta; -@@ -2399,12 +2402,15 @@ static inline bool cgfs_create(void *hdata) +@@ -2403,12 +2406,15 @@ static inline bool cgfs_create(void *hdata) return true; } @@ -63,7 +63,7 @@ index 3bfa5239..f305a561 100644 if (!d) return false; i = d->info; -@@ -2428,10 +2434,12 @@ static inline bool cgfs_create_legacy(void *hdata, pid_t pid) +@@ -2432,10 +2438,12 @@ static inline bool cgfs_create_legacy(void *hdata, pid_t pid) return true; } @@ -77,7 +77,7 @@ index 3bfa5239..f305a561 100644 if (!d) return NULL; return lxc_cgroup_get_hierarchy_path_data(subsystem, d); -@@ -2646,13 +2654,16 @@ static bool do_cgfs_chown(char *cgroup_path, struct lxc_conf *conf) +@@ -2651,13 +2659,16 @@ static bool do_cgfs_chown(char *cgroup_path, struct lxc_conf *conf) return true; } @@ -96,26 +96,26 @@ index 3bfa5239..f305a561 100644 return false; diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index ebd548b9..b26e1b27 100644 +index fe3fd706..896e6da9 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c -@@ -72,6 +72,7 @@ struct hierarchy { +@@ -77,6 +77,7 @@ struct hierarchy { char *mountpoint; char *base_cgroup; char *fullcgpath; + char *innercgpath; + bool is_cgroup_v2; }; - /* -@@ -820,6 +821,7 @@ static void add_controller(char **clist, char *mountpoint, char *base_cgroup) +@@ -813,6 +814,7 @@ static void add_controller(char **clist, char *mountpoint, char *base_cgroup) new->mountpoint = mountpoint; new->base_cgroup = base_cgroup; new->fullcgpath = NULL; -+ new->innercgpath = false; ++ new->innercgpath = NULL; - newentry = append_null_to_list((void ***)&hierarchies); - hierarchies[newentry] = new; -@@ -1304,6 +1306,8 @@ static void cgfsng_destroy(void *hdata, struct lxc_conf *conf) + /* record if this is the cgroup v2 hierarchy */ + if (!strcmp(base_cgroup, "cgroup2")) +@@ -1300,6 +1302,8 @@ static void cgfsng_destroy(void *hdata, struct lxc_conf *conf) free(h->fullcgpath); h->fullcgpath = NULL; } @@ -124,7 +124,7 @@ index ebd548b9..b26e1b27 100644 } } -@@ -1321,18 +1325,25 @@ struct cgroup_ops *cgfsng_ops_init(void) +@@ -1317,18 +1321,25 @@ struct cgroup_ops *cgfsng_ops_init(void) return &cgfsng_ops; } @@ -132,7 +132,7 @@ index ebd548b9..b26e1b27 100644 +static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname, bool inner) { - h->fullcgpath = must_make_path(h->mountpoint, h->base_cgroup, cgname, NULL); -- if (dir_exists(h->fullcgpath)) { // it must not already exist +- if (dir_exists(h->fullcgpath)) { /* it must not already exist */ - ERROR("Path \"%s\" already existed.", h->fullcgpath); + char *path; + if (inner) { @@ -156,46 +156,10 @@ index ebd548b9..b26e1b27 100644 } static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname) -@@ -1347,7 +1358,8 @@ static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname) - * Try to create the same cgroup in all hierarchies. - * Start with cgroup_pattern; next cgroup_pattern-1, -2, ..., -999 - */ --static inline bool cgfsng_create(void *hdata) -+static inline bool cgfsng_create_inner(struct cgfsng_handler_data*); -+static inline bool cgfsng_create(void *hdata, bool inner) - { - struct cgfsng_handler_data *d = hdata; - char *tmp, *cgname, *offset; -@@ -1357,9 +1369,15 @@ static inline bool cgfsng_create(void *hdata) - if (!d) - return false; - if (d->container_cgroup) { -+ if (inner) -+ return cgfsng_create_inner(d); - WARN("cgfsng_create called a second time"); - return false; - } -+ if (inner) { -+ ERROR("cgfsng_create called twice for innner cgroup"); -+ return false; -+ } - - tmp = lxc_string_replace("%n", d->name, d->cgroup_pattern); - if (!tmp) { -@@ -1380,7 +1398,7 @@ again: - if (idx) - snprintf(offset, 5, "-%d", idx); - for (i = 0; hierarchies[i]; i++) { -- if (!create_path_for_hierarchy(hierarchies[i], cgname)) { -+ if (!create_path_for_hierarchy(hierarchies[i], cgname, false)) { - int j; - SYSERROR("Failed to create %s: %s", hierarchies[i]->fullcgpath, strerror(errno)); - free(hierarchies[i]->fullcgpath); -@@ -1400,7 +1418,24 @@ out_free: - return false; +@@ -1339,11 +1350,27 @@ static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname) + h->fullcgpath = NULL; } --static bool cgfsng_enter(void *hdata, pid_t pid) +static inline bool cgfsng_create_inner(struct cgfsng_handler_data *d) +{ + size_t i; @@ -212,12 +176,50 @@ index ebd548b9..b26e1b27 100644 + return ret; +} + -+ + /* + * Try to create the same cgroup in all hierarchies. + * Start with cgroup_pattern; next cgroup_pattern-1, -2, ..., -999 + */ +-static inline bool cgfsng_create(void *hdata) ++static inline bool cgfsng_create(void *hdata, bool inner) + { + int i; + size_t len; +@@ -1355,9 +1382,15 @@ static inline bool cgfsng_create(void *hdata) + return false; + + if (d->container_cgroup) { ++ if (inner) ++ return cgfsng_create_inner(d); + WARN("cgfsng_create called a second time"); + return false; + } ++ if (inner) { ++ ERROR("cgfsng_create called twice for innner cgroup"); ++ return false; ++ } + + if (d->cgroup_meta.dir) + tmp = lxc_string_join("/", (const char *[]){d->cgroup_meta.dir, d->name, NULL}, false); +@@ -1393,7 +1426,7 @@ again: + } + } + for (i = 0; hierarchies[i]; i++) { +- if (!create_path_for_hierarchy(hierarchies[i], cgname)) { ++ if (!create_path_for_hierarchy(hierarchies[i], cgname, false)) { + int j; + ERROR("Failed to create \"%s\"", hierarchies[i]->fullcgpath); + free(hierarchies[i]->fullcgpath); +@@ -1413,7 +1446,7 @@ out_free: + return false; + } + +-static bool cgfsng_enter(void *hdata, pid_t pid) +static bool cgfsng_enter(void *hdata, pid_t pid, bool inner) { char pidstr[25]; int i, len; -@@ -1410,7 +1445,13 @@ static bool cgfsng_enter(void *hdata, pid_t pid) +@@ -1423,7 +1456,13 @@ static bool cgfsng_enter(void *hdata, pid_t pid) return false; for (i = 0; hierarchies[i]; i++) { @@ -232,15 +234,15 @@ index ebd548b9..b26e1b27 100644 "cgroup.procs", NULL); if (lxc_write_to_file(fullpath, pidstr, len, false) != 0) { SYSERROR("Failed to enter %s", fullpath); -@@ -1426,6 +1467,7 @@ static bool cgfsng_enter(void *hdata, pid_t pid) +@@ -1439,6 +1478,7 @@ static bool cgfsng_enter(void *hdata, pid_t pid) struct chown_data { struct cgfsng_handler_data *d; - uid_t origuid; // target uid in parent namespace + uid_t origuid; /* target uid in parent namespace */ + bool inner; }; /* -@@ -1454,13 +1496,20 @@ static int chown_cgroup_wrapper(void *data) +@@ -1467,13 +1507,20 @@ static int chown_cgroup_wrapper(void *data) for (i = 0; hierarchies[i]; i++) { char *fullpath, *path = hierarchies[i]->fullcgpath; @@ -261,12 +263,12 @@ index ebd548b9..b26e1b27 100644 return -1; } -@@ -1484,12 +1533,14 @@ static int chown_cgroup_wrapper(void *data) +@@ -1499,12 +1546,14 @@ static int chown_cgroup_wrapper(void *data) if (chmod(fullpath, 0664) < 0) - WARN("Error chmoding %s: %m", path); + WARN("Error chmoding %s: %s", path, strerror(errno)); free(fullpath); -+ -+ free(path); ++ if (arg->inner) ++ free(path); } return 0; @@ -277,15 +279,15 @@ index ebd548b9..b26e1b27 100644 { struct cgfsng_handler_data *d = hdata; struct chown_data wrap; -@@ -1502,6 +1553,7 @@ static bool cgfsns_chown(void *hdata, struct lxc_conf *conf) +@@ -1517,6 +1566,7 @@ static bool cgfsns_chown(void *hdata, struct lxc_conf *conf) wrap.d = d; wrap.origuid = geteuid(); + wrap.inner = inner; - if (userns_exec_1(conf, chown_cgroup_wrapper, &wrap) < 0) { - ERROR("Error requesting cgroup chown in new namespace"); -@@ -1796,12 +1848,15 @@ static bool cgfsng_unfreeze(void *hdata) + if (userns_exec_1(conf, chown_cgroup_wrapper, &wrap, + "chown_cgroup_wrapper") < 0) { +@@ -1813,12 +1863,15 @@ static bool cgfsng_unfreeze(void *hdata) return true; } @@ -302,20 +304,20 @@ index ebd548b9..b26e1b27 100644 return h->fullcgpath ? h->fullcgpath + strlen(h->mountpoint) : NULL; } -@@ -1836,7 +1891,7 @@ static bool cgfsng_attach(const char *name, const char *lxcpath, pid_t pid) +@@ -1846,7 +1899,7 @@ static bool cgfsng_attach(const char *name, const char *lxcpath, pid_t pid) char *path, *fullpath; struct hierarchy *h = hierarchies[i]; - path = lxc_cmd_get_cgroup_path(name, lxcpath, h->controllers[0]); + path = lxc_cmd_get_attach_cgroup_path(name, lxcpath, h->controllers[0]); - if (!path) // not running + if (!path) /* not running */ continue; diff --git a/src/lxc/cgroups/cgmanager.c b/src/lxc/cgroups/cgmanager.c -index f2756b07..ac966b6f 100644 +index 054eb171..04ae3a16 100644 --- a/src/lxc/cgroups/cgmanager.c +++ b/src/lxc/cgroups/cgmanager.c -@@ -609,7 +609,7 @@ static inline void cleanup_cgroups(char *path) +@@ -610,7 +610,7 @@ static inline void cleanup_cgroups(char *path) cgm_remove_cgroup(slist[i], path); } @@ -324,7 +326,7 @@ index f2756b07..ac966b6f 100644 { struct cgm_data *d = hdata; char **slist = subsystems; -@@ -617,6 +617,9 @@ static inline bool cgm_create(void *hdata) +@@ -618,6 +618,9 @@ static inline bool cgm_create(void *hdata) int32_t existed; char result[MAXPATHLEN], *tmp, *cgroup_path; @@ -333,8 +335,8 @@ index f2756b07..ac966b6f 100644 + if (!d) return false; - // XXX we should send a hint to the cgmanager that when these -@@ -709,13 +712,16 @@ static bool lxc_cgmanager_enter(pid_t pid, const char *controller, + +@@ -710,13 +713,16 @@ static bool lxc_cgmanager_enter(pid_t pid, const char *controller, return true; } @@ -352,7 +354,7 @@ index f2756b07..ac966b6f 100644 if (!d || !d->cgroup_path) return false; -@@ -737,10 +743,12 @@ out: +@@ -738,10 +744,12 @@ out: return ret; } @@ -366,7 +368,7 @@ index f2756b07..ac966b6f 100644 if (!d || !d->cgroup_path) return NULL; return d->cgroup_path; -@@ -1541,10 +1549,13 @@ out: +@@ -1542,10 +1550,13 @@ out: return ret; } @@ -382,49 +384,48 @@ index f2756b07..ac966b6f 100644 return false; if (!cgm_dbus_connect()) { diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c -index 78472d4f..4d26e720 100644 +index 674e3090..6f0d2fe8 100644 --- a/src/lxc/cgroups/cgroup.c +++ b/src/lxc/cgroups/cgroup.c -@@ -80,10 +80,10 @@ void cgroup_destroy(struct lxc_handler *handler) +@@ -80,19 +80,19 @@ void cgroup_destroy(struct lxc_handler *handler) } - /* Create the container cgroups for all requested controllers */ + /* Create the container cgroups for all requested controllers. */ -bool cgroup_create(struct lxc_handler *handler) +bool cgroup_create(struct lxc_handler *handler, bool inner) { if (ops) - return ops->create(handler->cgroup_data); + return ops->create(handler->cgroup_data, inner); + return false; } -@@ -91,10 +91,10 @@ bool cgroup_create(struct lxc_handler *handler) - * Enter the container init into its new cgroups for all - * requested controllers - */ + /* Enter the container init into its new cgroups for all requested controllers. */ -bool cgroup_enter(struct lxc_handler *handler) +bool cgroup_enter(struct lxc_handler *handler, bool inner) { if (ops) - return ops->enter(handler->cgroup_data, handler->pid); + return ops->enter(handler->cgroup_data, handler->pid, inner); + return false; } - -@@ -105,10 +105,10 @@ bool cgroup_create_legacy(struct lxc_handler *handler) - return true; +@@ -106,10 +106,11 @@ bool cgroup_create_legacy(struct lxc_handler *handler) } --const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *subsystem) -+const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *subsystem, bool inner) + const char *cgroup_get_cgroup(struct lxc_handler *handler, +- const char *subsystem) ++ const char *subsystem, ++ bool inner) { if (ops) - return ops->get_cgroup(handler->cgroup_data, subsystem); + return ops->get_cgroup(handler->cgroup_data, subsystem, inner); + return NULL; } - -@@ -150,10 +150,10 @@ bool cgroup_setup_limits(struct lxc_handler *handler, bool with_devices) +@@ -155,10 +156,10 @@ bool cgroup_setup_limits(struct lxc_handler *handler, bool with_devices) return false; } @@ -434,11 +435,11 @@ index 78472d4f..4d26e720 100644 if (ops && ops->chown) - return ops->chown(handler->cgroup_data, handler->conf); + return ops->chown(handler->cgroup_data, handler->conf, inner); + return true; } - diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h -index 11b251e6..f36c6f02 100644 +index f17a6abe..f05fda4e 100644 --- a/src/lxc/cgroups/cgroup.h +++ b/src/lxc/cgroups/cgroup.h @@ -28,6 +28,12 @@ @@ -456,7 +457,7 @@ index 11b251e6..f36c6f02 100644 struct lxc_list; @@ -43,10 +49,10 @@ struct cgroup_ops { - void *(*init)(const char *name); + void *(*init)(struct lxc_handler *handler); void (*destroy)(void *hdata, struct lxc_conf *conf); - bool (*create)(void *hdata); - bool (*enter)(void *hdata, pid_t pid); @@ -497,35 +498,10 @@ index 11b251e6..f36c6f02 100644 extern int cgroup_num_hierarchies(); extern bool cgroup_get_hierarchies(int i, char ***out); diff --git a/src/lxc/commands.c b/src/lxc/commands.c -index 27c8c084..0eb2741f 100644 +index 68fbd387..ccdbeeba 100644 --- a/src/lxc/commands.c +++ b/src/lxc/commands.c -@@ -133,15 +133,15 @@ static int fill_sock_name(char *path, int len, const char *lxcname, - static const char *lxc_cmd_str(lxc_cmd_t cmd) - { - static const char * const cmdname[LXC_CMD_MAX] = { -- [LXC_CMD_CONSOLE] = "console", -- [LXC_CMD_STOP] = "stop", -- [LXC_CMD_GET_STATE] = "get_state", -- [LXC_CMD_GET_INIT_PID] = "get_init_pid", -- [LXC_CMD_GET_CLONE_FLAGS] = "get_clone_flags", -- [LXC_CMD_GET_CGROUP] = "get_cgroup", -- [LXC_CMD_GET_CONFIG_ITEM] = "get_config_item", -- [LXC_CMD_GET_NAME] = "get_name", -- [LXC_CMD_GET_LXCPATH] = "get_lxcpath", -+ [LXC_CMD_CONSOLE] = "console", -+ [LXC_CMD_STOP] = "stop", -+ [LXC_CMD_GET_STATE] = "get_state", -+ [LXC_CMD_GET_INIT_PID] = "get_init_pid", -+ [LXC_CMD_GET_CLONE_FLAGS] = "get_clone_flags", -+ [LXC_CMD_GET_CGROUP] = "get_cgroup", -+ [LXC_CMD_GET_CONFIG_ITEM] = "get_config_item", -+ [LXC_CMD_GET_NAME] = "get_name", -+ [LXC_CMD_GET_LXCPATH] = "get_lxcpath", - }; - - if (cmd >= LXC_CMD_MAX) -@@ -437,30 +437,28 @@ static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req, +@@ -410,30 +410,29 @@ static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req, return lxc_cmd_rsp_send(fd, &rsp); } @@ -544,7 +520,8 @@ index 27c8c084..0eb2741f 100644 -char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath, - const char *subsystem) +static char *do_lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath, -+ const char *subsystem, bool inner) ++ const char *subsystem, ++ bool inner) { int ret, stopped; + size_t subsyslen = strlen(subsystem); @@ -567,9 +544,9 @@ index 27c8c084..0eb2741f 100644 + } + ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL); - if (ret < 0) - return NULL; -@@ -479,16 +477,42 @@ char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath, + if (ret < 0) { + TRACE("command %s failed for container \"%s\": %s.", +@@ -458,16 +457,61 @@ char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath, return cmd.rsp.data; } @@ -590,6 +567,25 @@ index 27c8c084..0eb2741f 100644 +{ + return do_lxc_cmd_get_cgroup_path(name, lxcpath, subsystem, false); +} ++ ++/* ++ * lxc_cmd_get_attach_cgroup_path: Calculate a container's inner cgroup path ++ * for a particular subsystem. This is the cgroup path relative to the root ++ * of the cgroup filesystem. ++ * ++ * @name : name of container to connect to ++ * @lxcpath : the lxcpath in which the container is running ++ * @subsystem : the subsystem being asked about ++ * ++ * Returns the path on success, NULL on failure. The caller must free() the ++ * returned path. ++ */ ++char *lxc_cmd_get_attach_cgroup_path(const char *name, const char *lxcpath, ++ const char *subsystem) ++{ ++ return do_lxc_cmd_get_cgroup_path(name, lxcpath, subsystem, true); ++} ++ + static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req, struct lxc_handler *handler) @@ -613,63 +609,11 @@ index 27c8c084..0eb2741f 100644 if (!path) return -1; rsp.datalen = strlen(path) + 1, -@@ -499,6 +523,24 @@ static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req, - } - - /* -+ * lxc_cmd_get_attach_cgroup_path: Calculate a container's inner cgroup path -+ * for a particular subsystem. This is the cgroup path relative to the root -+ * of the cgroup filesystem. -+ * -+ * @name : name of container to connect to -+ * @lxcpath : the lxcpath in which the container is running -+ * @subsystem : the subsystem being asked about -+ * -+ * Returns the path on success, NULL on failure. The caller must free() the -+ * returned path. -+ */ -+char *lxc_cmd_get_attach_cgroup_path(const char *name, const char *lxcpath, -+ const char *subsystem) -+{ -+ return do_lxc_cmd_get_cgroup_path(name, lxcpath, subsystem, true); -+} -+ -+/* - * lxc_cmd_get_config_item: Get config item the running container - * - * @name : name of container to connect to -@@ -849,16 +891,16 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, - typedef int (*callback)(int, struct lxc_cmd_req *, struct lxc_handler *); - - callback cb[LXC_CMD_MAX] = { -- [LXC_CMD_CONSOLE] = lxc_cmd_console_callback, -- [LXC_CMD_CONSOLE_WINCH] = lxc_cmd_console_winch_callback, -- [LXC_CMD_STOP] = lxc_cmd_stop_callback, -- [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback, -- [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback, -- [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback, -- [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback, -- [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback, -- [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback, -- [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback, -+ [LXC_CMD_CONSOLE] = lxc_cmd_console_callback, -+ [LXC_CMD_CONSOLE_WINCH] = lxc_cmd_console_winch_callback, -+ [LXC_CMD_STOP] = lxc_cmd_stop_callback, -+ [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback, -+ [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback, -+ [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback, -+ [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback, -+ [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback, -+ [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback, -+ [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback, - }; - - if (req->cmd >= LXC_CMD_MAX) { diff --git a/src/lxc/commands.h b/src/lxc/commands.h -index 184eefa0..6430b334 100644 +index 28428c77..9557dcaa 100644 --- a/src/lxc/commands.h +++ b/src/lxc/commands.h -@@ -77,6 +77,8 @@ extern int lxc_cmd_console(const char *name, int *ttynum, int *fd, +@@ -82,6 +82,8 @@ extern int lxc_cmd_console(const char *name, int *ttynum, int *fd, */ extern char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath, const char *subsystem); @@ -679,10 +623,10 @@ index 184eefa0..6430b334 100644 extern char *lxc_cmd_get_config_item(const char *name, const char *item, const char *lxcpath); extern char *lxc_cmd_get_name(const char *hashed_sock); diff --git a/src/lxc/criu.c b/src/lxc/criu.c -index d757bef6..64512193 100644 +index 676d759d..1dd41473 100644 --- a/src/lxc/criu.c +++ b/src/lxc/criu.c -@@ -283,7 +283,7 @@ static void exec_criu(struct criu_opts *opts) +@@ -324,7 +324,7 @@ static void exec_criu(struct criu_opts *opts) } else { const char *p; @@ -691,7 +635,7 @@ index d757bef6..64512193 100644 if (!p) { ERROR("failed to get cgroup path for %s", controllers[0]); goto err; -@@ -805,7 +805,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_ +@@ -857,7 +857,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_ goto out_fini_handler; } @@ -701,10 +645,10 @@ index d757bef6..64512193 100644 goto out_fini_handler; } diff --git a/src/lxc/start.c b/src/lxc/start.c -index bca7f8eb..2d7df0e7 100644 +index 1370d681..b653a157 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c -@@ -1115,7 +1115,7 @@ static int lxc_spawn(struct lxc_handler *handler) +@@ -1196,7 +1196,7 @@ static int lxc_spawn(struct lxc_handler *handler) cgroups_connected = true; @@ -713,7 +657,7 @@ index bca7f8eb..2d7df0e7 100644 ERROR("Failed creating cgroups."); goto out_delete_net; } -@@ -1202,10 +1202,10 @@ static int lxc_spawn(struct lxc_handler *handler) +@@ -1275,10 +1275,10 @@ static int lxc_spawn(struct lxc_handler *handler) goto out_delete_net; } @@ -726,9 +670,9 @@ index bca7f8eb..2d7df0e7 100644 goto out_delete_net; if (failed_before_rename) -@@ -1248,6 +1248,21 @@ static int lxc_spawn(struct lxc_handler *handler) - goto out_delete_net; +@@ -1333,6 +1333,21 @@ static int lxc_spawn(struct lxc_handler *handler) } + TRACE("Set up cgroup device limits"); + if (cgns_supported()) { + if (!cgroup_create(handler, true)) { diff --git a/debian/patches/0006-start-initutils-make-cgroupns-separation-level-confi.patch b/debian/patches/0006-start-initutils-make-cgroupns-separation-level-confi.patch index b60f8b3..ad732c3 100644 --- a/debian/patches/0006-start-initutils-make-cgroupns-separation-level-confi.patch +++ b/debian/patches/0006-start-initutils-make-cgroupns-separation-level-confi.patch @@ -1,7 +1,7 @@ -From 2b4c8a851ae299a840af3e5e0cdf128ea205b5a4 Mon Sep 17 00:00:00 2001 +From 3ec7cf35c1ca98f976a2c39cd58287d8137d0269 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Wed, 16 Nov 2016 09:53:42 +0100 -Subject: [PATCH 06/14] start/initutils: make cgroupns separation level +Subject: [PATCH 6/9] start/initutils: make cgroupns separation level configurable Adds a new global config variable `lxc.cgroup.separate` @@ -13,11 +13,11 @@ Signed-off-by: Wolfgang Bumiller --- src/lxc/initutils.c | 17 +++++++++-------- src/lxc/initutils.h | 1 + - src/lxc/start.c | 28 ++++++++++++++++------------ - 3 files changed, 26 insertions(+), 20 deletions(-) + src/lxc/start.c | 25 ++++++++++++++----------- + 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/lxc/initutils.c b/src/lxc/initutils.c -index 8d9016cd..06302935 100644 +index c190d6d5..97650e67 100644 --- a/src/lxc/initutils.c +++ b/src/lxc/initutils.c @@ -88,14 +88,15 @@ static char *copy_global_config_value(char *p) @@ -57,28 +57,11 @@ index c021fd61..443ad026 100644 extern void lxc_setup_fs(void); extern const char *lxc_global_config_value(const char *option_name); diff --git a/src/lxc/start.c b/src/lxc/start.c -index 2d7df0e7..a909c631 100644 +index b653a157..4fec27b9 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c -@@ -1061,6 +1061,7 @@ static int lxc_spawn(struct lxc_handler *handler) - int saved_ns_fd[LXC_NS_MAX]; - int preserve_mask = 0, i, flags; - int netpipepair[2], nveths; -+ bool privileged = lxc_list_empty(&handler->conf->id_map); - - netpipe = -1; - -@@ -1124,7 +1125,7 @@ static int lxc_spawn(struct lxc_handler *handler) - * it readonly. - * If the container is unprivileged then skip rootfs pinning. - */ -- if (lxc_list_empty(&handler->conf->id_map)) { -+ if (privileged) { - handler->pinfd = pin_rootfs(handler->conf->rootfs.path); - if (handler->pinfd == -1) - INFO("Failed to pin the rootfs for container \"%s\".", handler->name); -@@ -1249,17 +1250,20 @@ static int lxc_spawn(struct lxc_handler *handler) - } +@@ -1334,17 +1334,20 @@ static int lxc_spawn(struct lxc_handler *handler) + TRACE("Set up cgroup device limits"); if (cgns_supported()) { - if (!cgroup_create(handler, true)) { @@ -93,7 +76,7 @@ index 2d7df0e7..a909c631 100644 - ERROR("failed chown inner cgroup separation layer"); - goto out_delete_net; + const char *tmp = lxc_global_config_value("lxc.cgroup.protect_limits"); -+ if (!strcmp(tmp, "both") || !strcmp(tmp, privileged ? "privileged" : "unprivileged")) { ++ if (!strcmp(tmp, "both") || !strcmp(tmp, wants_to_map_ids ? "unprivileged" : "privileged")) { + if (!cgroup_create(handler, true)) { + ERROR("failed to create inner cgroup separation layer"); + goto out_delete_net; diff --git a/debian/patches/0007-rename-cgroup-namespace-directory-to-ns.patch b/debian/patches/0007-rename-cgroup-namespace-directory-to-ns.patch index ce331d2..ae93b5a 100644 --- a/debian/patches/0007-rename-cgroup-namespace-directory-to-ns.patch +++ b/debian/patches/0007-rename-cgroup-namespace-directory-to-ns.patch @@ -1,7 +1,7 @@ -From adf5f6720c85fe7059ff98942c136846b16880eb Mon Sep 17 00:00:00 2001 +From d80258c750c52470389056c212a0eb5f0901dd7b Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Fri, 23 Dec 2016 15:57:24 +0100 -Subject: [PATCH 07/14] rename cgroup namespace directory to ns +Subject: [PATCH 7/9] rename cgroup namespace directory to ns Signed-off-by: Wolfgang Bumiller --- @@ -9,7 +9,7 @@ Signed-off-by: Wolfgang Bumiller 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h -index f36c6f02..2c504c81 100644 +index f05fda4e..34c9d89c 100644 --- a/src/lxc/cgroups/cgroup.h +++ b/src/lxc/cgroups/cgroup.h @@ -32,7 +32,7 @@ diff --git a/debian/patches/0008-possibility-to-run-lxc-monitord-as-a-regular-daemon.patch b/debian/patches/0008-possibility-to-run-lxc-monitord-as-a-regular-daemon.patch index 9181fec..ad49e31 100644 --- a/debian/patches/0008-possibility-to-run-lxc-monitord-as-a-regular-daemon.patch +++ b/debian/patches/0008-possibility-to-run-lxc-monitord-as-a-regular-daemon.patch @@ -1,7 +1,7 @@ -From eea36cafdc53b5ed2200ea0910f4222bc4e7891f Mon Sep 17 00:00:00 2001 +From 9f5dc10171f3546530a326b8d427683109fd2818 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Fri, 10 Feb 2017 10:23:36 +0100 -Subject: [PATCH 08/14] possibility to run lxc-monitord as a regular daemon +Subject: [PATCH 8/9] possibility to run lxc-monitord as a regular daemon This includes an lxc-monitord.service, required by lxc@.service which is now of Type=forking. @@ -78,10 +78,10 @@ index 00000000..40635168 +[Install] +WantedBy=multi-user.target diff --git a/config/init/systemd/lxc@.service.in b/config/init/systemd/lxc@.service.in -index 6b8b5ff1..c35526b3 100644 +index 98d5a3a7..4ee90b21 100644 --- a/config/init/systemd/lxc@.service.in +++ b/config/init/systemd/lxc@.service.in -@@ -1,16 +1,17 @@ +@@ -1,15 +1,16 @@ [Unit] Description=LXC Container: %i # This pulls in apparmor, dev-setup, lxc-net @@ -95,18 +95,17 @@ index 6b8b5ff1..c35526b3 100644 -Type=simple +Type=forking KillMode=mixed - KillSignal=SIGPWR TimeoutStopSec=120s -ExecStart=@BINDIR@/lxc-start -F -n %i +ExecStart=@BINDIR@/lxc-start -n %i + ExecStop=@BINDIR@/lxc-stop -n %i # Environment=BOOTUP=serial # Environment=CONSOLETYPE=serial - StandardOutput=syslog diff --git a/configure.ac b/configure.ac -index bd2d82f6..fa3926a9 100644 +index 35fe7964..d34eda1e 100644 --- a/configure.ac +++ b/configure.ac -@@ -697,6 +697,7 @@ AC_CONFIG_FILES([ +@@ -709,6 +709,7 @@ AC_CONFIG_FILES([ config/init/systemd/lxc.service config/init/systemd/lxc@.service config/init/systemd/lxc-net.service @@ -115,10 +114,10 @@ index bd2d82f6..fa3926a9 100644 config/init/sysvinit/lxc-containers config/init/sysvinit/lxc-net diff --git a/lxc.spec.in b/lxc.spec.in -index 0e64907e..f35d81ca 100644 +index e31115de..36ab7d9d 100644 --- a/lxc.spec.in +++ b/lxc.spec.in -@@ -259,6 +259,7 @@ fi +@@ -260,6 +260,7 @@ fi %{_unitdir}/lxc-net.service %{_unitdir}/lxc.service %{_unitdir}/lxc@.service @@ -127,10 +126,10 @@ index 0e64907e..f35d81ca 100644 %{_sysconfdir}/rc.d/init.d/lxc %{_sysconfdir}/rc.d/init.d/lxc-net diff --git a/src/lxc/lxc_monitord.c b/src/lxc/lxc_monitord.c -index 62e21211..ad40dbef 100644 +index c4c2ba0d..c3534e3d 100644 --- a/src/lxc/lxc_monitord.c +++ b/src/lxc/lxc_monitord.c -@@ -344,16 +344,43 @@ static void lxc_monitord_sig_handler(int sig) +@@ -345,17 +345,44 @@ static void lxc_monitord_sig_handler(int sig) int main(int argc, char *argv[]) { @@ -143,6 +142,7 @@ index 62e21211..ad40dbef 100644 bool mainloop_opened = false; bool monitord_created = false; + bool persistent = false; + struct lxc_log log; - if (argc != 3) { + if (argc > 1 && !strcmp(argv[1], "--daemon")) { @@ -178,7 +178,7 @@ index 62e21211..ad40dbef 100644 "NOTE: lxc-monitord is intended for use by lxc internally\n" " and does not need to be run by hand\n\n"); exit(EXIT_FAILURE); -@@ -369,9 +396,6 @@ int main(int argc, char *argv[]) +@@ -377,9 +404,6 @@ int main(int argc, char *argv[]) INFO("Failed to open log file %s, log will be lost.", lxcpath); lxc_log_options_no_override(); @@ -188,7 +188,7 @@ index 62e21211..ad40dbef 100644 if (sigfillset(&mask) || sigdelset(&mask, SIGILL) || sigdelset(&mask, SIGSEGV) || -@@ -403,15 +427,17 @@ int main(int argc, char *argv[]) +@@ -411,15 +435,17 @@ int main(int argc, char *argv[]) goto on_error; monitord_created = true; @@ -215,14 +215,14 @@ index 62e21211..ad40dbef 100644 if (lxc_monitord_mainloop_add(&mon)) { ERROR("Failed to add mainloop handlers."); -@@ -421,7 +447,7 @@ int main(int argc, char *argv[]) +@@ -429,7 +455,7 @@ int main(int argc, char *argv[]) NOTICE("lxc-monitord with pid %d is now monitoring lxcpath %s.", getpid(), mon.lxcpath); for (;;) { - ret = lxc_mainloop(&mon.descr, 1000 * 30); + ret = lxc_mainloop(&mon.descr, persistent ? -1 : 1000 * 30); - if (mon.clientfds_cnt <= 0) { - NOTICE("No remaining clients. lxc-monitord is exiting."); + if (ret) { + ERROR("mainloop returned an error"); break; -- 2.11.0 diff --git a/debian/patches/0009-conf-implement-resource-limits.patch b/debian/patches/0009-conf-implement-resource-limits.patch deleted file mode 100644 index 1ed26d1..0000000 --- a/debian/patches/0009-conf-implement-resource-limits.patch +++ /dev/null @@ -1,513 +0,0 @@ -From 67a23f3f3fa65f1646ad20a8591b15895cada0a4 Mon Sep 17 00:00:00 2001 -From: Wolfgang Bumiller -Date: Fri, 4 Nov 2016 10:19:07 +0100 -Subject: [PATCH 09/14] conf: implement resource limits - -This adds lxc.limit. options consisting of one or two -colon separated numerical values (soft and optional hard -limit). If only one number is specified it'll be used for -both soft and hard limit. Additionally the word 'unlimited' -can be used instead of numbers. - -Eg. - lxc.limit.nofile = 30000:32768 - lxc.limit.stack = unlimited - -Signed-off-by: Wolfgang Bumiller ---- - configure.ac | 2 +- - src/lxc/attach.c | 5 ++ - src/lxc/conf.c | 122 +++++++++++++++++++++++++++++++++++++++++ - src/lxc/conf.h | 26 +++++++++ - src/lxc/confile.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/start.c | 5 ++ - 6 files changed, 320 insertions(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index fa3926a9..2857d5ae 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -633,7 +633,7 @@ AM_CONDITIONAL([IS_BIONIC], [test "x$is_bionic" = "xyes"]) - AC_CHECK_DECLS([PR_CAPBSET_DROP], [], [], [#include ]) - - # Check for some headers --AC_CHECK_HEADERS([sys/signalfd.h pty.h ifaddrs.h sys/memfd.h sys/personality.h utmpx.h sys/timerfd.h]) -+AC_CHECK_HEADERS([sys/signalfd.h pty.h ifaddrs.h sys/memfd.h sys/personality.h utmpx.h sys/timerfd.h sys/resource.h]) - - # lookup major()/minor()/makedev() - AC_HEADER_MAJOR -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 119b9c14..6fdc6e8a 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -854,6 +854,11 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun - goto on_error; - } - -+ /* Setup resource limits */ -+ if (!lxc_list_empty(&init_ctx->container->lxc_conf->limits) && setup_resource_limits(&init_ctx->container->lxc_conf->limits, pid)) { -+ goto on_error; -+ } -+ - /* Open /proc before setns() to the containers namespace so we - * don't rely on any information from inside the container. - */ -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 3bedcf0f..d68ab2e2 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -243,6 +243,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 -@@ -376,6 +381,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; -@@ -2534,6 +2590,45 @@ static int setup_network(struct lxc_list *network) - return 0; - } - -+static int parse_resource(const char *res) { -+ 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) == 0) -+ return limit_opt[i].value; -+ } -+ -+ /* try to see if it's numeric, so the user may specify -+ * resources that the running kernel knows about but -+ * we don't */ -+ if (lxc_safe_int(res, &resid) == 0) -+ return resid; -+ return -1; -+} -+ -+int setup_resource_limits(struct lxc_list *limits, pid_t pid) { -+ 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 (prlimit(pid, resid, &lim->limit, NULL) != 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) - { -@@ -2620,6 +2715,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; ihooks[i]); - lxc_list_init(&new->groups); -@@ -4317,6 +4413,31 @@ 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 = NULL; -+ -+ if (strcmp(key, "lxc.limit") == 0) -+ all = true; -+ else if (strncmp(key, "lxc.limit.", sizeof("lxc.limit.")-1) == 0) -+ k = key + sizeof("lxc.limit.")-1; -+ else -+ return -1; -+ -+ 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; -@@ -4462,6 +4583,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 c790bf7c..7dc05288 100644 ---- a/src/lxc/conf.h -+++ b/src/lxc/conf.h -@@ -30,6 +30,9 @@ - #include - #include - #include -+#if HAVE_SYS_RESOURCE_H -+#include -+#endif - #include - - #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 -@@ -378,6 +398,9 @@ struct lxc_conf { - - /* indicator if the container will be destroyed on shutdown */ - unsigned int ephemeral; -+ -+ /* RLIMIT_* limits */ -+ struct lxc_list limits; - }; - - #ifdef HAVE_TLS -@@ -421,6 +444,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, -@@ -433,6 +457,8 @@ extern int do_rootfs_setup(struct lxc_conf *conf, const char *name, - struct cgroup_process_info; - extern int lxc_setup(struct lxc_handler *handler); - -+extern int setup_resource_limits(struct lxc_list *limits, pid_t pid); -+ - extern void lxc_restore_phys_nics_to_netns(int netnsfd, struct lxc_conf *conf); - - extern int find_unmapped_nsuid(struct lxc_conf *conf, enum idtype idtype); -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 9b22c6d3..89f8c625 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -112,6 +112,7 @@ static int config_init_cmd(const char *, const char *, struct lxc_conf *); - 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_limit(const char *, const char *, struct lxc_conf *); - - static struct lxc_config_t config[] = { - -@@ -184,6 +185,7 @@ static struct lxc_config_t config[] = { - { "lxc.init_uid", config_init_uid }, - { "lxc.init_gid", config_init_gid }, - { "lxc.ephemeral", config_ephemeral }, -+ { "lxc.limit", config_limit }, - }; - - struct signame { -@@ -1500,6 +1502,110 @@ out: - 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"; -@@ -2233,6 +2339,55 @@ 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[LXC_NUMSTRLEN64*2+2]; /* 2 colon separated 64 bit integers or the word 'unlimited' */ -+ int partlen; -+ struct lxc_limit *lim = it->elem; -+ -+ 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); -+ } -+ if (lim->limit.rlim_cur != lim->limit.rlim_max) { -+ 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) - { -@@ -2594,6 +2749,10 @@ int lxc_get_config_item(struct lxc_conf *c, const char *key, char *retv, - return lxc_get_conf_int(c, retv, inlen, c->init_gid); - else if (strcmp(key, "lxc.ephemeral") == 0) - return lxc_get_conf_int(c, retv, inlen, c->ephemeral); -+ 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) -@@ -2627,6 +2786,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; - } - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index a909c631..29edb8f7 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -1244,6 +1244,11 @@ static int lxc_spawn(struct lxc_handler *handler) - if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_CONFIGURE)) - goto out_delete_net; - -+ if (!lxc_list_empty(&handler->conf->limits) && setup_resource_limits(&handler->conf->limits, handler->pid)) { -+ ERROR("failed to setup resource limits for '%s'", name); -+ return -1; -+ } -+ - if (!cgroup_setup_limits(handler, true)) { - ERROR("Failed to setup the devices cgroup for container \"%s\".", name); - goto out_delete_net; --- -2.11.0 - diff --git a/debian/patches/0009-network-add-missing-checks-for-empty-links.patch b/debian/patches/0009-network-add-missing-checks-for-empty-links.patch new file mode 100644 index 0000000..c739381 --- /dev/null +++ b/debian/patches/0009-network-add-missing-checks-for-empty-links.patch @@ -0,0 +1,35 @@ +From c1c1e55305a06786ee3dd938e421ca413db73dd1 Mon Sep 17 00:00:00 2001 +From: Wolfgang Bumiller +Date: Wed, 6 Sep 2017 11:51:03 +0200 +Subject: [PATCH 9/9] network: add missing checks for empty links + +Signed-off-by: Wolfgang Bumiller +--- + src/lxc/network.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/lxc/network.c b/src/lxc/network.c +index 3c0597c7..0ad42318 100644 +--- a/src/lxc/network.c ++++ b/src/lxc/network.c +@@ -2355,7 +2355,7 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler) + if (netdev->type != LXC_NET_VETH) + continue; + +- if (!is_ovs_bridge(netdev->link)) ++ if (netdev->link[0] == '\0' || !is_ovs_bridge(netdev->link)) + continue; + + if (netdev->priv.veth_attr.pair[0] != '\0') +@@ -2564,7 +2564,7 @@ bool lxc_delete_network_priv(struct lxc_handler *handler) + } + INFO("Removed interface \"%s\" from \"%s\"", hostveth, netdev->link); + +- if (!is_ovs_bridge(netdev->link)) { ++ if (netdev->link[0] == '\0' || !is_ovs_bridge(netdev->link)) { + netdev->priv.veth_attr.veth1[0] = '\0'; + continue; + } +-- +2.11.0 + diff --git a/debian/patches/0010-doc-add-lxc.limit-to-lxc.container.conf.patch b/debian/patches/0010-doc-add-lxc.limit-to-lxc.container.conf.patch deleted file mode 100644 index 13ab3ee..0000000 --- a/debian/patches/0010-doc-add-lxc.limit-to-lxc.container.conf.patch +++ /dev/null @@ -1,58 +0,0 @@ -From cd637b14e945486fb5be97b89102f679487584b5 Mon Sep 17 00:00:00 2001 -From: Wolfgang Bumiller -Date: Fri, 4 Nov 2016 12:03:28 +0100 -Subject: [PATCH 10/14] doc: add lxc.limit to lxc.container.conf - -Signed-off-by: Wolfgang Bumiller ---- - 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 a4ef46d6..13e0d66c 100644 ---- a/doc/lxc.container.conf.sgml.in -+++ b/doc/lxc.container.conf.sgml.in -@@ -1189,6 +1189,40 @@ proc proc proc nodev,noexec,nosuid 0 0 - - - -+ Resource limits -+ -+ 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. -+ -+ -+ -+ -+ -+ -+ -+ -+ 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 -+ -+ setrlimit -+ 2 -+ . -+ 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. -+ -+ -+ -+ -+ -+ -+ - Apparmor profile - - If lxc was compiled and installed with apparmor support, and the host --- -2.11.0 - diff --git a/debian/patches/0011-test-resource-limit-config-entries.patch b/debian/patches/0011-test-resource-limit-config-entries.patch deleted file mode 100644 index fe50c91..0000000 --- a/debian/patches/0011-test-resource-limit-config-entries.patch +++ /dev/null @@ -1,88 +0,0 @@ -From fd224d9bff0b269ea1524cf7546314488014c018 Mon Sep 17 00:00:00 2001 -From: Wolfgang Bumiller -Date: Fri, 4 Nov 2016 11:45:47 +0100 -Subject: [PATCH 11/14] test: resource limit config entries - -Signed-off-by: Wolfgang Bumiller ---- - 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 9750f312..93f2d965 100644 ---- a/src/tests/get_item.c -+++ b/src/tests/get_item.c -@@ -149,6 +149,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; --- -2.11.0 - diff --git a/debian/patches/0012-start-fix-error-handling-when-limits-fail-to-apply.patch b/debian/patches/0012-start-fix-error-handling-when-limits-fail-to-apply.patch deleted file mode 100644 index c4fc534..0000000 --- a/debian/patches/0012-start-fix-error-handling-when-limits-fail-to-apply.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 4b5238d5a7422f71abc4dbe8a7f01ab54dc9599b Mon Sep 17 00:00:00 2001 -From: Wolfgang Bumiller -Date: Tue, 11 Apr 2017 16:42:01 +0200 -Subject: [PATCH 12/14] start: fix error handling when limits fail to apply - -(The code was moved here from the child side of the startup -without adapting the error case.) - -Signed-off-by: Wolfgang Bumiller ---- - src/lxc/start.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 29edb8f7..8c2d2182 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -1246,7 +1246,7 @@ static int lxc_spawn(struct lxc_handler *handler) - - if (!lxc_list_empty(&handler->conf->limits) && setup_resource_limits(&handler->conf->limits, handler->pid)) { - ERROR("failed to setup resource limits for '%s'", name); -- return -1; -+ goto out_delete_net; - } - - if (!cgroup_setup_limits(handler, true)) { --- -2.11.0 - diff --git a/debian/patches/0013-start-don-t-call-lxc_map_ids-without-id-map.patch b/debian/patches/0013-start-don-t-call-lxc_map_ids-without-id-map.patch deleted file mode 100644 index e80544c..0000000 --- a/debian/patches/0013-start-don-t-call-lxc_map_ids-without-id-map.patch +++ /dev/null @@ -1,70 +0,0 @@ -From c1cf0e26f6dee988d73b4da760dc3f52f9c9a83b Mon Sep 17 00:00:00 2001 -From: Christian Brauner -Date: Sat, 13 May 2017 17:16:25 +0200 -Subject: [PATCH 13/14] start: don't call lxc_map_ids() without id map - -So far, we somehow always called lxc_map_ids(), even when no id map was -configured. Let's not do this. - -Closes #1555. - -Signed-off-by: Christian Brauner - -Conflicts: - namespace spearation patches -Squashed: - 0ee3505984e (start: pin rootfs when privileged) - -Signed-off-by: Wolfgang Bumiller ---- - src/lxc/start.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 8c2d2182..c8947f18 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -1061,9 +1061,12 @@ static int lxc_spawn(struct lxc_handler *handler) - int saved_ns_fd[LXC_NS_MAX]; - int preserve_mask = 0, i, flags; - int netpipepair[2], nveths; -- bool privileged = lxc_list_empty(&handler->conf->id_map); -+ bool wants_to_map_ids; -+ struct lxc_list *id_map; - - netpipe = -1; -+ id_map = &handler->conf->id_map; -+ wants_to_map_ids = !lxc_list_empty(id_map); - - for (i = 0; i < LXC_NS_MAX; i++) - if (handler->conf->inherit_ns_fd[i] != -1) -@@ -1125,7 +1128,7 @@ static int lxc_spawn(struct lxc_handler *handler) - * it readonly. - * If the container is unprivileged then skip rootfs pinning. - */ -- if (privileged) { -+ if (!wants_to_map_ids) { - handler->pinfd = pin_rootfs(handler->conf->rootfs.path); - if (handler->pinfd == -1) - INFO("Failed to pin the rootfs for container \"%s\".", handler->name); -@@ -1179,7 +1182,7 @@ static int lxc_spawn(struct lxc_handler *handler) - * mapped to something else on the host.) later to become a valid uid - * again. - */ -- if (lxc_map_ids(&handler->conf->id_map, handler->pid)) { -+ if (wants_to_map_ids && lxc_map_ids(id_map, handler->pid)) { - ERROR("Failed to set up id mapping."); - goto out_delete_net; - } -@@ -1256,7 +1259,7 @@ static int lxc_spawn(struct lxc_handler *handler) - - if (cgns_supported()) { - const char *tmp = lxc_global_config_value("lxc.cgroup.protect_limits"); -- if (!strcmp(tmp, "both") || !strcmp(tmp, privileged ? "privileged" : "unprivileged")) { -+ if (!strcmp(tmp, "both") || !strcmp(tmp, wants_to_map_ids ? "unprivileged" : "privileged")) { - if (!cgroup_create(handler, true)) { - ERROR("failed to create inner cgroup separation layer"); - goto out_delete_net; --- -2.11.0 - diff --git a/debian/patches/0014-Fix-the-bug-of-ts-stdoutfd-did-not-fill-with-paramet.patch b/debian/patches/0014-Fix-the-bug-of-ts-stdoutfd-did-not-fill-with-paramet.patch deleted file mode 100644 index d76e7a8..0000000 --- a/debian/patches/0014-Fix-the-bug-of-ts-stdoutfd-did-not-fill-with-paramet.patch +++ /dev/null @@ -1,29 +0,0 @@ -From c29c4928c88cf5bf88115b787f04cccc1664bfd1 Mon Sep 17 00:00:00 2001 -From: Li Feng -Date: Fri, 19 May 2017 22:40:07 +0800 -Subject: [PATCH 14/14] Fix the bug of 'ts->stdoutfd' did not fill with - parameters 'stdoutfd' - -Signed-off-by: Li Feng ---- - src/lxc/console.c | 1 + - 1 file changed, 1 insertion(+) - mode change 100644 => 100755 src/lxc/console.c - -diff --git a/src/lxc/console.c b/src/lxc/console.c -old mode 100644 -new mode 100755 -index 3baaed49..ad88a0ba ---- a/src/lxc/console.c -+++ b/src/lxc/console.c -@@ -697,6 +697,7 @@ int lxc_console(struct lxc_container *c, int ttynum, - ts->escape = escape; - ts->winch_proxy = c->name; - ts->winch_proxy_lxcpath = c->config_path; -+ ts->stdoutfd = stdoutfd; - - lxc_console_winsz(stdinfd, masterfd); - lxc_cmd_console_winch(ts->winch_proxy, ts->winch_proxy_lxcpath); --- -2.11.0 - diff --git a/debian/patches/0015-fix-segfault-in-lxc-attach.patch b/debian/patches/0015-fix-segfault-in-lxc-attach.patch deleted file mode 100644 index 2e68dec..0000000 --- a/debian/patches/0015-fix-segfault-in-lxc-attach.patch +++ /dev/null @@ -1,29 +0,0 @@ -From b68958e110feed24a632d9e157d235e0a1980a17 Mon Sep 17 00:00:00 2001 -From: Wolfgang Bumiller -Date: Fri, 30 Jun 2017 10:51:19 +0200 -Subject: [PATCH 15/15] fix segfault in lxc-attach - -Signed-off-by: Wolfgang Bumiller ---- - src/lxc/attach.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 6fdc6e8a..1dff59ca 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -855,7 +855,10 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun - } - - /* Setup resource limits */ -- if (!lxc_list_empty(&init_ctx->container->lxc_conf->limits) && setup_resource_limits(&init_ctx->container->lxc_conf->limits, pid)) { -+ if (init_ctx->container && -+ init_ctx->container->lxc_conf && -+ !lxc_list_empty(&init_ctx->container->lxc_conf->limits) -+ && setup_resource_limits(&init_ctx->container->lxc_conf->limits, pid)) { - goto on_error; - } - --- -2.11.0 - diff --git a/debian/patches/series b/debian/patches/series index 5d9c25d..9dbf12e 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -6,10 +6,4 @@ 0006-start-initutils-make-cgroupns-separation-level-confi.patch 0007-rename-cgroup-namespace-directory-to-ns.patch 0008-possibility-to-run-lxc-monitord-as-a-regular-daemon.patch -0009-conf-implement-resource-limits.patch -0010-doc-add-lxc.limit-to-lxc.container.conf.patch -0011-test-resource-limit-config-entries.patch -0012-start-fix-error-handling-when-limits-fail-to-apply.patch -0013-start-don-t-call-lxc_map_ids-without-id-map.patch -0014-Fix-the-bug-of-ts-stdoutfd-did-not-fill-with-paramet.patch -0015-fix-segfault-in-lxc-attach.patch +0009-network-add-missing-checks-for-empty-links.patch diff --git a/lxc.tgz b/lxc.tgz index 2897b33..2171b21 100644 Binary files a/lxc.tgz and b/lxc.tgz differ