mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 23:25:24 +00:00
libxl: implement virDomainGetNumaParameters
Although, having it depending on Xen >= 4.3 (by using the proper libxl feature flag). Xen currently implements a NUMA placement policy which is basically the same as the 'interleaved' policy of `numactl', although it can be applied on a subset of the available nodes. We therefore hardcode "interleave" as 'numa_mode', and we use the newly introduced libxl interface to figure out what nodes a domain spans ('numa_nodeset'). With this change, it is now possible to query the NUMA node affinity of a running domain: [raistlin@Zhaman ~]$ sudo virsh --connect xen:/// list Id Name State ---------------------------------------------------- 23 F18_x64 running [raistlin@Zhaman ~]$ sudo virsh --connect xen:/// numatune 23 numa_mode : interleave numa_nodeset : 1 Signed-off-by: Dario Faggioli <dario.faggioli@citrix.com>
This commit is contained in:
parent
98984b71a8
commit
261c4f5fb9
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <libxl.h>
|
#include <libxl.h>
|
||||||
|
#include <libxl_utils.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
|
||||||
@ -4499,6 +4500,143 @@ libxlDomainSetSchedulerParameters(virDomainPtr dom, virTypedParameterPtr params,
|
|||||||
return libxlDomainSetSchedulerParametersFlags(dom, params, nparams, 0);
|
return libxlDomainSetSchedulerParametersFlags(dom, params, nparams, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NUMA node affinity information is available through libxl
|
||||||
|
* starting from Xen 4.3. */
|
||||||
|
#ifdef LIBXL_HAVE_DOMAIN_NODEAFFINITY
|
||||||
|
|
||||||
|
/* Number of Xen NUMA parameters */
|
||||||
|
# define LIBXL_NUMA_NPARAM 2
|
||||||
|
|
||||||
|
static int
|
||||||
|
libxlDomainGetNumaParameters(virDomainPtr dom,
|
||||||
|
virTypedParameterPtr params,
|
||||||
|
int *nparams,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
libxlDriverPrivatePtr driver = dom->conn->privateData;
|
||||||
|
libxlDomainObjPrivatePtr priv;
|
||||||
|
virDomainObjPtr vm;
|
||||||
|
libxl_bitmap nodemap;
|
||||||
|
virBitmapPtr nodes = NULL;
|
||||||
|
char *nodeset = NULL;
|
||||||
|
int rc, ret = -1;
|
||||||
|
size_t i, j;
|
||||||
|
|
||||||
|
/* In Xen 4.3, it is possible to query the NUMA node affinity of a domain
|
||||||
|
* via libxl, but not to change it. We therefore only allow AFFECT_LIVE. */
|
||||||
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
||||||
|
VIR_TYPED_PARAM_STRING_OKAY, -1);
|
||||||
|
|
||||||
|
/* We blindly return a string, and let libvirt.c and remote_driver.c do
|
||||||
|
* the filtering on behalf of older clients that can't parse it. */
|
||||||
|
flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
|
||||||
|
|
||||||
|
libxlDriverLock(driver);
|
||||||
|
vm = virDomainObjListFindByUUID(driver->domains, dom->uuid);
|
||||||
|
libxlDriverUnlock(driver);
|
||||||
|
|
||||||
|
if (!vm) {
|
||||||
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
||||||
|
_("no domain with matching uuid"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virDomainGetNumaParametersEnsureACL(dom->conn, vm->def) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!virDomainObjIsActive(vm)) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||||
|
_("Domain is not running"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv = vm->privateData;
|
||||||
|
|
||||||
|
libxl_bitmap_init(&nodemap);
|
||||||
|
|
||||||
|
if ((*nparams) == 0) {
|
||||||
|
*nparams = LIBXL_NUMA_NPARAM;
|
||||||
|
ret = 0;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < LIBXL_NUMA_NPARAM && i < *nparams; i++) {
|
||||||
|
virMemoryParameterPtr param = ¶ms[i];
|
||||||
|
|
||||||
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
/* NUMA mode */
|
||||||
|
|
||||||
|
/* Xen implements something that is really close to numactl's
|
||||||
|
* 'interleave' policy (see `man 8 numactl' for details). */
|
||||||
|
if (virTypedParameterAssign(param, VIR_DOMAIN_NUMA_MODE,
|
||||||
|
VIR_TYPED_PARAM_INT,
|
||||||
|
VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
/* Node affinity */
|
||||||
|
|
||||||
|
/* Let's allocate both libxl and libvirt bitmaps */
|
||||||
|
if (libxl_node_bitmap_alloc(priv->ctx, &nodemap, 0) ||
|
||||||
|
!(nodes = virBitmapNew(libxl_get_max_nodes(priv->ctx)))) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = libxl_domain_get_nodeaffinity(priv->ctx,
|
||||||
|
vm->def->id,
|
||||||
|
&nodemap);
|
||||||
|
if (rc != 0) {
|
||||||
|
virReportSystemError(-rc, "%s",
|
||||||
|
_("unable to get numa affinity"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First, we convert libxl_bitmap into virBitmap. After that,
|
||||||
|
* we format virBitmap as a string that can be returned. */
|
||||||
|
virBitmapClearAll(nodes);
|
||||||
|
libxl_for_each_set_bit(j, nodemap) {
|
||||||
|
if (virBitmapSetBit(nodes, j)) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Node %zu out of range"), j);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeset = virBitmapFormat(nodes);
|
||||||
|
if (!nodeset && VIR_STRDUP(nodeset, "") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virTypedParameterAssign(param, VIR_DOMAIN_NUMA_NODESET,
|
||||||
|
VIR_TYPED_PARAM_STRING, nodeset) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
nodeset = NULL;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*nparams > LIBXL_NUMA_NPARAM)
|
||||||
|
*nparams = LIBXL_NUMA_NPARAM;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(nodeset);
|
||||||
|
virBitmapFree(nodes);
|
||||||
|
libxl_bitmap_dispose(&nodemap);
|
||||||
|
if (vm)
|
||||||
|
virObjectUnlock(vm);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
libxlDomainIsActive(virDomainPtr dom)
|
libxlDomainIsActive(virDomainPtr dom)
|
||||||
{
|
{
|
||||||
@ -4727,6 +4865,9 @@ static virDriver libxlDriver = {
|
|||||||
.domainGetSchedulerParametersFlags = libxlDomainGetSchedulerParametersFlags, /* 0.9.2 */
|
.domainGetSchedulerParametersFlags = libxlDomainGetSchedulerParametersFlags, /* 0.9.2 */
|
||||||
.domainSetSchedulerParameters = libxlDomainSetSchedulerParameters, /* 0.9.0 */
|
.domainSetSchedulerParameters = libxlDomainSetSchedulerParameters, /* 0.9.0 */
|
||||||
.domainSetSchedulerParametersFlags = libxlDomainSetSchedulerParametersFlags, /* 0.9.2 */
|
.domainSetSchedulerParametersFlags = libxlDomainSetSchedulerParametersFlags, /* 0.9.2 */
|
||||||
|
#ifdef LIBXL_HAVE_DOMAIN_NODEAFFINITY
|
||||||
|
.domainGetNumaParameters = libxlDomainGetNumaParameters, /* 1.1.1 */
|
||||||
|
#endif
|
||||||
.nodeGetFreeMemory = libxlNodeGetFreeMemory, /* 0.9.0 */
|
.nodeGetFreeMemory = libxlNodeGetFreeMemory, /* 0.9.0 */
|
||||||
.nodeGetCellsFreeMemory = libxlNodeGetCellsFreeMemory, /* 1.1.1 */
|
.nodeGetCellsFreeMemory = libxlNodeGetCellsFreeMemory, /* 1.1.1 */
|
||||||
.connectDomainEventRegister = libxlConnectDomainEventRegister, /* 0.9.0 */
|
.connectDomainEventRegister = libxlConnectDomainEventRegister, /* 0.9.0 */
|
||||||
|
Loading…
Reference in New Issue
Block a user