Add XML config for resource partitions

Allow VMs to be placed into resource groups using the
following syntax

  <resource>
    <partition>/virtualmachines/production</partition>
  </resource>

A resource cgroup will be backed by some hypervisor specific
functionality, such as cgroups with KVM/LXC.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2013-03-21 11:28:10 +00:00
parent aa8604dd45
commit 8d4adf3efa
5 changed files with 128 additions and 0 deletions

View File

@ -716,6 +716,35 @@
</dl>
<h3><a name="resPartition">Resource partitioning</a></h3>
<p>
Hypervisors may allow for virtual machines to be placed into
resource partitions, potentially with nesting of said partitions.
The <code>resource</code> element groups together configuration
related to resource partitioning. It currently supports a child
element <code>partition</code> 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.
</p>
<pre>
...
&lt;resource&gt;
&lt;partition&gt;/virtualmachines/production&lt;/partition&gt;
&lt;/resource&gt;
...
</pre>
<p>
Resource partitions are currently supported by the QEMU and
LXC drivers, which map partition paths onto cgroups directories,
in all mounted controllers. <span class="since">Since 1.0.5</span>
</p>
<h3><a name="elementsCPU">CPU model and topology</a></h3>
<p>

View File

@ -537,6 +537,10 @@
<optional>
<ref name="numatune"/>
</optional>
<optional>
<ref name="respartition"/>
</optional>
</interleave>
</define>
@ -680,6 +684,14 @@
</element>
</define>
<define name="respartition">
<element name="resource">
<element name="partition">
<ref name="absFilePath"/>
</element>
</element>
</define>
<define name="clock">
<optional>
<element name="clock">

View File

@ -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, " <resource>\n");
virBufferEscapeString(buf, " <partition>%s</partition>\n", def->partition);
virBufferAddLit(buf, " </resource>\n");
}
#define DUMPXML_FLAGS \
(VIR_DOMAIN_XML_SECURE | \
VIR_DOMAIN_XML_INACTIVE | \
@ -15307,6 +15381,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAddLit(buf, " </numatune>\n");
}
if (def->resource)
virDomainResourceDefFormat(buf, def->resource);
if (def->sysinfo)
virDomainSysinfoDefFormat(buf, def->sysinfo);

View File

@ -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);

View File

@ -5,6 +5,9 @@
<type>exe</type>
<init>/sh</init>
</os>
<resource>
<partition>/virtualmachines</partition>
</resource>
<memory unit='KiB'>500000</memory>
<devices>
<filesystem type='mount'>