|
|
43fe83 |
From ba776c58abac13bd5a539cd128c002284a363f58 Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <ba776c58abac13bd5a539cd128c002284a363f58.1375465853.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: "Daniel P. Berrange" <berrange@redhat.com>
|
|
|
43fe83 |
Date: Wed, 31 Jul 2013 19:48:20 +0100
|
|
|
43fe83 |
Subject: [PATCH] Enable support for systemd-machined in cgroups creation
|
|
|
43fe83 |
|
|
|
43fe83 |
https://bugzilla.redhat.com/show_bug.cgi?id=980929
|
|
|
43fe83 |
|
|
|
43fe83 |
Make the virCgroupNewMachine method try to use systemd-machined
|
|
|
43fe83 |
first. If that fails, then fallback to using the traditional
|
|
|
43fe83 |
cgroup setup code path.
|
|
|
43fe83 |
|
|
|
43fe83 |
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
|
|
43fe83 |
|
|
|
43fe83 |
(cherry picked from commit 2fe2470181ce3722788fd7125d3f1f9be87e6278)
|
|
|
43fe83 |
---
|
|
|
43fe83 |
src/lxc/lxc_process.c | 10 +--
|
|
|
43fe83 |
src/qemu/qemu_cgroup.c | 1 +
|
|
|
43fe83 |
src/util/vircgroup.c | 187 ++++++++++++++++++++++++++++++++++++++++++++-----
|
|
|
43fe83 |
src/util/vircgroup.h | 1 +
|
|
|
43fe83 |
4 files changed, 179 insertions(+), 20 deletions(-)
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
|
|
|
43fe83 |
index 247e516..0a28305 100644
|
|
|
43fe83 |
--- a/src/lxc/lxc_process.c
|
|
|
43fe83 |
+++ b/src/lxc/lxc_process.c
|
|
|
43fe83 |
@@ -1203,8 +1203,9 @@ int virLXCProcessStart(virConnectPtr conn,
|
|
|
43fe83 |
goto cleanup;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
- if (virCgroupNewDetectMachine(vm->def->name, "lxc",
|
|
|
43fe83 |
- vm->pid, -1, &priv->cgroup) < 0)
|
|
|
43fe83 |
+ if (virCgroupNewDetectMachine(vm->def->name, "lxc", vm->pid,
|
|
|
43fe83 |
+ vm->def->resource->partition,
|
|
|
43fe83 |
+ -1, &priv->cgroup) < 0)
|
|
|
43fe83 |
goto error;
|
|
|
43fe83 |
|
|
|
43fe83 |
if (!priv->cgroup) {
|
|
|
43fe83 |
@@ -1411,8 +1412,9 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm,
|
|
|
43fe83 |
if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
|
|
|
43fe83 |
goto error;
|
|
|
43fe83 |
|
|
|
43fe83 |
- if (virCgroupNewDetectMachine(vm->def->name, "lxc",
|
|
|
43fe83 |
- vm->pid, -1, &priv->cgroup) < 0)
|
|
|
43fe83 |
+ if (virCgroupNewDetectMachine(vm->def->name, "lxc", vm->pid,
|
|
|
43fe83 |
+ vm->def->resource->partition,
|
|
|
43fe83 |
+ -1, &priv->cgroup) < 0)
|
|
|
43fe83 |
goto error;
|
|
|
43fe83 |
|
|
|
43fe83 |
if (!priv->cgroup) {
|
|
|
43fe83 |
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
|
|
|
43fe83 |
index 9f6b251..787ddeb 100644
|
|
|
43fe83 |
--- a/src/qemu/qemu_cgroup.c
|
|
|
43fe83 |
+++ b/src/qemu/qemu_cgroup.c
|
|
|
43fe83 |
@@ -707,6 +707,7 @@ qemuConnectCgroup(virQEMUDriverPtr driver,
|
|
|
43fe83 |
if (virCgroupNewDetectMachine(vm->def->name,
|
|
|
43fe83 |
"qemu",
|
|
|
43fe83 |
vm->pid,
|
|
|
43fe83 |
+ vm->def->resource->partition,
|
|
|
43fe83 |
cfg->cgroupControllers,
|
|
|
43fe83 |
&priv->cgroup) < 0)
|
|
|
43fe83 |
goto cleanup;
|
|
|
43fe83 |
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
|
|
|
43fe83 |
index a70bb98..cfb4b3f 100644
|
|
|
43fe83 |
--- a/src/util/vircgroup.c
|
|
|
43fe83 |
+++ b/src/util/vircgroup.c
|
|
|
43fe83 |
@@ -50,6 +50,7 @@
|
|
|
43fe83 |
#include "virhash.h"
|
|
|
43fe83 |
#include "virhashcode.h"
|
|
|
43fe83 |
#include "virstring.h"
|
|
|
43fe83 |
+#include "virsystemd.h"
|
|
|
43fe83 |
|
|
|
43fe83 |
#define CGROUP_MAX_VAL 512
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -102,11 +103,13 @@ static bool
|
|
|
43fe83 |
virCgroupValidateMachineGroup(virCgroupPtr group,
|
|
|
43fe83 |
const char *name,
|
|
|
43fe83 |
const char *drivername,
|
|
|
43fe83 |
+ const char *partition,
|
|
|
43fe83 |
bool stripEmulatorSuffix)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
size_t i;
|
|
|
43fe83 |
bool valid = false;
|
|
|
43fe83 |
char *partname;
|
|
|
43fe83 |
+ char *scopename;
|
|
|
43fe83 |
|
|
|
43fe83 |
if (virAsprintf(&partname, "%s.libvirt-%s",
|
|
|
43fe83 |
name, drivername) < 0)
|
|
|
43fe83 |
@@ -115,6 +118,15 @@ virCgroupValidateMachineGroup(virCgroupPtr group,
|
|
|
43fe83 |
if (virCgroupPartitionEscape(&partname) < 0)
|
|
|
43fe83 |
goto cleanup;
|
|
|
43fe83 |
|
|
|
43fe83 |
+ if (!partition)
|
|
|
43fe83 |
+ partition = "/machine";
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (!(scopename = virSystemdMakeScopeName(name, drivername, partition)))
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (virCgroupPartitionEscape(&scopename) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
|
|
|
43fe83 |
char *tmp;
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -142,9 +154,10 @@ virCgroupValidateMachineGroup(virCgroupPtr group,
|
|
|
43fe83 |
tmp++;
|
|
|
43fe83 |
|
|
|
43fe83 |
if (STRNEQ(tmp, name) &&
|
|
|
43fe83 |
- STRNEQ(tmp, partname)) {
|
|
|
43fe83 |
- VIR_DEBUG("Name '%s' for controller '%s' does not match '%s' or '%s'",
|
|
|
43fe83 |
- tmp, virCgroupControllerTypeToString(i), name, partname);
|
|
|
43fe83 |
+ STRNEQ(tmp, partname) &&
|
|
|
43fe83 |
+ STRNEQ(tmp, scopename)) {
|
|
|
43fe83 |
+ VIR_DEBUG("Name '%s' for controller '%s' does not match '%s', '%s' or '%s'",
|
|
|
43fe83 |
+ tmp, virCgroupControllerTypeToString(i), name, partname, scopename);
|
|
|
43fe83 |
goto cleanup;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
}
|
|
|
43fe83 |
@@ -153,6 +166,7 @@ virCgroupValidateMachineGroup(virCgroupPtr group,
|
|
|
43fe83 |
|
|
|
43fe83 |
cleanup:
|
|
|
43fe83 |
VIR_FREE(partname);
|
|
|
43fe83 |
+ VIR_FREE(scopename);
|
|
|
43fe83 |
return valid;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
#else
|
|
|
43fe83 |
@@ -1649,6 +1663,7 @@ int virCgroupNewDetect(pid_t pid ATTRIBUTE_UNUSED,
|
|
|
43fe83 |
int virCgroupNewDetectMachine(const char *name,
|
|
|
43fe83 |
const char *drivername,
|
|
|
43fe83 |
pid_t pid,
|
|
|
43fe83 |
+ const char *partition,
|
|
|
43fe83 |
int controllers,
|
|
|
43fe83 |
virCgroupPtr *group)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
@@ -1658,7 +1673,7 @@ int virCgroupNewDetectMachine(const char *name,
|
|
|
43fe83 |
return -1;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
- if (!virCgroupValidateMachineGroup(*group, name, drivername, true)) {
|
|
|
43fe83 |
+ if (!virCgroupValidateMachineGroup(*group, name, drivername, partition, true)) {
|
|
|
43fe83 |
VIR_DEBUG("Failed to validate machine name for '%s' driver '%s'",
|
|
|
43fe83 |
name, drivername);
|
|
|
43fe83 |
virCgroupFree(group);
|
|
|
43fe83 |
@@ -1668,22 +1683,124 @@ int virCgroupNewDetectMachine(const char *name,
|
|
|
43fe83 |
return 0;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
-int virCgroupNewMachine(const char *name,
|
|
|
43fe83 |
- const char *drivername,
|
|
|
43fe83 |
- bool privileged ATTRIBUTE_UNUSED,
|
|
|
43fe83 |
- const unsigned char *uuid ATTRIBUTE_UNUSED,
|
|
|
43fe83 |
- const char *rootdir ATTRIBUTE_UNUSED,
|
|
|
43fe83 |
- pid_t pidleader ATTRIBUTE_UNUSED,
|
|
|
43fe83 |
- bool isContainer ATTRIBUTE_UNUSED,
|
|
|
43fe83 |
- const char *partition,
|
|
|
43fe83 |
- int controllers,
|
|
|
43fe83 |
- virCgroupPtr *group)
|
|
|
43fe83 |
+/*
|
|
|
43fe83 |
+ * Returns 0 on success, -1 on fatal error, -2 on systemd not available
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
+static int
|
|
|
43fe83 |
+virCgroupNewMachineSystemd(const char *name,
|
|
|
43fe83 |
+ const char *drivername,
|
|
|
43fe83 |
+ bool privileged,
|
|
|
43fe83 |
+ const unsigned char *uuid,
|
|
|
43fe83 |
+ const char *rootdir,
|
|
|
43fe83 |
+ pid_t pidleader,
|
|
|
43fe83 |
+ bool isContainer,
|
|
|
43fe83 |
+ const char *partition,
|
|
|
43fe83 |
+ int controllers,
|
|
|
43fe83 |
+ virCgroupPtr *group)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
- virCgroupPtr parent = NULL;
|
|
|
43fe83 |
int ret = -1;
|
|
|
43fe83 |
+ int rv;
|
|
|
43fe83 |
+ virCgroupPtr init, parent = NULL;
|
|
|
43fe83 |
+ char *path = NULL;
|
|
|
43fe83 |
+ char *offset;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ VIR_DEBUG("Trying to setup machine '%s' via systemd", name);
|
|
|
43fe83 |
+ if ((rv = virSystemdCreateMachine(name,
|
|
|
43fe83 |
+ drivername,
|
|
|
43fe83 |
+ privileged,
|
|
|
43fe83 |
+ uuid,
|
|
|
43fe83 |
+ rootdir,
|
|
|
43fe83 |
+ pidleader,
|
|
|
43fe83 |
+ isContainer,
|
|
|
43fe83 |
+ partition)) < 0)
|
|
|
43fe83 |
+ return rv;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (controllers != -1)
|
|
|
43fe83 |
+ controllers |= (1 << VIR_CGROUP_CONTROLLER_SYSTEMD);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ VIR_DEBUG("Detecting systemd placement");
|
|
|
43fe83 |
+ if (virCgroupNewDetect(pidleader,
|
|
|
43fe83 |
+ controllers,
|
|
|
43fe83 |
+ &init) < 0)
|
|
|
43fe83 |
+ return -1;
|
|
|
43fe83 |
|
|
|
43fe83 |
- *group = NULL;
|
|
|
43fe83 |
+ path = init->controllers[VIR_CGROUP_CONTROLLER_SYSTEMD].placement;
|
|
|
43fe83 |
+ init->controllers[VIR_CGROUP_CONTROLLER_SYSTEMD].placement = NULL;
|
|
|
43fe83 |
+ virCgroupFree(&init);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (!path || STREQ(path, "/") || path[0] != '/') {
|
|
|
43fe83 |
+ VIR_DEBUG("Systemd didn't setup its controller");
|
|
|
43fe83 |
+ ret = -2;
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ offset = path;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (virCgroupNew(pidleader,
|
|
|
43fe83 |
+ "",
|
|
|
43fe83 |
+ NULL,
|
|
|
43fe83 |
+ controllers,
|
|
|
43fe83 |
+ &parent) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ for (;;) {
|
|
|
43fe83 |
+ virCgroupPtr tmp;
|
|
|
43fe83 |
+ char *t = strchr(offset + 1, '/');
|
|
|
43fe83 |
+ if (t)
|
|
|
43fe83 |
+ *t = '\0';
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (virCgroupNew(pidleader,
|
|
|
43fe83 |
+ path,
|
|
|
43fe83 |
+ parent,
|
|
|
43fe83 |
+ controllers,
|
|
|
43fe83 |
+ &tmp) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (virCgroupMakeGroup(parent, tmp, true, VIR_CGROUP_NONE) < 0) {
|
|
|
43fe83 |
+ virCgroupFree(&tmp);
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ if (t) {
|
|
|
43fe83 |
+ *t = '/';
|
|
|
43fe83 |
+ offset = t;
|
|
|
43fe83 |
+ virCgroupFree(&parent);
|
|
|
43fe83 |
+ parent = tmp;
|
|
|
43fe83 |
+ } else {
|
|
|
43fe83 |
+ *group = tmp;
|
|
|
43fe83 |
+ break;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (virCgroupAddTask(*group, pidleader) < 0) {
|
|
|
43fe83 |
+ virErrorPtr saved = virSaveLastError();
|
|
|
43fe83 |
+ virCgroupRemove(*group);
|
|
|
43fe83 |
+ virCgroupFree(group);
|
|
|
43fe83 |
+ if (saved) {
|
|
|
43fe83 |
+ virSetError(saved);
|
|
|
43fe83 |
+ virFreeError(saved);
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ ret = 0;
|
|
|
43fe83 |
+ cleanup:
|
|
|
43fe83 |
+ virCgroupFree(&parent);
|
|
|
43fe83 |
+ VIR_FREE(path);
|
|
|
43fe83 |
+ return ret;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
|
|
|
43fe83 |
+static int
|
|
|
43fe83 |
+virCgroupNewMachineManual(const char *name,
|
|
|
43fe83 |
+ const char *drivername,
|
|
|
43fe83 |
+ pid_t pidleader,
|
|
|
43fe83 |
+ const char *partition,
|
|
|
43fe83 |
+ int controllers,
|
|
|
43fe83 |
+ virCgroupPtr *group)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ virCgroupPtr parent = NULL;
|
|
|
43fe83 |
+ int ret = -1;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ VIR_DEBUG("Fallback to non-systemd setup");
|
|
|
43fe83 |
if (virCgroupNewPartition(partition,
|
|
|
43fe83 |
STREQ(partition, "/machine"),
|
|
|
43fe83 |
controllers,
|
|
|
43fe83 |
@@ -1719,6 +1836,44 @@ cleanup:
|
|
|
43fe83 |
return ret;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
+int virCgroupNewMachine(const char *name,
|
|
|
43fe83 |
+ const char *drivername,
|
|
|
43fe83 |
+ bool privileged,
|
|
|
43fe83 |
+ const unsigned char *uuid,
|
|
|
43fe83 |
+ const char *rootdir,
|
|
|
43fe83 |
+ pid_t pidleader,
|
|
|
43fe83 |
+ bool isContainer,
|
|
|
43fe83 |
+ const char *partition,
|
|
|
43fe83 |
+ int controllers,
|
|
|
43fe83 |
+ virCgroupPtr *group)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ int rv;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ *group = NULL;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if ((rv = virCgroupNewMachineSystemd(name,
|
|
|
43fe83 |
+ drivername,
|
|
|
43fe83 |
+ privileged,
|
|
|
43fe83 |
+ uuid,
|
|
|
43fe83 |
+ rootdir,
|
|
|
43fe83 |
+ pidleader,
|
|
|
43fe83 |
+ isContainer,
|
|
|
43fe83 |
+ partition,
|
|
|
43fe83 |
+ controllers,
|
|
|
43fe83 |
+ group)) == 0)
|
|
|
43fe83 |
+ return 0;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (rv == -1)
|
|
|
43fe83 |
+ return -1;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ return virCgroupNewMachineManual(name,
|
|
|
43fe83 |
+ drivername,
|
|
|
43fe83 |
+ pidleader,
|
|
|
43fe83 |
+ partition,
|
|
|
43fe83 |
+ controllers,
|
|
|
43fe83 |
+ group);
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
bool virCgroupNewIgnoreError(void)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
if (virLastErrorIsSystemErrno(ENXIO) ||
|
|
|
43fe83 |
diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
|
|
|
43fe83 |
index e579f41..d7ce892 100644
|
|
|
43fe83 |
--- a/src/util/vircgroup.h
|
|
|
43fe83 |
+++ b/src/util/vircgroup.h
|
|
|
43fe83 |
@@ -83,6 +83,7 @@ int virCgroupNewDetect(pid_t pid,
|
|
|
43fe83 |
int virCgroupNewDetectMachine(const char *name,
|
|
|
43fe83 |
const char *drivername,
|
|
|
43fe83 |
pid_t pid,
|
|
|
43fe83 |
+ const char *partition,
|
|
|
43fe83 |
int controllers,
|
|
|
43fe83 |
virCgroupPtr *group);
|
|
|
43fe83 |
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.3.2
|
|
|
43fe83 |
|