From: "Daniel P. Berrange" <berrange(a)redhat.com>
Make the virCgroupNewMachine method try to use systemd-machined
first. If that fails, then fallback to using the traditional
cgroup setup code path.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/util/vircgroup.c | 115 ++++++++++++++++++++++++++++++++++++++++++++------
src/util/virsystemd.c | 8 +++-
2 files changed, 108 insertions(+), 15 deletions(-)
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 2141154..47d9763 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -50,6 +50,7 @@
#include "virhash.h"
#include "virhashcode.h"
#include "virstring.h"
+#include "virsystemd.h"
#define CGROUP_MAX_VAL 512
@@ -100,6 +101,7 @@ bool virCgroupIsValidMachineGroup(virCgroupPtr group,
size_t i;
bool valid = false;
char *partname;
+ char *scopename;
if (virAsprintf(&partname, "%s.libvirt-%s",
name, drivername) < 0)
@@ -108,6 +110,13 @@ bool virCgroupIsValidMachineGroup(virCgroupPtr group,
if (virCgroupPartitionEscape(&partname) < 0)
goto cleanup;
+ if (virAsprintf(&scopename, "machine-%s\\x2d%s.scope",
+ drivername, name) < 0)
+ goto cleanup;
+
+ if (virCgroupPartitionEscape(&scopename) < 0)
+ goto cleanup;
+
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
char *tmp;
@@ -120,7 +129,8 @@ bool virCgroupIsValidMachineGroup(virCgroupPtr group,
tmp++;
if (STRNEQ(tmp, name) &&
- STRNEQ(tmp, partname))
+ STRNEQ(tmp, partname) &&
+ STRNEQ(tmp, scopename))
goto cleanup;
}
@@ -129,6 +139,7 @@ bool virCgroupIsValidMachineGroup(virCgroupPtr group,
cleanup:
VIR_FREE(partname);
+ VIR_FREE(scopename);
return valid;
}
@@ -1573,22 +1584,63 @@ int virCgroupNewDetect(pid_t pid ATTRIBUTE_UNUSED,
}
#endif
-int virCgroupNewMachine(const char *name,
- const char *drivername,
- bool privileged ATTRIBUTE_UNUSED,
- const unsigned char *uuid ATTRIBUTE_UNUSED,
- const char *rootdir ATTRIBUTE_UNUSED,
- pid_t pidleader ATTRIBUTE_UNUSED,
- bool isContainer ATTRIBUTE_UNUSED,
- const char *partition,
- int controllers,
- virCgroupPtr *group)
+/*
+ * Retujrns 0 on success, -1 on fatal error, -2 on systemd not available
+ */
+static int
+virCgroupNewMachineSystemd(const char *name,
+ const char *drivername,
+ bool privileged,
+ const unsigned char *uuid,
+ const char *rootdir,
+ pid_t pidleader,
+ bool isContainer,
+ const char *partition,
+ virCgroupPtr *group)
+{
+ int rv;
+
+ VIR_DEBUG("Trying to setup machine '%s' via systemd", name);
+ if ((rv = virSystemdCreateMachine(name,
+ drivername,
+ privileged,
+ uuid,
+ rootdir,
+ pidleader,
+ isContainer,
+ partition)) < 0)
+ return rv;
+
+ VIR_DEBUG("Detecting systemd placement");
+ if (virCgroupNewDetect(pidleader,
+ group) < 0)
+ return -1;
+
+ if (!virCgroupIsValidMachineGroup(*group,
+ name,
+ drivername)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Cgroup name is not valid for machine %s"),
+ name);
+ virCgroupFree(group);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+virCgroupNewMachineManual(const char *name,
+ const char *drivername,
+ pid_t pidleader,
+ const char *partition,
+ int controllers,
+ virCgroupPtr *group)
{
virCgroupPtr parent = NULL;
int ret = -1;
- *group = NULL;
-
+ VIR_DEBUG("Fallback to non-systemd setup");
if (virCgroupNewPartition(partition,
STREQ(partition, "/machine"),
controllers,
@@ -1624,6 +1676,43 @@ cleanup:
return ret;
}
+int virCgroupNewMachine(const char *name,
+ const char *drivername,
+ bool privileged,
+ const unsigned char *uuid,
+ const char *rootdir,
+ pid_t pidleader,
+ bool isContainer,
+ const char *partition,
+ int controllers,
+ virCgroupPtr *group)
+{
+ int rv;
+
+ *group = NULL;
+
+ if ((rv = virCgroupNewMachineSystemd(name,
+ drivername,
+ privileged,
+ uuid,
+ rootdir,
+ pidleader,
+ isContainer,
+ partition,
+ group)) == 0)
+ return 0;
+
+ if (rv == -1)
+ return -1;
+
+ return virCgroupNewMachineManual(name,
+ drivername,
+ pidleader,
+ partition,
+ controllers,
+ group);
+}
+
bool virCgroupNewIgnoreError(void)
{
if (virLastErrorIsSystemErrno(ENXIO) ||
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
index 11d1153..dd44806 100644
--- a/src/util/virsystemd.c
+++ b/src/util/virsystemd.c
@@ -138,8 +138,12 @@ int virSystemdCreateMachine(const char *name,
iscontainer ? "container" : "vm",
(unsigned int)pidleader,
rootdir ? rootdir : "",
- 1, "Slice", "s",
- slicename) < 0) {
+ 4,
+ "Slice", "s", slicename,
+ "CPUAccounting", "b", 1,
+ "BlockIOAccounting", "b", 1,
+ "MemoryAccounting", "b", 1
+ ) < 0) {
virErrorPtr err = virGetLastError();
if (err->code == VIR_ERR_DBUS_SERVICE &&
STREQ(err->str2, "org.freedesktop.DBus.Error.ServiceUnknown"))
{
--
1.8.1.4