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 @@
+
+
+
+ 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
+
+
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