Just like command "domblklist", the command extracts "type", "source", "target", "model", and "MAC" of all virtual interfaces from domain XML (live or persistent). --- tools/virsh.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 9 +++++ 2 files changed, 107 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index fb940b8..3af2fd7 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -1984,6 +1984,103 @@ cleanup: } /* + * "domiflist" command + */ +static const vshCmdInfo info_domiflist[] = { + {"help", N_("list all domain virtual interfaces")}, + {"desc", N_("Get the summary of virtual interfaces for a domain.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_domiflist[] = { + {"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 +cmdDomiflist(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + bool ret = false; + unsigned int flags = 0; + char *xml = NULL; + xmlDocPtr xmldoc = NULL; + xmlXPathContextPtr ctxt = NULL; + int ninterfaces; + xmlNodePtr *interfaces = 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_definition)"), &ctxt); + if (!xmldoc) + goto cleanup; + + ninterfaces = virXPathNodeSet("./devices/interface", ctxt, &interfaces); + if (ninterfaces < 0) + goto cleanup; + + vshPrint(ctl, "%-10s %-10s %-10s %-11s %s\n", _("Type"), _("Source"), + _("Target"), _("Model"), _("MAC")); + vshPrint(ctl, "-------------------------------------------------------\n"); + + for (i = 0; i < ninterfaces; i++) { + char *type = NULL; + char *source = NULL; + char *target = NULL; + char *model = NULL; + char *mac = NULL; + + ctxt->node = interfaces[i]; + type = virXPathString("string(./@type)", ctxt); + + source = virXPathString("string(./source/@bridge" + "|./source/@dev" + "|./source/@network" + "|./source/@name)", ctxt); + + target = virXPathString("string(./target/@dev)", ctxt); + model = virXPathString("string(./model/@type)", ctxt); + mac = virXPathString("string(./mac/@address)", ctxt); + + vshPrint(ctl, "%-10s %-10s %-10s %-11s %-10s\n", type, + source ? source : "-", + target ? target : "-", + model ? model : "-", + mac ? mac : "-"); + + VIR_FREE(type); + VIR_FREE(source); + VIR_FREE(target); + VIR_FREE(model); + VIR_FREE(mac); + } + + ret = true; + +cleanup: + VIR_FREE(interfaces); + virDomainFree(dom); + VIR_FREE(xml); + xmlFreeDoc(xmldoc); + xmlXPathFreeContext(ctxt); + return ret; +} + +/* * "suspend" command */ static const vshCmdInfo info_suspend[] = { @@ -15595,6 +15692,7 @@ static const vshCmdDef domMonitoringCmds[] = { {"domblkstat", cmdDomblkstat, opts_domblkstat, info_domblkstat, 0}, {"domcontrol", cmdDomControl, opts_domcontrol, info_domcontrol, 0}, {"domif-getlink", cmdDomIfGetLink, opts_domif_getlink, info_domif_getlink, 0}, + {"domiflist", cmdDomiflist, opts_domiflist, info_domiflist, 0}, {"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat, 0}, {"dominfo", cmdDominfo, opts_dominfo, info_dominfo, 0}, {"dommemstat", cmdDomMemStat, opts_dommemstat, info_dommemstat, 0}, diff --git a/tools/virsh.pod b/tools/virsh.pod index 1abf448..bae6a13 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -522,6 +522,15 @@ 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<domiflist> I<domain> [I<--inactive>] + +Print a table showing the brief information of all virtual interfaces +associated with I<domain>. If I<--inactive> is specified, query the +virtual interfaces that will be used on the next boot, rather than those +currently in use by a running domain. Other contexts that require a MAC +address of virtual interface (such as I<detach-interface> or +I<domif-setlink>) will accept the MAC address 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.7.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list