提交 b46e0054 编写于 作者: G Guido Günther

Introduce virDomainParseScaledValue

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.
上级 4c7973e1
...@@ -4138,6 +4138,63 @@ cleanup: ...@@ -4138,6 +4138,63 @@ cleanup:
goto 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 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 /* Parse the XML definition for a disk
* @param node XML nodeset to parse for disk definition * @param node XML nodeset to parse for disk definition
*/ */
...@@ -7768,53 +7825,24 @@ static int ...@@ -7768,53 +7825,24 @@ static int
virDomainParseMemory(const char *xpath, xmlXPathContextPtr ctxt, virDomainParseMemory(const char *xpath, xmlXPathContextPtr ctxt,
unsigned long long *mem, bool required) unsigned long long *mem, bool required)
{ {
char *xpath_full = NULL;
char *unit = NULL;
int ret = -1; int ret = -1;
unsigned long long bytes; unsigned long long bytes, max;
unsigned long long 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 /* On 32-bit machines, our bound is 0xffffffff * KiB. On 64-bit
* machines, our bound is off_t (2^63). */ * machines, our bound is off_t (2^63). */
if (sizeof(unsigned long) < sizeof(long long)) if (sizeof(unsigned long) < sizeof(long long))
max = 1024ull * ULONG_MAX; max = 1024ull * ULONG_MAX;
else else
max = LLONG_MAX; max = LLONG_MAX;
if (virScaleInteger(&bytes, unit, 1024, max) < 0)
ret = virDomainParseScaledValue(xpath, ctxt, &bytes, 1024, max, required);
if (ret < 0)
goto cleanup; goto cleanup;
/* Yes, we really do use kibibytes for our internal sizing. */ /* Yes, we really do use kibibytes for our internal sizing. */
*mem = VIR_DIV_UP(bytes, 1024); *mem = VIR_DIV_UP(bytes, 1024);
ret = 0; ret = 0;
cleanup: cleanup:
VIR_FREE(xpath_full);
VIR_FREE(unit);
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册