}
+static int
+virDomainResctrlVcpuMatch(virDomainDefPtr def,
+ virBitmapPtr vcpus,
+ virResctrlAllocPtr *alloc)
+{
+ ssize_t i = 0;
+
+ for (i = 0; i < def->nresctrls; i++) {
+ /* vcpus group has been created, directly use the existing one.
+ * Just updating memory allocation information of that group
+ */
+ if (virBitmapEqual(def->resctrls[i]->vcpus, vcpus)) {
+ *alloc = def->resctrls[i]->alloc;
+ break;
+ }
+ if (virBitmapOverlaps(def->resctrls[i]->vcpus, vcpus)) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Overlapping vcpus in resctrls"));
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
static int
virDomainCachetuneDefParseCache(xmlXPathContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr oldnode = ctxt->node;
xmlNodePtr *nodes = NULL;
virBitmapPtr vcpus = NULL;
- virResctrlAllocPtr alloc = virResctrlAllocNew();
+ virResctrlAllocPtr alloc = NULL;
virDomainResctrlDefPtr tmp_resctrl = NULL;
char *tmp = NULL;
char *vcpus_str = NULL;
ctxt->node = node;
- if (!alloc)
- goto cleanup;
-
if (VIR_ALLOC(tmp_resctrl) < 0)
goto cleanup;
goto cleanup;
}
+ if (virDomainResctrlVcpuMatch(def, vcpus, &alloc) < 0)
+ goto cleanup;
+
+ if (!alloc) {
+ alloc = virResctrlAllocNew();
+ if (!alloc)
+ goto cleanup;
+ } else {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Identical vcpus in cachetunes found"));
+ goto cleanup;
+ }
+
for (i = 0; i < n; i++) {
if (virDomainCachetuneDefParseCache(ctxt, nodes[i], alloc) < 0)
goto cleanup;
goto cleanup;
}
- for (i = 0; i < def->nresctrls; i++) {
- if (virBitmapOverlaps(def->resctrls[i]->vcpus, vcpus)) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("Overlapping vcpus in cachetunes"));
- goto cleanup;
- }
- }
-
/* We need to format it back because we need to be consistent in the naming
* even when users specify some "sub-optimal" string there. */
VIR_FREE(vcpus_str);