update to lxc-2.1.0

This commit is contained in:
Wolfgang Bumiller 2017-09-06 10:43:45 +02:00
parent 78b723632b
commit f39a178ac4
19 changed files with 228 additions and 1092 deletions

View File

@ -1,6 +1,6 @@
PACKAGE=lxc-pve
LXCVER=2.0.8
DEBREL=3
LXCVER=2.1.0
DEBREL=1
SRCDIR=lxc
SRCTAR=${SRCDIR}.tgz

View File

@ -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 <w.bumiller@proxmox.com>
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 <w.bumiller@proxmox.com>
---

View File

@ -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 <w.bumiller@proxmox.com>
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 <w.bumiller@proxmox.com>
---
@ -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

View File

@ -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 <w.bumiller@proxmox.com>
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 <w.bumiller@proxmox.com>
---
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

View File

@ -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?= <f.gruenbichler@proxmox.com>
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

View File

@ -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 <w.bumiller@proxmox.com>
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 <w.bumiller@proxmox.com>
---
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)) {

View File

@ -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 <w.bumiller@proxmox.com>
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 <w.bumiller@proxmox.com>
---
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;

View File

@ -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 <w.bumiller@proxmox.com>
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 <w.bumiller@proxmox.com>
---
@ -9,7 +9,7 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
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 @@

View File

@ -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 <w.bumiller@proxmox.com>
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

View File

@ -1,513 +0,0 @@
From 67a23f3f3fa65f1646ad20a8591b15895cada0a4 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Fri, 4 Nov 2016 10:19:07 +0100
Subject: [PATCH 09/14] conf: implement resource limits
This adds lxc.limit.<name> 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 <w.bumiller@proxmox.com>
---
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 <sys/prctl.h>])
# 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; i<NUM_LXC_HOOKS; i++)
lxc_list_init(&new->hooks[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 <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
@@ -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

View File

@ -0,0 +1,35 @@
From c1c1e55305a06786ee3dd938e421ca413db73dd1 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
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 <w.bumiller@proxmox.com>
---
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

View File

@ -1,58 +0,0 @@
From cd637b14e945486fb5be97b89102f679487584b5 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
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 <w.bumiller@proxmox.com>
---
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
</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
--
2.11.0

View File

@ -1,88 +0,0 @@
From fd224d9bff0b269ea1524cf7546314488014c018 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Fri, 4 Nov 2016 11:45:47 +0100
Subject: [PATCH 11/14] test: resource limit config entries
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
---
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

View File

@ -1,29 +0,0 @@
From 4b5238d5a7422f71abc4dbe8a7f01ab54dc9599b Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
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 <w.bumiller@proxmox.com>
---
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

View File

@ -1,70 +0,0 @@
From c1cf0e26f6dee988d73b4da760dc3f52f9c9a83b Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner@ubuntu.com>
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 <christian.brauner@ubuntu.com>
Conflicts:
namespace spearation patches
Squashed:
0ee3505984e (start: pin rootfs when privileged)
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
---
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

View File

@ -1,29 +0,0 @@
From c29c4928c88cf5bf88115b787f04cccc1664bfd1 Mon Sep 17 00:00:00 2001
From: Li Feng <lifeng68@huawei.com>
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 <lifeng68@huawei.com>
---
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

View File

@ -1,29 +0,0 @@
From b68958e110feed24a632d9e157d235e0a1980a17 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Fri, 30 Jun 2017 10:51:19 +0200
Subject: [PATCH 15/15] fix segfault in lxc-attach
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
---
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

View File

@ -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

BIN
lxc.tgz

Binary file not shown.