[lxc-devel] [PATCH RFC] detect which cgroups we cannot use
Serge Hallyn
serge.hallyn at ubuntu.com
Thu Dec 24 02:14:39 UTC 2015
and continue without them if possible
This patch only handles cgmanger - we need to handle this in cgfs too.
Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
src/lxc/cgmanager.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 113 insertions(+), 3 deletions(-)
diff --git a/src/lxc/cgmanager.c b/src/lxc/cgmanager.c
index d69eb3d..95af043 100644
--- a/src/lxc/cgmanager.c
+++ b/src/lxc/cgmanager.c
@@ -1202,6 +1202,116 @@ static bool verify_and_prune(const char *cgroup_use)
return true;
}
+static void drop_subsystem(int which)
+{
+ int i;
+
+ if (which <= 0 || which > nr_subsystems) {
+ ERROR("code error: dropping invalid subsystem index\n");
+ exit(1);
+ }
+
+ free(subsystems[which]);
+ /* note - we have nr_subsystems+1 entries, last one a NULL */
+ for (i = which; i < nr_subsystems; i++)
+ subsystems[i] = subsystems[i+1];
+ nr_subsystems -= 1;
+}
+
+/*
+ * Check whether we can create the cgroups we would want
+ */
+static bool subsys_is_writeable(const char *controller, const char *probe)
+{
+ int32_t existed;
+ bool ret = true;
+
+ if ( cgmanager_create_sync(NULL, cgroup_manager, controller,
+ probe, &existed) != 0) {
+ NihError *nerr;
+ nerr = nih_error_get();
+ ERROR("call to cgmanager_create_sync failed: %s", nerr->message);
+ nih_free(nerr);
+ ERROR("Failed to create %s:%s", controller, probe);
+ ret = false;
+ }
+
+ return ret;
+}
+
+/*
+ * Return true if this is a subsystem which we cannot do
+ * without
+ */
+static bool is_crucial_subsys(const char *s)
+{
+ if (strcmp(s, "systemd") == 0)
+ return true;
+ if (strcmp(s, "name=systemd") == 0)
+ return true;
+ if (strcmp(s, "freezer") == 0)
+ return true;
+ return false;
+}
+
+/*
+ * Make sure that all the controllers are writeable.
+ * If any are not, then
+ * - if they are listed in lxc.cgroup.use, refuse to start
+ * - else if they are crucial subsystems, refuse to start
+ * - else warn and do not use them
+ */
+static bool verify_final_subsystems(const char *cgroup_use)
+{
+ int i = 0;
+ bool dropped_any = false;
+ bool ret = false;
+ const char *cgroup_pattern;
+ char tmpnam[50], *probe;
+
+ if (!cgm_dbus_connect()) {
+ ERROR("Error connecting to cgroup manager");
+ return false;
+ }
+
+ cgroup_pattern = lxc_global_config_value("lxc.cgroup.pattern");
+ snprintf(tmpnam, 50, "lxcprobe-%d", getpid());
+ probe = lxc_string_replace("%n", tmpnam, cgroup_pattern);
+ if (!probe)
+ goto out;
+
+ while (i < nr_subsystems) {
+ if (!subsys_is_writeable(subsystems[i], probe)) {
+ if (is_crucial_subsys(subsystems[i])) {
+ ERROR("Cannot write to crucial subsystem %s\n",
+ subsystems[i]);
+ goto out;
+ }
+ if (cgroup_use && in_comma_list(subsystems[i], cgroup_use)) {
+ ERROR("Cannot write to subsystem %s which is requested in lxc.cgroup.use\n",
+ subsystems[i]);
+ goto out;
+ }
+ WARN("Cannot write to subsystem %s, continuing with out it\n",
+ subsystems[i]);
+ dropped_any = true;
+ drop_subsystem(i);
+ } else {
+ cgm_remove_cgroup(subsystems[i], probe);
+ i++;
+ }
+ }
+
+ if (dropped_any)
+ cgm_all_controllers_same = false;
+ ret = true;
+
+out:
+ free(probe);
+ cgm_dbus_disconnect();
+ return ret;
+}
+
static bool collect_subsytems(void)
{
char *line = NULL;
@@ -1285,7 +1395,7 @@ collected:
/* make sure that cgroup.use can be and is honored */
const char *cgroup_use = lxc_global_config_value("lxc.cgroup.use");
if (!cgroup_use && errno != 0)
- goto out_good;
+ goto final_verify;
if (cgroup_use) {
if (!verify_and_prune(cgroup_use)) {
free_subsystems();
@@ -1295,8 +1405,8 @@ collected:
cgm_all_controllers_same = false;
}
-out_good:
- return true;
+final_verify:
+ return verify_final_subsystems(cgroup_use);
out_free:
free(line);
--
2.5.0
More information about the lxc-devel
mailing list