提交 01b4de2b 编写于 作者: M Michal Privoznik

domain_conf: Use virDomainParseMemory more widely

As reviewing patches upstream it occurred to me, that we have two
functions doing nearly the same: virDomainParseMemory which
expects XML in the following format:

  <memory unit='MiB'>1337</memory>

The other function being virDomainHugepagesParseXML expecting the
following format:

  <someElement size='1337' unit='MiB'/>

It wouldn't matter to have two functions handle two different
scenarios like this if we could only not copy code that handles
32bit arches around. So this code merges the common parts into
one by inventing new @units_xpath argument to
virDomainParseMemory which allows overriding the default location
of @unit attribute in XML. With this change both scenarios above
can be parsed with virDomainParseMemory.
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
上级 4039e22e
...@@ -6318,14 +6318,31 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, ...@@ -6318,14 +6318,31 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
goto cleanup; goto cleanup;
} }
/**
/* Parse a value located at XPATH within CTXT, and store the * virDomainParseScaledValue:
* result into val. If REQUIRED, then the value must exist; * @xpath: XPath to memory amount
* otherwise, the value is optional. The value is in bytes. * @units_xpath: XPath to units attribute
* Return 1 on success, 0 if the value was not present and * @ctxt: XPath context
* is not REQUIRED, -1 on failure after issuing error. */ * @val: scaled value is stored here
* @scale: default scale for @val
* @max: maximal @val allowed
* @required: is the value required?
*
* Parse a value located at @xpath within @ctxt, and store the
* result into @val. The value is scaled by units located at
* @units_xpath (or the 'unit' attribute under @xpath if
* @units_xpath is NULL). If units are not present, the default
* @scale is used. If @required is set, then the value must
* exist; otherwise, the value is optional. The resulting value
* is in bytes.
*
* Returns 1 on success,
* 0 if the value was not present and !@required,
* -1 on failure after issuing error.
*/
static int static int
virDomainParseScaledValue(const char *xpath, virDomainParseScaledValue(const char *xpath,
const char *units_xpath,
xmlXPathContextPtr ctxt, xmlXPathContextPtr ctxt,
unsigned long long *val, unsigned long long *val,
unsigned long long scale, unsigned long long scale,
...@@ -6348,7 +6365,7 @@ virDomainParseScaledValue(const char *xpath, ...@@ -6348,7 +6365,7 @@ virDomainParseScaledValue(const char *xpath,
ret = 0; ret = 0;
} else { } else {
virReportError(VIR_ERR_XML_ERROR, virReportError(VIR_ERR_XML_ERROR,
_("missing element %s"), _("missing element or attribute '%s'"),
xpath); xpath);
} }
goto cleanup; goto cleanup;
...@@ -6357,12 +6374,15 @@ virDomainParseScaledValue(const char *xpath, ...@@ -6357,12 +6374,15 @@ virDomainParseScaledValue(const char *xpath,
if (virStrToLong_ullp(bytes_str, NULL, 10, &bytes) < 0) { if (virStrToLong_ullp(bytes_str, NULL, 10, &bytes) < 0) {
virReportError(VIR_ERR_XML_ERROR, virReportError(VIR_ERR_XML_ERROR,
_("Invalid value '%s' for element '%s'"), _("Invalid value '%s' for element or attribute '%s'"),
bytes_str, xpath); bytes_str, xpath);
goto cleanup; goto cleanup;
} }
if (virAsprintf(&xpath_full, "string(%s/@unit)", xpath) < 0) if ((units_xpath &&
virAsprintf(&xpath_full, "string(%s)", units_xpath) < 0) ||
(!units_xpath &&
virAsprintf(&xpath_full, "string(%s/@unit)", xpath) < 0))
goto cleanup; goto cleanup;
unit = virXPathString(xpath_full, ctxt); unit = virXPathString(xpath_full, ctxt);
...@@ -6379,17 +6399,35 @@ virDomainParseScaledValue(const char *xpath, ...@@ -6379,17 +6399,35 @@ virDomainParseScaledValue(const char *xpath,
} }
/* Parse a memory element located at XPATH within CTXT, and store the /**
* result into MEM, in blocks of 1024. If REQUIRED, then the value * virDomainParseMemory:
* must exist; otherwise, the value is optional. The value must not * @xpath: XPath to memory amount
* exceed VIR_DOMAIN_MEMORY_PARAM_UNLIMITED once scaled; additionally, * @units_xpath: XPath to units attribute
* if CAPPED is true, the value must fit within an unsigned long (only * @ctxt: XPath context
* matters on 32-bit platforms). * @mem: scaled memory amount is stored here
* @required: whether value is required
* @capped: whether scaled value must fit within unsigned long
* *
* Return 0 on success, -1 on failure after issuing error. */ * Parse a memory element or attribute located at @xpath within
* @ctxt, and store the result into @mem, in blocks of 1024. The
* value is scaled by units located at @units_xpath (or the
* 'unit' attribute under @xpath if @units_xpath is NULL). If
* units are not present, he default scale of 1024 is used. If
* @required is set, then the value must exist; otherwise, the
* value is optional. The value must not exceed
* VIR_DOMAIN_MEMORY_PARAM_UNLIMITED once scaled; additionally,
* if @capped is true, the value must fit within an unsigned long
* (only matters on 32-bit platforms).
*
* Return 0 on success, -1 on failure after issuing error.
*/
static int static int
virDomainParseMemory(const char *xpath, xmlXPathContextPtr ctxt, virDomainParseMemory(const char *xpath,
unsigned long long *mem, bool required, bool capped) const char *units_xpath,
xmlXPathContextPtr ctxt,
unsigned long long *mem,
bool required,
bool capped)
{ {
int ret = -1; int ret = -1;
unsigned long long bytes, max; unsigned long long bytes, max;
...@@ -6401,7 +6439,8 @@ virDomainParseMemory(const char *xpath, xmlXPathContextPtr ctxt, ...@@ -6401,7 +6439,8 @@ virDomainParseMemory(const char *xpath, xmlXPathContextPtr ctxt,
else else
max = LLONG_MAX; max = LLONG_MAX;
ret = virDomainParseScaledValue(xpath, ctxt, &bytes, 1024, max, required); ret = virDomainParseScaledValue(xpath, units_xpath, ctxt,
&bytes, 1024, max, required);
if (ret < 0) if (ret < 0)
goto cleanup; goto cleanup;
...@@ -6585,8 +6624,8 @@ virDomainControllerDefParseXML(xmlNodePtr node, ...@@ -6585,8 +6624,8 @@ virDomainControllerDefParseXML(xmlNodePtr node,
"should have index 0")); "should have index 0"));
goto error; goto error;
} }
if ((rc = virDomainParseScaledValue("./pcihole64", ctxt, if ((rc = virDomainParseScaledValue("./pcihole64", NULL,
&bytes, 1024, ctxt, &bytes, 1024,
1024ULL * ULONG_MAX, false)) < 0) 1024ULL * ULONG_MAX, false)) < 0)
goto error; goto error;
...@@ -6684,14 +6723,14 @@ virDomainFSDefParseXML(xmlNodePtr node, ...@@ -6684,14 +6723,14 @@ virDomainFSDefParseXML(xmlNodePtr node,
def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH; def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH;
} }
if (virDomainParseScaledValue("./space_hard_limit[1]", ctxt, if (virDomainParseScaledValue("./space_hard_limit[1]",
&def->space_hard_limit, 1, NULL, ctxt, &def->space_hard_limit,
ULLONG_MAX, false) < 0) 1, ULLONG_MAX, false) < 0)
goto error; goto error;
if (virDomainParseScaledValue("./space_soft_limit[1]", ctxt, if (virDomainParseScaledValue("./space_soft_limit[1]",
&def->space_soft_limit, 1, NULL, ctxt, &def->space_soft_limit,
ULLONG_MAX, false) < 0) 1, ULLONG_MAX, false) < 0)
goto error; goto error;
cur = node->children; cur = node->children;
...@@ -9824,8 +9863,8 @@ virDomainShmemDefParseXML(xmlNodePtr node, ...@@ -9824,8 +9863,8 @@ virDomainShmemDefParseXML(xmlNodePtr node,
goto cleanup; goto cleanup;
} }
if (virDomainParseScaledValue("./size[1]", ctxt, &def->size, if (virDomainParseScaledValue("./size[1]", NULL, ctxt,
1, ULLONG_MAX, false) < 0) &def->size, 1, ULLONG_MAX, false) < 0)
goto cleanup; goto cleanup;
if ((server = virXPathNode("./server[1]", ctxt))) { if ((server = virXPathNode("./server[1]", ctxt))) {
...@@ -11965,30 +12004,15 @@ virDomainHugepagesParseXML(xmlNodePtr node, ...@@ -11965,30 +12004,15 @@ virDomainHugepagesParseXML(xmlNodePtr node,
{ {
int ret = -1; int ret = -1;
xmlNodePtr oldnode = ctxt->node; xmlNodePtr oldnode = ctxt->node;
unsigned long long bytes, max;
char *unit = NULL, *nodeset = NULL; char *unit = NULL, *nodeset = NULL;
ctxt->node = node; ctxt->node = node;
/* On 32-bit machines, our bound is 0xffffffff * KiB. On 64-bit if (virDomainParseMemory("./@size", "./@unit", ctxt,
* machines, our bound is off_t (2^63). */ &hugepage->size, true, false) < 0)
if (sizeof(unsigned long) < sizeof(long long))
max = 1024ull * ULONG_MAX;
else
max = LLONG_MAX;
if (virXPathULongLong("string(./@size)", ctxt, &bytes) < 0) {
virReportError(VIR_ERR_XML_DETAIL, "%s",
_("unable to parse size attribute"));
goto cleanup;
}
unit = virXPathString("string(./@unit)", ctxt);
if (virScaleInteger(&bytes, unit, 1024, max) < 0)
goto cleanup; goto cleanup;
if (!(hugepage->size = VIR_DIV_UP(bytes, 1024))) { if (!hugepage->size) {
virReportError(VIR_ERR_XML_DETAIL, "%s", virReportError(VIR_ERR_XML_DETAIL, "%s",
_("hugepage size can't be zero")); _("hugepage size can't be zero"));
goto cleanup; goto cleanup;
...@@ -12225,11 +12249,11 @@ virDomainDefParseXML(xmlDocPtr xml, ...@@ -12225,11 +12249,11 @@ virDomainDefParseXML(xmlDocPtr xml,
goto error; goto error;
/* Extract domain memory */ /* Extract domain memory */
if (virDomainParseMemory("./memory[1]", ctxt, if (virDomainParseMemory("./memory[1]", NULL, ctxt,
&def->mem.max_balloon, true, true) < 0) &def->mem.max_balloon, true, true) < 0)
goto error; goto error;
if (virDomainParseMemory("./currentMemory[1]", ctxt, if (virDomainParseMemory("./currentMemory[1]", NULL, ctxt,
&def->mem.cur_balloon, false, true) < 0) &def->mem.cur_balloon, false, true) < 0)
goto error; goto error;
...@@ -12349,19 +12373,19 @@ virDomainDefParseXML(xmlDocPtr xml, ...@@ -12349,19 +12373,19 @@ virDomainDefParseXML(xmlDocPtr xml,
VIR_FREE(nodes); VIR_FREE(nodes);
/* Extract other memory tunables */ /* Extract other memory tunables */
if (virDomainParseMemory("./memtune/hard_limit[1]", ctxt, if (virDomainParseMemory("./memtune/hard_limit[1]", NULL, ctxt,
&def->mem.hard_limit, false, false) < 0) &def->mem.hard_limit, false, false) < 0)
goto error; goto error;
if (virDomainParseMemory("./memtune/soft_limit[1]", ctxt, if (virDomainParseMemory("./memtune/soft_limit[1]", NULL, ctxt,
&def->mem.soft_limit, false, false) < 0) &def->mem.soft_limit, false, false) < 0)
goto error; goto error;
if (virDomainParseMemory("./memtune/min_guarantee[1]", ctxt, if (virDomainParseMemory("./memtune/min_guarantee[1]", NULL, ctxt,
&def->mem.min_guarantee, false, false) < 0) &def->mem.min_guarantee, false, false) < 0)
goto error; goto error;
if (virDomainParseMemory("./memtune/swap_hard_limit[1]", ctxt, if (virDomainParseMemory("./memtune/swap_hard_limit[1]", NULL, ctxt,
&def->mem.swap_hard_limit, false, false) < 0) &def->mem.swap_hard_limit, false, false) < 0)
goto error; goto error;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册