1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2024-12-22 17:34:18 +03:00

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> </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> <h3><a name="elementsCPU">CPU model and topology</a></h3>
<p> <p>

View File

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

View File

@ -1822,6 +1822,18 @@ virDomainVcpuPinDefArrayFree(virDomainVcpuPinDefPtr *def,
VIR_FREE(def); VIR_FREE(def);
} }
void
virDomainResourceDefFree(virDomainResourceDefPtr resource)
{
if (!resource)
return;
VIR_FREE(resource->partition);
VIR_FREE(resource);
}
void virDomainDefFree(virDomainDefPtr def) void virDomainDefFree(virDomainDefPtr def)
{ {
unsigned int i; unsigned int i;
@ -1829,6 +1841,8 @@ void virDomainDefFree(virDomainDefPtr def)
if (!def) if (!def)
return; return;
virDomainResourceDefFree(def->resource);
/* hostdevs must be freed before nets (or any future "intelligent /* hostdevs must be freed before nets (or any future "intelligent
* hostdevs") because the pointer to the hostdev is really * hostdevs") because the pointer to the hostdev is really
* pointing into the middle of the higher level device's object, * 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 static virDomainDefPtr
virDomainDefParseXML(xmlDocPtr xml, virDomainDefParseXML(xmlDocPtr xml,
xmlNodePtr root, xmlNodePtr root,
@ -10374,6 +10419,24 @@ virDomainDefParseXML(xmlDocPtr xml,
} }
VIR_FREE(nodes); 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) if ((n = virXPathNodeSet("./features/*", ctxt, &nodes)) < 0)
goto error; 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 \ #define DUMPXML_FLAGS \
(VIR_DOMAIN_XML_SECURE | \ (VIR_DOMAIN_XML_SECURE | \
VIR_DOMAIN_XML_INACTIVE | \ VIR_DOMAIN_XML_INACTIVE | \
@ -15307,6 +15381,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAddLit(buf, " </numatune>\n"); virBufferAddLit(buf, " </numatune>\n");
} }
if (def->resource)
virDomainResourceDefFormat(buf, def->resource);
if (def->sysinfo) if (def->sysinfo)
virDomainSysinfoDefFormat(buf, def->sysinfo); virDomainSysinfoDefFormat(buf, def->sysinfo);

View File

@ -1778,6 +1778,11 @@ struct _virDomainRNGDef {
void virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights, void virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights,
int ndevices); int ndevices);
typedef struct _virDomainResourceDef virDomainResourceDef;
typedef virDomainResourceDef *virDomainResourceDefPtr;
struct _virDomainResourceDef {
char *partition;
};
/* /*
* Guest VM main configuration * Guest VM main configuration
@ -1829,6 +1834,7 @@ struct _virDomainDef {
} cputune; } cputune;
virNumaTuneDef numatune; virNumaTuneDef numatune;
virDomainResourceDefPtr resource;
/* These 3 are based on virDomainLifeCycleAction enum flags */ /* These 3 are based on virDomainLifeCycleAction enum flags */
int onReboot; int onReboot;
@ -2046,6 +2052,7 @@ virDomainObjPtr virDomainObjListFindByName(const virDomainObjListPtr doms,
bool virDomainObjTaint(virDomainObjPtr obj, bool virDomainObjTaint(virDomainObjPtr obj,
enum virDomainTaintFlags taint); enum virDomainTaintFlags taint);
void virDomainResourceDefFree(virDomainResourceDefPtr resource);
void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def); void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def);
void virDomainInputDefFree(virDomainInputDefPtr def); void virDomainInputDefFree(virDomainInputDefPtr def);
void virDomainDiskDefFree(virDomainDiskDefPtr def); void virDomainDiskDefFree(virDomainDiskDefPtr def);

View File

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