fixed handling of sourceless disks in 'domblkinfo' cmd

virDomainGetBlockInfo() returns error if called on a disk with no
source (a sourceless disk might be a removable media drive with no
media in it, for instance an empty CDROM or floppy drive).

So far this caused the virsh domblkinfo --all command to abort and
ignore any remaining (not yet displayed) disk devices.  This patch
fixes the problem by first checking for existence of a <source>
element in the corresponding XML.  If none is found, we avoid calling
virDomainGetBlockInfo() altogether as we know it's bound to fail in
that case.

https://bugzilla.redhat.com/show_bug.cgi?id=1619625

Signed-off-by: Pavel Mores <pmores@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Pavel Mores 2019-10-04 13:35:09 +02:00 committed by Ján Tomko
parent 2de75faa28
commit 5be0d28b3e
1 changed files with 19 additions and 12 deletions

View File

@ -507,20 +507,27 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
protocol = virXPathString("string(./source/@protocol)", ctxt);
target = virXPathString("string(./target/@dev)", ctxt);
rc = virDomainGetBlockInfo(dom, target, &info, 0);
if (virXPathBoolean("boolean(./source)", ctxt) == 1) {
if (rc < 0) {
/* If protocol is present that's an indication of a networked
* storage device which cannot provide statistics, so generate
* 0 based data and get the next disk. */
if (protocol && !active &&
virGetLastErrorCode() == VIR_ERR_INTERNAL_ERROR &&
virGetLastErrorDomain() == VIR_FROM_STORAGE) {
memset(&info, 0, sizeof(info));
vshResetLibvirtError();
} else {
goto cleanup;
rc = virDomainGetBlockInfo(dom, target, &info, 0);
if (rc < 0) {
/* If protocol is present that's an indication of a
* networked storage device which cannot provide statistics,
* so generate 0 based data and get the next disk. */
if (protocol && !active &&
virGetLastErrorCode() == VIR_ERR_INTERNAL_ERROR &&
virGetLastErrorDomain() == VIR_FROM_STORAGE) {
memset(&info, 0, sizeof(info));
vshResetLibvirtError();
} else {
goto cleanup;
}
}
} else {
/* if we don't call virDomainGetBlockInfo() who clears 'info'
* we have to do it manually */
memset(&info, 0, sizeof(info));
}
if (!cmdDomblkinfoGet(ctl, &info, &cap, &alloc, &phy, human))