]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add XML config for resource partitions
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 21 Mar 2013 11:28:10 +0000 (11:28 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 15 Apr 2013 16:35:31 +0000 (17:35 +0100)
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>
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
tests/domainschemadata/domain-lxc-simple.xml

index 2def22290fda28f1796ae10d89b4ba515fd2bd16..0cc56d934c686931b75435156dac1a0e9cb4398a 100644 (file)
     </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>
index 8af667a7c37d0afcdc02604aab596ba48c378456..468c49c84f4c949da0bbfe1a93c7522803e8934a 100644 (file)
       <optional>
         <ref name="numatune"/>
       </optional>
+
+      <optional>
+        <ref name="respartition"/>
+      </optional>
     </interleave>
   </define>
 
     </element>
   </define>
 
+  <define name="respartition">
+    <element name="resource">
+      <element name="partition">
+        <ref name="absFilePath"/>
+      </element>
+    </element>
+  </define>
+
   <define name="clock">
     <optional>
       <element name="clock">
index e9c97d0c63788a2e30320e3f25e84a5a9440f61c..548368e56fd174737c9adb8df1668eb632ad3ad6 100644 (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);
 
index 8f35f6e5281ed0036a6f04f664811e35e09de87f..f1f01fa4679cec5fe4a8c24bbfb7e5482bc8133f 100644 (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);
index e61434faccb76c13514b66c8f95e14e2de04b747..56a01174fddfbc51b4284df57fbccce70118c4c4 100644 (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'>