This API returns dynamically allocated XML document showing IP addresses for all domain interfaces. --- docs/schemas/interfaces.rng | 57 ++++++++++++++++++++++++++++++++++++++++++ include/libvirt/libvirt.h.in | 2 + src/driver.h | 4 +++ src/libvirt.c | 49 ++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 12 ++++++++- src/remote_protocol-structs | 8 ++++++ 8 files changed, 133 insertions(+), 1 deletions(-) create mode 100644 docs/schemas/interfaces.rng diff --git a/docs/schemas/interfaces.rng b/docs/schemas/interfaces.rng new file mode 100644 index 0000000..95c939e --- /dev/null +++ b/docs/schemas/interfaces.rng @@ -0,0 +1,57 @@ +<!-- A Relax NG schema for the libvirt interfaces (return of + virDomainGetInterfacesAddresses) XML format --> +<grammar xmlns="http://relaxng.org/ns/structure/1.0" + datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + <include href='basictypes.rng'/> + <start> + <ref name='interfaces'/> + </start> + + + <define name='interfaces'> + <element name='interfaces'> + <zeroOrMore> + <ref name='interface'/> + </zeroOrMore> + </element> + </define> + + <define name='interface'> + <element name='interface'> + <element name='name'> + <text/> + </element> + <optional> + <element name='hwaddr'> + <text/> + </element> + </optional> + <optional> + <ref name='addresses'/> + </optional> + </element> + </define> + + <define name='addresses'> + <element name='addresses'> + <zeroOrMore> + <ref name='ip'/> + </zeroOrMore> + </element> + </define> + + <define name='ip'> + <element name='ip'> + <attribute name='type'> + <choice> + <value>ipv4</value> + <value>ipv6</value> + </choice> + </attribute> + <attribute name='prefix'> + <ref name='unsignedInt'/> + </attribute> + <text/> + </element> + </define> +</grammar> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 024c4ec..90660d1 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1659,6 +1659,8 @@ int virDomainGetInterfaceParameters (virDomainPtr dom, const char *device, virTypedParameterPtr params, int *nparams, unsigned int flags); +char * virDomainGetInterfacesAddresses (virDomainPtr dom, + unsigned int flags); /* Management of domain block devices */ diff --git a/src/driver.h b/src/driver.h index b3c1740..b2ed4b0 100644 --- a/src/driver.h +++ b/src/driver.h @@ -398,6 +398,9 @@ typedef int const char *device, virTypedParameterPtr params, int *nparams, unsigned int flags); +typedef char * + (*virDrvDomainGetInterfacesAddresses) (virDomainPtr dom, + unsigned int flags); typedef int (*virDrvDomainMemoryStats) @@ -966,6 +969,7 @@ struct _virDriver { virDrvDomainInterfaceStats domainInterfaceStats; virDrvDomainSetInterfaceParameters domainSetInterfaceParameters; virDrvDomainGetInterfaceParameters domainGetInterfaceParameters; + virDrvDomainGetInterfacesAddresses domainGetInterfacesAddresses; virDrvDomainMemoryStats domainMemoryStats; virDrvDomainBlockPeek domainBlockPeek; virDrvDomainMemoryPeek domainMemoryPeek; diff --git a/src/libvirt.c b/src/libvirt.c index 0aa50cb..2dadd6f 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -7357,6 +7357,55 @@ error: } /** + * virDomainGetInterfacesAddresses: + * @domain: domain object + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Return an XML document representing domain interfaces among with their IP + * addresses assigned. It's worth noticing that one interface can have multiple + * addresses or even none. + * + * For some hypervisors (e.g. qemu) a configured guest agent is needed. If + * guest agent is used, then the interface name will be the as seen by guest + * OS. To match such interface with the one from @domain XML us HW address or + * IP range. + * + * Returns an XML document or NULL on error. + * Callers *must* free returned pointer. + */ +char * +virDomainGetInterfacesAddresses(virDomainPtr domain, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "flags=%x", flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + goto error; + } + + conn = domain->conn; + + if (conn->driver->domainGetInterfacesAddresses) { + char *ret; + ret = conn->driver->domainGetInterfacesAddresses(domain, flags); + if (!ret) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain ? domain->conn : NULL); + return NULL; +} + +/** * virDomainMemoryStats: * @dom: pointer to the domain object * @stats: nr_stats-sized array of stat structures (returned) diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 2913a81..20dd08d 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -542,6 +542,7 @@ LIBVIRT_0.9.13 { virDomainSnapshotIsCurrent; virDomainSnapshotListAllChildren; virDomainSnapshotRef; + virDomainGetInterfacesAddresses; } LIBVIRT_0.9.11; # .... define new API here using predicted next version number .... diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 6f53264..40a7a9c 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -5226,6 +5226,7 @@ static virDriver remote_driver = { .domainInterfaceStats = remoteDomainInterfaceStats, /* 0.3.2 */ .domainSetInterfaceParameters = remoteDomainSetInterfaceParameters, /* 0.9.9 */ .domainGetInterfaceParameters = remoteDomainGetInterfaceParameters, /* 0.9.9 */ + .domainGetInterfacesAddresses = remoteDomainGetInterfacesAddresses, /* 0.9.13 */ .domainMemoryStats = remoteDomainMemoryStats, /* 0.7.5 */ .domainBlockPeek = remoteDomainBlockPeek, /* 0.4.2 */ .domainMemoryPeek = remoteDomainMemoryPeek, /* 0.4.2 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 1da9f3e..ea37270 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -653,6 +653,15 @@ struct remote_domain_get_interface_parameters_ret { int nparams; }; +struct remote_domain_get_interfaces_addresses_args { + remote_nonnull_domain dom; + unsigned int flags; +}; + +struct remote_domain_get_interfaces_addresses_ret { + remote_nonnull_string xml; +}; + struct remote_domain_memory_stats_args { remote_nonnull_domain dom; unsigned int maxStats; @@ -2838,7 +2847,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_SNAPSHOT_HAS_METADATA = 272, /* autogen autogen */ REMOTE_PROC_CONNECT_LIST_ALL_DOMAINS = 273, /* skipgen skipgen priority:high */ REMOTE_PROC_DOMAIN_LIST_ALL_SNAPSHOTS = 274, /* skipgen skipgen priority:high */ - REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_ALL_CHILDREN = 275 /* skipgen skipgen priority:high */ + REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_ALL_CHILDREN = 275, /* skipgen skipgen priority:high */ + REMOTE_PROC_DOMAIN_GET_INTERFACES_ADDRESSES = 276 /* autogen autogen */ /* * Notice how the entries are grouped in sets of 10 ? diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index b667527..fadff38 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -354,6 +354,13 @@ struct remote_domain_get_interface_parameters_ret { } params; int nparams; }; +struct remote_domain_get_interfaces_addresses_args { + remote_nonnull_domain dom; + u_int flags; +}; +struct remote_domain_get_interfaces_addresses_ret { + remote_nonnull_string xml; +}; struct remote_domain_memory_stats_args { remote_nonnull_domain dom; u_int maxStats; @@ -2246,4 +2253,5 @@ enum remote_procedure { REMOTE_PROC_CONNECT_LIST_ALL_DOMAINS = 273, REMOTE_PROC_DOMAIN_LIST_ALL_SNAPSHOTS = 274, REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_ALL_CHILDREN = 275, + REMOTE_PROC_DOMAIN_GET_INTERFACES_ADDRESSES = 276, }; -- 1.7.8.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list