[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