---
src/qemu/qemu_cgroup.c | 195 +++++++++++++++++++++++++++----------------------
1 file changed, 107 insertions(+), 88 deletions(-)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 2751be0..1e8afb1 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -521,6 +521,111 @@ qemuSetupMemoryCgroup(virDomainObjPtr vm) {
return 0;
}
+static int
+qemuSetupDevicesCgroup(virQEMUDriverPtr driver,
+ virDomainObjPtr vm)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ virQEMUDriverConfigPtr cfg = NULL;
+ const char *const *deviceACL = NULL;
+ int rc = -1;
+ int ret = -1;
+ int i;
+
+ if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
+ return 0;
+
+ rc = virCgroupDenyAllDevices(priv->cgroup);
+ virDomainAuditCgroup(vm, priv->cgroup, "deny", "all", rc ==
0);
+ if (rc != 0) {
+ if (rc == -EPERM) {
+ VIR_WARN("Group devices ACL is not accessible, disabling
whitelisting");
+ return 0;
+ }
+
+ virReportSystemError(-rc,
+ _("Unable to deny all devices for %s"),
vm->def->name);
+ goto cleanup;
+ }
+
+ for (i = 0; i < vm->def->ndisks ; i++) {
+ if (qemuSetupDiskCgroup(vm, vm->def->disks[i]) < 0)
+ goto cleanup;
+ }
+
+ rc = virCgroupAllowDeviceMajor(priv->cgroup, 'c', DEVICE_PTY_MAJOR,
+ VIR_CGROUP_DEVICE_RW);
+ virDomainAuditCgroupMajor(vm, priv->cgroup, "allow", DEVICE_PTY_MAJOR,
+ "pty", "rw", rc == 0);
+ if (rc != 0) {
+ virReportSystemError(-rc, "%s",
+ _("unable to allow /dev/pts/ devices"));
+ goto cleanup;
+ }
+
+ cfg = virQEMUDriverGetConfig(driver);
+ deviceACL = cfg->cgroupDeviceACL ?
+ (const char *const *)cfg->cgroupDeviceACL :
+ defaultDeviceACL;
+
+ if (vm->def->nsounds &&
+ (!vm->def->ngraphics ||
+ ((vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC
&&
+ cfg->vncAllowHostAudio) ||
+ (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL)))) {
+ rc = virCgroupAllowDeviceMajor(priv->cgroup, 'c', DEVICE_SND_MAJOR,
+ VIR_CGROUP_DEVICE_RW);
+ virDomainAuditCgroupMajor(vm, priv->cgroup, "allow",
DEVICE_SND_MAJOR,
+ "sound", "rw", rc == 0);
+ if (rc != 0) {
+ virReportSystemError(-rc, "%s",
+ _("unable to allow /dev/snd/ devices"));
+ goto cleanup;
+ }
+ }
+
+ for (i = 0; deviceACL[i] != NULL ; i++) {
+ if (access(deviceACL[i], F_OK) < 0) {
+ VIR_DEBUG("Ignoring non-existant device %s",
+ deviceACL[i]);
+ continue;
+ }
+
+ rc = virCgroupAllowDevicePath(priv->cgroup, deviceACL[i],
+ VIR_CGROUP_DEVICE_RW);
+ virDomainAuditCgroupPath(vm, priv->cgroup, "allow", deviceACL[i],
"rw", rc);
+ if (rc < 0 &&
+ rc != -ENOENT) {
+ virReportSystemError(-rc,
+ _("unable to allow device %s"),
+ deviceACL[i]);
+ goto cleanup;
+ }
+ }
+
+ if (virDomainChrDefForeach(vm->def,
+ true,
+ qemuSetupChardevCgroup,
+ vm) < 0)
+ goto cleanup;
+
+ if (vm->def->tpm &&
+ (qemuSetupTPMCgroup(vm->def,
+ vm->def->tpm,
+ vm) < 0))
+ goto cleanup;
+
+ for (i = 0; i < vm->def->nhostdevs; i++) {
+ if (qemuSetupHostdevCGroup(vm, vm->def->hostdevs[i]) < 0)
+ goto cleanup;
+ }
+
+ ret = 0;
+cleanup:
+ virObjectUnref(cfg);
+ return ret;
+}
+
int qemuInitCgroup(virQEMUDriverPtr driver,
virDomainObjPtr vm,
bool startup)
@@ -635,13 +740,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
virBitmapPtr nodemask)
{
int rc = -1;
- unsigned int i;
- virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
qemuDomainObjPrivatePtr priv = vm->privateData;
- const char *const *deviceACL =
- cfg->cgroupDeviceACL ?
- (const char *const *)cfg->cgroupDeviceACL :
- defaultDeviceACL;
if (qemuInitCgroup(driver, vm, true) < 0)
return -1;
@@ -649,87 +748,8 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
if (!priv->cgroup)
goto done;
- if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) {
- rc = virCgroupDenyAllDevices(priv->cgroup);
- virDomainAuditCgroup(vm, priv->cgroup, "deny", "all", rc
== 0);
- if (rc != 0) {
- if (rc == -EPERM) {
- VIR_WARN("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(vm, vm->def->disks[i]) < 0)
- goto cleanup;
- }
-
- rc = virCgroupAllowDeviceMajor(priv->cgroup, 'c', DEVICE_PTY_MAJOR,
- VIR_CGROUP_DEVICE_RW);
- virDomainAuditCgroupMajor(vm, priv->cgroup, "allow",
DEVICE_PTY_MAJOR,
- "pty", "rw", rc == 0);
- if (rc != 0) {
- virReportSystemError(-rc, "%s",
- _("unable to allow /dev/pts/ devices"));
- goto cleanup;
- }
-
- if (vm->def->nsounds &&
- (!vm->def->ngraphics ||
- ((vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC
&&
- cfg->vncAllowHostAudio) ||
- (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL)))) {
- rc = virCgroupAllowDeviceMajor(priv->cgroup, 'c',
DEVICE_SND_MAJOR,
- VIR_CGROUP_DEVICE_RW);
- virDomainAuditCgroupMajor(vm, priv->cgroup, "allow",
DEVICE_SND_MAJOR,
- "sound", "rw", rc == 0);
- if (rc != 0) {
- virReportSystemError(-rc, "%s",
- _("unable to allow /dev/snd/ devices"));
- goto cleanup;
- }
- }
-
- for (i = 0; deviceACL[i] != NULL ; i++) {
- if (access(deviceACL[i], F_OK) < 0) {
- VIR_DEBUG("Ignoring non-existant device %s",
- deviceACL[i]);
- continue;
- }
-
- rc = virCgroupAllowDevicePath(priv->cgroup, deviceACL[i],
- VIR_CGROUP_DEVICE_RW);
- virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
deviceACL[i], "rw", rc);
- if (rc < 0 &&
- rc != -ENOENT) {
- virReportSystemError(-rc,
- _("unable to allow device %s"),
- deviceACL[i]);
- goto cleanup;
- }
- }
-
- if (virDomainChrDefForeach(vm->def,
- true,
- qemuSetupChardevCgroup,
- vm) < 0)
- goto cleanup;
-
- if (vm->def->tpm &&
- (qemuSetupTPMCgroup(vm->def,
- vm->def->tpm,
- vm) < 0))
- goto cleanup;
-
- for (i = 0; i < vm->def->nhostdevs; i++) {
- if (qemuSetupHostdevCGroup(vm, vm->def->hostdevs[i]) < 0)
- goto cleanup;
- }
- }
+ if (qemuSetupDevicesCgroup(driver, vm) < 0)
+ goto cleanup;
if (qemuSetupBlkioCgroup(vm) < 0)
goto cleanup;
@@ -782,7 +802,6 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
done:
rc = 0;
cleanup:
- virObjectUnref(cfg);
return rc == 0 ? 0 : -1;
}
--
1.8.1.4