This points out that core dumps (still) don't work for root-squash NFS, since the fd is not opened correctly. This patch should not introduce any functionality change, it is just a refactoring to avoid duplicated code. * src/qemu/qemu_driver.c (qemuDomainMigrateToFile): New function. (qemudDomainSaveFlag, doCoreDump): Use it. --- src/qemu/qemu_driver.c | 249 +++++++++++++++++++++--------------------------- 1 files changed, 110 insertions(+), 139 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 9de19ea..2422482 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1766,6 +1766,101 @@ endjob: return ret; } +/* Internal function called while driver lock is held and vm is active. */ +static int +qemuDomainMigrateToFile(struct qemud_driver *driver, virDomainObjPtr vm, + virBitmapPtr qemuCaps, + int fd, off_t offset, const char *path, + int compressed, + bool is_reg, bool bypassSecurityDriver) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + virCgroupPtr cgroup = NULL; + int ret = -1; + int rc; + + if (!is_reg && + 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"), + vm->def->name); + goto cleanup; + } + rc = virCgroupAllowDevicePath(cgroup, path, + VIR_CGROUP_DEVICE_RW); + qemuAuditCgroupPath(vm, cgroup, "allow", path, "rw", rc); + if (rc < 0) { + virReportSystemError(-rc, + _("Unable to allow device %s for %s"), + path, vm->def->name); + goto cleanup; + } + } + + if ((!bypassSecurityDriver) && + virSecurityManagerSetSavedStateLabel(driver->securityManager, + vm, path) < 0) + goto cleanup; + + if (compressed == QEMUD_SAVE_FORMAT_RAW) { + const char *args[] = { "cat", NULL }; + + qemuDomainObjEnterMonitorWithDriver(driver, vm); + if (qemuCaps && qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && + priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX) { + rc = qemuMonitorMigrateToFd(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, + fd); + } else { + rc = qemuMonitorMigrateToFile(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, + args, path, offset); + } + qemuDomainObjExitMonitorWithDriver(driver, vm); + } else { + const char *prog = qemudSaveCompressionTypeToString(compressed); + const char *args[] = { + prog, + "-c", + NULL + }; + qemuDomainObjEnterMonitorWithDriver(driver, vm); + rc = qemuMonitorMigrateToFile(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, + args, path, offset); + qemuDomainObjExitMonitorWithDriver(driver, vm); + } + + if (rc < 0) + goto cleanup; + + rc = qemuMigrationWaitForCompletion(driver, vm); + + if (rc < 0) + goto cleanup; + + ret = 0; + +cleanup: + if ((!bypassSecurityDriver) && + virSecurityManagerRestoreSavedStateLabel(driver->securityManager, + vm, path) < 0) + VIR_WARN("failed to restore save state label on %s", path); + + if (cgroup != NULL) { + rc = virCgroupDenyDevicePath(cgroup, path, + VIR_CGROUP_DEVICE_RWM); + qemuAuditCgroupPath(vm, cgroup, "deny", path, "rwm", rc); + if (rc < 0) + VIR_WARN("Unable to deny device %s for %s %d", + path, vm->def->name, rc); + virCgroupFree(&cgroup); + } + return ret; +} + /* This internal function expects the driver lock to already be held on * entry and the vm must be active. */ @@ -1775,15 +1870,14 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, { char *xml = NULL; struct qemud_save_header header; - int bypassSecurityDriver = 0; + bool bypassSecurityDriver = false; int ret = -1; int rc; virDomainEventPtr event = NULL; qemuDomainObjPrivatePtr priv; struct stat sb; - int is_reg = 0; + bool is_reg = false; unsigned long long offset; - virCgroupPtr cgroup = NULL; virBitmapPtr qemuCaps = NULL; int fd = -1; @@ -1838,9 +1932,9 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, * that with NFS we can't actually stat() the file. * The subsequent codepaths will still raise an error * if a truely fatal problem is hit */ - is_reg = 1; + is_reg = true; } else { - is_reg = S_ISREG(sb.st_mode); + is_reg = !!S_ISREG(sb.st_mode); } offset = sizeof(header) + header.xml_len; @@ -1935,7 +2029,7 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, is NFS, we assume it's a root-squashing NFS share, and that the security driver stuff would have failed anyway */ - bypassSecurityDriver = 1; + bypassSecurityDriver = true; } } @@ -1945,86 +2039,13 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, goto endjob; } - /* Allow qemu to access file */ - - if (!is_reg && - 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"), - vm->def->name); - goto endjob; - } - rc = virCgroupAllowDevicePath(cgroup, path, - VIR_CGROUP_DEVICE_RW); - qemuAuditCgroupPath(vm, cgroup, "allow", path, "rw", rc); - if (rc < 0) { - virReportSystemError(-rc, - _("Unable to allow device %s for %s"), - path, vm->def->name); - goto endjob; - } - } - - if ((!bypassSecurityDriver) && - virSecurityManagerSetSavedStateLabel(driver->securityManager, - vm, path) < 0) - goto endjob; - - if (header.compressed == QEMUD_SAVE_FORMAT_RAW) { - const char *args[] = { "cat", NULL }; - - qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && - priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX) { - rc = qemuMonitorMigrateToFd(priv->mon, - QEMU_MONITOR_MIGRATE_BACKGROUND, - fd); - } else { - rc = qemuMonitorMigrateToFile(priv->mon, - QEMU_MONITOR_MIGRATE_BACKGROUND, - args, path, offset); - } - qemuDomainObjExitMonitorWithDriver(driver, vm); - } else { - const char *prog = qemudSaveCompressionTypeToString(header.compressed); - const char *args[] = { - prog, - "-c", - NULL - }; - qemuDomainObjEnterMonitorWithDriver(driver, vm); - rc = qemuMonitorMigrateToFile(priv->mon, - QEMU_MONITOR_MIGRATE_BACKGROUND, - args, path, offset); - qemuDomainObjExitMonitorWithDriver(driver, vm); - } - - if (rc < 0) - goto endjob; - + /* Perform the migration */ + if (qemuDomainMigrateToFile(driver, vm, qemuCaps, fd, offset, path, + compressed, is_reg, bypassSecurityDriver) < 0) + goto cleanup; if (VIR_CLOSE(fd) < 0) { virReportSystemError(errno, _("unable to close %s"), path); - goto endjob; - } - - rc = qemuMigrationWaitForCompletion(driver, vm); - - if (rc < 0) - goto endjob; - - if ((!bypassSecurityDriver) && - virSecurityManagerRestoreSavedStateLabel(driver->securityManager, - vm, path) < 0) - VIR_WARN("failed to restore save state label on %s", path); - - if (cgroup != NULL) { - rc = virCgroupDenyDevicePath(cgroup, path, - VIR_CGROUP_DEVICE_RWM); - qemuAuditCgroupPath(vm, cgroup, "deny", path, "rwm", rc); - if (rc < 0) - VIR_WARN("Unable to deny device %s for %s %d", - path, vm->def->name, rc); + goto cleanup; } ret = 0; @@ -2050,22 +2071,7 @@ endjob: if (rc < 0) VIR_WARN0("Unable to resume guest CPUs after save failure"); } - - if (cgroup != NULL) { - rc = virCgroupDenyDevicePath(cgroup, path, - VIR_CGROUP_DEVICE_RWM); - qemuAuditCgroupPath(vm, cgroup, "deny", path, "rwm", rc); - if (rc < 0) - VIR_WARN("Unable to deny device %s for %s: %d", - path, vm->def->name, rc); - } - - if ((!bypassSecurityDriver) && - virSecurityManagerRestoreSavedStateLabel(driver->securityManager, - vm, path) < 0) - VIR_WARN("failed to restore save state label on %s", path); } - if (qemuDomainObjEndJob(vm) == 0) vm = NULL; } @@ -2078,7 +2084,6 @@ cleanup: unlink(path); if (event) qemuDomainEventQueue(driver, event); - virCgroupFree(&cgroup); return ret; } @@ -2282,9 +2287,6 @@ static int doCoreDump(struct qemud_driver *driver, { int fd = -1; int ret = -1; - qemuDomainObjPrivatePtr priv; - - priv = vm->privateData; /* Create an empty file with appropriate ownership. */ if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) { @@ -2293,6 +2295,10 @@ static int doCoreDump(struct qemud_driver *driver, goto cleanup; } + if (qemuDomainMigrateToFile(driver, vm, NULL, fd, 0, path, + compress, true, false) < 0) + goto cleanup; + if (VIR_CLOSE(fd) < 0) { virReportSystemError(errno, _("unable to save file %s"), @@ -2300,42 +2306,7 @@ static int doCoreDump(struct qemud_driver *driver, goto cleanup; } - if (virSecurityManagerSetSavedStateLabel(driver->securityManager, - vm, path) < 0) - goto cleanup; - - qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (compress == QEMUD_SAVE_FORMAT_RAW) { - const char *args[] = { - "cat", - NULL, - }; - ret = qemuMonitorMigrateToFile(priv->mon, - QEMU_MONITOR_MIGRATE_BACKGROUND, - args, path, 0); - } else { - const char *prog = qemudSaveCompressionTypeToString(compress); - const char *args[] = { - prog, - "-c", - NULL, - }; - ret = qemuMonitorMigrateToFile(priv->mon, - QEMU_MONITOR_MIGRATE_BACKGROUND, - args, path, 0); - } - qemuDomainObjExitMonitorWithDriver(driver, vm); - if (ret < 0) - goto cleanup; - - ret = qemuMigrationWaitForCompletion(driver, vm); - - if (ret < 0) - goto cleanup; - - if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager, - vm, path) < 0) - goto cleanup; + ret = 0; cleanup: if (ret != 0) -- 1.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list