diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 2def22290f..0cc56d934c 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -716,6 +716,35 @@ +

Resource partitioning

+ +

+ Hypervisors may allow for virtual machines to be placed into + resource partitions, potentially with nesting of said partitions. + The resource element groups together configuration + related to resource partitioning. It currently supports a child + element partition whose content defines the path + of the resource partition in which to place the domain. If no + partition is listed, then the domain will be placed in a default + partition. It is the responsibility of the app/admin to ensure + that the partition exists prior to starting the guest. Only the + (hypervisor specific) default partition can be assumed to exist + by default. +

+
+  ...
+  <resource>
+    <partition>/virtualmachines/production</partition>
+  </resource>
+  ...
+
+ +

+ Resource partitions are currently supported by the QEMU and + LXC drivers, which map partition paths onto cgroups directories, + in all mounted controllers. Since 1.0.5 +

+

CPU model and topology

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 8af667a7c3..468c49c84f 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -537,6 +537,10 @@ + + + + @@ -680,6 +684,14 @@ + + + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e9c97d0c63..548368e56f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1822,6 +1822,18 @@ virDomainVcpuPinDefArrayFree(virDomainVcpuPinDefPtr *def, VIR_FREE(def); } + +void +virDomainResourceDefFree(virDomainResourceDefPtr resource) +{ + if (!resource) + return; + + VIR_FREE(resource->partition); + VIR_FREE(resource); +} + + void virDomainDefFree(virDomainDefPtr def) { unsigned int i; @@ -1829,6 +1841,8 @@ void virDomainDefFree(virDomainDefPtr def) if (!def) return; + virDomainResourceDefFree(def->resource); + /* hostdevs must be freed before nets (or any future "intelligent * hostdevs") because the pointer to the hostdev is really * pointing into the middle of the higher level device's object, @@ -9805,6 +9819,37 @@ cleanup: } +static virDomainResourceDefPtr +virDomainResourceDefParse(xmlNodePtr node, + xmlXPathContextPtr ctxt) +{ + virDomainResourceDefPtr def = NULL; + xmlNodePtr tmp = ctxt->node; + + ctxt->node = node; + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(); + goto error; + } + + /* Find out what type of virtualization to use */ + if (!(def->partition = virXPathString("string(./partition)", ctxt))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("missing resource partition attribute")); + goto error; + } + + ctxt->node = tmp; + return def; + +error: + ctxt->node = tmp; + virDomainResourceDefFree(def); + return NULL; +} + + static virDomainDefPtr virDomainDefParseXML(xmlDocPtr xml, xmlNodePtr root, @@ -10374,6 +10419,24 @@ virDomainDefParseXML(xmlDocPtr xml, } VIR_FREE(nodes); + /* Extract numatune if exists. */ + if ((n = virXPathNodeSet("./resource", ctxt, &nodes)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("cannot extract resource nodes")); + goto error; + } + + if (n > 1) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only one resource element is supported")); + goto error; + } + + if (n && + !(def->resource = virDomainResourceDefParse(nodes[0], ctxt))) + goto error; + VIR_FREE(nodes); + if ((n = virXPathNodeSet("./features/*", ctxt, &nodes)) < 0) goto error; @@ -15039,6 +15102,17 @@ virDomainIsAllVcpupinInherited(virDomainDefPtr def) } } + +static void +virDomainResourceDefFormat(virBufferPtr buf, + virDomainResourceDefPtr def) +{ + virBufferAddLit(buf, " \n"); + virBufferEscapeString(buf, " %s\n", def->partition); + virBufferAddLit(buf, " \n"); +} + + #define DUMPXML_FLAGS \ (VIR_DOMAIN_XML_SECURE | \ VIR_DOMAIN_XML_INACTIVE | \ @@ -15307,6 +15381,9 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAddLit(buf, " \n"); } + if (def->resource) + virDomainResourceDefFormat(buf, def->resource); + if (def->sysinfo) virDomainSysinfoDefFormat(buf, def->sysinfo); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 8f35f6e528..f1f01fa467 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1778,6 +1778,11 @@ struct _virDomainRNGDef { void virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights, int ndevices); +typedef struct _virDomainResourceDef virDomainResourceDef; +typedef virDomainResourceDef *virDomainResourceDefPtr; +struct _virDomainResourceDef { + char *partition; +}; /* * Guest VM main configuration @@ -1829,6 +1834,7 @@ struct _virDomainDef { } cputune; virNumaTuneDef numatune; + virDomainResourceDefPtr resource; /* These 3 are based on virDomainLifeCycleAction enum flags */ int onReboot; @@ -2046,6 +2052,7 @@ virDomainObjPtr virDomainObjListFindByName(const virDomainObjListPtr doms, bool virDomainObjTaint(virDomainObjPtr obj, enum virDomainTaintFlags taint); +void virDomainResourceDefFree(virDomainResourceDefPtr resource); void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def); void virDomainInputDefFree(virDomainInputDefPtr def); void virDomainDiskDefFree(virDomainDiskDefPtr def); diff --git a/tests/domainschemadata/domain-lxc-simple.xml b/tests/domainschemadata/domain-lxc-simple.xml index e61434facc..56a01174fd 100644 --- a/tests/domainschemadata/domain-lxc-simple.xml +++ b/tests/domainschemadata/domain-lxc-simple.xml @@ -5,6 +5,9 @@ exe /sh + + /virtualmachines + 500000