mirror of
https://git.proxmox.com/git/lxc
synced 2025-08-14 16:15:26 +00:00
update to lxc-2.1.0
This commit is contained in:
parent
78b723632b
commit
f39a178ac4
4
Makefile
4
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
|
||||
|
@ -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>
|
||||
---
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
@ -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 @@
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
35
debian/patches/0009-network-add-missing-checks-for-empty-links.patch
vendored
Normal file
35
debian/patches/0009-network-add-missing-checks-for-empty-links.patch
vendored
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
8
debian/patches/series
vendored
8
debian/patches/series
vendored
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user