<div dir="ltr"><div class="gmail_extra">On Mon, Aug 19, 2013 at 1:19 PM, Giuseppe Scrivano <span dir="ltr"><<a href="mailto:gscrivan@redhat.com" target="_blank">gscrivan@redhat.com</a>></span> wrote:<br><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">---<br>
I have started working on:<br>
<br>
  <a href="https://bugzilla.redhat.com/show_bug.cgi?id=916786" target="_blank">https://bugzilla.redhat.com/show_bug.cgi?id=916786</a><br>
<br>
Before I split it in a series of commits, test it better and then<br>
proceed to virt-manager, are you ok with this idea?<br>
<br>
<br>
 include/libvirt/<a href="http://libvirt.h.in" target="_blank">libvirt.h.in</a> | 11 +++++++++++<br>
 src/driver.h                 |  4 ++++<br>
 src/libvirt.c                | 38 ++++++++++++++++++++++++++++++++++++++<br>
 src/libvirt_private.syms     |  1 +<br>
 src/libvirt_public.syms      |  1 +<br>
 src/lxc/lxc_driver.c         | 11 +++++++++++<br>
 src/qemu/qemu_driver.c       | 10 ++++++++++<br>
 src/remote/remote_driver.c   |  1 +<br>
 src/remote/remote_protocol.x | 12 +++++++++++-<br>
 src/remote_protocol-structs  |  4 ++++<br>
 src/test/test_driver.c       |  6 ++++++<br>
 src/uml/uml_driver.c         | 11 +++++++++++<br>
 src/util/virutil.c           | 23 +++++++++++++++++++++++<br>
 src/util/virutil.h           |  3 +++<br>
 tools/virsh-host.c           | 21 +++++++++++++++++++++<br>
 tools/virsh.pod              |  5 +++++<br>
 16 files changed, 161 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/include/libvirt/<a href="http://libvirt.h.in" target="_blank">libvirt.h.in</a> b/include/libvirt/<a href="http://libvirt.h.in" target="_blank">libvirt.h.in</a><br>
index a47e33c..d6e0d9a 100644<br>
--- a/include/libvirt/<a href="http://libvirt.h.in" target="_blank">libvirt.h.in</a><br>
+++ b/include/libvirt/<a href="http://libvirt.h.in" target="_blank">libvirt.h.in</a><br>
@@ -4006,6 +4006,17 @@ int virConnectCompareCPU(virConnectPtr conn,<br>
                          const char *xmlDesc,<br>
                          unsigned int flags);<br>
