[libvirt] [PATCH] Support reporting live interface IP/netmask.
Laine Stump
laine at laine.org
Tue Sep 29 20:38:27 UTC 2009
On 09/29/2009 04:02 PM, Laine Stump wrote:
> From: root<root at vlap.laine.org>
>
Note that I accidentally did the local commit as root, and didn't notice
it until now. If this patch gets committed, please change the From: first.
> This patch adds the flag VIR_INTERFACE_XML_INACTIVE to
> virInterfaceGetXMLDesc's flags. When it is *not* set (the default),
> the live interface info will be returned in the XML. in particular,
> the IP address(es) and netmask(s) will be retrieved by querying the
> device directly, rather than just reporting what's in the config
> file. The backend of this is in netcf's new ncf_if_xml_state()
> function.
>
> Any live interface ip address info in the xml will have the property
> "source" set to "device", eg:
>
> <ip address='10.24.0.1' prefix='24' source='device'/>
>
> Also, if an interface is currently inactive, no ip addresses will be
> returned, since an inactive interface device can't be queried for IP
> addresses (effectively it has none).
>
> A difference in the XML from previously - it is now acceptable to have
> both a dhcp *and* an ip node (or neither) within the protocol
> node. Before you had to have one or the other, but couldn't have both.
>
> Note that you need at least netcf 0.1.2 for this to build and work,
> and an upcoming release (patches submitted today) for it to work
> exactly as described above.
>
> ---
> include/libvirt/libvirt.h.in | 4 +++
> src/conf/interface_conf.c | 62 ++++++++++++++++++++++-------------------
> src/conf/interface_conf.h | 1 +
> src/interface/netcf_driver.c | 8 ++++-
> src/libvirt.c | 15 +++++++---
> tools/virsh.c | 10 +++++-
> 6 files changed, 63 insertions(+), 37 deletions(-)
>
> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
> index 4e63e48..fd0c90b 100644
> --- a/include/libvirt/libvirt.h.in
> +++ b/include/libvirt/libvirt.h.in
> @@ -922,6 +922,10 @@ virInterfacePtr virInterfaceLookupByMACString (virConnectPtr conn,
> const char* virInterfaceGetName (virInterfacePtr iface);
> const char* virInterfaceGetMACString (virInterfacePtr iface);
>
> +typedef enum {
> + VIR_INTERFACE_XML_INACTIVE = 1 /* dump inactive interface information */
> +} virInterfaceXMLFlags;
> +
> char * virInterfaceGetXMLDesc (virInterfacePtr iface,
> unsigned int flags);
> virInterfacePtr virInterfaceDefineXML (virConnectPtr conn,
> diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c
> index e646351..b422464 100644
> --- a/src/conf/interface_conf.c
> +++ b/src/conf/interface_conf.c
> @@ -92,6 +92,7 @@ void virInterfaceDefFree(virInterfaceDefPtr def)
> VIR_FREE(def->proto.family);
> VIR_FREE(def->proto.address);
> VIR_FREE(def->proto.gateway);
> + VIR_FREE(def->proto.source);
>
> VIR_FREE(def);
> }
> @@ -272,6 +273,8 @@ virInterfaceDefParseIp(virConnectPtr conn, virInterfaceDefPtr def,
> "%s", _("Invalid ip address prefix value"));
> return(-1);
> }
> + tmp = virXPathString(conn, "string(./ip[1]/@source)", ctxt);
> + def->proto.source = tmp;
> }
> tmp = virXPathString(conn, "string(./route[1]/@gateway)", ctxt);
> def->proto.gateway = tmp;
> @@ -282,22 +285,19 @@ virInterfaceDefParseIp(virConnectPtr conn, virInterfaceDefPtr def,
> static int
> virInterfaceDefParseProtoIPv4(virConnectPtr conn, virInterfaceDefPtr def,
> xmlXPathContextPtr ctxt) {
> - xmlNodePtr cur;
> - int ret;
> + xmlNodePtr dhcp, ip;
> + int ret = 0;
>
> - cur = virXPathNode(conn, "./dhcp", ctxt);
> - if (cur != NULL)
> - ret = virInterfaceDefParseDhcp(conn, def, cur, ctxt);
> - else {
> - cur = virXPathNode(conn, "./ip", ctxt);
> - if (cur != NULL)
> - ret = virInterfaceDefParseIp(conn, def, cur, ctxt);
> - else {
> - virInterfaceReportError(conn, VIR_ERR_XML_ERROR,
> - "%s", _("interface miss dhcp or ip adressing"));
> - ret = -1;
> - }
> - }
> + dhcp = virXPathNode(conn, "./dhcp", ctxt);
> + if (dhcp != NULL)
> + ret = virInterfaceDefParseDhcp(conn, def, dhcp, ctxt);
> +
> + if (ret != 0)
> + return(ret);
> +
> + ip = virXPathNode(conn, "./ip", ctxt);
> + if (ip != NULL)
> + ret = virInterfaceDefParseIp(conn, def, ip, ctxt);
> return(ret);
> }
>
> @@ -1005,6 +1005,7 @@ virInterfaceVlanDefFormat(virConnectPtr conn, virBufferPtr buf,
> static int
> virInterfaceProtocolDefFormat(virConnectPtr conn ATTRIBUTE_UNUSED,
> virBufferPtr buf, const virInterfaceDefPtr def) {
> + char prefixStr[16];
> if (def->proto.family == NULL)
> return(0);
> virBufferVSprintf(buf, "<protocol family='%s'>\n", def->proto.family);
> @@ -1015,20 +1016,23 @@ virInterfaceProtocolDefFormat(virConnectPtr conn ATTRIBUTE_UNUSED,
> virBufferAddLit(buf, "<dhcp peerdns='yes'/>\n");
> else
> virBufferAddLit(buf, "<dhcp/>\n");
> - } else {
> - /* theorically if we don't have dhcp we should have an address */
> - if (def->proto.address != NULL) {
> - if (def->proto.prefix != 0)
> - virBufferVSprintf(buf, "<ip address='%s' prefix='%d'/>\n",
> - def->proto.address, def->proto.prefix);
> - else
> - virBufferVSprintf(buf, "<ip address='%s'/>\n",
> - def->proto.address);
> - }
> - if (def->proto.gateway != NULL) {
> - virBufferVSprintf(buf, "<route gateway='%s'/>\n",
> - def->proto.gateway);
> - }
> + }
> + if (def->proto.address != NULL) {
> + if (def->proto.prefix != 0)
> + snprintf(prefixStr, sizeof(prefixStr), "%d", def->proto.prefix);
> +
> + virBufferVSprintf(buf, "<ip address='%s'%s%s%s%s%s%s/>\n",
> + def->proto.address,
> + def->proto.prefix ? " prefix='" : "",
> + def->proto.prefix ? prefixStr : "",
> + def->proto.prefix ? "'" : "",
> + def->proto.source ? " source='" : "",
> + def->proto.source ? def->proto.source : "",
> + def->proto.source ? "'" : "");
> + }
> + if (def->proto.gateway != NULL) {
> + virBufferVSprintf(buf, "<route gateway='%s'/>\n",
> + def->proto.gateway);
> }
> virBufferAddLit(buf, "</protocol>\n");
> return(0);
> diff --git a/src/conf/interface_conf.h b/src/conf/interface_conf.h
> index bb9dce4..df871aa 100644
> --- a/src/conf/interface_conf.h
> +++ b/src/conf/interface_conf.h
> @@ -132,6 +132,7 @@ struct _virInterfaceProtocolDef {
> char *address; /* ip address */
> int prefix; /* ip prefix */
> char *gateway; /* route gateway */
> + char *source; /* source of address - "device" or "config" (default) */
> };
>
>
> diff --git a/src/interface/netcf_driver.c b/src/interface/netcf_driver.c
> index ca14fb0..b5c3664 100644
> --- a/src/interface/netcf_driver.c
> +++ b/src/interface/netcf_driver.c
> @@ -326,7 +326,7 @@ cleanup:
> }
>
> static char *interfaceGetXMLDesc(virInterfacePtr ifinfo,
> - unsigned int flags ATTRIBUTE_UNUSED)
> + unsigned int flags)
> {
> struct interface_driver *driver = ifinfo->conn->interfacePrivateData;
> struct netcf_if *iface = NULL;
> @@ -342,7 +342,11 @@ static char *interfaceGetXMLDesc(virInterfacePtr ifinfo,
> goto cleanup;
> }
>
> - xmlstr = ncf_if_xml_desc(iface);
> + if ((flags& VIR_INTERFACE_XML_INACTIVE)) {
> + xmlstr = ncf_if_xml_desc(iface);
> + } else {
> + xmlstr = ncf_if_xml_state(iface);
> + }
> if (!xmlstr) {
> const char *errmsg, *details;
> int errcode = ncf_error(driver->netcf,&errmsg,&details);
> diff --git a/src/libvirt.c b/src/libvirt.c
> index bcb89e1..bd712dc 100644
> --- a/src/libvirt.c
> +++ b/src/libvirt.c
> @@ -5915,10 +5915,17 @@ virInterfaceGetMACString(virInterfacePtr iface)
> /**
> * virInterfaceGetXMLDesc:
> * @iface: an interface object
> - * @flags: an OR'ed set of extraction flags, not used yet
> + * @flags: an OR'ed set of extraction flags. Current valid bits:
> + *
> + * VIR_INTERFACE_XML_INACTIVE - return the static configuration,
> + * suitable for use redefining the
> + * interface via virInterfaceDefineXML()
> *
> - * Provide an XML description of the interface. The description may be reused
> - * later to redefine the interface with virInterfaceDefineXML().
> + * Provide an XML description of the interface. If
> + * VIR_INTERFACE_XML_INACTIVE is set, the description may be reused
> + * later to redefine the interface with virInterfaceDefineXML(). If it
> + * is not set, the ip address and netmask will be the current live
> + * setting of the interface, not the settings from the config files.
> *
> * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
> * the caller must free() the returned value.
> @@ -5935,7 +5942,7 @@ virInterfaceGetXMLDesc(virInterfacePtr iface, unsigned int flags)
> virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
> return (NULL);
> }
> - if (flags != 0) {
> + if ((flags& ~VIR_INTERFACE_XML_INACTIVE) != 0) {
> virLibInterfaceError(iface, VIR_ERR_INVALID_ARG, __FUNCTION__);
> goto error;
> }
> diff --git a/tools/virsh.c b/tools/virsh.c
> index 3482389..77f1d70 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -2763,7 +2763,7 @@ cmdInterfaceEdit (vshControl *ctl, const vshCmd *cmd)
> char *doc = NULL;
> char *doc_edited = NULL;
> char *doc_reread = NULL;
> - int flags = 0;
> + int flags = VIR_INTERFACE_XML_INACTIVE;
>
> if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
> goto cleanup;
> @@ -3297,6 +3297,7 @@ static const vshCmdInfo info_interface_dumpxml[] = {
>
> static const vshCmdOptDef opts_interface_dumpxml[] = {
> {"interface", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("interface name or MAC address")},
> + {"inactive", VSH_OT_BOOL, 0, gettext_noop("show inactive defined XML")},
> {NULL, 0, 0, NULL}
> };
>
> @@ -3306,6 +3307,11 @@ cmdInterfaceDumpXML(vshControl *ctl, const vshCmd *cmd)
> virInterfacePtr iface;
> int ret = TRUE;
> char *dump;
> + int flags = 0;
> + int inactive = vshCommandOptBool(cmd, "inactive");
> +
> + if (inactive)
> + flags |= VIR_INTERFACE_XML_INACTIVE;
>
> if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
> return FALSE;
> @@ -3313,7 +3319,7 @@ cmdInterfaceDumpXML(vshControl *ctl, const vshCmd *cmd)
> if (!(iface = vshCommandOptInterface(ctl, cmd, NULL)))
> return FALSE;
>
> - dump = virInterfaceGetXMLDesc(iface, 0);
> + dump = virInterfaceGetXMLDesc(iface, flags);
> if (dump != NULL) {
> printf("%s", dump);
> free(dump);
>
More information about the libvir-list
mailing list