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:
parent
aa8604dd45
commit
8d4adf3efa
@ -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>
|
||||||
|
...
|
||||||
|
<resource>
|
||||||
|
<partition>/virtualmachines/production</partition>
|
||||||
|
</resource>
|
||||||
|
...
|
||||||
|
</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>
|
||||||
|
@ -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">
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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'>
|
||||||
|
Loading…
Reference in New Issue
Block a user