
On Wed, Apr 21, 2010 at 05:56:13PM +0100, Daniel P. Berrange wrote:
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; }
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/