domifaddr: Add virsh support

tools/virsh-domain-monitor.c
   * Introduce new command : domifaddr
     Usage: domifaddr <domain> [interface] [--full] [--source lease|agent]

     Example outputs:
     virsh # domifaddr f20
     Name       MAC address          Protocol     Address
     -------------------------------------------------------------------------------
     lo         00:00:00:00:00:00    ipv4         127.0.0.1/8
     -          -                    ipv6         ::1/128
     vnet0      52:54:00:2e:45:ce    ipv4         10.1.33.188/24
     -          -                    ipv6         2001:db8:0:f101::2/64
     -          -                    ipv6         fe80::5054:ff:fe2e:45ce/64
     vnet1      52:54:00:b1:70:19    ipv4         192.168.105.201/16
     -          -                    ipv4         192.168.201.195/16
     -          -                    ipv6         fe80::5054:ff:feb1:7019/64
     vnet2      52:54:00:36:2a:e5    N/A          N/A
     vnet3      52:54:00:20:70:3d    ipv4         192.168.105.240/16
     -          -                    ipv6         fe80::5054:ff:fe20:703d/64

     virsh # domifaddr f20 eth1 --source lease
     Name       MAC address          Protocol     Address
     -------------------------------------------------------------------------------
     vnet1      52:54:00:b1:70:19    ipv4         192.168.105.201/16
     -          -                    ipv4         192.168.201.195/16
     -          -                    ipv6         fe80::5054:ff:feb1:7019/64

     virsh # domifaddr f20 eth0 --source agent --full
     Name       MAC address          Protocol     Address
     -------------------------------------------------------------------------------
     eth0       52:54:00:2e:45:ce    ipv4         10.1.33.188/24
     eth0       52:54:00:2e:45:ce    ipv6         2001:db8:0:f101::2/64
     eth0       52:54:00:2e:45:ce    ipv6         fe80::5054:ff:fe2e:45ce/64

tools/virsh.pod
   * Document new command

Signed-off-by: Nehal J Wani <nehaljw.kkd1@gmail.com>
This commit is contained in:
Nehal J Wani 2015-01-26 00:08:49 +05:30 committed by Daniel P. Berrange
parent 0977b8aa07
commit 2f36e6944e
2 changed files with 159 additions and 0 deletions

View File

