This adds a convenience function to virsh that parses out block information from the domain xml, making it much easier to see what strings can be used in all other contexts that demand a specific block name, especially when given the previous patch that allows using either target or unique source name. As an example on a domain with one disk and an empty cdrom drive: Target Source ------------------------------------------- vda /var/lib/libvirt/images/fedora_12.img hdc - * tools/virsh.c (cmdDomblklist): New function. * tools/virsh.pod (domblklist): Document it. --- tools/virsh.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 10 +++++++ 2 files changed, 91 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 14ec429..3c9420e 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -1277,6 +1277,86 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd) } /* + * "domblklist" command + */ +static const vshCmdInfo info_domblklist[] = { + {"help", N_("list all domain blocks")}, + {"desc", N_("Get the names of block devices for a domain.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_domblklist[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"inactive", VSH_OT_BOOL, 0, + N_("get inactive rather than running configuration")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdDomblklist(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + bool ret = false; + unsigned int flags = 0; + char *xml = NULL; + xmlDocPtr xmldoc = NULL; + xmlXPathContextPtr ctxt = NULL; + int ndisks; + xmlNodePtr *disks = NULL; + int i; + + if (vshCommandOptBool(cmd, "inactive")) + flags |= VIR_DOMAIN_XML_INACTIVE; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return false; + + xml = virDomainGetXMLDesc(dom, flags); + if (!xml) + goto cleanup; + + xmldoc = virXMLParseStringCtxt(xml, "domain.xml", &ctxt); + if (!xmldoc) + goto cleanup; + + ndisks = virXPathNodeSet("./devices/disk", ctxt, &disks); + if (ndisks < 0) + goto cleanup; + + vshPrint(ctl, "%-10s %s\n", _("Target"), _("Source")); + vshPrint(ctl, "------------------------------------------------\n"); + + for (i = 0; i < ndisks; i++) { + char *target; + char *source; + + ctxt->node = disks[i]; + target = virXPathString("string(./target/@dev)", ctxt); + if (!target) { + vshError(ctl, "unable to query block list"); + goto cleanup; + } + source = virXPathString("string(./source/@file" + "|./source/@dev" + "|./source/@dir" + "|./source/@name)", ctxt); + vshPrint(ctl, "%-10s %s\n", target, source ? source : "-"); + VIR_FREE(target); + VIR_FREE(source); + } + + ret = 0; + +cleanup: + VIR_FREE(disks); + virDomainFree(dom); + return ret; +} + +/* * "suspend" command */ static const vshCmdInfo info_suspend[] = { @@ -13052,6 +13132,7 @@ static const vshCmdDef domManagementCmds[] = { static const vshCmdDef domMonitoringCmds[] = { {"domblkinfo", cmdDomblkinfo, opts_domblkinfo, info_domblkinfo, 0}, + {"domblklist", cmdDomblklist, opts_domblklist, info_domblklist, 0}, {"domblkstat", cmdDomblkstat, opts_domblkstat, info_domblkstat, 0}, {"domcontrol", cmdDomControl, opts_domcontrol, info_domcontrol, 0}, {"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat, 0}, diff --git a/tools/virsh.pod b/tools/virsh.pod index c40e9f3..b00f49c 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -521,6 +521,16 @@ 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>. +=item B<domblklist> I<domain> [I<--inactive>] + +Print a table showing the names of all block devices associated with +I<domain>, as well as the path to the source of each device. If +I<--inactive> is specified, query the block devices that will be used +on the next boot, rather than those currently in use by a running +domain. Other contexts that require a block device name (such as +I<domblkinfo> or I<snapshot-create> for disk snapshots) will accept +either target or unique source names printed by this command. + =item B<blockpull> I<domain> I<path> [I<bandwidth>] Populate a disk from its backing image. Once all data from its backing -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list