node_device: Expose link state & speed

While exposing the info under <interface/> in previous patch works, it
may work only in cases where interface is configured on the host.
However, orchestrating application may want to know the link state and
speed even in that case. That's why we ought to expose this in nodedev
XML too:

virsh # nodedev-dumpxml net_eth0_f0_de_f1_2b_1b_f3
<device>
  <name>net_eth0_f0_de_f1_2b_1b_f3</name>
  <path>/sys/devices/pci0000:00/0000:00:19.0/net/eth0</path>
  <parent>pci_0000_00_19_0</parent>
  <capability type='net'>
    <interface>eth0</interface>
    <address>f0🇩🇪f1:2b:1b:f3</address>
    <link speed='1000' state='up'/>
    <capability type='80203'/>
  </capability>
</device>

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Michal Privoznik 2014-06-05 17:36:31 +02:00
parent b2019ee470
commit 0311ef3d65
7 changed files with 28 additions and 4 deletions

View File

@ -161,6 +161,13 @@
<dd>The interface name tied to this device.</dd> <dd>The interface name tied to this device.</dd>
<dt><code>address</code></dt> <dt><code>address</code></dt>
<dd>If present, the MAC address of the device.</dd> <dd>If present, the MAC address of the device.</dd>
<dt><code>link</code></dt>
<dd>Optional to reflect the status of the link. It has
two optional attributes: <code>speed</code> in Mbits per
second and <code>state</code> to tell the state of the
link. So far, the whole element is just for output,
not setting.
</dd>
<dt><code>capability</code></dt> <dt><code>capability</code></dt>
<dd>A network protocol exposed by the device, where the <dd>A network protocol exposed by the device, where the
attribute <code>type</code> can be "80203" for IEEE attribute <code>type</code> can be "80203" for IEEE

View File

@ -243,6 +243,7 @@
<ref name='mac'/> <ref name='mac'/>
</element> </element>
</optional> </optional>
<ref name="link-speed-state"/>
<zeroOrMore> <zeroOrMore>
<ref name='subcapnet'/> <ref name='subcapnet'/>

View File

@ -1519,7 +1519,7 @@ libvirt_driver_nodedev_la_SOURCES = $(NODE_DEVICE_DRIVER_SOURCES)
libvirt_driver_nodedev_la_CFLAGS = \ libvirt_driver_nodedev_la_CFLAGS = \
-I$(top_srcdir)/src/access \ -I$(top_srcdir)/src/access \
-I$(top_srcdir)/src/conf \ -I$(top_srcdir)/src/conf \
$(AM_CFLAGS) $(AM_CFLAGS) $(LIBNL_CFLAGS)
libvirt_driver_nodedev_la_LDFLAGS = $(AM_LDFLAGS) libvirt_driver_nodedev_la_LDFLAGS = $(AM_LDFLAGS)
libvirt_driver_nodedev_la_LIBADD = libvirt_driver_nodedev_la_LIBADD =

View File

@ -389,6 +389,7 @@ char *virNodeDeviceDefFormat(const virNodeDeviceDef *def)
if (data->net.address) if (data->net.address)
virBufferEscapeString(&buf, "<address>%s</address>\n", virBufferEscapeString(&buf, "<address>%s</address>\n",
data->net.address); data->net.address);
virInterfaceLinkFormat(&buf, &data->net.lnk);
if (data->net.subtype != VIR_NODE_DEV_CAP_NET_LAST) { if (data->net.subtype != VIR_NODE_DEV_CAP_NET_LAST) {
const char *subtyp = const char *subtyp =
virNodeDevNetCapTypeToString(data->net.subtype); virNodeDevNetCapTypeToString(data->net.subtype);
@ -875,7 +876,7 @@ virNodeDevCapNetParseXML(xmlXPathContextPtr ctxt,
xmlNodePtr node, xmlNodePtr node,
union _virNodeDevCapData *data) union _virNodeDevCapData *data)
{ {
xmlNodePtr orignode; xmlNodePtr orignode, lnk;
int ret = -1; int ret = -1;
char *tmp; char *tmp;
@ -907,6 +908,10 @@ virNodeDevCapNetParseXML(xmlXPathContextPtr ctxt,
data->net.subtype = val; data->net.subtype = val;
} }
lnk = virXPathNode("./link", ctxt);
if (lnk && virInterfaceLinkParseXML(lnk, &data->net.lnk) < 0)
goto out;
ret = 0; ret = 0;
out: out:
ctxt->node = orignode; ctxt->node = orignode;

View File

@ -29,6 +29,7 @@
# include "virutil.h" # include "virutil.h"
# include "virthread.h" # include "virthread.h"
# include "virpci.h" # include "virpci.h"
# include "device_conf.h"
# include <libxml/tree.h> # include <libxml/tree.h>
@ -136,6 +137,7 @@ struct _virNodeDevCapsDef {
char *address; char *address;
unsigned int address_len; unsigned int address_len;
char *ifname; char *ifname;
virInterfaceLink lnk;
virNodeDevNetCapType subtype; /* LAST -> no subtype */ virNodeDevNetCapType subtype; /* LAST -> no subtype */
} net; } net;
struct { struct {

View File

@ -39,6 +39,7 @@
#include "node_device_driver.h" #include "node_device_driver.h"
#include "virutil.h" #include "virutil.h"
#include "viraccessapicheck.h" #include "viraccessapicheck.h"
#include "virnetdev.h"
#define VIR_FROM_THIS VIR_FROM_NODEDEV #define VIR_FROM_THIS VIR_FROM_NODEDEV
@ -47,10 +48,13 @@ static int update_caps(virNodeDeviceObjPtr dev)
virNodeDevCapsDefPtr cap = dev->def->caps; virNodeDevCapsDefPtr cap = dev->def->caps;
while (cap) { while (cap) {
/* The only caps that currently need updating are FC related. */
if (cap->type == VIR_NODE_DEV_CAP_SCSI_HOST) { if (cap->type == VIR_NODE_DEV_CAP_SCSI_HOST) {
detect_scsi_host_caps(&dev->def->caps->data); detect_scsi_host_caps(&dev->def->caps->data);
} }
if (cap->type == VIR_NODE_DEV_CAP_NET &&
virNetDevGetLinkInfo(cap->data.net.ifname, &cap->data.net.lnk) < 0)
return -1;
cap = cap->next; cap = cap->next;
} }
@ -315,7 +319,8 @@ nodeDeviceGetXMLDesc(virNodeDevicePtr dev,
goto cleanup; goto cleanup;
update_driver_name(obj); update_driver_name(obj);
update_caps(obj); if (update_caps(obj) < 0)
goto cleanup;
ret = virNodeDeviceDefFormat(obj->def); ret = virNodeDeviceDefFormat(obj->def);

View File

@ -40,6 +40,7 @@
#include "virfile.h" #include "virfile.h"
#include "virpci.h" #include "virpci.h"
#include "virstring.h" #include "virstring.h"
#include "virnetdev.h"
#define VIR_FROM_THIS VIR_FROM_NODEDEV #define VIR_FROM_THIS VIR_FROM_NODEDEV
@ -679,6 +680,9 @@ static int udevProcessNetworkInterface(struct udev_device *device,
goto out; goto out;
} }
if (virNetDevGetLinkInfo(data->net.ifname, &data->net.lnk) < 0)
goto out;
ret = 0; ret = 0;
out: out: