[libvirt] [PATCHv2 1/4] Introduce filesystem limits to virDomainFSDef

Guido Günther agx at sigxcpu.org
Fri May 11 21:14:19 UTC 2012


---
 docs/formatdomain.html.in     |   12 ++++++
 docs/schemas/domaincommon.rng |   12 ++++++
 src/conf/domain_conf.c        |   88 +++++++++++++++++++++++++++++++++++++++--
 src/conf/domain_conf.h        |    2 +
 4 files changed, 111 insertions(+), 3 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index e1fe0c4..8ef20c0 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1673,6 +1673,18 @@
         default read-write access is given (currently only works for
         QEMU/KVM driver).
       </dd>
+
+      <dt><code>space_hard_limit</code></dt>
+      <dd>
+        Maximum space available to this guests's filesystem.
+      </dd>
+
+      <dt><code>space_soft_limit</code></dt>
+      <dd>
+        Maximum space available to this guest's filesystem. The container is
+        is permitted to exceed its soft limits for a grace period of time. Afterwards
+        the hard limit is enforced.
+      </dd>
     </dl>
 
     <h4><a name="elementsAddress">Device Addresses</a></h4>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 8419ccc..f068ff7 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1300,6 +1300,18 @@
           <ref name="address"/>
         </optional>
       </interleave>
+      <interleave>
+        <optional>
+          <element name="space_hard_limit">
+            <ref name='scaledInteger'/>
+          </element>
+        </optional>
+        <optional>
+          <element name="space_soft_limit">
+            <ref name='scaledInteger'/>
+          </element>
+        </optional>
+      </interleave>
     </element>
   </define>
   <!--
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3fce7e5..d5e01a8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4086,14 +4086,72 @@ cleanup:
     goto cleanup;
 }
 
+
+/* Parse a value located at XPATH within CTXT, and store the
+ * result into val.  If REQUIRED, then the value must exist;
+ * otherwise, the value is optional.  The value is in bytes.
+ * Return 0 on success, -1 on failure after issuing error. */
+static int
+virDomainParseScaledValue(const char *xpath,
+                          xmlXPathContextPtr ctxt,
+                          unsigned long long *val,
+                          unsigned long long scale,
+                          unsigned long long max,
+                          bool required)
+{
+    char *xpath_full = NULL;
+    char *unit = NULL;
+    int ret = -1;
+    unsigned long long bytes;
+
+    *val = 0;
+    if (virAsprintf(&xpath_full, "string(%s)", xpath) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+    ret = virXPathULongLong(xpath_full, ctxt, &bytes);
+    if (ret < 0) {
+        if (ret == -2)
+            virDomainReportError(VIR_ERR_XML_ERROR,
+                                 _("could not parse memory element %s"),
+                                 xpath);
+        else if (required)
+            virDomainReportError(VIR_ERR_XML_ERROR,
+                                 _("missing element %s"),
+                                 xpath);
+        else
+            ret = 0;
+        goto cleanup;
+    }
+    VIR_FREE(xpath_full);
+
+    if (virAsprintf(&xpath_full, "string(%s/@unit)", xpath) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+    unit = virXPathString(xpath_full, ctxt);
+
+    if (virScaleInteger(&bytes, unit, scale, max) < 0)
+        goto cleanup;
+
+    *val = bytes;
+    ret = 0;
+cleanup:
+    VIR_FREE(xpath_full);
+    VIR_FREE(unit);
+    return ret;
+}
+
+
 /* Parse the XML definition for a disk
  * @param node XML nodeset to parse for disk definition
  */
 static virDomainFSDefPtr
 virDomainFSDefParseXML(xmlNodePtr node,
+                       xmlXPathContextPtr ctxt,
                        unsigned int flags) {
     virDomainFSDefPtr def;
-    xmlNodePtr cur;
+    xmlNodePtr cur, safe_node = ctxt->node;
     char *type = NULL;
     char *fsdriver = NULL;
     char *source = NULL;
@@ -4101,6 +4159,8 @@ virDomainFSDefParseXML(xmlNodePtr node,
     char *accessmode = NULL;
     char *wrpolicy = NULL;
 
+    ctxt->node = node;
+
     if (VIR_ALLOC(def) < 0) {
         virReportOOMError();
         return NULL;
@@ -4128,6 +4188,18 @@ virDomainFSDefParseXML(xmlNodePtr node,
         def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH;
     }
 
+    if (virDomainParseScaledValue("./space_hard_limit[1]", ctxt,
+                                  &def->space_hard_limit, 1,
+                                  ULONG_LONG_MAX,
+                                  false) < 0)
+        goto error;
+
+    if (virDomainParseScaledValue("./space_soft_limit[1]", ctxt,
+                                  &def->space_soft_limit, 1,
+                                  ULONG_LONG_MAX,
+                                  false) < 0)
+        goto error;
+
     cur = node->children;
     while (cur != NULL) {
         if (cur->type == XML_ELEMENT_NODE) {
@@ -4194,6 +4266,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
         goto error;
 
 cleanup:
+    ctxt->node = safe_node;
     VIR_FREE(type);
     VIR_FREE(fsdriver);
     VIR_FREE(target);
@@ -6883,7 +6956,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
             goto error;
     } else if (xmlStrEqual(node->name, BAD_CAST "filesystem")) {
         dev->type = VIR_DOMAIN_DEVICE_FS;
-        if (!(dev->data.fs = virDomainFSDefParseXML(node, flags)))
+        if (!(dev->data.fs = virDomainFSDefParseXML(node, ctxt, flags)))
             goto error;
     } else if (xmlStrEqual(node->name, BAD_CAST "interface")) {
         dev->type = VIR_DOMAIN_DEVICE_NET;
@@ -8404,7 +8478,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
     if (n && VIR_ALLOC_N(def->fss, n) < 0)
         goto no_memory;
     for (i = 0 ; i < n ; i++) {
-        virDomainFSDefPtr fs = virDomainFSDefParseXML(nodes[i],
+        virDomainFSDefPtr fs = virDomainFSDefParseXML(nodes[i], ctxt,
                                                       flags);
         if (!fs)
             goto error;
@@ -11101,6 +11175,14 @@ virDomainFSDefFormat(virBufferPtr buf,
     if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
         return -1;
 
+
+    if (def->space_hard_limit)
+        virBufferAsprintf(buf, "      <space_hard_limit unit='B'>"
+                          "%llu</space_hard_limit>\n", def->space_hard_limit);
+    if (def->space_soft_limit) {
+        virBufferAsprintf(buf, "      <space_soft_limit unit='B'>"
+                          "%llu</space_soft_limit>\n", def->space_soft_limit);
+    }
     virBufferAddLit(buf, "    </filesystem>\n");
 
     return 0;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5aa8fc1..7331ef5 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -692,6 +692,8 @@ struct _virDomainFSDef {
     char *dst;
     unsigned int readonly : 1;
     virDomainDeviceInfo info;
+    unsigned long long space_hard_limit; /* in bytes */
+    unsigned long long space_soft_limit; /* in bytes */
 };
 
 
-- 
1.7.10




More information about the libvir-list mailing list