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