@ -2197,6 +2197,143 @@ cmdDomstats(vshControl *ctl, const vshCmd *cmd)
return ret;
}
/* "domifaddr" command
*/
static const vshCmdInfo info_domifaddr[] = {
{"help", N_("Get network interfaces' addresses for a running domain")},
{"desc", N_("Get network interfaces' addresses for a running domain")},
{NULL, NULL}
};
static const vshCmdOptDef opts_domifaddr[] = {
{.name = "domain",
.type = VSH_OT_DATA,
.flags = VSH_OFLAG_REQ,
.help = N_("domain name, id or uuid")},
{.name = "interface",
.type = VSH_OT_STRING,
.flags = VSH_OFLAG_NONE,
.help = N_("network interface name")},
{.name = "full",
.type = VSH_OT_BOOL,
.flags = VSH_OFLAG_NONE,
.help = N_("display full fields")},
{.name = "source",
.type = VSH_OT_STRING,
.flags = VSH_OFLAG_NONE,
.help = N_("address source: 'lease' or 'agent'")},
{.name = NULL}
};
static bool
cmdDomIfAddr(vshControl *ctl, const vshCmd *cmd)
{
virDomainPtr dom = NULL;
const char *interface = NULL;
virDomainInterfacePtr *ifaces = NULL;
size_t i, j;
int ifaces_count = 0;
bool ret = false;
bool full = vshCommandOptBool(cmd, "full");
const char *sourcestr = NULL;
int source = VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE;
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return false;
if (vshCommandOptString(cmd, "interface", &interface) < 0)
goto cleanup;
if (vshCommandOptString(cmd, "source", &sourcestr) < 0)
goto cleanup;
if (sourcestr) {
if (STREQ(sourcestr, "lease")) {
source = VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE;
} else if (STREQ(sourcestr, "agent")) {
source = VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT;
} else {
vshError(ctl, _("Unknown data source '%s'"), sourcestr);
goto cleanup;
}
}
if ((ifaces_count = virDomainInterfaceAddresses(dom, &ifaces, source, 0)) < 0) {
vshError(ctl, _("Failed to query for interfaces addresses"));
goto cleanup;
}
vshPrintExtra(ctl, " %-10s %-20s %-8s %s\n%s%s\n", _("Name"),
_("MAC address"), _("Protocol"), _("Address"),
_("-------------------------------------------------"),
_("------------------------------"));
for (i = 0; i < ifaces_count; i++) {
virDomainInterfacePtr iface = ifaces[i];
const char *ip_addr_str = NULL;
const char *type = NULL;
if (interface && STRNEQ(interface, iface->name))
continue;
/* When the interface has no IP address */
if (!iface->naddrs) {
vshPrintExtra(ctl, " %-10s %-17s %-12s %s\n",
iface->name, iface->hwaddr, "N/A", "N/A");
continue;
}
for (j = 0; j < iface->naddrs; j++) {
virBuffer buf = VIR_BUFFER_INITIALIZER;
switch (iface->addrs[j].type) {
case VIR_IP_ADDR_TYPE_IPV4:
type = "ipv4";
break;
case VIR_IP_ADDR_TYPE_IPV6:
type = "ipv6";
break;
}
virBufferAsprintf(&buf, "%-12s %s/%d",
type, iface->addrs[j].addr,
iface->addrs[j].prefix);
if (virBufferError(&buf)) {
virBufferFreeAndReset(&buf);
virReportOOMError();
goto cleanup;
}
ip_addr_str = virBufferContentAndReset(&buf);
if (!ip_addr_str)
ip_addr_str = "";
/* Don't repeat interface name */
if (full || !j)
vshPrintExtra(ctl, " %-10s %-17s %s\n",
iface->name, iface->hwaddr, ip_addr_str);
else
vshPrintExtra(ctl, " %-10s %-17s %s\n",
"-", "-", ip_addr_str);
virBufferFreeAndReset(&buf);
}
}
ret = true;
cleanup:
if (ifaces && ifaces_count > 0) {
for (i = 0; i < ifaces_count; i++)
virDomainInterfaceFree(ifaces[i]);
}
VIR_FREE(ifaces);
virDomainFree(dom);
return ret;
}
const vshCmdDef domMonitoringCmds[] = {
{.name = "domblkerror",
.handler = cmdDomBlkError,
@ -2234,6 +2371,12 @@ const vshCmdDef domMonitoringCmds[] = {
.info = info_domif_getlink,
.flags = 0
},
{.name = "domifaddr",
.handler = cmdDomIfAddr,
.opts = opts_domifaddr,
.info = info_domifaddr,
.flags = 0
},
{.name = "domiflist",
.handler = cmdDomiflist,
.opts = opts_domiflist,

View File

@ -731,6 +731,22 @@ B<Explanation of fields> (fields appear in the following order):
flush_total_times - total time flush operations took (ns)
<-- other fields provided by hypervisor -->
=item B<domifaddr> I<domain> [I<interface>] [I<--full>]
[I<--source lease|agent>]
Get a list of interfaces of a running domain along with their IP and MAC
addresses, or limited output just for one interface if I<interface> is
specified. Note that I<interface> can be driver dependent, it can be the name
within guest OS or the name you would see in domain XML. Moreover, the whole
command may require a guest agent to be configured for the queried domain under
some drivers, notably qemu. If I<--full> is specified, the interface name is
always displayed when the interface has multiple addresses or alias, otherwise
it only displays the interface name for the first address, and "-" for the
others. The I<--source> argument specifies what data source to use for the
addresses, currently one of 'lease' to read DHCP leases, or 'agent' to query
the guest OS via an agent. If unspecified, 'lease' is the default.
=item B<domifstat> I<domain> I<interface-device>
Get network interface stats for a running domain.