[libvirt] [PATCH 06/10] Move QEMU cgroup helper code out of the QEMU driver

Daniel P. Berrange berrange at redhat.com
Thu Dec 16 16:50:06 UTC 2010


The QEMU driver file is far too large. Move all the cgroup
helper code out into a separate file. No functional change.

* src/qemu/qemu_cgroup.c, src/qemu/qemu_cgroup.h,
  src/Makefile.am: Add cgroup helper file
* src/qemu/qemu_driver.c: Delete cgroup code
---
 src/Makefile.am        |    1 +
 src/qemu/qemu_cgroup.c |  377 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_cgroup.h |   61 ++++++++
 src/qemu/qemu_driver.c |  343 +-------------------------------------------
 4 files changed, 440 insertions(+), 342 deletions(-)
 create mode 100644 src/qemu/qemu_cgroup.c
 create mode 100644 src/qemu/qemu_cgroup.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 381ca3d..da3bd6f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -271,6 +271,7 @@ QEMU_DRIVER_SOURCES =						\
 		qemu/qemu_command.c qemu/qemu_command.h		\
 		qemu/qemu_domain.c qemu/qemu_domain.h		\
 		qemu/qemu_audit.c qemu/qemu_audit.h		\
+		qemu/qemu_cgroup.c qemu/qemu_cgroup.c		\
 		qemu/qemu_conf.c qemu/qemu_conf.h		\
 		qemu/qemu_monitor.c qemu/qemu_monitor.h		\
 		qemu/qemu_monitor_text.c			\
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
new file mode 100644
index 0000000..0fd12ca
--- /dev/null
+++ b/src/qemu/qemu_cgroup.c
@@ -0,0 +1,377 @@
+/*
+ * qemu_cgroup.c: QEMU cgroup management
+ *
+ * Copyright (C) 2006-2007, 2009-2010 Red Hat, Inc.
+ * Copyright (C) 2006 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Daniel P. Berrange <berrange at redhat.com>
+ */
+
+#include <config.h>
+
+#include "qemu_cgroup.h"
+#include "cgroup.h"
+#include "logging.h"
+#include "memory.h"
+#include "virterror_internal.h"
+#include "util.h"
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+static const char *const defaultDeviceACL[] = {
+    "/dev/null", "/dev/full", "/dev/zero",
+    "/dev/random", "/dev/urandom",
+    "/dev/ptmx", "/dev/kvm", "/dev/kqemu",
+    "/dev/rtc", "/dev/hpet", "/dev/net/tun",
+    NULL,
+};
+#define DEVICE_PTY_MAJOR 136
+#define DEVICE_SND_MAJOR 116
+
+int qemuCgroupControllerActive(struct qemud_driver *driver,
+                               int controller)
+{
+    if (driver->cgroup == NULL)
+        return 0;
+    if (!virCgroupMounted(driver->cgroup, controller))
+        return 0;
+    if (driver->cgroupControllers & (1 << controller))
+        return 1;
+    return 0;
+}
+
+
+int qemuSetupDiskPathAllow(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+                           const char *path,
+                           size_t depth ATTRIBUTE_UNUSED,
+                           void *opaque)
+{
+    virCgroupPtr cgroup = opaque;
+    int rc;
+
+    VIR_DEBUG("Process path %s for disk", path);
+    /* XXX RO vs RW */
+    rc = virCgroupAllowDevicePath(cgroup, path);
+    if (rc != 0) {
+        /* Get this for non-block devices */
+        if (rc == -EINVAL) {
+            VIR_DEBUG("Ignoring EINVAL for %s", path);
+        } else if (rc == -EACCES) { /* Get this for root squash NFS */
+            VIR_DEBUG("Ignoring EACCES for %s", path);
+        } else {
+            virReportSystemError(-rc,
+                                 _("Unable to allow access for disk path %s"),
+                                 path);
+            return -1;
+        }
+    }
+    return 0;
+}
+
+
+int qemuSetupDiskCgroup(struct qemud_driver *driver,
+                        virCgroupPtr cgroup,
+                        virDomainDiskDefPtr disk)
+{
+    return virDomainDiskDefForeachPath(disk,
+                                       driver->allowDiskFormatProbing,
+                                       true,
+                                       qemuSetupDiskPathAllow,
+                                       cgroup);
+}
+
+
+int qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+                             const char *path,
+                             size_t depth ATTRIBUTE_UNUSED,
+                             void *opaque)
+{
+    virCgroupPtr cgroup = opaque;
+    int rc;
+
+    VIR_DEBUG("Process path %s for disk", path);
+    /* XXX RO vs RW */
+    rc = virCgroupDenyDevicePath(cgroup, path);
+    if (rc != 0) {
+        /* Get this for non-block devices */
+        if (rc == -EINVAL) {
+            VIR_DEBUG("Ignoring EINVAL for %s", path);
+        } else if (rc == -EACCES) { /* Get this for root squash NFS */
+            VIR_DEBUG("Ignoring EACCES for %s", path);
+        } else {
+            virReportSystemError(-rc,
+                                 _("Unable to deny access for disk path %s"),
+                                 path);
+            return -1;
+        }
+    }
+    return 0;
+}
+
+
+int qemuTeardownDiskCgroup(struct qemud_driver *driver,
+                           virCgroupPtr cgroup,
+                           virDomainDiskDefPtr disk)
+{
+    return virDomainDiskDefForeachPath(disk,
+                                       driver->allowDiskFormatProbing,
+                                       true,
+                                       qemuTeardownDiskPathDeny,
+                                       cgroup);
+}
+
+
+int qemuSetupChardevCgroup(virDomainDefPtr def,
+                           virDomainChrDefPtr dev,
+                           void *opaque)
+{
+    virCgroupPtr cgroup = opaque;
+    int rc;
+
+    if (dev->type != VIR_DOMAIN_CHR_TYPE_DEV)
+        return 0;
+
+
+    VIR_DEBUG("Process path '%s' for disk", dev->data.file.path);
+    rc = virCgroupAllowDevicePath(cgroup, dev->data.file.path);
+    if (rc != 0) {
+        virReportSystemError(-rc,
+                             _("Unable to allow device %s for %s"),
+                             dev->data.file.path, def->name);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+int qemuSetupHostUsbDeviceCgroup(usbDevice *dev ATTRIBUTE_UNUSED,
+                                 const char *path,
+                                 void *opaque)
+{
+    virCgroupPtr cgroup = opaque;
+    int rc;
+
+    VIR_DEBUG("Process path '%s' for USB device", path);
+    rc = virCgroupAllowDevicePath(cgroup, path);
+    if (rc != 0) {
+        virReportSystemError(-rc,
+                             _("Unable to allow device %s"),
+                             path);
+        return -1;
+    }
+
+    return 0;
+}
+
+int qemuSetupCgroup(struct qemud_driver *driver,
+                    virDomainObjPtr vm)
+{
+    virCgroupPtr cgroup = NULL;
+    int rc;
+    unsigned int i;
+    const char *const *deviceACL =
+        driver->cgroupDeviceACL ?
+        (const char *const *)driver->cgroupDeviceACL :
+        defaultDeviceACL;
+
+    if (driver->cgroup == NULL)
+        return 0; /* Not supported, so claim success */
+
+    rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 1);
+    if (rc != 0) {
+        virReportSystemError(-rc,
+                             _("Unable to create cgroup for %s"),
+                             vm->def->name);
+        goto cleanup;
+    }
+
+    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
+        rc = virCgroupDenyAllDevices(cgroup);
+        if (rc != 0) {
+            if (rc == -EPERM) {
+                VIR_WARN0("Group devices ACL is not accessible, disabling whitelisting");
+                goto done;
+            }
+
+            virReportSystemError(-rc,
+                                 _("Unable to deny all devices for %s"), vm->def->name);
+            goto cleanup;
+        }
+
+        for (i = 0; i < vm->def->ndisks ; i++) {
+            if (qemuSetupDiskCgroup(driver, cgroup, vm->def->disks[i]) < 0)
+                goto cleanup;
+        }
+
+        rc = virCgroupAllowDeviceMajor(cgroup, 'c', DEVICE_PTY_MAJOR);
+        if (rc != 0) {
+            virReportSystemError(-rc, "%s",
+                                 _("unable to allow /dev/pts/ devices"));
+            goto cleanup;
+        }
+
+        if (vm->def->nsounds) {
+            rc = virCgroupAllowDeviceMajor(cgroup, 'c', DEVICE_SND_MAJOR);
+            if (rc != 0) {
+                virReportSystemError(-rc, "%s",
+                                     _("unable to allow /dev/snd/ devices"));
+                goto cleanup;
+            }
+        }
+
+        for (i = 0; deviceACL[i] != NULL ; i++) {
+            rc = virCgroupAllowDevicePath(cgroup,
+                                          deviceACL[i]);
+            if (rc < 0 &&
+                rc != -ENOENT) {
+                virReportSystemError(-rc,
+                                     _("unable to allow device %s"),
+                                     deviceACL[i]);
+                goto cleanup;
+            }
+        }
+
+        if (virDomainChrDefForeach(vm->def,
+                                   true,
+                                   qemuSetupChardevCgroup,
+                                   cgroup) < 0)
+            goto cleanup;
+
+        for (i = 0; i < vm->def->nhostdevs; i++) {
+            virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
+            usbDevice *usb;
+
+            if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+                continue;
+            if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
+                continue;
+
+            if ((usb = usbGetDevice(hostdev->source.subsys.u.usb.bus,
+                                    hostdev->source.subsys.u.usb.device)) == NULL)
+                goto cleanup;
+
+            if (usbDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup, cgroup) < 0 )
+                goto cleanup;
+        }
+    }
+
+    if ((rc = qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY))) {
+        if (vm->def->mem.hard_limit != 0) {
+            rc = virCgroupSetMemoryHardLimit(cgroup, vm->def->mem.hard_limit);
+            if (rc != 0) {
+                virReportSystemError(-rc,
+                                     _("Unable to set memory hard limit for domain %s"),
+                                     vm->def->name);
+                goto cleanup;
+            }
+        }
+        if (vm->def->mem.soft_limit != 0) {
+            rc = virCgroupSetMemorySoftLimit(cgroup, vm->def->mem.soft_limit);
+            if (rc != 0) {
+                virReportSystemError(-rc,
+                                     _("Unable to set memory soft limit for domain %s"),
+                                     vm->def->name);
+                goto cleanup;
+            }
+        }
+
+        if (vm->def->mem.swap_hard_limit != 0) {
+            rc = virCgroupSetSwapHardLimit(cgroup, vm->def->mem.swap_hard_limit);
+            if (rc != 0) {
+                virReportSystemError(-rc,
+                                     _("Unable to set swap hard limit for domain %s"),
+                                     vm->def->name);
+                goto cleanup;
+            }
+        }
+    } else {
+        VIR_WARN("Memory cgroup is disabled in qemu configuration file: %s",
+                 vm->def->name);
+    }
+
+done:
+    virCgroupFree(&cgroup);
+    return 0;
+
+cleanup:
+    if (cgroup) {
+        virCgroupRemove(cgroup);
+        virCgroupFree(&cgroup);
+    }
+    return -1;
+}
+
+
+int qemuRemoveCgroup(struct qemud_driver *driver,
+                     virDomainObjPtr vm,
+                     int quiet)
+{
+    virCgroupPtr cgroup;
+    int rc;
+
+    if (driver->cgroup == NULL)
+        return 0; /* Not supported, so claim success */
+
+    rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0);
+    if (rc != 0) {
+        if (!quiet)
+            qemuReportError(VIR_ERR_INTERNAL_ERROR,
+                            _("Unable to find cgroup for %s\n"),
+                            vm->def->name);
+        return rc;
+    }
+
+    rc = virCgroupRemove(cgroup);
+    virCgroupFree(&cgroup);
+    return rc;
+}
+
+int qemuAddToCgroup(struct qemud_driver *driver,
+                    virDomainDefPtr def)
+{
+    virCgroupPtr cgroup = NULL;
+    int ret = -1;
+    int rc;
+
+    if (driver->cgroup == NULL)
+        return 0; /* Not supported, so claim success */
+
+    rc = virCgroupForDomain(driver->cgroup, def->name, &cgroup, 0);
+    if (rc != 0) {
+        virReportSystemError(-rc,
+                             _("unable to find cgroup for domain %s"),
+                             def->name);
+        goto cleanup;
+    }
+
+    rc = virCgroupAddTask(cgroup, getpid());
+    if (rc != 0) {
+        virReportSystemError(-rc,
+                             _("unable to add domain %s task %d to cgroup"),
+                             def->name, getpid());
+        goto cleanup;
+    }
+
+    ret = 0;
+
+cleanup:
+    virCgroupFree(&cgroup);
+    return ret;
+}
+
+
diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
new file mode 100644
index 0000000..193778a
--- /dev/null
+++ b/src/qemu/qemu_cgroup.h
@@ -0,0 +1,61 @@
+/*
+ * qemu_cgroup.h: QEMU cgroup management
+ *
+ * Copyright (C) 2006-2007, 2009-2010 Red Hat, Inc.
+ * Copyright (C) 2006 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Daniel P. Berrange <berrange at redhat.com>
+ */
+
+#ifndef __QEMU_CGROUP_H__
+# define __QEMU_CGROUP_H__
+
+#include "hostusb.h"
+#include "domain_conf.h"
+#include "qemu_conf.h"
+
+int qemuCgroupControllerActive(struct qemud_driver *driver,
+                               int controller);
+int qemuSetupDiskPathAllow(virDomainDiskDefPtr disk,
+                           const char *path,
+                           size_t depth,
+                           void *opaque);
+int qemuSetupDiskCgroup(struct qemud_driver *driver,
+                        virCgroupPtr cgroup,
+                        virDomainDiskDefPtr disk);
+int qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk,
+                             const char *path,
+                             size_t depth,
+                             void *opaque);
+int qemuTeardownDiskCgroup(struct qemud_driver *driver,
+                           virCgroupPtr cgroup,
+                           virDomainDiskDefPtr disk);
+int qemuSetupChardevCgroup(virDomainDefPtr def,
+                           virDomainChrDefPtr dev,
+                           void *opaque);
+int qemuSetupHostUsbDeviceCgroup(usbDevice *dev,
+                                 const char *path,
+                                 void *opaque);
+int qemuSetupCgroup(struct qemud_driver *driver,
+                    virDomainObjPtr vm);
+int qemuRemoveCgroup(struct qemud_driver *driver,
+                     virDomainObjPtr vm,
+                     int quiet);
+int qemuAddToCgroup(struct qemud_driver *driver,
+                    virDomainDefPtr def);
+
+#endif /* __QEMU_CGROUP_H__ */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c4afe20..585b259 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -55,6 +55,7 @@
 #include "qemu_conf.h"
 #include "qemu_capabilities.h"
 #include "qemu_command.h"
