Commit id '
ac9a0963' refactored out the 'withCapacity' for the
virStorageBackendUpdateVolInfo() API. See:
http://www.redhat.com/archives/libvir-list/2014-April/msg00043.html
This resulted in a difference in how 'virsh vol-info --pool <poolName>
<volume>' or 'virsh vol-list vol-list --pool <poolName> --details' outputs
the capacity information for a directory pool with a qcow2 sparse file.
For example, using the following XML
mkdir /home/TestPool
cat testpool.xml
<pool type='dir'>
<name>TestPool</name>
<uuid>
6bf80895-10b6-75a6-6059-
89fdea2aefb7</uuid>
<source>
</source>
<target>
<path>/home/TestPool</path>
<permissions>
<mode>0755</mode>
<owner>0</owner>
<group>0</group>
</permissions>
</target>
</pool>
virsh pool-create testpool.xml
virsh vol-create-as --pool TestPool temp_vol_1 \
--capacity
1048576 --allocation
1048576 --format qcow2
virsh vol-info --pool TestPool temp_vol_1
Results in listing a Capacity value. Prior to the commit, the value would
be '1.0 MiB' (
1048576 bytes). However, after the commit the output would be
(for example) '192.50 KiB', which for my system was the size of the volume
in my file system (eg 'ls -l TestPool/temp_vol_1' results in '197120' bytes
or 192.50 KiB). While perhaps technically correct, it's not necessarily
what the user expected (certainly virt-test didn't expect it).
This patch restores the code to not update the target capacity for this path
int
virStorageBackendUpdateVolTargetInfo(virStorageSourcePtr target,
+ bool updateCapacity,
bool withBlockVolFormat,
unsigned int openflags)
{
goto cleanup;
fd = ret;
- if ((ret = virStorageBackendUpdateVolTargetInfoFD(target, fd, &sb)) < 0)
+ if ((ret = virStorageBackendUpdateVolTargetInfoFD(target, fd, &sb,
+ updateCapacity)) < 0)
goto cleanup;
if (withBlockVolFormat) {
int
virStorageBackendUpdateVolInfo(virStorageVolDefPtr vol,
+ bool updateCapacity,
bool withBlockVolFormat,
unsigned int openflags)
{
int ret;
if ((ret = virStorageBackendUpdateVolTargetInfo(&vol->target,
+ updateCapacity,
withBlockVolFormat,
openflags)) < 0)
return ret;
if (vol->backingStore.path &&
(ret = virStorageBackendUpdateVolTargetInfo(&vol->backingStore,
+ updateCapacity,
withBlockVolFormat,
VIR_STORAGE_VOL_OPEN_DEFAULT)) < 0)
return ret;
* @target: target definition ptr of volume to update
* @fd: fd of storage volume to update, via virStorageBackendOpenVol*, or -1
* @sb: details about file (must match @fd, if that is provided)
- * @allocation: If not NULL, updated allocation information will be stored
- * @capacity: If not NULL, updated capacity info will be stored
+ * @updateCapacity: If true, updated capacity info will be stored
*
* Returns 0 for success, -1 on a legitimate error condition.
*/
int
virStorageBackendUpdateVolTargetInfoFD(virStorageSourcePtr target,
int fd,
- struct stat *sb)
+ struct stat *sb,
+ bool updateCapacity)
{
#if WITH_SELINUX
security_context_t filecon = NULL;
/* Regular files may be sparse, so logical size (capacity) is not same
* as actual allocation above
*/
- target->capacity = sb->st_size;
+ if (updateCapacity)
+ target->capacity = sb->st_size;
} else if (S_ISDIR(sb->st_mode)) {
target->allocation = 0;
- target->capacity = 0;
+ if (updateCapacity)
+ target->capacity = 0;
} else if (fd >= 0) {
off_t end;
/* XXX this is POSIX compliant, but doesn't work for CHAR files,
return -1;
}
target->allocation = end;
- target->capacity = end;
+ if (updateCapacity)
+ target->capacity = end;
}
if (!target->perms && VIR_ALLOC(target->perms) < 0)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int virStorageBackendUpdateVolInfo(virStorageVolDefPtr vol,
+ bool updateCapacity,
bool withBlockVolFormat,
unsigned int openflags);
int virStorageBackendUpdateVolTargetInfo(virStorageSourcePtr target,
+ bool updateCapacity,
bool withBlockVolFormat,
unsigned int openflags);
int virStorageBackendUpdateVolTargetInfoFD(virStorageSourcePtr target,
int fd,
- struct stat *sb);
+ struct stat *sb,
+ bool updateCapacity);
char *virStorageBackendStablePath(virStoragePoolObjPtr pool,
const char *devpath,
}
/* Refresh allocation/capacity/perms */
- if (virStorageBackendUpdateVolInfo(vol, false,
+ if (virStorageBackendUpdateVolInfo(vol, true, false,
VIR_STORAGE_VOL_OPEN_DEFAULT) < 0)
return -1;
goto error; /* Take care to propagate ret, it is not always -1 */
fd = ret;
- if ((ret = virStorageBackendUpdateVolTargetInfoFD(target, fd, &sb)) < 0) {
+ if ((ret = virStorageBackendUpdateVolTargetInfoFD(target, fd,
+ &sb, true)) < 0) {
goto error;
}
vol->backingStore.format = backingStoreFormat;
ignore_value(virStorageBackendUpdateVolTargetInfo(
- &vol->backingStore, false,
+ &vol->backingStore, true, false,
VIR_STORAGE_VOL_OPEN_DEFAULT));
/* If this failed, the backing file is currently unavailable,
* the capacity, allocation, owner, group and mode are unknown.
{
int ret;
- /* Refresh allocation / permissions info in case its changed */
- ret = virStorageBackendUpdateVolInfo(vol, false,
+ /* Refresh allocation / permissions info in case its changed
+ * don't update the capacity value for this pass
+ */
+ ret = virStorageBackendUpdateVolInfo(vol, false, false,
VIR_STORAGE_VOL_FS_OPEN_FLAGS);
if (ret < 0)
return ret;
if (VIR_ALLOC(vol) < 0)
goto cleanup;
- if (virStorageBackendUpdateVolTargetInfoFD(&vol->target, -1, st) < 0)
+ if (virStorageBackendUpdateVolTargetInfoFD(&vol->target, -1, st, true) < 0)
goto cleanup;
if (virStorageBackendGlusterSetMetadata(state, vol, name) < 0)
if (!vol->key && VIR_STRDUP(vol->key, groups[2]) < 0)
goto cleanup;
- if (virStorageBackendUpdateVolInfo(vol, false,
+ if (virStorageBackendUpdateVolInfo(vol, true, false,
VIR_STORAGE_VOL_OPEN_DEFAULT) < 0)
goto cleanup;
if (virAsprintf(&vol->target.path, "/dev/%s", dev) < 0)
goto cleanup;
- if (virStorageBackendUpdateVolInfo(vol, true,
+ if (virStorageBackendUpdateVolInfo(vol, true, true,
VIR_STORAGE_VOL_OPEN_DEFAULT) < 0) {
goto cleanup;
}
goto free_vol;
}
- if (virStorageBackendUpdateVolInfo(vol, true,
+ if (virStorageBackendUpdateVolInfo(vol, true, true,
VIR_STORAGE_VOL_OPEN_DEFAULT) < 0) {
retval = -1;
goto free_vol;