src/conf/netdev_vport_profile_conf.c
src/conf/network_conf.c
src/conf/node_device_conf.c
+src/conf/numatune_conf.c
src/conf/nwfilter_conf.c
src/conf/nwfilter_params.c
src/conf/object_event.c
virDomainVcpuPinDefFree(def->cputune.emulatorpin);
- virBitmapFree(def->numatune.memory.nodemask);
+ virDomainNumatuneFree(def->numatune);
virSysinfoDefFree(def->sysinfo);
unsigned long count;
bool uuid_generated = false;
virHashTablePtr bootHash = NULL;
- xmlNodePtr cur;
bool usb_none = false;
bool usb_other = false;
bool usb_master = false;
}
}
- /* Extract numatune if exists. */
- if ((n = virXPathNodeSet("./numatune", ctxt, &nodes)) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("cannot extract numatune nodes"));
+ if (virDomainNumatuneParseXML(def, ctxt) < 0)
goto error;
- }
-
- if (n > 1) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("only one numatune is supported"));
- VIR_FREE(nodes);
- goto error;
- }
-
- if (n) {
- cur = nodes[0]->children;
- while (cur != NULL) {
- if (cur->type == XML_ELEMENT_NODE) {
- if (xmlStrEqual(cur->name, BAD_CAST "memory")) {
- char *mode = NULL;
- char *placement = NULL;
- char *nodeset = NULL;
-
- mode = virXMLPropString(cur, "mode");
- if (mode) {
- if ((def->numatune.memory.mode =
- virDomainNumatuneMemModeTypeFromString(mode)) < 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Unsupported NUMA memory "
- "tuning mode '%s'"),
- mode);
- VIR_FREE(mode);
- goto error;
- }
- VIR_FREE(mode);
- } else {
- def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
- }
-
- nodeset = virXMLPropString(cur, "nodeset");
- if (nodeset) {
- if (virBitmapParse(nodeset,
- 0,
- &def->numatune.memory.nodemask,
- VIR_DOMAIN_CPUMASK_LEN) < 0) {
- VIR_FREE(nodeset);
- goto error;
- }
- VIR_FREE(nodeset);
- }
-
- placement = virXMLPropString(cur, "placement");
- int placement_mode = 0;
- if (placement) {
- if ((placement_mode =
- virDomainNumatunePlacementTypeFromString(placement)) < 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Unsupported memory placement "
- "mode '%s'"), placement);
- VIR_FREE(placement);
- goto error;
- }
- VIR_FREE(placement);
- } else if (def->numatune.memory.nodemask) {
- /* Defaults to "static" if nodeset is specified. */
- placement_mode = VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
- } else {
- /* Defaults to "placement" of <vcpu> if nodeset is
- * not specified.
- */
- if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC)
- placement_mode = VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
- else
- placement_mode = VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO;
- }
-
- if (placement_mode == VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC &&
- !def->numatune.memory.nodemask) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("nodeset for NUMA memory tuning must be set "
- "if 'placement' is 'static'"));
- goto error;
- }
-
- /* Ignore 'nodeset' if 'placement' is 'auto' finally */
- if (placement_mode == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO) {
- virBitmapFree(def->numatune.memory.nodemask);
- def->numatune.memory.nodemask = NULL;
- }
-
- /* Copy 'placement' of <numatune> to <vcpu> if its 'placement'
- * is not specified and 'placement' of <numatune> is specified.
- */
- if (placement_mode == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO &&
- !def->cpumask)
- def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO;
-
- def->numatune.memory.placement_mode = placement_mode;
- } else {
- virReportError(VIR_ERR_XML_ERROR,
- _("unsupported XML element %s"),
- (const char *)cur->name);
- goto error;
- }
- }
- cur = cur->next;
- }
- } else {
- /* Defaults NUMA memory placement mode to 'auto' if no <numatune>
- * and 'placement' of <vcpu> is 'auto'.
- */
- if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
- def->numatune.memory.placement_mode = VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO;
- def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
- }
- }
- VIR_FREE(nodes);
if ((n = virXPathNodeSet("./resource", ctxt, &nodes)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
def->cputune.emulator_period || def->cputune.emulator_quota)
virBufferAddLit(buf, "</cputune>\n");
- if (def->numatune.memory.nodemask ||
- def->numatune.memory.placement_mode) {
- const char *mode;
- char *nodemask = NULL;
- const char *placement;
-
- virBufferAddLit(buf, "<numatune>\n");
- virBufferAdjustIndent(buf, 2);
- mode = virDomainNumatuneMemModeTypeToString(def->numatune.memory.mode);
- virBufferAsprintf(buf, "<memory mode='%s' ", mode);
-
- if (def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC) {
- if (!(nodemask = virBitmapFormat(def->numatune.memory.nodemask)))
- goto error;
- virBufferAsprintf(buf, "nodeset='%s'/>\n", nodemask);
- VIR_FREE(nodemask);
- } else if (def->numatune.memory.placement_mode) {
- placement = virDomainNumatunePlacementTypeToString(def->numatune.memory.placement_mode);
- virBufferAsprintf(buf, "placement='%s'/>\n", placement);
- }
- virBufferAdjustIndent(buf, -2);
- virBufferAddLit(buf, "</numatune>\n");
- }
+ if (virDomainNumatuneFormatXML(buf, def->numatune) < 0)
+ goto error;
if (def->resource)
virDomainResourceDefFormat(buf, def->resource);
return 0;
}
+
+
+bool
+virDomainDefNeedsPlacementAdvice(virDomainDefPtr def)
+{
+ if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
+ return true;
+
+ if (virDomainNumatuneHasPlacementAuto(def->numatune))
+ return true;
+
+ return false;
+}
typedef struct _virDomainNetDef virDomainNetDef;
typedef virDomainNetDef *virDomainNetDefPtr;
+typedef struct _virDomainNumatune virDomainNumatune;
+typedef virDomainNumatune *virDomainNumatunePtr;
+
typedef struct _virDomainInputDef virDomainInputDef;
typedef virDomainInputDef *virDomainInputDefPtr;
virDomainVcpuPinDefPtr emulatorpin;
} cputune;
- virDomainNumatune numatune;
+ virDomainNumatunePtr numatune;
virDomainResourceDefPtr resource;
virDomainIdMapDef idmap;
const char *configDir,
unsigned int flags);
+bool virDomainDefNeedsPlacementAdvice(virDomainDefPtr def)
+ ATTRIBUTE_NONNULL(1);
+
#endif /* __DOMAIN_CONF_H */
#include "numatune_conf.h"
+#include "domain_conf.h"
+#include "viralloc.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_DOMAIN
+
VIR_ENUM_IMPL(virDomainNumatuneMemMode,
VIR_DOMAIN_NUMATUNE_MEM_LAST,
"strict",
"default",
"static",
"auto");
+
+struct _virDomainNumatune {
+ struct {
+ virBitmapPtr nodeset;
+ virDomainNumatuneMemMode mode;
+ virDomainNumatunePlacement placement;
+ } memory; /* pinning for all the memory */
+
+ /* Future NUMA tuning related stuff should go here. */
+};
+
+
+int
+virDomainNumatuneParseXML(virDomainDefPtr def,
+ xmlXPathContextPtr ctxt)
+{
+ char *tmp = NULL;
+ int mode = -1;
+ int n = 0;
+ int placement = -1;
+ int ret = -1;
+ virBitmapPtr nodeset = NULL;
+ xmlNodePtr node = NULL;
+
+ if (virXPathInt("count(./numatune)", ctxt, &n) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot extract numatune nodes"));
+ goto cleanup;
+ } else if (n > 1) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only one numatune is supported"));
+ goto cleanup;
+ }
+
+ node = virXPathNode("./numatune/memory[1]", ctxt);
+
+ if (def->numatune) {
+ virDomainNumatuneFree(def->numatune);
+ def->numatune = NULL;
+ }
+
+ if (!node && def->placement_mode != VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
+ return 0;
+
+ if (!node) {
+ /* We know that def->placement_mode is "auto" if we're here */
+ if (virDomainNumatuneSet(def, VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO,
+ -1, NULL) < 0)
+ goto cleanup;
+ return 0;
+ }
+
+ tmp = virXMLPropString(node, "mode");
+ if (tmp) {
+ mode = virDomainNumatuneMemModeTypeFromString(tmp);
+ if (mode < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unsupported NUMA memory tuning mode '%s'"),
+ tmp);
+ goto cleanup;
+ }
+ }
+ VIR_FREE(tmp);
+
+ tmp = virXMLPropString(node, "placement");
+ if (tmp) {
+ placement = virDomainNumatunePlacementTypeFromString(tmp);
+ if (placement < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unsupported NUMA memory placement mode '%s'"),
+ tmp);
+ goto cleanup;
+ }
+ }
+ VIR_FREE(tmp);
+
+ tmp = virXMLPropString(node, "nodeset");
+ if (tmp && virBitmapParse(tmp, 0, &nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0)
+ goto cleanup;
+ VIR_FREE(tmp);
+
+ if (virDomainNumatuneSet(def, placement, mode, nodeset) < 0)
+ goto cleanup;
+
+ if (!n) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ ret = 0;
+ cleanup:
+ virBitmapFree(nodeset);
+ VIR_FREE(tmp);
+ return ret;
+}
+
+int
+virDomainNumatuneFormatXML(virBufferPtr buf,
+ virDomainNumatunePtr numatune)
+{
+ const char *tmp = NULL;
+ char *nodeset = NULL;
+
+ if (!numatune)
+ return 0;
+
+ virBufferAddLit(buf, "<numatune>\n");
+ virBufferAdjustIndent(buf, 2);
+
+ tmp = virDomainNumatuneMemModeTypeToString(numatune->memory.mode);
+ virBufferAsprintf(buf, "<memory mode='%s' ", tmp);
+
+ if (numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC) {
+ if (!(nodeset = virBitmapFormat(numatune->memory.nodeset)))
+ return -1;
+ virBufferAsprintf(buf, "nodeset='%s'/>\n", nodeset);
+ VIR_FREE(nodeset);
+ } else if (numatune->memory.placement) {
+ tmp = virDomainNumatunePlacementTypeToString(numatune->memory.placement);
+ virBufferAsprintf(buf, "placement='%s'/>\n", tmp);
+ }
+
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</numatune>\n");
+ return 0;
+}
+
+void
+virDomainNumatuneFree(virDomainNumatunePtr numatune)
+{
+ if (!numatune)
+ return;
+
+ virBitmapFree(numatune->memory.nodeset);
+
+ VIR_FREE(numatune);
+}
+
+virDomainNumatuneMemMode
+virDomainNumatuneGetMode(virDomainNumatunePtr numatune)
+{
+ return numatune ? numatune->memory.mode : 0;
+}
+
+virBitmapPtr
+virDomainNumatuneGetNodeset(virDomainNumatunePtr numatune,
+ virBitmapPtr auto_nodeset)
+{
+ if (!numatune)
+ return NULL;
+
+ if (numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)
+ return auto_nodeset;
+
+ /*
+ * This weird logic has the same meaning as switch with
+ * auto/static/default, but can be more readably changed later.
+ */
+ if (numatune->memory.placement != VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC)
+ return NULL;
+
+ return numatune->memory.nodeset;
+}
+
+char *
+virDomainNumatuneFormatNodeset(virDomainNumatunePtr numatune,
+ virBitmapPtr auto_nodeset)
+{
+ return virBitmapFormat(virDomainNumatuneGetNodeset(numatune,
+ auto_nodeset));
+}
+
+int
+virDomainNumatuneMaybeFormatNodeset(virDomainNumatunePtr numatune,
+ virBitmapPtr auto_nodeset,
+ char **mask)
+{
+ *mask = NULL;
+
+ if (!numatune)
+ return 0;
+
+ if (numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO &&
+ !auto_nodeset) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Advice from numad is needed in case of "
+ "automatic numa placement"));
+ return -1;
+ }
+
+ *mask = virDomainNumatuneFormatNodeset(numatune, auto_nodeset);
+ if (!*mask)
+ return -1;
+
+ return 0;
+}
+
+int
+virDomainNumatuneSet(virDomainDefPtr def,
+ int placement,
+ int mode,
+ virBitmapPtr nodeset)
+{
+ bool create = !def->numatune; /* Whether we are creating new struct */
+ int ret = -1;
+ virDomainNumatunePtr numatune = NULL;
+
+ /* No need to do anything in this case */
+ if (mode == -1 && placement == -1 && !nodeset)
+ return 0;
+
+ /* Range checks */
+ if (mode != -1 &&
+ (mode < 0 || mode >= VIR_DOMAIN_NUMATUNE_MEM_LAST)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unsupported numatune mode '%d'"),
+ mode);
+ goto cleanup;
+ }
+ if (placement != -1 &&
+ (placement < 0 || placement >= VIR_DOMAIN_NUMATUNE_PLACEMENT_LAST)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unsupported numatune placement '%d'"),
+ mode);
+ goto cleanup;
+ }
+
+ if (create && VIR_ALLOC(def->numatune) < 0)
+ goto cleanup;
+ numatune = def->numatune;
+
+ if (create) {
+ /* Defaults for new struct */
+ if (mode == -1)
+ mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+
+ if (placement == -1)
+ placement = VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT;
+ }
+
+ if (mode != -1)
+ numatune->memory.mode = mode;
+ if (nodeset) {
+ virBitmapFree(numatune->memory.nodeset);
+ numatune->memory.nodeset = virBitmapNewCopy(nodeset);
+ if (!numatune->memory.nodeset)
+ goto cleanup;
+ if (placement == -1)
+ placement = VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
+ }
+
+ if (placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT) {
+ if (numatune->memory.nodeset ||
+ def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC)
+ placement = VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
+ else
+ placement = VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO;
+ }
+
+ if (placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC &&
+ !numatune->memory.nodeset) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("nodeset for NUMA memory tuning must be set "
+ "if 'placement' is 'static'"));
+ goto cleanup;
+ }
+
+ if (placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO) {
+ virBitmapFree(numatune->memory.nodeset);
+ numatune->memory.nodeset = NULL;
+ if (!def->cpumask)
+ def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO;
+ }
+
+ if (placement != -1)
+ numatune->memory.placement = placement;
+
+ ret = 0;
+ cleanup:
+ return ret;
+}
+
+bool
+virDomainNumatuneEquals(virDomainNumatunePtr n1,
+ virDomainNumatunePtr n2)
+{
+ if (!n1 && !n2)
+ return true;
+
+ if (!n1 || !n2)
+ return false;
+
+ if (n1->memory.mode != n2->memory.mode)
+ return false;
+
+ if (n1->memory.placement != n2->memory.placement)
+ return false;
+
+ return virBitmapEqual(n1->memory.nodeset, n2->memory.nodeset);
+}
+
+bool
+virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr numatune)
+{
+ if (!numatune)
+ return false;
+
+ if (numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)
+ return true;
+
+ return false;
+}
#ifndef __NUMATUNE_CONF_H__
# define __NUMATUNE_CONF_H__
+# include <libxml/xpath.h>
+
# include "internal.h"
# include "virutil.h"
# include "virbitmap.h"
+# include "virbuffer.h"
+
+/*
+ * Since numatune configuration is closely bound to the whole config,
+ * and because we don't have separate domain_conf headers for
+ * typedefs, structs and functions, we need to have a forward
+ * declaration here for virDomainDef due to circular dependencies.
+ */
+typedef struct _virDomainDef virDomainDef;
+typedef virDomainDef *virDomainDefPtr;
+
+
+typedef struct _virDomainNumatune virDomainNumatune;
+typedef virDomainNumatune *virDomainNumatunePtr;
typedef enum {
VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT = 0,
} virDomainNumatunePlacement;
VIR_ENUM_DECL(virDomainNumatunePlacement)
-
VIR_ENUM_DECL(virDomainNumatuneMemMode)
-typedef struct _virDomainNumatune virDomainNumatune;
-typedef virDomainNumatune *virDomainNumatunePtr;
-struct _virDomainNumatune {
- struct {
- virBitmapPtr nodemask;
- int mode; /* enum virDomainNumatuneMemMode */
- int placement_mode; /* enum virDomainNumatunePlacement */
- } memory; /* pinning for all the memory */
-
- /* Future NUMA tuning related stuff should go here. */
-};
+
+void virDomainNumatuneFree(virDomainNumatunePtr numatune);
+
+/*
+ * XML Parse/Format functions
+ */
+int virDomainNumatuneParseXML(virDomainDefPtr def, xmlXPathContextPtr ctxt)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+int virDomainNumatuneFormatXML(virBufferPtr buf, virDomainNumatunePtr numatune)
+ ATTRIBUTE_NONNULL(1);
+
+/*
+ * Getters
+ */
+virDomainNumatuneMemMode virDomainNumatuneGetMode(virDomainNumatunePtr numatune);
+
+virBitmapPtr virDomainNumatuneGetNodeset(virDomainNumatunePtr numatune,
+ virBitmapPtr auto_nodeset);
+
+/*
+ * Formatters
+ */
+char *virDomainNumatuneFormatNodeset(virDomainNumatunePtr numatune,
+ virBitmapPtr auto_nodeset);
+
+int virDomainNumatuneMaybeFormatNodeset(virDomainNumatunePtr numatune,
+ virBitmapPtr auto_nodeset,
+ char **mask);
+
+/*
+ * Setters
+ */
+int virDomainNumatuneSet(virDomainDefPtr def, int placement,
+ int mode, virBitmapPtr nodeset)
+ ATTRIBUTE_NONNULL(1);
+
+/*
+ * Other accessors
+ */
+bool virDomainNumatuneEquals(virDomainNumatunePtr n1,
+ virDomainNumatunePtr n2);
+
+bool virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr numatune);
#endif /* __NUMATUNE_CONF_H__ */
virDomainDefGetSecurityLabelDef;
virDomainDefMaybeAddController;
virDomainDefMaybeAddInput;
+virDomainDefNeedsPlacementAdvice;
virDomainDefNew;
virDomainDefParseFile;
virDomainDefParseNode;
# conf/numatune_conf.h
+virDomainNumatuneEquals;
+virDomainNumatuneFormatNodeset;
+virDomainNumatuneFormatXML;
+virDomainNumatuneFree;
+virDomainNumatuneGetMode;
+virDomainNumatuneGetNodeset;
+virDomainNumatuneHasPlacementAuto;
+virDomainNumatuneMaybeFormatNodeset;
virDomainNumatuneMemModeTypeFromString;
virDomainNumatuneMemModeTypeToString;
+virDomainNumatuneParseXML;
virDomainNumatunePlacementTypeFromString;
virDomainNumatunePlacementTypeToString;
+virDomainNumatuneSet;
# conf/nwfilter_conf.h
goto cleanup;
}
- if ((def->numatune.memory.nodemask ||
- (def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)) &&
- def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
- if (def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)
- mask = virBitmapFormat(nodemask);
- else
- mask = virBitmapFormat(def->numatune.memory.nodemask);
-
- if (!mask)
- return -1;
+ if (virDomainNumatuneMaybeFormatNodeset(def->numatune, nodemask, &mask) < 0)
+ goto cleanup;
- if (virCgroupSetCpusetMems(cgroup, mask) < 0)
- goto cleanup;
- }
+ if (mask && virCgroupSetCpusetMems(cgroup, mask) < 0)
+ goto cleanup;
ret = 0;
cleanup:
/* Get the advisory nodeset from numad if 'placement' of
* either <vcpu> or <numatune> is 'auto'.
*/
- if ((ctrl->def->placement_mode ==
- VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
- (ctrl->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)) {
+ if (virDomainDefNeedsPlacementAdvice(ctrl->def)) {
nodeset = virNumaGetAutoPlacementAdvice(ctrl->def->vcpus,
ctrl->def->mem.cur_balloon);
if (!nodeset)
/*
* lxc_native.c: LXC native configuration import
*
+ * Copyright (c) 2014 Red Hat, Inc.
* Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
*
* This library is free software; you can redistribute it and/or
lxcSetCpusetTune(virDomainDefPtr def, virConfPtr properties)
{
virConfValuePtr value;
+ virBitmapPtr nodeset = NULL;
if ((value = virConfGetValue(properties, "lxc.cgroup.cpuset.cpus")) &&
value->str) {
}
if ((value = virConfGetValue(properties, "lxc.cgroup.cpuset.mems")) &&
- value->str) {
- def->numatune.memory.placement_mode = VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
- def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
- if (virBitmapParse(value->str, 0, &def->numatune.memory.nodemask,
- VIR_DOMAIN_CPUMASK_LEN) < 0)
+ value->str) {
+ if (virBitmapParse(value->str, 0, &nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0)
return -1;
+ if (virDomainNumatuneSet(def, VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC,
+ VIR_DOMAIN_NUMATUNE_MEM_STRICT, nodeset) < 0) {
+ virBitmapFree(nodeset);
+ return -1;
+ }
+ virBitmapFree(nodeset);
}
return 0;
return -1;
}
- if (old->numatune.memory.mode != new->numatune.memory.mode ||
- old->numatune.memory.placement_mode != new->numatune.memory.placement_mode ||
- ((old->numatune.memory.nodemask != NULL || new->numatune.memory.nodemask != NULL) &&
- (old->numatune.memory.nodemask == NULL || new->numatune.memory.nodemask == NULL ||
- !virBitmapEqual(old->numatune.memory.nodemask, new->numatune.memory.nodemask)))){
-
+ if (!virDomainNumatuneEquals(old->numatune, new->numatune)) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
_("numa parameters are not supported "
"by parallels driver"));
if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
return 0;
- if ((vm->def->numatune.memory.nodemask ||
- (vm->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)) &&
- vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
-
- if (vm->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)
- mem_mask = virBitmapFormat(nodemask);
- else
- mem_mask = virBitmapFormat(vm->def->numatune.memory.nodemask);
-
- if (!mem_mask)
- goto cleanup;
+ if (virDomainNumatuneMaybeFormatNodeset(vm->def->numatune,
+ nodemask,
+ &mem_mask) < 0)
+ goto cleanup;
- if (virCgroupSetCpusetMems(priv->cgroup, mem_mask) < 0)
- goto cleanup;
- }
+ if (mem_mask &&
+ virCgroupSetCpusetMems(priv->cgroup, mem_mask) < 0)
+ goto cleanup;
if (vm->def->cpumask ||
(vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)) {
size_t i = 0;
int ret = -1;
- if (vm->def->numatune.memory.mode != VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
+ if (virDomainNumatuneGetMode(vm->def->numatune) !=
+ VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("change of nodeset for running domain "
"requires strict numa mode"));
virQEMUDriverConfigPtr cfg = NULL;
virCapsPtr caps = NULL;
qemuDomainObjPrivatePtr priv;
+ virBitmapPtr nodeset = NULL;
+ int mode = -1;
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG, -1);
virTypedParameterPtr param = ¶ms[i];
if (STREQ(param->field, VIR_DOMAIN_NUMA_MODE)) {
- int mode = param->value.i;
+ mode = param->value.i;
- if (mode >= VIR_DOMAIN_NUMATUNE_PLACEMENT_LAST ||
- mode < VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT)
- {
+ if (mode < 0 || mode >= VIR_DOMAIN_NUMATUNE_MEM_LAST) {
virReportError(VIR_ERR_INVALID_ARG,
- _("unsupported numa_mode: '%d'"), mode);
+ _("unsupported numatune mode: '%d'"), mode);
goto cleanup;
}
- if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
- vm->def->numatune.memory.mode != mode) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("can't change numa mode for running domain"));
- goto cleanup;
- }
-
- if (flags & VIR_DOMAIN_AFFECT_CONFIG)
- persistentDef->numatune.memory.mode = mode;
-
} else if (STREQ(param->field, VIR_DOMAIN_NUMA_NODESET)) {
- virBitmapPtr nodeset = NULL;
-
if (virBitmapParse(param->value.s, 0, &nodeset,
- VIR_DOMAIN_CPUMASK_LEN) < 0) {
+ VIR_DOMAIN_CPUMASK_LEN) < 0)
goto cleanup;
- }
- if (flags & VIR_DOMAIN_AFFECT_LIVE) {
- if (qemuDomainSetNumaParamsLive(vm, caps, nodeset) < 0) {
- virBitmapFree(nodeset);
- goto cleanup;
- }
-
- /* update vm->def here so that dumpxml can read the new
- * values from vm->def. */
- virBitmapFree(vm->def->numatune.memory.nodemask);
-
- vm->def->numatune.memory.placement_mode =
- VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
- vm->def->numatune.memory.nodemask = virBitmapNewCopy(nodeset);
+ if (virBitmapIsAllClear(nodeset)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Invalid nodeset for numatune"));
+ goto cleanup;
}
+ }
+ }
- if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
- virBitmapFree(persistentDef->numatune.memory.nodemask);
-
- persistentDef->numatune.memory.nodemask = nodeset;
- persistentDef->numatune.memory.placement_mode =
- VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
- nodeset = NULL;
- }
- virBitmapFree(nodeset);
+ if (flags & VIR_DOMAIN_AFFECT_LIVE) {
+ if (mode != -1 &&
+ virDomainNumatuneGetMode(vm->def->numatune) != mode) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("can't change numatune mode for running domain"));
+ goto cleanup;
}
+
+ if (nodeset &&
+ qemuDomainSetNumaParamsLive(vm, caps, nodeset) < 0)
+ goto cleanup;
+
+ if (virDomainNumatuneSet(vm->def, -1, mode, nodeset) < 0)
+ goto cleanup;
}
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
- if (!persistentDef->numatune.memory.placement_mode)
- persistentDef->numatune.memory.placement_mode =
- VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO;
+ if (virDomainNumatuneSet(persistentDef, -1, mode, nodeset) < 0)
+ goto cleanup;
+
if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
goto cleanup;
}
ret = 0;
cleanup:
+ virBitmapFree(nodeset);
if (vm)
virObjectUnlock(vm);
virObjectUnref(caps);
if (virTypedParameterAssign(param, VIR_DOMAIN_NUMA_MODE,
VIR_TYPED_PARAM_INT, 0) < 0)
goto cleanup;
+
if (flags & VIR_DOMAIN_AFFECT_CONFIG)
- param->value.i = persistentDef->numatune.memory.mode;
+ param->value.i = virDomainNumatuneGetMode(persistentDef->numatune);
else
- param->value.i = vm->def->numatune.memory.mode;
+ param->value.i = virDomainNumatuneGetMode(vm->def->numatune);
break;
case 1: /* fill numa nodeset here */
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
- nodeset = virBitmapFormat(persistentDef->numatune.memory.nodemask);
+ nodeset = virDomainNumatuneFormatNodeset(persistentDef->numatune,
+ NULL);
if (!nodeset)
goto cleanup;
} else {
/* Get the advisory nodeset from numad if 'placement' of
* either <vcpu> or <numatune> is 'auto'.
*/
- if ((vm->def->placement_mode ==
- VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
- (vm->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)) {
+ if (virDomainDefNeedsPlacementAdvice(vm->def)) {
nodeset = virNumaGetAutoPlacementAdvice(vm->def->vcpus,
vm->def->mem.max_balloon);
if (!nodeset)
VIR_DEBUG("Nodeset returned from numad: %s", nodeset);
- if (virBitmapParse(nodeset, 0, &nodemask,
- VIR_DOMAIN_CPUMASK_LEN) < 0)
+ if (virBitmapParse(nodeset, 0, &nodemask, VIR_DOMAIN_CPUMASK_LEN) < 0)
goto cleanup;
}
hookData.nodemask = nodemask;
#if WITH_NUMACTL
int
-virNumaSetupMemoryPolicy(virDomainNumatune numatune,
+virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
virBitmapPtr nodemask)
{
nodemask_t mask;
- int mode = -1;
int node = -1;
int ret = -1;
int bit = 0;
int maxnode = 0;
virBitmapPtr tmp_nodemask = NULL;
- if (numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC) {
- if (!numatune.memory.nodemask)
- return 0;
- VIR_DEBUG("Set NUMA memory policy with specified nodeset");
- tmp_nodemask = numatune.memory.nodemask;
- } else if (numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO) {
- VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
- tmp_nodemask = nodemask;
- } else {
+ tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask);
+ if (!tmp_nodemask)
return 0;
- }
if (numa_available() < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
nodemask_set(&mask, bit);
}
- mode = numatune.memory.mode;
-
- if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
+ switch (virDomainNumatuneGetMode(numatune)) {
+ case VIR_DOMAIN_NUMATUNE_MEM_STRICT:
numa_set_bind_policy(1);
numa_set_membind(&mask);
numa_set_bind_policy(0);
- } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
+ break;
+
+ case VIR_DOMAIN_NUMATUNE_MEM_PREFERRED:
+ {
int nnodes = 0;
for (i = 0; i < NUMA_NUM_NODES; i++) {
if (nodemask_isset(&mask, i)) {
numa_set_bind_policy(0);
numa_set_preferred(node);
- } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
- numa_set_interleave_mask(&mask);
- } else {
- /* XXX: Shouldn't go here, as we already do checking when
- * parsing domain XML.
- */
- virReportError(VIR_ERR_XML_ERROR,
- "%s", _("Invalid mode for memory NUMA tuning."));
- goto cleanup;
}
+ break;
+ case VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE:
+ numa_set_interleave_mask(&mask);
+ break;
+
+ case VIR_DOMAIN_NUMATUNE_MEM_LAST:
+ break;
+ }
ret = 0;
cleanup:
#else
int
-virNumaSetupMemoryPolicy(virDomainNumatune numatune,
+virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
virBitmapPtr nodemask ATTRIBUTE_UNUSED)
{
- if (numatune.memory.nodemask) {
+ if (virDomainNumatuneGetNodeset(numatune, NULL)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("libvirt is compiled without NUMA tuning support"));
char *virNumaGetAutoPlacementAdvice(unsigned short vcups,
unsigned long long balloon);
-int virNumaSetupMemoryPolicy(virDomainNumatune numatune,
+int virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
virBitmapPtr nodemask);
bool virNumaIsAvailable(void);
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest</name>
+ <uuid>9f4b6512-e73a-4a25-93e8-5307802821ce</uuid>
+ <memory unit='KiB'>65536</memory>
+ <currentMemory unit='KiB'>65536</currentMemory>
+ <vcpu placement='auto'>1</vcpu>
+ <numatune>
+ <memory mode='preferred'/>
+ </numatune>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu>
+ <numa>
+ <cell id='0' cpus='0' memory='65536'/>
+ </numa>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/kvm</emulator>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest</name>
+ <uuid>9f4b6512-e73a-4a25-93e8-5307802821ce</uuid>
+ <memory unit='KiB'>65536</memory>
+ <currentMemory unit='KiB'>65536</currentMemory>
+ <vcpu placement='auto'>1</vcpu>
+ <numatune>
+ <memory mode='preferred' placement='auto'/>
+ </numatune>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu>
+ <numa>
+ <cell id='0' cpus='0' memory='65536'/>
+ </numa>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/kvm</emulator>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
DO_TEST_DIFFERENT("cpu-numa1");
DO_TEST_DIFFERENT("cpu-numa2");
+ DO_TEST_DIFFERENT("numatune-auto-prefer");
+
virObjectUnref(driver.caps);
virObjectUnref(driver.xmlopt);