Wire together the previous patches to support O_DIRECT via API request in qemu. * src/qemu/qemu_driver.c (qemuDomainSaveInternal, doCoreDump): Add parameter. (qemuDomainSaveFlags, qemuDomainManagedSave, qemudDomainCoreDump) (processWatchdogEvent): Update callers. --- src/qemu/qemu_driver.c | 53 ++++++++++++++++++++++++++++++++--------------- 1 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ceeef1c..7687e18 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -87,6 +87,7 @@ #include "configmake.h" #include "threadpool.h" #include "locking/lock_manager.h" +#include "virdirect.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -2110,7 +2111,7 @@ qemuCompressProgramName(int compress) static int qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, virDomainObjPtr vm, const char *path, - int compressed) + int compressed, bool direct) { char *xml = NULL; struct qemud_save_header header; @@ -2125,6 +2126,7 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, int fd = -1; uid_t uid = getuid(); gid_t gid = getgid(); + virDirectFdPtr directFd = NULL; memset(&header, 0, sizeof(header)); memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic)); @@ -2208,14 +2210,14 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, /* First try creating the file as root */ if (!is_reg) { - fd = open(path, O_WRONLY | O_TRUNC); + fd = open(path, O_WRONLY | O_TRUNC | (direct ? O_DIRECT : 0)); if (fd < 0) { virReportSystemError(errno, _("unable to open %s"), path); goto endjob; } } else { - if ((fd = virFileOpenAs(path, O_CREAT|O_TRUNC|O_WRONLY, - S_IRUSR|S_IWUSR, + int oflags = O_CREAT | O_TRUNC | O_WRONLY | (direct ? O_DIRECT : 0); + if ((fd = virFileOpenAs(path, oflags, S_IRUSR | S_IWUSR, uid, gid, 0)) < 0) { /* If we failed as root, and the error was permission-denied (EACCES or EPERM), assume it's on a network-connected share @@ -2261,7 +2263,7 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, /* Retry creating the file as driver->user */ - if ((fd = virFileOpenAs(path, O_CREAT|O_TRUNC|O_WRONLY, + if ((fd = virFileOpenAs(path, oflags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, driver->user, driver->group, VIR_FILE_OPEN_AS_UID)) < 0) { @@ -2279,6 +2281,9 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, } } + if (direct && (directFd = virDirectFdNew(&fd, path)) == NULL) + goto endjob; + /* Write header to file, followed by XML */ if (qemuDomainSaveHeader(fd, path, xml, &header) < 0) { VIR_FORCE_CLOSE(fd); @@ -2294,6 +2299,8 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, virReportSystemError(errno, _("unable to close %s"), path); goto endjob; } + if (virDirectFdClose(directFd) < 0) + goto endjob; ret = 0; @@ -2326,6 +2333,7 @@ endjob: cleanup: VIR_FORCE_CLOSE(fd); + virDirectFdFree(directFd); VIR_FREE(xml); if (ret != 0 && is_reg) unlink(path); @@ -2361,7 +2369,7 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml, int ret = -1; virDomainObjPtr vm = NULL; - virCheckFlags(0, -1); + virCheckFlags(VIR_DOMAIN_SAVE_DIRECT, -1); if (dxml) { qemuReportError(VIR_ERR_INVALID_ARG, "%s", _("xml modification unsupported")); @@ -2403,7 +2411,8 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml, goto cleanup; } - ret = qemuDomainSaveInternal(driver, dom, vm, path, compressed); + ret = qemuDomainSaveInternal(driver, dom, vm, path, compressed, + (flags & VIR_DOMAIN_SAVE_DIRECT) != 0); vm = NULL; cleanup: @@ -2441,7 +2450,7 @@ qemuDomainManagedSave(virDomainPtr dom, unsigned int flags) int ret = -1; int compressed; - virCheckFlags(0, -1); + virCheckFlags(VIR_DOMAIN_SAVE_DIRECT, -1); qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); @@ -2466,7 +2475,8 @@ qemuDomainManagedSave(virDomainPtr dom, unsigned int flags) VIR_INFO("Saving state to %s", name); compressed = QEMUD_SAVE_FORMAT_RAW; - ret = qemuDomainSaveInternal(driver, dom, vm, name, compressed); + ret = qemuDomainSaveInternal(driver, dom, vm, name, compressed, + (flags & VIR_DOMAIN_SAVE_DIRECT) != 0); vm = NULL; cleanup: @@ -2550,18 +2560,24 @@ static int doCoreDump(struct qemud_driver *driver, virDomainObjPtr vm, const char *path, - enum qemud_save_formats compress) + enum qemud_save_formats compress, + bool direct) { int fd = -1; int ret = -1; + virDirectFdPtr directFd = NULL; /* Create an empty file with appropriate ownership. */ - if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) { + if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY | (direct ? O_DIRECT : 0), + S_IRUSR|S_IWUSR)) < 0) { qemuReportError(VIR_ERR_OPERATION_FAILED, _("failed to create '%s'"), path); goto cleanup; } + if (direct && (directFd = virDirectFdNew(&fd, path)) == NULL) + goto cleanup; + if (qemuMigrationToFile(driver, vm, fd, 0, path, qemuCompressProgramName(compress), true, false) < 0) goto cleanup; @@ -2572,11 +2588,14 @@ doCoreDump(struct qemud_driver *driver, path); goto cleanup; } + if (virDirectFdClose(directFd) < 0) + goto cleanup; ret = 0; cleanup: VIR_FORCE_CLOSE(fd); + virDirectFdClose(directFd); if (ret != 0) unlink(path); return ret; @@ -2620,7 +2639,7 @@ static int qemudDomainCoreDump(virDomainPtr dom, int ret = -1; virDomainEventPtr event = NULL; - virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH, -1); + virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH | VIR_DUMP_DIRECT, -1); qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); @@ -2661,7 +2680,8 @@ static int qemudDomainCoreDump(virDomainPtr dom, } } - ret = doCoreDump(driver, vm, path, getCompressionType(driver)); + ret = doCoreDump(driver, vm, path, getCompressionType(driver), + (flags & VIR_DUMP_DIRECT) != 0); if (ret < 0) goto endjob; @@ -2832,10 +2852,9 @@ static void processWatchdogEvent(void *data, void *opaque) goto endjob; } - ret = doCoreDump(driver, - wdEvent->vm, - dumpfile, - getCompressionType(driver)); + /* XXX wire up qemu.conf to support whether to do direct dumps */ + ret = doCoreDump(driver, wdEvent->vm, dumpfile, + getCompressionType(driver), false); if (ret < 0) qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Dump failed")); -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list