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

--- 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

On 05/11/2012 03:14 PM, Guido Günther wrote:
--- 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.
Needs a <span class="since">Since 0.9.13</span>.
+++ 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) +{
Looks like this is a generalization of virDomainParseMemory; I'd like to see that function refactored to use this function instead of duplicating the bulk of the code between the two functions. In fact, it might even be worth to add this function and do the refactoring as a pre-req patch.
static virDomainFSDefPtr virDomainFSDefParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, unsigned int flags) { virDomainFSDefPtr def; - xmlNodePtr cur; + xmlNodePtr cur, safe_node = ctxt->node;
s/safe_node/save_node/, here and below
@@ -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'>"
s/B/bytes/, to match what we've done in storage_conf.c. Probably worth a v3, but I like where it's heading. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Eric Blake
-
Guido Günther