Split out the opening of the file and fetch of the stat buffer into a helper qemuDomainStorageOpenStat. This will handle either opening the local or remote storage. Additionally split out the cleanup of that into a separate helper qemuDomainStorageCloseStat which will either close the file or call the virStorageFileDeinit function. Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/qemu/qemu_driver.c | 93 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 21 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 653fe5d..6a312d2 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -11537,6 +11537,74 @@ qemuDomainMemoryPeek(virDomainPtr dom, * @cfg: driver configuration data * @vm: domain object * @src: storage source data + * @ret_fd: pointer to return open'd file descriptor + * @ret_sb: pointer to return stat buffer (local or remote) + * + * For local storage, open the file using qemuOpenFile and then use + * fstat() to grab the stat struct data for the caller. + * + * For remote storage, attempt to access the file and grab the stat + * struct data if the remote connection supports it. + * + * Returns 0 on success with @ret_fd and @ret_sb populated, -1 on failure + */ +static int +qemuDomainStorageOpenStat(virQEMUDriverPtr driver, + virQEMUDriverConfigPtr cfg, + virDomainObjPtr vm, + virStorageSourcePtr src, + int *ret_fd, + struct stat *ret_sb) +{ + if (virStorageSourceIsLocalStorage(src)) { + if ((*ret_fd = qemuOpenFile(driver, vm, src->path, O_RDONLY, + NULL, NULL)) == -1) + return -1; + + if (fstat(*ret_fd, ret_sb) < 0) { + virReportSystemError(errno, _("cannot stat file '%s'"), src->path); + VIR_FORCE_CLOSE(*ret_fd); + return -1; + } + } else { + if (virStorageFileInitAs(src, cfg->user, cfg->group) < 0) + return -1; + + if (virStorageFileStat(src, ret_sb) < 0) { + virStorageFileDeinit(src); + virReportSystemError(errno, _("failed to stat remote file '%s'"), + NULLSTR(src->path)); + return -1; + } + } + + return 0; +} + + +/** + * @src: storage source data + * @fd: file descriptor to close for local + * + * If local, then just close the file descriptor. + * else remote, then tear down the storage driver backend connection. + */ +static void +qemuDomainStorageCloseStat(virStorageSourcePtr src, + int *fd) +{ + if (virStorageSourceIsLocalStorage(src)) + VIR_FORCE_CLOSE(*fd); + else + virStorageFileDeinit(src); +} + + +/** + * @driver: qemu driver data + * @cfg: driver configuration data + * @vm: domain object + * @src: storage source data * * Refresh the capacity and allocation limits of a given storage source. * @@ -11575,35 +11643,19 @@ qemuStorageLimitsRefresh(virQEMUDriverPtr driver, char *buf = NULL; ssize_t len; - if (virStorageSourceIsLocalStorage(src)) { - if ((fd = qemuOpenFile(driver, vm, src->path, O_RDONLY, - NULL, NULL)) == -1) - goto cleanup; - - if (fstat(fd, &sb) < 0) { - virReportSystemError(errno, - _("cannot stat file '%s'"), src->path); - goto cleanup; - } + if (qemuDomainStorageOpenStat(driver, cfg, vm, src, &fd, &sb) < 0) + goto cleanup; + if (virStorageSourceIsLocalStorage(src)) { if ((len = virFileReadHeaderFD(fd, VIR_STORAGE_MAX_HEADER, &buf)) < 0) { virReportSystemError(errno, _("cannot read header '%s'"), src->path); goto cleanup; } } else { - if (virStorageFileInitAs(src, cfg->user, cfg->group) < 0) - goto cleanup; - if ((len = virStorageFileReadHeader(src, VIR_STORAGE_MAX_HEADER, &buf)) < 0) goto cleanup; - - if (virStorageFileStat(src, &sb) < 0) { - virReportSystemError(errno, _("failed to stat remote file '%s'"), - NULLSTR(src->path)); - goto cleanup; - } } /* Get info for normal formats */ @@ -11671,8 +11723,7 @@ qemuStorageLimitsRefresh(virQEMUDriverPtr driver, cleanup: VIR_FREE(buf); virStorageSourceFree(meta); - VIR_FORCE_CLOSE(fd); - virStorageFileDeinit(src); + qemuDomainStorageCloseStat(src, &fd); return ret; } -- 2.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list