[libvirt] [PATCH v3 4/7] qemu: Implement virDomainInterfacesAddresses

Michal Privoznik mprivozn at redhat.com
Thu Aug 2 18:08:46 UTC 2012


---
 include/libvirt/libvirt.h.in |    1 +
 src/qemu/qemu_driver.c       |   76 ++++++++++++++++++++++++++++++++++++++++++
 tools/virsh-domain-monitor.c |   19 ++++++++++
 tools/virsh.pod              |   19 +++++-----
 4 files changed, 106 insertions(+), 9 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index d5d131a..7f25a0a 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1742,6 +1742,7 @@ struct _virDomainInterface {
 
 typedef enum {
     VIR_DOMAIN_INTERFACE_ADDRS_DEFAULT      = 0, /* hypervisor choice */
+    VIR_DOMAIN_INTERFACE_ADDRS_GUEST_AGENT  = (1 << 0), /* use guest agent */
 } virDomainInterfacesAddressesFlags;
 
 int             virDomainInterfacesAddresses (virDomainPtr dom,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 270e4dd..f90ab41 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13173,6 +13173,81 @@ qemuListAllDomains(virConnectPtr conn,
     return ret;
 }
 
+static int
+qemuDomainInterfacesAddresses(virDomainPtr dom,
+                              virDomainInterfacePtr *ifaces,
+                              unsigned int flags)
+{
+    struct qemud_driver *driver = dom->conn->privateData;
+    qemuDomainObjPrivatePtr priv = NULL;
+    virDomainObjPtr vm = NULL;
+    int ret = -1;
+
+    virCheckFlags(VIR_DOMAIN_INTERFACE_ADDRS_DEFAULT |
+                  VIR_DOMAIN_INTERFACE_ADDRS_GUEST_AGENT, -1);
+
+    if (!ifaces) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("ifaces cannot be NULL"));
+        return -1;
+    }
+
+    qemuDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+    qemuDriverUnlock(driver);
+
+    if (!vm) {
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
+        virUUIDFormat(dom->uuid, uuidstr);
+        virReportError(VIR_ERR_NO_DOMAIN,
+                       _("no domain with matching uuid '%s'"), uuidstr);
+        goto cleanup;
+    }
+
+    if (!virDomainObjIsActive(vm)) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("domain is not running"));
+        goto cleanup;
+    }
+
+    priv = vm->privateData;
+
+    if (priv->agentError) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("QEMU guest agent is not "
+                         "available due to an error"));
+        goto cleanup;
+    }
+
+    if (!priv->agent) {
+        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+                       _("QEMU guest agent is not configured"));
+        goto cleanup;
+    }
+
+    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
+        goto cleanup;
+
+    if (!virDomainObjIsActive(vm)) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("domain is not running"));
+        goto endjob;
+    }
+
+    qemuDomainObjEnterAgent(driver, vm);
+    ret = qemuAgentGetInterfaces(priv->agent, ifaces);
+    qemuDomainObjExitAgent(driver, vm);
+
+endjob:
+    if (qemuDomainObjEndJob(driver, vm) == 0)
+        vm = NULL;
+
+cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    return ret;
+}
+
 static virDriver qemuDriver = {
     .no = VIR_DRV_QEMU,
     .name = QEMU_DRIVER_NAME,
@@ -13338,6 +13413,7 @@ static virDriver qemuDriver = {
     .domainPMSuspendForDuration = qemuDomainPMSuspendForDuration, /* 0.9.11 */
     .domainPMWakeup = qemuDomainPMWakeup, /* 0.9.11 */
     .domainGetCPUStats = qemuDomainGetCPUStats, /* 0.9.11 */
+    .domainInterfacesAddresses = qemuDomainInterfacesAddresses, /* 0.10.0 */
 };
 
 
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index fb6fe23..b4a5088 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -1694,6 +1694,7 @@ static const vshCmdInfo info_domifaddr[] = {
 static const vshCmdOptDef opts_domifaddr[] = {
     {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
     {"interface", VSH_OT_DATA, VSH_OFLAG_NONE, N_("network interface name")},
+    {"mode", VSH_OT_STRING, VSH_OFLAG_NONE, N_("querying mode: default|agent")},
     {NULL, 0, 0, NULL}
 };
 
@@ -1703,6 +1704,7 @@ cmdDomIfAddr(vshControl *ctl, const vshCmd *cmd)
     virDomainPtr dom = NULL;
     const char *device = NULL;
     virDomainInterfacePtr ifaces = NULL;
+    const char *mode = NULL;
     int i, j, ifaces_count = 0;
     unsigned int flags = 0;
     bool ret = false;
@@ -1717,6 +1719,23 @@ cmdDomIfAddr(vshControl *ctl, const vshCmd *cmd)
         goto cleanup;
     }
 
+    if (vshCommandOptString(cmd, "mode", &mode) < 0) {
+        vshError(ctl, "%s", _("Invalid type"));
+        return false;
+    }
+
+    if (mode) {
+        if (STREQ(mode, "default")) {
+            flags |= VIR_DOMAIN_INTERFACE_ADDRS_DEFAULT;
+        } else if (STREQ(mode, "agent")) {
+            flags |= VIR_DOMAIN_INTERFACE_ADDRS_GUEST_AGENT;
+        } else {
+            vshError(ctl, _("Unknown mode %s value, "
+                            "expecting 'default' or 'agent'"), mode);
+            return false;
+        }
+    }
+
     ifaces_count = virDomainInterfacesAddresses(dom, &ifaces, flags);
     if (ifaces_count < 0) {
         vshError(ctl, _("Failed to query for interfaces addresses"));
diff --git a/tools/virsh.pod b/tools/virsh.pod
index daf5889..f4f7a33 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -605,15 +605,16 @@ B<Explanation of fields> (fields appear in the folowing order):
   flush_total_times - total time flush operations took (ns)
     <-- other fields provided by hypervisor -->
 
-=item B<domifaddr> I<domain> [I<interface-device>]
-
-Get a list of interfaces of domain among with their IP and hardware
-addresses, or if I<interface-device> is specified limit output just
-for that one interface. Note, that interface name can be driver
-dependent meaning it can be 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.
+=item B<domifaddr> [I<--mode default,agent>] I<domain> [I<interface-device>]
+
+Get a list of interfaces of domain among with their IP and hardware addresses,
+or if I<interface-device> is specified limit output just for that one
+interface. Note, that interface name can be driver dependent meaning it can be
+name within guest OS or the name you would see in domain XML. Moreover, upon
+I<--mode> choice command may require a guest agent to be configured for the
+queried domain under some drivers, notably qemu. Accepted values for I<--mode>
+are 'default' (meaning hypervisor will choose the most suitable method) and
+'agent' (guest agent is used).
 
 =item B<domifstat> I<domain> I<interface-device>
 
-- 
1.7.8.6




More information about the libvir-list mailing list