and use it for virDomainParseMemory. This allows to parse arbitrary scaled value, not only memory related values as needed for the filesystem limits code following later in this series. --- src/conf/domain_conf.c | 94 +++++++++++++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 33 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9def71d..5ac911e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4138,6 +4138,63 @@ 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 */ @@ -7768,53 +7825,24 @@ static int virDomainParseMemory(const char *xpath, xmlXPathContextPtr ctxt, unsigned long long *mem, bool required) { - char *xpath_full = NULL; - char *unit = NULL; int ret = -1; - unsigned long long bytes; - unsigned long long max; + unsigned long long bytes, max; - *mem = 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 memory 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); /* On 32-bit machines, our bound is 0xffffffff * KiB. On 64-bit * machines, our bound is off_t (2^63). */ if (sizeof(unsigned long) < sizeof(long long)) max = 1024ull * ULONG_MAX; else max = LLONG_MAX; - if (virScaleInteger(&bytes, unit, 1024, max) < 0) + + ret = virDomainParseScaledValue(xpath, ctxt, &bytes, 1024, max, required); + if (ret < 0) goto cleanup; /* Yes, we really do use kibibytes for our internal sizing. */ *mem = VIR_DIV_UP(bytes, 1024); ret = 0; cleanup: - VIR_FREE(xpath_full); - VIR_FREE(unit); return ret; } -- 1.7.10 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list