[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 4/4] Fix QEMU domain save to block devices with cgroups enabled



When cgroups is enabled, access to block devices is likely to be
restricted to a whitelist. Prior to saving a guest to a block device,
it is neccessary to add the block device to the whitelist. THis is
not required upon restore, since QEMU reads from stdin

* src/qemu/qemu_driver.c: Add block device to cgroups whitelist
  if neccessary during dmoain save.
---
 src/qemu/qemu_driver.c |   39 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1f1e703..d5fc4d1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4790,6 +4790,7 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
     struct stat sb;
     int is_bdev = 0;
     unsigned long long offset;
+    virCgroupPtr cgroup = NULL;
 
     memset(&header, 0, sizeof(header));
     memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic));
@@ -4979,6 +4980,23 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
     }
 
 
+    if (is_bdev &&
+        qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
+        if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
+            qemuReportError(VIR_ERR_INTERNAL_ERROR,
+                            _("Unable to find cgroup for %s\n"),
+                            vm->def->name);
+            goto endjob;
+        }
+        rc = virCgroupAllowDevicePath(cgroup, path);
+        if (rc != 0) {
+            virReportSystemError(-rc,
+                                 _("Unable to allow device %s for %s"),
+                                 path, vm->def->name);
+            goto endjob;
+        }
+    }
+
     if ((!bypassSecurityDriver) &&
         driver->securityDriver &&
         driver->securityDriver->domainSetSavedStateLabel &&
@@ -5016,6 +5034,16 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
         driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1)
         goto endjob;
 
+    if (is_bdev && cgroup != NULL) {
+        rc = virCgroupDenyDevicePath(cgroup, path);
+        if (rc != 0) {
+            virReportSystemError(-rc,
+                                 _("Unable to deny device %s for %s"),
+                                 path, vm->def->name);
+            goto endjob;
+        }
+    }
+
     ret = 0;
 
     /* Shut it down */
@@ -5042,6 +5070,16 @@ endjob:
                 vm->state = VIR_DOMAIN_RUNNING;
         }
 
+        if (ret != 0 && is_bdev && cgroup != NULL) {
+            rc = virCgroupDenyDevicePath(cgroup, path);
+            if (rc != 0) {
+                virReportSystemError(-rc,
+                                     _("Unable to deny device %s for %s"),
+                                     path, vm->def->name);
+                goto endjob;
+            }
+        }
+
         if (qemuDomainObjEndJob(vm) == 0)
             vm = NULL;
     }
@@ -5054,6 +5092,7 @@ cleanup:
         virDomainObjUnlock(vm);
     if (event)
         qemuDomainEventQueue(driver, event);
+    virCgroupFree(&cgroup);
     qemuDriverUnlock(driver);
     return ret;
 }
-- 
1.6.5.2


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]