<br>
+/**<br>
+ * virConnectGetCPUMapDesc:<br>
+ *<br>
+ * @conn: virConnect connection<br>
+ *<br>
+ * Get the content of the cpu_map.xml file used by the connection.<br>
+ *<br>
+ * Returns XML description of the cpu_map.xml file.<br>
+ */<br>
+char *virConnectGetCPUMapDesc(virConnectPtr conn);<br>
+<br></blockquote><div><br></div><div style>So maybe others disagree with me but the naming really doesn't feel good here. I know that's a terrible reason but it really just feels like we're modeling the name of a file to an API. virConnectGetCPUTemplates(virConnectPtr conn) maybe? I don't really know. For hypervisors other than qemu, they won't call that cpu_map.xml.</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
 /**<br>
  * virConnectBaselineCPUFlags<br>
diff --git a/src/driver.h b/src/driver.h<br>
index be64333..ab31262 100644<br>
--- a/src/driver.h<br>
+++ b/src/driver.h<br>
@@ -681,6 +681,9 @@ typedef char *<br>
                             unsigned int ncpus,<br>
                             unsigned int flags);<br>
<br>
+typedef char *<br>
+(*virDrvConnectGetCPUMapDesc)(virConnectPtr conn);<br>
+<br>
 typedef int<br>
 (*virDrvDomainGetJobInfo)(virDomainPtr domain,<br>
                           virDomainJobInfoPtr info);<br>
@@ -1332,6 +1335,7 @@ struct _virDriver {<br>
     virDrvDomainMigratePerform3Params domainMigratePerform3Params;<br>
     virDrvDomainMigrateFinish3Params domainMigrateFinish3Params;<br>
     virDrvDomainMigrateConfirm3Params domainMigrateConfirm3Params;<br>
+    virDrvConnectGetCPUMapDesc connectGetCPUMapDesc;<br>
 };<br>
<br>
<br>
diff --git a/src/libvirt.c b/src/libvirt.c<br>
index 07a3fd5..5e5e594 100644<br>
--- a/src/libvirt.c<br>
+++ b/src/libvirt.c<br>
@@ -18519,6 +18519,44 @@ error:<br>
<br>
<br>
 /**<br>
+ * virConnectGetCPUMapDesc:<br>
+ *<br>
+ * @conn: virConnect connection<br>
+ *<br>
+ * Get the content of the cpu_map.xml file used by the connection.<br>
+ *<br>
+ * Returns the content of the cpu_map.xml file.  The result must be freed<br>
+ * by the caller of this function.<br>
+ */<br>
+char *<br>
+virConnectGetCPUMapDesc(virConnectPtr conn)<br>
+{<br>
+    VIR_DEBUG("conn=%p", conn);<br>
+<br>
+    virResetLastError();<br>
+<br>
+    if (!VIR_IS_CONNECT(conn)) {<br>
+        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);<br>
+        virDispatchError(NULL);<br>
+        return NULL;<br>
+    }<br>
+<br>
+    if (conn->driver->connectGetCPUMapDesc) {<br>
+        char *ret = conn->driver->connectGetCPUMapDesc(conn);<br>
+        if (ret == NULL)<br>
+            goto error;<br>
+        return ret;<br>
+    }<br>
+<br>
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);<br>
+<br>
+error:<br>
+    virDispatchError(conn);<br>
+    return NULL;<br>
+}<br>
+<br>
+<br>
+/**<br>
  * virConnectBaselineCPU:<br>
  *<br>
  * @conn: virConnect connection<br>
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms<br>
index c25a61f..ed6d2a0 100644<br>
--- a/src/libvirt_private.syms<br>
+++ b/src/libvirt_private.syms<br>
@@ -2074,6 +2074,7 @@ virSetUIDGID;<br>
 virSetUIDGIDWithCaps;<br>
 virStrIsPrint;<br>
 virValidateWWN;<br>
+virGetCPUMapDesc;<br>
<br>
<br>
 # util/viruuid.h<br>
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms<br>
index bbdf78a..8023c7e 100644<br>
--- a/src/libvirt_public.syms<br>
+++ b/src/libvirt_public.syms<br>
@@ -629,6 +629,7 @@ LIBVIRT_1.1.0 {<br>
<br>
 LIBVIRT_1.1.1 {<br>
     global:<br>
+        virConnectGetCPUMapDesc;<br>
         virDomainCreateWithFiles;<br>
         virDomainCreateXMLWithFiles;<br>
         virDomainSetMemoryStatsPeriod;<br></blockquote><div><br></div><div><br></div><div style>You can't add that to 1.1.1 since this won't actually be in 1.1.1. You need to do something like:</div><div style><br>
</div><div style>LIBVIRT_1.1.2 {</div><div style>    global:</div><div style>        virConnectGetCPUMapDesc;</div><div style>} LIBVIRT_1.1.1;   </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c<br>
index 9cb95ff..633248b 100644<br>
--- a/src/lxc/lxc_driver.c<br>
+++ b/src/lxc/lxc_driver.c<br>
@@ -4590,6 +4590,16 @@ lxcNodeSuspendForDuration(virConnectPtr conn,<br>
 }<br>
<br>
<br>
+static char *<br>
+lxcConnectGetCPUMapDesc(virConnectPtr conn)<br>
+{<br>
+    if (virConnectGetCPUMapDescEnsureACL(conn) < 0)<br>
+        return NULL;<br>
+<br>
+    return virGetCPUMapDesc();<br>
+}<br>
+<br>
+<br>
 /* Function Tables */<br>
 static virDriver lxcDriver = {<br>
     .no = VIR_DRV_LXC,<br>
@@ -4671,6 +4681,7 @@ static virDriver lxcDriver = {<br>
     .domainShutdownFlags = lxcDomainShutdownFlags, /* 1.0.1 */<br>
     .domainReboot = lxcDomainReboot, /* 1.0.1 */<br>
     .domainLxcOpenNamespace = lxcDomainLxcOpenNamespace, /* 1.0.2 */<br>
+    .connectGetCPUMapDesc = lxcConnectGetCPUMapDesc, /* 1.1.0 */<br>
 };</blockquote><div><br></div><div style>Does this even make sense to wire up LXC? You can't change CPUs for LXC.</div><div style><br></div><div style> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
 static virStateDriver lxcStateDriver = {<br>
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c<br>
index 2ad236e..4a1d6fa 100644<br>
--- a/src/qemu/qemu_driver.c<br>
+++ b/src/qemu/qemu_driver.c<br>
@@ -16033,6 +16033,15 @@ qemuNodeSuspendForDuration(virConnectPtr conn,<br>
     return nodeSuspendForDuration(target, duration, flags);<br>
 }<br>
<br>
+static char *<br>
+qemuConnectGetCPUMapDesc(virConnectPtr conn)<br>
+{<br>
+    if (virConnectGetCPUMapDescEnsureACL(conn) < 0)<br>
+        return NULL;<br>
+<br>
+    return virGetCPUMapDesc();<br>
+}<br>
+<br>
<br>
 static virDriver qemuDriver = {<br>
     .no = VIR_DRV_QEMU,<br>
@@ -16220,6 +16229,7 @@ static virDriver qemuDriver = {<br>
     .domainMigratePerform3Params = qemuDomainMigratePerform3Params, /* 1.1.0 */<br>
     .domainMigrateFinish3Params = qemuDomainMigrateFinish3Params, /* 1.1.0 */<br>
     .domainMigrateConfirm3Params = qemuDomainMigrateConfirm3Params, /* 1.1.0 */<br>
+    .connectGetCPUMapDesc = qemuConnectGetCPUMapDesc, /* 1.1.0 */<br>
 };<br></blockquote><div><br></div><div style>1.1.0 is already released. The next version is 1.1.2</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c<br>
index 71d0034..017c7af 100644<br>
--- a/src/remote/remote_driver.c<br>
+++ b/src/remote/remote_driver.c<br>
@@ -6811,6 +6811,7 @@ static virDriver remote_driver = {<br>
     .domainMigratePerform3Params = remoteDomainMigratePerform3Params, /* 1.1.0 */<br>
     .domainMigrateFinish3Params = remoteDomainMigrateFinish3Params, /* 1.1.0 */<br>
     .domainMigrateConfirm3Params = remoteDomainMigrateConfirm3Params, /* 1.1.0 */<br>
+    .connectGetCPUMapDesc = remoteConnectGetCPUMapDesc, /* 1.1.0 */<br>
 };<br></blockquote><div><br></div><div style>Same.</div><div style> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
 static virNetworkDriver network_driver = {<br>
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x<br>
index 7cfebdf..6e17b41 100644<br>
--- a/src/remote/remote_protocol.x<br>
+++ b/src/remote/remote_protocol.x<br>
@@ -2837,6 +2837,10 @@ struct remote_domain_event_device_removed_msg {<br>
     remote_nonnull_string devAlias;<br>
 };<br>
<br>
+struct remote_connect_get_cpu_map_desc_ret {<br>
+    remote_nonnull_string xml;<br>
+};<br>
+<br>
 /*----- Protocol. -----*/<br>
<br>
 /* Define the program number, protocol version and procedure numbers here. */<br>
@@ -5000,5 +5004,11 @@ enum remote_procedure {<br>
      * @generate: both<br>
      * @acl: none<br>
      */<br>
-    REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311<br>
+    REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311,<br>
+<br>
+    /**<br>
+     * @generate: both<br>
+     * @acl: connect:read<br>
+     */<br>
+    REMOTE_PROC_CONNECT_GET_CPU_MAP_DESC = 312<br>
 };<br>
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs<br>
index 4e27aae..ce1e9f5 100644<br>
--- a/src/remote_protocol-structs<br>
+++ b/src/remote_protocol-structs<br>
@@ -2316,6 +2316,9 @@ struct remote_domain_event_device_removed_msg {<br>
         remote_nonnull_domain      dom;<br>
         remote_nonnull_string      devAlias;<br>
 };<br>
+struct remote_connect_get_cpu_map_desc_ret {<br>
+    remote_nonnull_string xml;<br>
+};<br>
 enum remote_procedure {<br>
         REMOTE_PROC_CONNECT_OPEN = 1,<br>
         REMOTE_PROC_CONNECT_CLOSE = 2,<br>
@@ -2628,4 +2631,5 @@ enum remote_procedure {<br>
         REMOTE_PROC_DOMAIN_CREATE_XML_WITH_FILES = 309,<br>
         REMOTE_PROC_DOMAIN_CREATE_WITH_FILES = 310,<br>
         REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311,<br>
+        REMOTE_PROC_CONNECT_GET_CPU_MAP_DESC = 312,<br>
 };<br>
diff --git a/src/test/test_driver.c b/src/test/test_driver.c<br>
index d7b2e40..82610b3 100644<br>
--- a/src/test/test_driver.c<br>
+++ b/src/test/test_driver.c<br>
@@ -5801,6 +5801,11 @@ testDomainScreenshot(virDomainPtr dom ATTRIBUTE_UNUSED,<br>
     return ret;<br>
 }<br>
<br>
+static char *<br>
+testConnectGetCPUMapDesc(virConnectPtr conn ATTRIBUTE_UNUSED)<br>
+{<br>
+    return virGetCPUMapDesc();<br>
+}<br>
<br>
 static virDriver testDriver = {<br>
     .no = VIR_DRV_TEST,<br>
@@ -5872,6 +5877,7 @@ static virDriver testDriver = {<br>
     .connectIsAlive = testConnectIsAlive, /* 0.9.8 */<br>
     .nodeGetCPUMap = testNodeGetCPUMap, /* 1.0.0 */<br>
     .domainScreenshot = testDomainScreenshot, /* 1.0.5 */<br>
+    .connectGetCPUMapDesc = testConnectGetCPUMapDesc, /* 1.1.0 */<br>
 };<br>
<br>
 static virNetworkDriver testNetworkDriver = {<br>
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c<br>
index 9ca352f..2aa2c08 100644<br>
--- a/src/uml/uml_driver.c<br>
+++ b/src/uml/uml_driver.c<br>
@@ -2831,6 +2831,16 @@ umlNodeSuspendForDuration(virConnectPtr conn,<br>
 }<br>
<br>
<br>
+static char *<br>
+umlConnectGetCPUMapDesc(virConnectPtr conn)<br>
+{<br>
+    if (virConnectGetCPUMapDescEnsureACL(conn) < 0)<br>
+        return NULL;<br>
+<br>
+    return virGetCPUMapDesc();<br>
+}<br>
+<br>
+<br>
 static virDriver umlDriver = {<br>
     .no = VIR_DRV_UML,<br>
     .name = "UML",<br>
@@ -2892,6 +2902,7 @@ static virDriver umlDriver = {<br>
     .nodeSuspendForDuration = umlNodeSuspendForDuration, /* 0.9.8 */<br>
     .nodeGetMemoryParameters = umlNodeGetMemoryParameters, /* 0.10.2 */<br>
     .nodeSetMemoryParameters = umlNodeSetMemoryParameters, /* 0.10.2 */<br>
+    .connectGetCPUMapDesc = umlConnectGetCPUMapDesc, /* 1.1.0 */<br>
 };<br></blockquote><div><br></div><div>1.1.2 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
 static virStateDriver umlStateDriver = {<br>
diff --git a/src/util/virutil.c b/src/util/virutil.c<br>
index 34f5998..9d71a53 100644<br>
--- a/src/util/virutil.c<br>
+++ b/src/util/virutil.c<br>
@@ -80,6 +80,7 @@<br>
 #include "virprocess.h"<br>
 #include "virstring.h"<br>
 #include "virutil.h"<br>
+#include "configmake.h"<br>
<br>
 #ifndef NSIG<br>
 # define NSIG 32<br>
@@ -2116,3 +2117,25 @@ cleanup:<br>
<br>
     return rc;<br>
 }<br>
+<br>
+char *<br>
+virGetCPUMapDesc(void)<br>
+{<br>
+    char *data, *ret = NULL;<br>
+    int len;<br>
+    const char *cpumapfile = PKGDATADIR "/cpu_map.xml";<br>
+    if ((len = virFileReadAll(cpumapfile, 1024 * 1024, &data)) < 0) {<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    if (VIR_ALLOC_N(ret, len + 1) < 0) {<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    memcpy(ret, data, len);<br>
+    ret[len] = '\0';<br>
+<br>
+cleanup:<br>
+    VIR_FREE(data);<br>
+    return ret;<br>
+}<br></blockquote><div><br></div><div style>Does this make any sense to wire up for UML? Same case as LXC.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

diff --git a/src/util/virutil.h b/src/util/virutil.h<br>
index 4b06992..11030c5 100644<br>
--- a/src/util/virutil.h<br>
+++ b/src/util/virutil.h<br>
@@ -172,4 +172,7 @@ int virCompareLimitUlong(unsigned long long a, unsigned long b);<br>
<br>
 int virParseOwnershipIds(const char *label, uid_t *uidPtr, gid_t *gidPtr);<br>
<br>
+<br>
+char *virGetCPUMapDesc(void);<br>
+<br>
 #endif /* __VIR_UTIL_H__ */<br>
diff --git a/tools/virsh-host.c b/tools/virsh-host.c<br>
index 880ae4b..3bc4f73 100644<br>
--- a/tools/virsh-host.c<br>
+++ b/tools/virsh-host.c<br>
@@ -626,6 +626,21 @@ cmdURI(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)<br>
     return true;<br>
 }<br>
<br>
+static bool<br>
+cmdCPUMapDesc(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)<br>
+{<br>
+    char *xml = virConnectGetCPUMapDesc(ctl->conn);<br>
+    if (xml == NULL) {<br>
+        vshError(ctl, "%s", _("failed to get CPU Map XML file"));<br>
+        return false;<br>
+    }<br>
+<br>
+    vshPrint(ctl, "%s\n", xml);<br>
+    VIR_FREE(xml);<br>
+<br>
+    return true;<br>
+}<br>
+<br>
 /*<br>
  * "version" command<br>
  */<br>
@@ -851,6 +866,12 @@ const vshCmdDef hostAndHypervisorCmds[] = {<br>
      .info = info_capabilities,<br>
      .flags = 0<br>
     },<br>
+    {.name = "cpu-map-desc",<br>
+     .handler = cmdCPUMapDesc,<br>
+     .opts = NULL,<br>
+     .info = info_uri,<br>
+     .flags = 0<br>
+    },<br></blockquote><div><br></div><div style>Even if we keep the API name you suggested above, we definitely want a better name here. This is way too vague for someone to know what this command name is/does.</div><div>
<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
     {.name = "freecell",<br>
      .handler = cmdFreecell,<br>
      .opts = opts_freecell,<br>
diff --git a/tools/virsh.pod b/tools/virsh.pod<br>
index 0ae5178..d705a54 100644<br>
--- a/tools/virsh.pod<br>
+++ b/tools/virsh.pod<br>
@@ -163,6 +163,7 @@ group as an option.  For example:<br>
<br>
   Host and Hypervisor (help keyword 'host'):<br>
      capabilities                   capabilities<br>
+     cpu-map-desc                   print the content of the cpu_map.xml file<br>
      connect                        (re)connect to hypervisor<br>
      freecell                       NUMA free memory<br>
      hostname                       print the hypervisor hostname<br>
@@ -358,6 +359,10 @@ current domain is in.<br>
<br>
 =over 4<br>
<br>
+=item B<cpu-map-desc><br>
+<br>
+Print the content of the cpu_map.xml file used by the hypervisor.<br>
+<br>
 =item B<running><br>
<br>
 The domain is currently running on a CPU<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.3.1<br>
<br>
--<br>
libvir-list mailing list<br>
<a href="mailto:libvir-list@redhat.com">libvir-list@redhat.com</a><br>
<a href="https://www.redhat.com/mailman/listinfo/libvir-list" target="_blank">https://www.redhat.com/mailman/listinfo/libvir-list</a><br>
</font></span></blockquote></div><br><br clear="all"><div style>I'm wondering if this could some how be done as an extension to the virConnectBaselineCPU APIs? It would probably have to be another API entirely but at least similar in naming scope.</div>
<div style><br></div><div style>Or potentially generic-ify this a bit more to make it like a virConnectHypervisorCapabilities() where right now it just returns back the CPUs the HV can emulate. In the future it can have support for other things if we need it to.</div>
<div style><br></div><div style>Just trying to step back and see the potential for a bigger picture or expandability in the API in the future, if that's not what's wanted then ignore my comments. But do fix the versioning reviews above.</div>
<div><br></div>-- <br>Doug Goldstein
</div></div>