mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
qemu: Fix reporting of physical capacity for block devices
Qemu reports physical size 0 for block devices. As 15fa84acbb
changed the behavior of qemuDomainGetBlockInfo to just query the monitor
this created a regression since we didn't report the size correctly any
more.
This patch adds code to refresh the physical size of a block device by
opening it and seeking to the end and uses it both in
qemuDomainGetBlockInfo and also in qemuDomainGetStatsOneBlock that was
broken since it was introduced in this respect.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1250982
This commit is contained in:
parent
e3810db34f
commit
8dc2725925
@ -2156,6 +2156,7 @@ virStorageSourceParseRBDColonString;
|
||||
virStorageSourcePoolDefFree;
|
||||
virStorageSourcePoolModeTypeFromString;
|
||||
virStorageSourcePoolModeTypeToString;
|
||||
virStorageSourceUpdateBlockPhysicalSize;
|
||||
virStorageTypeFromString;
|
||||
virStorageTypeToString;
|
||||
|
||||
|
@ -11827,8 +11827,16 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
|
||||
info->allocation = entry->wr_highest_offset;
|
||||
}
|
||||
|
||||
if (entry->physical) {
|
||||
info->physical = entry->physical;
|
||||
} else {
|
||||
if (virStorageSourceUpdateBlockPhysicalSize(disk->src, true) < 0)
|
||||
goto endjob;
|
||||
|
||||
info->physical = disk->src->physical;
|
||||
}
|
||||
|
||||
info->capacity = entry->capacity;
|
||||
info->physical = entry->physical;
|
||||
|
||||
ret = 0;
|
||||
|
||||
@ -19274,9 +19282,15 @@ qemuDomainGetStatsOneBlock(virQEMUDriverPtr driver,
|
||||
if (entry->capacity)
|
||||
QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, block_idx,
|
||||
"capacity", entry->capacity);
|
||||
if (entry->physical)
|
||||
if (entry->physical) {
|
||||
QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, block_idx,
|
||||
"physical", entry->physical);
|
||||
} else {
|
||||
if (virStorageSourceUpdateBlockPhysicalSize(src, false) == 0) {
|
||||
QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, block_idx,
|
||||
"physical", src->physical);
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
|
@ -2587,6 +2587,45 @@ virStorageSourceNewFromBacking(virStorageSourcePtr parent)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @src: disk source definiton structure
|
||||
* @report: report libvirt errors if set to true
|
||||
*
|
||||
* Updates src->physical for block devices since qemu doesn't report the current
|
||||
* size correctly for them. Returns 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
virStorageSourceUpdateBlockPhysicalSize(virStorageSourcePtr src,
|
||||
bool report)
|
||||
{
|
||||
int fd = -1;
|
||||
off_t end;
|
||||
int ret = -1;
|
||||
|
||||
if (virStorageSourceGetActualType(src) != VIR_STORAGE_TYPE_BLOCK)
|
||||
return 0;
|
||||
|
||||
if ((fd = open(src->path, O_RDONLY)) < 0) {
|
||||
if (report)
|
||||
virReportSystemError(errno, _("failed to open block device '%s'"),
|
||||
src->path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((end = lseek(fd, 0, SEEK_END)) == (off_t) -1) {
|
||||
if (report)
|
||||
virReportSystemError(errno,
|
||||
_("failed to seek to end of '%s'"), src->path);
|
||||
} else {
|
||||
src->physical = end;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
virStorageFileCanonicalizeFormatPath(char **components,
|
||||
size_t ncomponents,
|
||||
|
@ -362,6 +362,8 @@ bool virStorageSourceIsLocalStorage(virStorageSourcePtr src);
|
||||
bool virStorageSourceIsEmpty(virStorageSourcePtr src);
|
||||
void virStorageSourceFree(virStorageSourcePtr def);
|
||||
void virStorageSourceBackingStoreClear(virStorageSourcePtr def);
|
||||
int virStorageSourceUpdateBlockPhysicalSize(virStorageSourcePtr src,
|
||||
bool report);
|
||||
virStorageSourcePtr virStorageSourceNewFromBacking(virStorageSourcePtr parent);
|
||||
virStorageSourcePtr virStorageSourceCopy(const virStorageSource *src,
|
||||
bool backingChain)
|
||||
|
Loading…
Reference in New Issue
Block a user