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(a)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(a)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