+#include "qemu_cgroup.h"
 #include "qemu_monitor.h"
 #include "qemu_bridge_filter.h"
 #include "qemu_audit.h"
@@ -74,7 +75,6 @@
 #include "processinfo.h"
 #include "qemu_security_stacked.h"
 #include "qemu_security_dac.h"
-#include "cgroup.h"
 #include "libvirt_internal.h"
 #include "xml.h"
 #include "cpu/cpu.h"
@@ -410,17 +410,6 @@ static int doStopCPUs(struct qemud_driver *driver, virDomainObjPtr vm)
     return ret;
 }
 
-static int qemuCgroupControllerActive(struct qemud_driver *driver,
-                                      int controller)
-{
-    if (driver->cgroup == NULL)
-        return 0;
-    if (!virCgroupMounted(driver->cgroup, controller))
-        return 0;
-    if (driver->cgroupControllers & (1 << controller))
-        return 1;
-    return 0;
-}
 
 static int
 qemudLogFD(struct qemud_driver *driver, const char* name, bool append)
@@ -3050,336 +3039,6 @@ qemuDomainReAttachHostDevices(struct qemud_driver *driver,
     qemuDomainReAttachHostdevDevices(driver, def->hostdevs, def->nhostdevs);
 }
 
-static const char *const defaultDeviceACL[] = {
-    "/dev/null", "/dev/full", "/dev/zero",
-    "/dev/random", "/dev/urandom",
-    "/dev/ptmx", "/dev/kvm", "/dev/kqemu",
-    "/dev/rtc", "/dev/hpet", "/dev/net/tun",
-    NULL,
-};
-#define DEVICE_PTY_MAJOR 136
-#define DEVICE_SND_MAJOR 116
-
-
-static int qemuSetupDiskPathAllow(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
-                                  const char *path,
-                                  size_t depth ATTRIBUTE_UNUSED,
-                                  void *opaque)
-{
-    virCgroupPtr cgroup = opaque;
-    int rc;
-
-    VIR_DEBUG("Process path %s for disk", path);
-    /* XXX RO vs RW */
-    rc = virCgroupAllowDevicePath(cgroup, path);
-    if (rc != 0) {
-        /* Get this for non-block devices */
-        if (rc == -EINVAL) {
-            VIR_DEBUG("Ignoring EINVAL for %s", path);
-        } else if (rc == -EACCES) { /* Get this for root squash NFS */
-            VIR_DEBUG("Ignoring EACCES for %s", path);
-        } else {
-            virReportSystemError(-rc,
-                                 _("Unable to allow access for disk path %s"),
-                                 path);
-            return -1;
-        }
-    }
-    return 0;
-}
-
-
-static int qemuSetupDiskCgroup(struct qemud_driver *driver,
-                               virCgroupPtr cgroup,
-                               virDomainDiskDefPtr disk)
-{
-    return virDomainDiskDefForeachPath(disk,
-                                       driver->allowDiskFormatProbing,
-                                       true,
-                                       qemuSetupDiskPathAllow,
-                                       cgroup);
-}
-
-
-static int qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
-                                    const char *path,
-                                    size_t depth ATTRIBUTE_UNUSED,
-                                    void *opaque)
-{
-    virCgroupPtr cgroup = opaque;
-    int rc;
-
-    VIR_DEBUG("Process path %s for disk", path);
-    /* XXX RO vs RW */
-    rc = virCgroupDenyDevicePath(cgroup, path);
-    if (rc != 0) {
-        /* Get this for non-block devices */
-        if (rc == -EINVAL) {
-            VIR_DEBUG("Ignoring EINVAL for %s", path);
-        } else if (rc == -EACCES) { /* Get this for root squash NFS */
-            VIR_DEBUG("Ignoring EACCES for %s", path);
-        } else {
-            virReportSystemError(-rc,
-                                 _("Unable to deny access for disk path %s"),
-                                 path);
-            return -1;
-        }
-    }
-    return 0;
-}
-
-
-static int qemuTeardownDiskCgroup(struct qemud_driver *driver,
-                                  virCgroupPtr cgroup,
-                                  virDomainDiskDefPtr disk)
-{
-    return virDomainDiskDefForeachPath(disk,
-                                       driver->allowDiskFormatProbing,
-                                       true,
-                                       qemuTeardownDiskPathDeny,
-                                       cgroup);
-}
-
-
-static int qemuSetupChardevCgroup(virDomainDefPtr def,
-                                  virDomainChrDefPtr dev,
-                                  void *opaque)
-{
-    virCgroupPtr cgroup = opaque;
-    int rc;
-
-    if (dev->type != VIR_DOMAIN_CHR_TYPE_DEV)
-        return 0;
-
-
-    VIR_DEBUG("Process path '%s' for disk", dev->data.file.path);
-    rc = virCgroupAllowDevicePath(cgroup, dev->data.file.path);
-    if (rc != 0) {
-        virReportSystemError(-rc,
-                             _("Unable to allow device %s for %s"),
-                             dev->data.file.path, def->name);
-        return -1;
-    }
-
-    return 0;
-}
-
-
-static int qemuSetupHostUsbDeviceCgroup(usbDevice *dev ATTRIBUTE_UNUSED,
-                                        const char *path,
-                                        void *opaque)
-{
-    virCgroupPtr cgroup = opaque;
-    int rc;
-
-    VIR_DEBUG("Process path '%s' for USB device", path);
-    rc = virCgroupAllowDevicePath(cgroup, path);
-    if (rc != 0) {
-        virReportSystemError(-rc,
-                             _("Unable to allow device %s"),
-                             path);
-        return -1;
-    }
-
-    return 0;
-}
-
-static int qemuSetupCgroup(struct qemud_driver *driver,
-                           virDomainObjPtr vm)
-{
-    virCgroupPtr cgroup = NULL;
-    int rc;
-    unsigned int i;
-    const char *const *deviceACL =
-        driver->cgroupDeviceACL ?
-        (const char *const *)driver->cgroupDeviceACL :
-        defaultDeviceACL;
-
-    if (driver->cgroup == NULL)
-        return 0; /* Not supported, so claim success */
-
-    rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 1);
-    if (rc != 0) {
-        virReportSystemError(-rc,
-                             _("Unable to create cgroup for %s"),
-                             vm->def->name);
-        goto cleanup;
-    }
-
-    if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
-        rc = virCgroupDenyAllDevices(cgroup);
-        if (rc != 0) {
-            if (rc == -EPERM) {
-                VIR_WARN0("Group devices ACL is not accessible, disabling whitelisting");
-                goto done;
-            }
-
-            virReportSystemError(-rc,
-                                 _("Unable to deny all devices for %s"), vm->def->name);
-            goto cleanup;
-        }
-
-        for (i = 0; i < vm->def->ndisks ; i++) {
-            if (qemuSetupDiskCgroup(driver, cgroup, vm->def->disks[i]) < 0)
-                goto cleanup;
-        }
-
-        rc = virCgroupAllowDeviceMajor(cgroup, 'c', DEVICE_PTY_MAJOR);
-        if (rc != 0) {
-            virReportSystemError(-rc, "%s",
-                                 _("unable to allow /dev/pts/ devices"));
-            goto cleanup;
-        }
-
-        if (vm->def->nsounds) {
-            rc = virCgroupAllowDeviceMajor(cgroup, 'c', DEVICE_SND_MAJOR);
-            if (rc != 0) {
-                virReportSystemError(-rc, "%s",
-                                     _("unable to allow /dev/snd/ devices"));
-                goto cleanup;
-            }
-        }
-
-        for (i = 0; deviceACL[i] != NULL ; i++) {
-            rc = virCgroupAllowDevicePath(cgroup,
-                                          deviceACL[i]);
-            if (rc < 0 &&
-                rc != -ENOENT) {
-                virReportSystemError(-rc,
-                                     _("unable to allow device %s"),
-                                     deviceACL[i]);
-                goto cleanup;
-            }
-        }
-
-        if (virDomainChrDefForeach(vm->def,
-                                   true,
-                                   qemuSetupChardevCgroup,
-                                   cgroup) < 0)
-            goto cleanup;
-
-        for (i = 0; i < vm->def->nhostdevs; i++) {
-            virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
-            usbDevice *usb;
-
-            if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-                continue;
-            if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
-                continue;
-
-            if ((usb = usbGetDevice(hostdev->source.subsys.u.usb.bus,
-                                    hostdev->source.subsys.u.usb.device)) == NULL)
-                goto cleanup;
-
-            if (usbDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup, cgroup) < 0 )
-                goto cleanup;
-        }
-    }
-
-    if ((rc = qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY))) {
-        if (vm->def->mem.hard_limit != 0) {
-            rc = virCgroupSetMemoryHardLimit(cgroup, vm->def->mem.hard_limit);
-            if (rc != 0) {
-                virReportSystemError(-rc,
-                                     _("Unable to set memory hard limit for domain %s"),
-                                     vm->def->name);
-                goto cleanup;
-            }
-        }
-        if (vm->def->mem.soft_limit != 0) {
-            rc = virCgroupSetMemorySoftLimit(cgroup, vm->def->mem.soft_limit);
-            if (rc != 0) {
-                virReportSystemError(-rc,
-                                     _("Unable to set memory soft limit for domain %s"),
-                                     vm->def->name);
-                goto cleanup;
-            }
-        }
-
-        if (vm->def->mem.swap_hard_limit != 0) {
-            rc = virCgroupSetSwapHardLimit(cgroup, vm->def->mem.swap_hard_limit);
-            if (rc != 0) {
-                virReportSystemError(-rc,
-                                     _("Unable to set swap hard limit for domain %s"),
-                                     vm->def->name);
-                goto cleanup;
-            }
-        }
-    } else {
-        VIR_WARN("Memory cgroup is disabled in qemu configuration file: %s",
-                 vm->def->name);
-    }
-
-done:
-    virCgroupFree(&cgroup);
-    return 0;
-
-cleanup:
-    if (cgroup) {
-        virCgroupRemove(cgroup);
-        virCgroupFree(&cgroup);
-    }
-    return -1;
-}
-
-
-static int qemuRemoveCgroup(struct qemud_driver *driver,
-                            virDomainObjPtr vm,
-                            int quiet)
-{
-    virCgroupPtr cgroup;
-    int rc;
-
-    if (driver->cgroup == NULL)
-        return 0; /* Not supported, so claim success */
-
-    rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0);
-    if (rc != 0) {
-        if (!quiet)
-            qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                            _("Unable to find cgroup for %s\n"),
-                            vm->def->name);
-        return rc;
-    }
-
-    rc = virCgroupRemove(cgroup);
-    virCgroupFree(&cgroup);
-    return rc;
-}
-
-static int qemuAddToCgroup(struct qemud_driver *driver,
-                           virDomainDefPtr def)
-{
-    virCgroupPtr cgroup = NULL;
-    int ret = -1;
-    int rc;
-
-    if (driver->cgroup == NULL)
-        return 0; /* Not supported, so claim success */
-
-    rc = virCgroupForDomain(driver->cgroup, def->name, &cgroup, 0);
-    if (rc != 0) {
-        virReportSystemError(-rc,
-                             _("unable to find cgroup for domain %s"),
-                             def->name);
-        goto cleanup;
-    }
-
-    rc = virCgroupAddTask(cgroup, getpid());
-    if (rc != 0) {
-        virReportSystemError(-rc,
-                             _("unable to add domain %s task %d to cgroup"),
-                             def->name, getpid());
-        goto cleanup;
-    }
-
-    ret = 0;
-
-cleanup:
-    virCgroupFree(&cgroup);
-    return ret;
-}
-
 
 struct qemudHookData {
     virConnectPtr conn;
-- 
1.7.2.3




More information about the libvir-list mailing list