Instead of having duplicated code in qemuStorageLimitsRefresh and virStorageBackendUpdateVolTargetInfoFD to fill in the storage backing source or volume allocation, capacity, and physical values - create a common API that will handle the details for both. The common API will fill in "default" capacity values as well - although those more than likely will be overridden by subsequent code. Having just one place to make the determination of what the values should be will make things be more consistent. For the QEMU code - the data filled in will be for inactive domains for the GetBlockInfo and DomainGetStatsOneBlock API's. For the storage backend code - the data will be filled in during the volume updates. Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 31 ++------------------- src/storage/storage_backend.c | 33 ++--------------------- src/util/virstoragefile.c | 63 +++++++++++++++++++++++++++++++++++++++++++ src/util/virstoragefile.h | 3 +++ 5 files changed, 71 insertions(+), 60 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index eaaa088..7a78905 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2442,6 +2442,7 @@ virStorageSourceParseRBDColonString; virStorageSourcePoolDefFree; virStorageSourcePoolModeTypeFromString; virStorageSourcePoolModeTypeToString; +virStorageSourceUpdateBackingSizes; virStorageSourceUpdatePhysicalSize; virStorageTypeFromString; virStorageTypeToString; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6563a1e..3d20e30 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -11657,7 +11657,6 @@ qemuStorageLimitsRefresh(virQEMUDriverPtr driver, { int ret = -1; int fd = -1; - off_t end; virStorageSourcePtr meta = NULL; struct stat sb; int format; @@ -11679,34 +11678,8 @@ qemuStorageLimitsRefresh(virQEMUDriverPtr driver, goto cleanup; } - /* Get info for normal formats */ - if (S_ISREG(sb.st_mode) || fd == -1) { -#ifndef WIN32 - src->allocation = (unsigned long long)sb.st_blocks * - (unsigned long long)DEV_BSIZE; -#else - src->allocation = sb.st_size; -#endif - /* Allocation tracks when the file is sparse, physical is the - * last offset of the file. */ - src->physical = sb.st_size; - } else { - /* NB. Because we configure with AC_SYS_LARGEFILE, off_t - * should be 64 bits on all platforms. For block devices, we - * have to seek (safe even if someone else is writing) to - * determine physical size, and assume that allocation is the - * same as physical (but can refine that assumption later if - * qemu is still running). - */ - end = lseek(fd, 0, SEEK_END); - if (end == (off_t)-1) { - virReportSystemError(errno, - _("failed to seek to end of %s"), src->path); - goto cleanup; - } - src->physical = end; - src->allocation = end; - } + if (virStorageSourceUpdateBackingSizes(src, fd, &sb) < 0) + goto cleanup; /* Raw files: capacity is physical size. For all other files: if * the metadata has a capacity, use that, otherwise fall back to diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index d4334dc..0810ced 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -2004,37 +2004,8 @@ virStorageBackendUpdateVolTargetInfoFD(virStorageSourcePtr target, security_context_t filecon = NULL; #endif - if (S_ISREG(sb->st_mode)) { -#ifndef WIN32 - target->allocation = (unsigned long long)sb->st_blocks * - (unsigned long long)DEV_BSIZE; -#else - target->allocation = sb->st_size; -#endif - /* Regular files may be sparse, so logical size (capacity) is not same - * as actual allocation above - */ - target->capacity = sb->st_size; - } else if (S_ISDIR(sb->st_mode)) { - target->allocation = 0; - target->capacity = 0; - } else if (fd >= 0) { - off_t end; - /* XXX this is POSIX compliant, but doesn't work for CHAR files, - * only BLOCK. There is a Linux specific ioctl() for getting - * size of both CHAR / BLOCK devices we should check for in - * configure - */ - end = lseek(fd, 0, SEEK_END); - if (end == (off_t)-1) { - virReportSystemError(errno, - _("cannot seek to end of file '%s'"), - target->path); - return -1; - } - target->allocation = end; - target->capacity = end; - } + if (virStorageSourceUpdateBackingSizes(target, fd, sb) < 0) + return -1; if (!target->perms && VIR_ALLOC(target->perms) < 0) return -1; diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 809d825..ab0f9bd 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -3226,6 +3226,69 @@ virStorageSourceUpdatePhysicalSize(virStorageSourcePtr src, } +/** + * @src: disk source definition structure + * @fd: file descriptor + * @sb: stat buffer + * + * Update the capacity, allocation, physical values for the storage @src + * + * Returns 0 on success, -1 on error. + */ +int +virStorageSourceUpdateBackingSizes(virStorageSourcePtr src, + int fd, + struct stat const *sb) +{ + /* Get info for normal formats */ + if (S_ISREG(sb->st_mode) || fd == -1) { +#ifndef WIN32 + src->allocation = (unsigned long long)sb->st_blocks * + (unsigned long long)DEV_BSIZE; +#else + src->allocation = sb->st_size; +#endif + /* Regular files may be sparse, so logical size (capacity) is not same + * as actual allocation above + */ + src->capacity = sb->st_size; + + /* Allocation tracks when the file is sparse, physical is the + * last offset of the file. */ + src->physical = sb->st_size; + } else if (S_ISDIR(sb->st_mode)) { + src->allocation = 0; + src->capacity = 0; + src->physical = 0; + } else if (fd >= 0) { + off_t end; + + /* XXX this is POSIX compliant, but doesn't work for CHAR files, + * only BLOCK. There is a Linux specific ioctl() for getting + * size of both CHAR / BLOCK devices we should check for in + * configure + * + * NB. Because we configure with AC_SYS_LARGEFILE, off_t + * should be 64 bits on all platforms. For block devices, we + * have to seek (safe even if someone else is writing) to + * determine physical size, and assume that allocation is the + * same as physical (but can refine that assumption later if + * qemu is still running). + */ + if ((end = lseek(fd, 0, SEEK_END)) == (off_t)-1) { + virReportSystemError(errno, + _("failed to seek to end of %s"), src->path); + return -1; + } + src->physical = end; + src->allocation = end; + src->capacity = end; + } + + return 0; +} + + static char * virStorageFileCanonicalizeFormatPath(char **components, size_t ncomponents, diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index e38d01f..b91045b 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -359,6 +359,9 @@ void virStorageSourceFree(virStorageSourcePtr def); void virStorageSourceBackingStoreClear(virStorageSourcePtr def); int virStorageSourceUpdatePhysicalSize(virStorageSourcePtr src, int fd, struct stat const *sb); +int virStorageSourceUpdateBackingSizes(virStorageSourcePtr src, + int fd, struct stat const *sb); + virStorageSourcePtr virStorageSourceNewFromBacking(virStorageSourcePtr parent); virStorageSourcePtr virStorageSourceCopy(const virStorageSource *src, bool backingChain) -- 2.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list