add nchannels to the struct and adapt the APIs slightly. Add a new API virQEMUSaveFdAddChannels to set the number of channels, which might not be known at Init time. Signed-off-by: Claudio Fontana <cfontana@xxxxxxx> --- src/qemu/qemu_driver.c | 10 +++++----- src/qemu/qemu_saveimage.c | 27 ++++++++++++++++++++++++--- src/qemu/qemu_saveimage.h | 6 +++++- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 986bbf9e58..d403ff6bf2 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5883,7 +5883,7 @@ qemuDomainRestoreInternal(virConnectPtr conn, } oflags |= O_DIRECT; } - if (virQEMUSaveFdInit(&saveFd, path, oflags, cfg) < 0) + if (virQEMUSaveFdInit(&saveFd, path, oflags, cfg, false) < 0) return -1; if (qemuSaveImageOpen(driver, NULL, &def, &data, false, &saveFd) < 0) goto cleanup; @@ -6017,7 +6017,7 @@ qemuDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *path, virCheckFlags(VIR_DOMAIN_SAVE_IMAGE_XML_SECURE, NULL); - if (virQEMUSaveFdInit(&saveFd, path, O_RDONLY, cfg) < 0) + if (virQEMUSaveFdInit(&saveFd, path, O_RDONLY, cfg, false) < 0) return NULL; if (qemuSaveImageOpen(driver, NULL, &def, &data, false, &saveFd) < 0) goto cleanup; @@ -6055,7 +6055,7 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path, else if (flags & VIR_DOMAIN_SAVE_PAUSED) state = 0; - if (virQEMUSaveFdInit(&saveFd, path, O_RDWR, cfg) < 0) + if (virQEMUSaveFdInit(&saveFd, path, O_RDWR, cfg, false) < 0) return -1; if (qemuSaveImageOpen(driver, NULL, &def, &data, false, &saveFd) < 0) goto cleanup; @@ -6136,7 +6136,7 @@ qemuDomainManagedSaveGetXMLDesc(virDomainPtr dom, unsigned int flags) goto cleanup; } - if (virQEMUSaveFdInit(&saveFd, path, O_RDONLY, cfg) < 0) + if (virQEMUSaveFdInit(&saveFd, path, O_RDONLY, cfg, false) < 0) goto cleanup; if (qemuSaveImageOpen(driver, priv->qemuCaps, &def, &data, false, &saveFd) < 0) @@ -6212,7 +6212,7 @@ qemuDomainObjRestore(virConnectPtr conn, } oflags |= O_DIRECT; } - if (virQEMUSaveFdInit(&saveFd, path, oflags, cfg) < 0) + if (virQEMUSaveFdInit(&saveFd, path, oflags, cfg, false) < 0) goto cleanup; ret = qemuSaveImageOpen(driver, NULL, &def, &data, true, &saveFd); if (ret < 0) { diff --git a/src/qemu/qemu_saveimage.c b/src/qemu/qemu_saveimage.c index 70ded3c439..6418114d8a 100644 --- a/src/qemu/qemu_saveimage.c +++ b/src/qemu/qemu_saveimage.c @@ -403,12 +403,13 @@ qemuSaveImageGetCompressionCommand(virQEMUSaveFormat compression) * @base: the file name * @oflags the file descriptor open flags * @cfg: the driver config + * @parallel: whether parallel save/restore is enabled * * Returns -1 on error, 0 on success, * and in both cases virQEMUSaveFdFini must be called to free resources. */ int virQEMUSaveFdInit(virQEMUSaveFd *saveFd, const char *base, - int oflags, virQEMUDriverConfig *cfg) + int oflags, virQEMUDriverConfig *cfg, bool parallel) { unsigned int wrapperFlags = VIR_FILE_WRAPPER_NON_BLOCKING; bool isCreat = oflags & O_CREAT; @@ -430,11 +431,14 @@ int virQEMUSaveFdInit(virQEMUSaveFd *saveFd, const char *base, } if (saveFd->fd < 0) return -1; + + saveFd->nchannels = 0; /* + * iohelper Wrapper is never required for multifd parallel save. * For O_CREAT, we always add the wrapper, * and for !O_CREAT, we only add the wrapper if using O_DIRECT. */ - if (isDirect || isCreat) { + if (!parallel && (isDirect || isCreat)) { saveFd->wrapper = virFileWrapperFdNew(&saveFd->fd, saveFd->path, wrapperFlags); if (!saveFd->wrapper) return -1; @@ -442,6 +446,23 @@ int virQEMUSaveFdInit(virQEMUSaveFd *saveFd, const char *base, return 0; } +/* + * virQEMUSaveFdAddChannels: add multifd channels to a virQEMUSaveFd + * + * @saveFd: the structure to add channels to. + * @nchannels:number of multifd channels, must be > 0. + * + * Returns -1 on error, 0 on success. + */ +int virQEMUSaveFdAddChannels(virQEMUSaveFd *saveFd, int nchannels) +{ + if (nchannels > 0) { + saveFd->nchannels = nchannels; + return 0; + } + return -1; +} + /* * virQEMUSaveFdClose: close a virQEMUSaveFd descriptor with normal close. * @@ -539,7 +560,7 @@ qemuSaveImageCreate(virQEMUDriver *driver, oflags |= O_DIRECT; } - if (virQEMUSaveFdInit(&saveFd, path, oflags, cfg) < 0) + if (virQEMUSaveFdInit(&saveFd, path, oflags, cfg, false) < 0) goto cleanup; if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, saveFd.fd) < 0) goto cleanup; diff --git a/src/qemu/qemu_saveimage.h b/src/qemu/qemu_saveimage.h index 9b04af2fb9..dcc9aa7d63 100644 --- a/src/qemu/qemu_saveimage.h +++ b/src/qemu/qemu_saveimage.h @@ -62,17 +62,21 @@ struct _virQEMUSaveFd { bool need_unlink; virFileWrapperFd *wrapper; virQEMUDriverConfig *cfg; + int nchannels; }; #define QEMU_SAVEFD_INVALID (virQEMUSaveFd) { \ .path = NULL, .fd = -1, .oflags = 0, \ .need_unlink = false, .wrapper = NULL, .cfg = NULL, \ + .nchannels = 0, \ } int virQEMUSaveFdInit(virQEMUSaveFd *saveFd, const char *base, - int oflags, virQEMUDriverConfig *cfg) + int oflags, virQEMUDriverConfig *cfg, bool parallel) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); +int virQEMUSaveFdAddChannels(virQEMUSaveFd *saveFd, int nchannels); + int virQEMUSaveFdClose(virQEMUSaveFd *saveFd, virDomainObj *vm); int virQEMUSaveFdFini(virQEMUSaveFd *saveFd, virDomainObj *vm, int ret); -- 2.26.2