[libvirt] [PATCH 13/13] Enable support for systemd-machined in cgroups creation

Daniel P. Berrange berrange at redhat.com
Tue Jul 23 15:21:18 UTC 2013


From: "Daniel P. Berrange" <berrange at 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 at 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




More information about the libvir-list mailing list