From: Chen Hanxiao <chenhanxiao@xxxxxxxxx> This patch introduces --all to show all block devices info of guests like: virsh # domblkinfo w08 --all Target Capacity Allocation Physical --------------------------------------------------- hda 42949672960 9878110208 9878110208 vda 10737418240 10736439296 10737418240 Signed-off-by: Chen Hanxiao <chenhanxiao@xxxxxxxxx> --- v1.1: fix self-test tools/virsh-domain-monitor.c | 84 +++++++++++++++++++++++++++--------- tools/virsh.pod | 5 ++- 2 files changed, 68 insertions(+), 21 deletions(-) diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index 39cb2ce7f0..fe31838e30 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -389,8 +389,7 @@ static const vshCmdInfo info_domblkinfo[] = { static const vshCmdOptDef opts_domblkinfo[] = { VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name = "device", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, + .type = VSH_OT_STRING, .completer = virshDomainDiskTargetCompleter, .help = N_("block device") }, @@ -398,6 +397,10 @@ static const vshCmdOptDef opts_domblkinfo[] = { .type = VSH_OT_BOOL, .help = N_("Human readable output") }, + {.name = "all", + .type = VSH_OT_BOOL, + .help = N_("display all block devices info") + }, {.name = NULL} }; @@ -408,38 +411,79 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd) virDomainPtr dom; bool ret = false; bool human = false; + bool all = false; const char *device = NULL; + xmlDocPtr xmldoc = NULL; + xmlXPathContextPtr ctxt = NULL; + int ndisks; + size_t i; + xmlNodePtr *disks = NULL; + char *target = NULL; if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) return false; - if (vshCommandOptStringReq(ctl, cmd, "device", &device) < 0) + all = vshCommandOptBool(cmd, "all"); + if (!all && vshCommandOptStringQuiet(ctl, cmd, "device", &device) <= 0) { + vshError(ctl, "command 'domblkinfo' requires <device> option"); goto cleanup; + } - if (virDomainGetBlockInfo(dom, device, &info, 0) < 0) - goto cleanup; + if (all) { + if (virshDomainGetXML(ctl, cmd, 0, &xmldoc, &ctxt) < 0) + goto cleanup; - human = vshCommandOptBool(cmd, "human"); + ndisks = virXPathNodeSet("./devices/disk", ctxt, &disks); + if (ndisks < 0) + goto cleanup; - if (!human) { - vshPrint(ctl, "%-15s %llu\n", _("Capacity:"), info.capacity); - vshPrint(ctl, "%-15s %llu\n", _("Allocation:"), info.allocation); - vshPrint(ctl, "%-15s %llu\n", _("Physical:"), info.physical); - } else { - double val; - const char *unit; - - val = vshPrettyCapacity(info.capacity, &unit); - vshPrint(ctl, "%-15s %-.3lf %s\n", _("Capacity:"), val, unit); - val = vshPrettyCapacity(info.allocation, &unit); - vshPrint(ctl, "%-15s %-.3lf %s\n", _("Allocation:"), val, unit); - val = vshPrettyCapacity(info.physical, &unit); - vshPrint(ctl, "%-15s %-.3lf %s\n", _("Physical:"), val, unit); + vshPrintExtra(ctl, "%-10s %-15s %-15s %-15s\n", _("Target"), + _("Capacity"), _("Allocation"), _("Physical")); + vshPrintExtra(ctl, "-----------------------------" + "----------------------\n"); + + for (i = 0; i < ndisks; i++) { + ctxt->node = disks[i]; + target = virXPathString("string(./target/@dev)", ctxt); + + if (virDomainGetBlockInfo(dom, target, &info, 0) < 0) + goto cleanup; + + vshPrint(ctl, "%-10s %-15llu %-15llu %-15llu\n", target, + info.capacity, info.allocation, info.physical); + + VIR_FREE(target); + } + } else if (device) { + if (virDomainGetBlockInfo(dom, device, &info, 0) < 0) + goto cleanup; + + human = vshCommandOptBool(cmd, "human"); + + if (!human) { + vshPrint(ctl, "%-15s %llu\n", _("Capacity:"), info.capacity); + vshPrint(ctl, "%-15s %llu\n", _("Allocation:"), info.allocation); + vshPrint(ctl, "%-15s %llu\n", _("Physical:"), info.physical); + } else { + double val; + const char *unit; + + val = vshPrettyCapacity(info.capacity, &unit); + vshPrint(ctl, "%-15s %-.3lf %s\n", _("Capacity:"), val, unit); + val = vshPrettyCapacity(info.allocation, &unit); + vshPrint(ctl, "%-15s %-.3lf %s\n", _("Allocation:"), val, unit); + val = vshPrettyCapacity(info.physical, &unit); + vshPrint(ctl, "%-15s %-.3lf %s\n", _("Physical:"), val, unit); + } } ret = true; cleanup: + VIR_FREE(target); + VIR_FREE(disks); + xmlXPathFreeContext(ctxt); + xmlFreeDoc(xmldoc); virshDomainFree(dom); return ret; } diff --git a/tools/virsh.pod b/tools/virsh.pod index 3f3314a87e..584defa201 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -949,13 +949,16 @@ B<domstate> command says that a domain was paused due to I/O error. The B<domblkerror> command lists all block devices in error state and the error seen on each of them. -=item B<domblkinfo> I<domain> I<block-device> [I<--human>] +=item B<domblkinfo> I<domain> { I<block-device> [I<--human>] } [I<--all>] Get block device size info for a domain. A I<block-device> corresponds to a unique target name (<target dev='name'/>) or source file (<source file='name'/>) for one of the disk devices attached to I<domain> (see also B<domblklist> for listing these names). If I<--human> is set, the output will have a human readable output. +If I<--all> is set, the output will be a table showing all block devices +size info associated with I<domain>. +The I<--all> option takes precedence of the others. =item B<domblklist> I<domain> [I<--inactive>] [I<--details>] -- 2.17.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list