--- I have started working on: https://bugzilla.redhat.com/show_bug.cgi?id=916786 Before I split it in a series of commits, test it better and then proceed to virt-manager, are you ok with this idea? include/libvirt/libvirt.h.in | 11 +++++++++++ src/driver.h | 4 ++++ src/libvirt.c | 38 ++++++++++++++++++++++++++++++++++++++ src/libvirt_private.syms | 1 + src/libvirt_public.syms | 1 + src/lxc/lxc_driver.c | 11 +++++++++++ src/qemu/qemu_driver.c | 10 ++++++++++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 12 +++++++++++- src/remote_protocol-structs | 4 ++++ src/test/test_driver.c | 6 ++++++ src/uml/uml_driver.c | 11 +++++++++++ src/util/virutil.c | 23 +++++++++++++++++++++++ src/util/virutil.h | 3 +++ tools/virsh-host.c | 21 +++++++++++++++++++++ tools/virsh.pod | 5 +++++ 16 files changed, 161 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index a47e33c..d6e0d9a 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4006,6 +4006,17 @@ int virConnectCompareCPU(virConnectPtr conn, const char *xmlDesc, unsigned int flags); +/** + * virConnectGetCPUMapDesc: + * + * @conn: virConnect connection + * + * Get the content of the cpu_map.xml file used by the connection. + * + * Returns XML description of the cpu_map.xml file. + */ +char *virConnectGetCPUMapDesc(virConnectPtr conn); + /** * virConnectBaselineCPUFlags diff --git a/src/driver.h b/src/driver.h index be64333..ab31262 100644 --- a/src/driver.h +++ b/src/driver.h @@ -681,6 +681,9 @@ typedef char * unsigned int ncpus, unsigned int flags); +typedef char * +(*virDrvConnectGetCPUMapDesc)(virConnectPtr conn); + typedef int (*virDrvDomainGetJobInfo)(virDomainPtr domain, virDomainJobInfoPtr info); @@ -1332,6 +1335,7 @@ struct _virDriver { virDrvDomainMigratePerform3Params domainMigratePerform3Params; virDrvDomainMigrateFinish3Params domainMigrateFinish3Params; virDrvDomainMigrateConfirm3Params domainMigrateConfirm3Params; + virDrvConnectGetCPUMapDesc connectGetCPUMapDesc; }; diff --git a/src/libvirt.c b/src/libvirt.c index 07a3fd5..5e5e594 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -18519,6 +18519,44 @@ error: /** + * virConnectGetCPUMapDesc: + * + * @conn: virConnect connection + * + * Get the content of the cpu_map.xml file used by the connection. + * + * Returns the content of the cpu_map.xml file. The result must be freed + * by the caller of this function. + */ +char * +virConnectGetCPUMapDesc(virConnectPtr conn) +{ + VIR_DEBUG("conn=%p", conn); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return NULL; + } + + if (conn->driver->connectGetCPUMapDesc) { + char *ret = conn->driver->connectGetCPUMapDesc(conn); + if (ret == NULL) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(conn); + return NULL; +} + + +/** * virConnectBaselineCPU: * * @conn: virConnect connection diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c25a61f..ed6d2a0 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2074,6 +2074,7 @@ virSetUIDGID; virSetUIDGIDWithCaps; virStrIsPrint; virValidateWWN; +virGetCPUMapDesc; # util/viruuid.h diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index bbdf78a..8023c7e 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -629,6 +629,7 @@ LIBVIRT_1.1.0 { LIBVIRT_1.1.1 { global: + virConnectGetCPUMapDesc; virDomainCreateWithFiles; virDomainCreateXMLWithFiles; virDomainSetMemoryStatsPeriod; diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 9cb95ff..633248b 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -4590,6 +4590,16 @@ lxcNodeSuspendForDuration(virConnectPtr conn, } +static char * +lxcConnectGetCPUMapDesc(virConnectPtr conn) +{ + if (virConnectGetCPUMapDescEnsureACL(conn) < 0) + return NULL; + + return virGetCPUMapDesc(); +} + + /* Function Tables */ static virDriver lxcDriver = { .no = VIR_DRV_LXC, @@ -4671,6 +4681,7 @@ static virDriver lxcDriver = { .domainShutdownFlags = lxcDomainShutdownFlags, /* 1.0.1 */ .domainReboot = lxcDomainReboot, /* 1.0.1 */ .domainLxcOpenNamespace = lxcDomainLxcOpenNamespace, /* 1.0.2 */ + .connectGetCPUMapDesc = lxcConnectGetCPUMapDesc, /* 1.1.0 */ }; static virStateDriver lxcStateDriver = { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2ad236e..4a1d6fa 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16033,6 +16033,15 @@ qemuNodeSuspendForDuration(virConnectPtr conn, return nodeSuspendForDuration(target, duration, flags); } +static char * +qemuConnectGetCPUMapDesc(virConnectPtr conn) +{ + if (virConnectGetCPUMapDescEnsureACL(conn) < 0) + return NULL; + + return virGetCPUMapDesc(); +} + static virDriver qemuDriver = { .no = VIR_DRV_QEMU, @@ -16220,6 +16229,7 @@ static virDriver qemuDriver = { .domainMigratePerform3Params = qemuDomainMigratePerform3Params, /* 1.1.0 */ .domainMigrateFinish3Params = qemuDomainMigrateFinish3Params, /* 1.1.0 */ .domainMigrateConfirm3Params = qemuDomainMigrateConfirm3Params, /* 1.1.0 */ + .connectGetCPUMapDesc = qemuConnectGetCPUMapDesc, /* 1.1.0 */ }; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 71d0034..017c7af 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -6811,6 +6811,7 @@ static virDriver remote_driver = { .domainMigratePerform3Params = remoteDomainMigratePerform3Params, /* 1.1.0 */ .domainMigrateFinish3Params = remoteDomainMigrateFinish3Params, /* 1.1.0 */ .domainMigrateConfirm3Params = remoteDomainMigrateConfirm3Params, /* 1.1.0 */ + .connectGetCPUMapDesc = remoteConnectGetCPUMapDesc, /* 1.1.0 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 7cfebdf..6e17b41 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2837,6 +2837,10 @@ struct remote_domain_event_device_removed_msg { remote_nonnull_string devAlias; }; +struct remote_connect_get_cpu_map_desc_ret { + remote_nonnull_string xml; +}; + /*----- Protocol. -----*/ /* Define the program number, protocol version and procedure numbers here. */ @@ -5000,5 +5004,11 @@ enum remote_procedure { * @generate: both * @acl: none */ - REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311 + REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311, + + /** + * @generate: both + * @acl: connect:read + */ + REMOTE_PROC_CONNECT_GET_CPU_MAP_DESC = 312 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 4e27aae..ce1e9f5 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2316,6 +2316,9 @@ struct remote_domain_event_device_removed_msg { remote_nonnull_domain dom; remote_nonnull_string devAlias; }; +struct remote_connect_get_cpu_map_desc_ret { + remote_nonnull_string xml; +}; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN = 1, REMOTE_PROC_CONNECT_CLOSE = 2, @@ -2628,4 +2631,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_CREATE_XML_WITH_FILES = 309, REMOTE_PROC_DOMAIN_CREATE_WITH_FILES = 310, REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311, + REMOTE_PROC_CONNECT_GET_CPU_MAP_DESC = 312, }; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index d7b2e40..82610b3 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -5801,6 +5801,11 @@ testDomainScreenshot(virDomainPtr dom ATTRIBUTE_UNUSED, return ret; } +static char * +testConnectGetCPUMapDesc(virConnectPtr conn ATTRIBUTE_UNUSED) +{ + return virGetCPUMapDesc(); +} static virDriver testDriver = { .no = VIR_DRV_TEST, @@ -5872,6 +5877,7 @@ static virDriver testDriver = { .connectIsAlive = testConnectIsAlive, /* 0.9.8 */ .nodeGetCPUMap = testNodeGetCPUMap, /* 1.0.0 */ .domainScreenshot = testDomainScreenshot, /* 1.0.5 */ + .connectGetCPUMapDesc = testConnectGetCPUMapDesc, /* 1.1.0 */ }; static virNetworkDriver testNetworkDriver = { diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 9ca352f..2aa2c08 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -2831,6 +2831,16 @@ umlNodeSuspendForDuration(virConnectPtr conn, } +static char * +umlConnectGetCPUMapDesc(virConnectPtr conn) +{ + if (virConnectGetCPUMapDescEnsureACL(conn) < 0) + return NULL; + + return virGetCPUMapDesc(); +} + + static virDriver umlDriver = { .no = VIR_DRV_UML, .name = "UML", @@ -2892,6 +2902,7 @@ static virDriver umlDriver = { .nodeSuspendForDuration = umlNodeSuspendForDuration, /* 0.9.8 */ .nodeGetMemoryParameters = umlNodeGetMemoryParameters, /* 0.10.2 */ .nodeSetMemoryParameters = umlNodeSetMemoryParameters, /* 0.10.2 */ + .connectGetCPUMapDesc = umlConnectGetCPUMapDesc, /* 1.1.0 */ }; static virStateDriver umlStateDriver = { diff --git a/src/util/virutil.c b/src/util/virutil.c index 34f5998..9d71a53 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -80,6 +80,7 @@ #include "virprocess.h" #include "virstring.h" #include "virutil.h" +#include "configmake.h" #ifndef NSIG # define NSIG 32 @@ -2116,3 +2117,25 @@ cleanup: return rc; } + +char * +virGetCPUMapDesc(void) +{ + char *data, *ret = NULL; + int len; + const char *cpumapfile = PKGDATADIR "/cpu_map.xml"; + if ((len = virFileReadAll(cpumapfile, 1024 * 1024, &data)) < 0) { + goto cleanup; + } + + if (VIR_ALLOC_N(ret, len + 1) < 0) { + goto cleanup; + } + + memcpy(ret, data, len); + ret[len] = '\0'; + +cleanup: + VIR_FREE(data); + return ret; +} diff --git a/src/util/virutil.h b/src/util/virutil.h index 4b06992..11030c5 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -172,4 +172,7 @@ int virCompareLimitUlong(unsigned long long a, unsigned long b); int virParseOwnershipIds(const char *label, uid_t *uidPtr, gid_t *gidPtr); + +char *virGetCPUMapDesc(void); + #endif /* __VIR_UTIL_H__ */ diff --git a/tools/virsh-host.c b/tools/virsh-host.c index 880ae4b..3bc4f73 100644 --- a/tools/virsh-host.c +++ b/tools/virsh-host.c @@ -626,6 +626,21 @@ cmdURI(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) return true; } +static bool +cmdCPUMapDesc(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) +{ + char *xml = virConnectGetCPUMapDesc(ctl->conn); + if (xml == NULL) { + vshError(ctl, "%s", _("failed to get CPU Map XML file")); + return false; + } + + vshPrint(ctl, "%s\n", xml); + VIR_FREE(xml); + + return true; +} + /* * "version" command */ @@ -851,6 +866,12 @@ const vshCmdDef hostAndHypervisorCmds[] = { .info = info_capabilities, .flags = 0 }, + {.name = "cpu-map-desc", + .handler = cmdCPUMapDesc, + .opts = NULL, + .info = info_uri, + .flags = 0 + }, {.name = "freecell", .handler = cmdFreecell, .opts = opts_freecell, diff --git a/tools/virsh.pod b/tools/virsh.pod index 0ae5178..d705a54 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -163,6 +163,7 @@ group as an option. For example: Host and Hypervisor (help keyword 'host'): capabilities capabilities + cpu-map-desc print the content of the cpu_map.xml file connect (re)connect to hypervisor freecell NUMA free memory hostname print the hypervisor hostname @@ -358,6 +359,10 @@ current domain is in. =over 4 +=item B<cpu-map-desc> + +Print the content of the cpu_map.xml file used by the hypervisor. + =item B<running> The domain is currently running on a CPU -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list