|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] libxl: fix "xl mem-set" regression from 0c029c4da2
On Wed, 22 Apr 2015, Jan Beulich wrote:
> Said commit ("libxl_set_memory_target: retain the same maxmem offset on
> top of the current target") caused a regression for "xl mem-set"
> against Dom0: While prior to creation of the first domain this works,
> the first domain creation involving ballooning breaks. Due to "enforce"
> not being set in the domain creation case, and due to Dom0's initial
> ->max_pages (in the hypervisor) being UINT_MAX, the calculation of
> "memorykb" in the first "xl mem-set" adusting the target upwards
> subsequent to domain creation and termination may cause an overflow,
> resulting in Dom0's maximum getting to a very small value. This small
> maximum will the make the subsequent setting of the PoD target fail.
>
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
> ---
> Note that this only fixes the immediate problem - there appear to be
> further issues lurking here:
> - libxl_set_memory_target()'s *_memkb variables all being 32-bit,
> - libxl_domain_setmaxmem()'s max_memkb parameter being 32-bit,
> - other similar code living elsewhere?
> Note also that this requires
> http://lists.xenproject.org/archives/html/xen-devel/2015-04/msg02485.html
> (or some other change avoiding truncation) to also be in place in order
> to address the observed problem.
> Note further that xc_domain_setmaxmem() is being used by upstream qemu
> and hence the libxc interface change here may represent a compatibility
> issue.
> Finally the setting of a PoD target for non-HVM domains seems bogus too
> (even if it's expected to just be a no-op in that case).
>
> --- a/tools/libxc/include/xenctrl.h
> +++ b/tools/libxc/include/xenctrl.h
> @@ -1256,7 +1256,7 @@ int xc_getcpuinfo(xc_interface *xch, int
>
> int xc_domain_setmaxmem(xc_interface *xch,
> uint32_t domid,
> - unsigned int max_memkb);
> + uint64_t max_memkb);
>
> int xc_domain_set_memmap_limit(xc_interface *xch,
> uint32_t domid,
> --- a/tools/libxc/xc_domain.c
> +++ b/tools/libxc/xc_domain.c
> @@ -634,7 +634,7 @@ int xc_shadow_control(xc_interface *xch,
>
> int xc_domain_setmaxmem(xc_interface *xch,
> uint32_t domid,
> - unsigned int max_memkb)
> + uint64_t max_memkb)
> {
> DECLARE_DOMCTL;
> domctl.cmd = XEN_DOMCTL_max_mem;
>
> --- a/tools/libxl/libxl.c
> +++ b/tools/libxl/libxl.c
> @@ -4726,7 +4726,8 @@ int libxl_set_memory_target(libxl_ctx *c
> {
> GC_INIT(ctx);
> int rc = 1, abort_transaction = 0;
> - uint32_t memorykb = 0, videoram = 0;
> + uint64_t memorykb;
> + uint32_t videoram = 0;
> uint32_t current_target_memkb = 0, new_target_memkb = 0;
> uint32_t current_max_memkb = 0;
> char *memmax, *endptr, *videoram_s = NULL, *target = NULL;
From the description of the problem above, we have two issues:
1) we don't detect that maxmem is already UINT_MAX*4, so we shouldn't try
to increase it
2) unsigned int / uint64_t mismatch
1) is pretty easy and might just come down to one more if statement in
libxl_set_memory_target. Something like:
#define MAXMEM_MAX_KB ((uint64_t)UINT32_MAX * 4)
if ((new_target_memkb - current_target_memkb) > 0 &&
(ptr.max_memkb - new_target_memkb + current_target_memkb) < ptr.max_memkb)
{
/* avoid overflow */
rc = xc_domain_setmaxmem(ctx->xch, domid, MAXMEM_MAX_KB);
} else {
rc = xc_domain_setmaxmem(ctx->xch, domid, memorykb);
}
2) is difficult as we have unsigned int in many many places. Not only
we need to fix the libxc interface, but as far as I can tell we also
need to fix at least libxl_set_memory_target,
libxl__fill_dom0_memory_info, libxl__get_memory_target, all the callers.
This is the minimum set of changes I think are required:
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 511eef1..3e91203 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -4641,8 +4641,8 @@ out:
return rc;
}
-static int libxl__fill_dom0_memory_info(libxl__gc *gc, uint32_t *target_memkb,
- uint32_t *max_memkb)
+static int libxl__fill_dom0_memory_info(libxl__gc *gc, uint64_t *target_memkb,
+ uint64_t *max_memkb)
{
int rc;
libxl_dominfo info;
@@ -4666,7 +4666,7 @@ retry_transaction:
}
if (target) {
- *target_memkb = strtoul(target, &endptr, 10);
+ *target_memkb = strtoull(target, &endptr, 10);
if (*endptr != '\0') {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
"invalid memory target %s from %s\n", target, target_path);
@@ -4676,7 +4676,7 @@ retry_transaction:
}
if (staticmax) {
- *max_memkb = strtoul(staticmax, &endptr, 10);
+ *max_memkb = strtoull(staticmax, &endptr, 10);
if (*endptr != '\0') {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
"invalid memory static-max %s from %s\n",
@@ -4697,14 +4697,14 @@ retry_transaction:
goto out;
if (target == NULL) {
- libxl__xs_write(gc, t, target_path, "%"PRIu32,
- (uint32_t) info.current_memkb);
- *target_memkb = (uint32_t) info.current_memkb;
+ libxl__xs_write(gc, t, target_path, "%"PRIu64,
+ info.current_memkb);
+ *target_memkb = info.current_memkb;
}
if (staticmax == NULL) {
- libxl__xs_write(gc, t, max_path, "%"PRIu32,
- (uint32_t) info.max_memkb);
- *max_memkb = (uint32_t) info.max_memkb;
+ libxl__xs_write(gc, t, max_path, "%"PRIu64,
+ info.max_memkb);
+ *max_memkb = info.max_memkb;
}
rc = 0;
@@ -4726,9 +4726,9 @@ int libxl_set_memory_target(libxl_ctx *ctx, uint32_t
domid,
{
GC_INIT(ctx);
int rc = 1, abort_transaction = 0;
- uint32_t memorykb = 0, videoram = 0;
- uint32_t current_target_memkb = 0, new_target_memkb = 0;
- uint32_t current_max_memkb = 0;
+ uint64_t memorykb = 0, videoram = 0;
+ uint64_t current_target_memkb = 0, new_target_memkb = 0;
+ uint64_t current_max_memkb = 0;
char *memmax, *endptr, *videoram_s = NULL, *target = NULL;
char *dompath = libxl__xs_get_dompath(gc, domid);
libxl_dominfo ptr;
@@ -4761,7 +4761,7 @@ retry_transaction:
abort_transaction = 1;
goto out;
} else {
- current_target_memkb = strtoul(target, &endptr, 10);
+ current_target_memkb = strtoull(target, &endptr, 10);
if (*endptr != '\0') {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
"invalid memory target %s from %s/memory/target\n",
@@ -4779,7 +4779,7 @@ retry_transaction:
abort_transaction = 1;
goto out;
}
- memorykb = strtoul(memmax, &endptr, 10);
+ memorykb = strtoull(memmax, &endptr, 10);
if (*endptr != '\0') {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
"invalid max memory %s from %s/memory/static-max\n",
@@ -4790,7 +4790,17 @@ retry_transaction:
videoram_s = libxl__xs_read(gc, t, libxl__sprintf(gc,
"%s/memory/videoram", dompath));
- videoram = videoram_s ? atoi(videoram_s) : 0;
+ if (!videoram_s) {
+ videoram = 0;
+ } else {
+ videoram = strtoull(videoram_s, &endptr, 10);
+ if (*endptr != '\0') {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+ "invalid videoram %s\n", videoram_s);
+ abort_transaction = 1;
+ goto out;
+ }
+ }
if (relative) {
if (target_memkb < 0 && abs(target_memkb) > current_target_memkb)
@@ -4809,7 +4819,7 @@ retry_transaction:
if (!domid && new_target_memkb < LIBXL_MIN_DOM0_MEM) {
LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
- "new target %d for dom0 is below the minimum threshold\n",
+ "new target %"PRIu64" for dom0 is below the minimum
threshold\n",
new_target_memkb);
abort_transaction = 1;
goto out;
@@ -4820,7 +4830,7 @@ retry_transaction:
rc = xc_domain_setmaxmem(ctx->xch, domid, memorykb);
if (rc != 0) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
- "xc_domain_setmaxmem domid=%d memkb=%d failed "
+ "xc_domain_setmaxmem domid=%d memkb=%"PRIu64" failed "
"rc=%d\n", domid, memorykb, rc);
abort_transaction = 1;
goto out;
@@ -4831,7 +4841,7 @@ retry_transaction:
new_target_memkb / 4, NULL, NULL, NULL);
if (rc != 0) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
- "xc_domain_set_pod_target domid=%d, memkb=%d "
+ "xc_domain_set_pod_target domid=%d, memkb=%"PRIu64" "
"failed rc=%d\n", domid, new_target_memkb / 4,
rc);
abort_transaction = 1;
@@ -4839,10 +4849,10 @@ retry_transaction:
}
libxl__xs_write(gc, t, libxl__sprintf(gc, "%s/memory/target",
- dompath), "%"PRIu32, new_target_memkb);
+ dompath), "%"PRIu64, new_target_memkb);
libxl__xs_write(gc, t, libxl__sprintf(gc, "/vm/%s/memory", uuid),
- "%"PRIu32, new_target_memkb / 1024);
+ "%"PRIu64, new_target_memkb / 1024);
out:
if (!xs_transaction_end(ctx->xsh, t, abort_transaction)
@@ -4858,13 +4868,13 @@ out_no_transaction:
/* out_target_memkb and out_max_memkb can be NULL */
static int libxl__get_memory_target(libxl__gc *gc, uint32_t domid,
- uint32_t *out_target_memkb,
- uint32_t *out_max_memkb)
+ uint64_t *out_target_memkb,
+ uint64_t *out_max_memkb)
{
int rc;
char *target = NULL, *static_max = NULL, *endptr = NULL;
char *dompath = libxl__xs_get_dompath(gc, domid);
- uint32_t target_memkb, max_memkb;
+ uint64_t target_memkb, max_memkb;
target = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc,
"%s/memory/target", dompath));
@@ -4888,14 +4898,14 @@ static int libxl__get_memory_target(libxl__gc *gc,
uint32_t domid,
dompath);
goto out;
} else {
- target_memkb = strtoul(target, &endptr, 10);
+ target_memkb = strtoull(target, &endptr, 10);
if (*endptr != '\0') {
LIBXL__LOG_ERRNO(CTX, LIBXL__LOG_ERROR,
"invalid memory target %s from %s/memory/target\n",
target, dompath);
goto out;
}
- max_memkb = strtoul(static_max, &endptr, 10);
+ max_memkb = strtoull(static_max, &endptr, 10);
if (*endptr != '\0') {
LIBXL__LOG_ERRNO(CTX, LIBXL__LOG_ERROR,
"invalid memory target %s from %s/memory/static-max\n",
@@ -4918,7 +4928,7 @@ out:
}
int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid,
- uint32_t *out_target)
+ uint64_t *out_target)
{
GC_INIT(ctx);
int rc;
@@ -5006,7 +5016,7 @@ out:
int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs)
{
int rc = 0;
- uint32_t target_memkb = 0;
+ uint64_t target_memkb = 0;
uint64_t current_memkb, prev_memkb;
libxl_dominfo info;
@@ -6652,7 +6662,7 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx,
uint32_t domid,
* "target" and "static-max".
*/
{
- uint32_t target_memkb = 0, max_memkb = 0;
+ uint64_t target_memkb = 0, max_memkb = 0;
/* "target" */
rc = libxl__get_memory_target(gc, domid, &target_memkb, &max_memkb);
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 6bc75c5..3b2daa8 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1047,7 +1047,7 @@ int libxl_domain_core_dump(libxl_ctx *ctx, uint32_t domid,
int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t
target_memkb);
int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, int32_t
target_memkb, int relative, int enforce);
-int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t
*out_target);
+int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid, uint64_t
*out_target);
/*
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |