|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] libxl: carve out memory specific functions from libxl.c
commit c8cbddd8d62cee152c9d45e16995453551017802
Author: Juergen Gross <jgross@xxxxxxxx>
AuthorDate: Wed Feb 8 17:09:30 2017 +0100
Commit: Wei Liu <wei.liu2@xxxxxxxxxx>
CommitDate: Mon Feb 13 10:59:19 2017 +0000
libxl: carve out memory specific functions from libxl.c
libxl.c has grown to an uncomfortable size. Carve out the memory
related functions to libxl_mem.c.
Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
Reviewed-by: Wei Liu <wei.liu2@xxxxxxxxxx>
Acked-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
---
tools/libxl/Makefile | 2 +-
tools/libxl/libxl.c | 577 ----------------------------------------------
tools/libxl/libxl_mem.c | 601 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 602 insertions(+), 578 deletions(-)
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index dd7aa41..4b05e34 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -137,7 +137,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o
libxl_pci.o \
libxl_qmp.o libxl_event.o libxl_fork.o \
libxl_dom_suspend.o libxl_dom_save.o libxl_usb.o \
libxl_vtpm.o libxl_nic.o libxl_disk.o libxl_console.o \
- libxl_cpupool.o libxl_sched.o \
+ libxl_cpupool.o libxl_mem.o libxl_sched.o \
$(LIBXL_OBJS-y)
LIBXL_OBJS += libxl_genid.o
LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index bdf39602..9f2e6b3 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -15,7 +15,6 @@
#include "libxl_osdeps.h"
#include "libxl_internal.h"
-#include "libxl_arch.h"
#define PAGE_TO_MEMKB(pages) ((pages) * 4)
@@ -1952,582 +1951,6 @@ out:
}
/******************************************************************************/
-
-/*
- * Set the maximum memory size of the domain in the hypervisor. There is no
- * change of the current memory size involved. The specified memory size can
- * even be above the configured maxmem size of the domain, but the related
- * Xenstore entry memory/static-max isn't modified!
- */
-int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint64_t max_memkb)
-{
- GC_INIT(ctx);
- char *mem, *endptr;
- uint64_t memorykb, size;
- char *dompath = libxl__xs_get_dompath(gc, domid);
- int rc = 1;
- libxl__domain_userdata_lock *lock = NULL;
- libxl_domain_config d_config;
-
- libxl_domain_config_init(&d_config);
-
- CTX_LOCK;
-
- lock = libxl__lock_domain_userdata(gc, domid);
- if (!lock) {
- rc = ERROR_LOCK_FAIL;
- goto out;
- }
-
- mem = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/memory/target", dompath));
- if (!mem) {
- LOGED(ERROR, domid, "Cannot get memory info from %s/memory/target",
- dompath);
- goto out;
- }
- memorykb = strtoull(mem, &endptr, 10);
- if (*endptr != '\0') {
- LOGED(ERROR, domid, "Invalid memory %s from %s/memory/target\n",
- mem, dompath);
- goto out;
- }
-
- if (max_memkb < memorykb) {
- LOGED(ERROR, domid,
- "memory_static_max must be greater than or or equal to
memory_dynamic_max");
- goto out;
- }
-
- rc = libxl__get_domain_configuration(gc, domid, &d_config);
- if (rc < 0) {
- LOGE(ERROR, "unable to retrieve domain configuration");
- goto out;
- }
-
- rc = libxl__arch_extra_memory(gc, &d_config.b_info, &size);
- if (rc < 0) {
- LOGE(ERROR, "Couldn't get arch extra constant memory size");
- goto out;
- }
-
- rc = xc_domain_setmaxmem(ctx->xch, domid, max_memkb + size);
- if (rc != 0) {
- LOGED(ERROR, domid,
- "xc_domain_setmaxmem domid=%d memkb=%"PRIu64" failed ""rc=%d\n",
- domid, max_memkb + size, rc);
- goto out;
- }
-
- rc = 0;
-out:
- libxl_domain_config_dispose(&d_config);
- if (lock) libxl__unlock_domain_userdata(lock);
- CTX_UNLOCK;
- GC_FREE;
- return rc;
-}
-
-static int libxl__fill_dom0_memory_info(libxl__gc *gc, uint64_t *target_memkb,
- uint64_t *max_memkb)
-{
- int rc;
- libxl_dominfo info;
- libxl_physinfo physinfo;
- char *target = NULL, *staticmax = NULL, *endptr = NULL;
- char *target_path = "/local/domain/0/memory/target";
- char *max_path = "/local/domain/0/memory/static-max";
- xs_transaction_t t;
- libxl_ctx *ctx = libxl__gc_owner(gc);
-
- libxl_dominfo_init(&info);
-
-retry_transaction:
- t = xs_transaction_start(ctx->xsh);
-
- target = libxl__xs_read(gc, t, target_path);
- staticmax = libxl__xs_read(gc, t, max_path);
- if (target && staticmax) {
- rc = 0;
- goto out;
- }
-
- if (target) {
- *target_memkb = strtoull(target, &endptr, 10);
- if (*endptr != '\0') {
- LOGED(ERROR, 0, "Invalid memory target %s from %s\n", target,
- target_path);
- rc = ERROR_FAIL;
- goto out;
- }
- }
-
- if (staticmax) {
- *max_memkb = strtoull(staticmax, &endptr, 10);
- if (*endptr != '\0') {
- LOGED(ERROR, 0, "Invalid memory static-max %s from %s\n",
- staticmax,
- max_path);
- rc = ERROR_FAIL;
- goto out;
- }
- }
-
- libxl_dominfo_dispose(&info);
- libxl_dominfo_init(&info);
- rc = libxl_domain_info(ctx, &info, 0);
- if (rc < 0)
- goto out;
-
- rc = libxl_get_physinfo(ctx, &physinfo);
- if (rc < 0)
- goto out;
-
- if (target == NULL) {
- libxl__xs_printf(gc, t, target_path, "%"PRIu64, info.current_memkb);
- *target_memkb = info.current_memkb;
- }
- if (staticmax == NULL) {
- libxl__xs_printf(gc, t, max_path, "%"PRIu64, info.max_memkb);
- *max_memkb = info.max_memkb;
- }
-
- rc = 0;
-
-out:
- if (!xs_transaction_end(ctx->xsh, t, 0)) {
- if (errno == EAGAIN)
- goto retry_transaction;
- else
- rc = ERROR_FAIL;
- }
-
- libxl_dominfo_dispose(&info);
- return rc;
-}
-
-int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid,
- int64_t target_memkb, int relative, int enforce)
-{
- GC_INIT(ctx);
- int rc, r, lrc, abort_transaction = 0;
- uint64_t memorykb, size;
- uint64_t 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);
- xc_domaininfo_t info;
- libxl_dominfo ptr;
- char *uuid;
- xs_transaction_t t;
- libxl__domain_userdata_lock *lock;
- libxl_domain_config d_config;
-
- libxl_domain_config_init(&d_config);
-
- CTX_LOCK;
-
- lock = libxl__lock_domain_userdata(gc, domid);
- if (!lock) {
- rc = ERROR_LOCK_FAIL;
- goto out_no_transaction;
- }
-
- rc = libxl__get_domain_configuration(gc, domid, &d_config);
- if (rc < 0) {
- LOGE(ERROR, "unable to retrieve domain configuration");
- goto out_no_transaction;
- }
-
- rc = libxl__arch_extra_memory(gc, &d_config.b_info, &size);
- if (rc < 0) {
- LOGE(ERROR, "Couldn't get arch extra constant memory size");
- goto out_no_transaction;
- }
-
-retry_transaction:
- t = xs_transaction_start(ctx->xsh);
-
- target = libxl__xs_read(gc, t, GCSPRINTF("%s/memory/target", dompath));
- if (!target && !domid) {
- if (!xs_transaction_end(ctx->xsh, t, 1)) {
- rc = ERROR_FAIL;
- goto out_no_transaction;
- }
- lrc = libxl__fill_dom0_memory_info(gc, ¤t_target_memkb,
- ¤t_max_memkb);
- if (lrc < 0) { rc = ERROR_FAIL; goto out_no_transaction; }
- goto retry_transaction;
- } else if (!target) {
- LOGED(ERROR, domid, "Cannot get target memory info from
%s/memory/target",
- dompath);
- abort_transaction = 1;
- rc = ERROR_FAIL;
- goto out;
- } else {
- current_target_memkb = strtoull(target, &endptr, 10);
- if (*endptr != '\0') {
- LOGED(ERROR, domid, "Invalid memory target %s from
%s/memory/target\n",
- target, dompath);
- abort_transaction = 1;
- rc = ERROR_FAIL;
- goto out;
- }
- }
- memmax = libxl__xs_read(gc, t, GCSPRINTF("%s/memory/static-max", dompath));
- if (!memmax) {
- LOGED(ERROR, domid, "Cannot get memory info from %s/memory/static-max",
- dompath);
- abort_transaction = 1;
- rc = ERROR_FAIL;
- goto out;
- }
- memorykb = strtoull(memmax, &endptr, 10);
- if (*endptr != '\0') {
- LOGED(ERROR, domid, "Invalid max memory %s from
%s/memory/static-max\n",
- memmax, dompath);
- abort_transaction = 1;
- rc = ERROR_FAIL;
- goto out;
- }
-
- videoram_s = libxl__xs_read(gc, t, GCSPRINTF("%s/memory/videoram",
- dompath));
- videoram = videoram_s ? atoi(videoram_s) : 0;
-
- if (relative) {
- if (target_memkb < 0 && llabs(target_memkb) > current_target_memkb)
- new_target_memkb = 0;
- else
- new_target_memkb = current_target_memkb + target_memkb;
- } else
- new_target_memkb = target_memkb - videoram;
- if (new_target_memkb > memorykb) {
- LOGD(ERROR, domid,
- "memory_dynamic_max must be less than or equal to"
- " memory_static_max\n");
- abort_transaction = 1;
- rc = ERROR_INVAL;
- goto out;
- }
-
- if (!domid && new_target_memkb < LIBXL_MIN_DOM0_MEM) {
- LOGD(ERROR, domid,
- "New target %"PRIu64" for dom0 is below the minimum threshold",
- new_target_memkb);
- abort_transaction = 1;
- rc = ERROR_INVAL;
- goto out;
- }
-
- if (enforce) {
- memorykb = new_target_memkb + videoram;
- r = xc_domain_setmaxmem(ctx->xch, domid, memorykb + size);
- if (r != 0) {
- LOGED(ERROR, domid,
- "xc_domain_setmaxmem memkb=%"PRIu64" failed ""rc=%d\n",
- memorykb + size,
- r);
- abort_transaction = 1;
- rc = ERROR_FAIL;
- goto out;
- }
- }
-
- r = xc_domain_set_pod_target(ctx->xch, domid,
- (new_target_memkb + size) / 4, NULL, NULL, NULL);
- if (r != 0) {
- LOGED(ERROR, domid,
- "xc_domain_set_pod_target memkb=%"PRIu64" failed rc=%d\n",
- (new_target_memkb + size) / 4,
- r);
- abort_transaction = 1;
- rc = ERROR_FAIL;
- goto out;
- }
-
- libxl__xs_printf(gc, t, GCSPRINTF("%s/memory/target", dompath),
- "%"PRIu64, new_target_memkb);
-
- r = xc_domain_getinfolist(ctx->xch, domid, 1, &info);
- if (r != 1 || info.domain != domid) {
- abort_transaction = 1;
- rc = ERROR_FAIL;
- goto out;
- }
-
- libxl_dominfo_init(&ptr);
- libxl__xcinfo2xlinfo(ctx, &info, &ptr);
- uuid = libxl__uuid2string(gc, ptr.uuid);
- libxl__xs_printf(gc, t, GCSPRINTF("/vm/%s/memory", uuid),
- "%"PRIu64, new_target_memkb / 1024);
- libxl_dominfo_dispose(&ptr);
-
- rc = 0;
-out:
- if (!xs_transaction_end(ctx->xsh, t, abort_transaction)
- && !abort_transaction)
- if (errno == EAGAIN)
- goto retry_transaction;
-
-out_no_transaction:
- libxl_domain_config_dispose(&d_config);
- if (lock) libxl__unlock_domain_userdata(lock);
- CTX_UNLOCK;
- GC_FREE;
- return rc;
-}
-
-/* out_target_memkb and out_max_memkb can be NULL */
-int libxl__get_memory_target(libxl__gc *gc, uint32_t domid,
- 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);
- uint64_t target_memkb, max_memkb;
-
- target = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/memory/target",
- dompath));
- static_max = libxl__xs_read(gc, XBT_NULL,
- GCSPRINTF("%s/memory/static-max", dompath));
-
- rc = ERROR_FAIL;
- if ((!target || !static_max) && !domid) {
- rc = libxl__fill_dom0_memory_info(gc, &target_memkb,
- &max_memkb);
- if (rc < 0)
- goto out;
- } else if (!target) {
- LOGED(ERROR, domid, "Cannot get target memory info from
%s/memory/target",
- dompath);
- goto out;
- } else if (!static_max) {
- LOGED(ERROR, domid,
- "Cannot get target memory info from %s/memory/static-max",
- dompath);
- goto out;
- } else {
- target_memkb = strtoull(target, &endptr, 10);
- if (*endptr != '\0') {
- LOGED(ERROR, domid, "Invalid memory target %s from
%s/memory/target\n",
- target, dompath);
- goto out;
- }
- max_memkb = strtoull(static_max, &endptr, 10);
- if (*endptr != '\0') {
- LOGED(ERROR, domid,
- "Invalid memory target %s from %s/memory/static-max\n",
- static_max,
- dompath);
- goto out;
- }
-
- }
-
- if (out_target_memkb)
- *out_target_memkb = target_memkb;
-
- if (out_max_memkb)
- *out_max_memkb = max_memkb;
-
- rc = 0;
-
-out:
- return rc;
-}
-
-static int libxl__memkb_64to32(libxl_ctx *ctx, int rc,
- uint64_t val64, uint32_t *ptr32)
-{
- GC_INIT(ctx);
-
- if (rc)
- goto out;
-
- *ptr32 = val64;
- if (*ptr32 == val64)
- goto out;
-
- LOGE(ERROR, "memory size %"PRIu64" too large for 32 bit value\n", val64);
- rc = ERROR_FAIL;
-
-out:
- GC_FREE;
- return rc;
-}
-
-int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid,
- uint64_t *out_target)
-{
- GC_INIT(ctx);
- int rc;
-
- rc = libxl__get_memory_target(gc, domid, out_target, NULL);
-
- GC_FREE;
- return rc;
-}
-
-int libxl_get_memory_target_0x040700(
- libxl_ctx *ctx, uint32_t domid, uint32_t *out_target)
-{
- uint64_t my_out_target;
- int rc;
-
- rc = libxl_get_memory_target(ctx, domid, &my_out_target);
- return libxl__memkb_64to32(ctx, rc, my_out_target, out_target);
-}
-
-int libxl_domain_need_memory(libxl_ctx *ctx,
- const libxl_domain_build_info *b_info_in,
- uint64_t *need_memkb)
-{
- GC_INIT(ctx);
- libxl_domain_build_info b_info[1];
- int rc;
-
- libxl_domain_build_info_init(b_info);
- libxl_domain_build_info_copy(ctx, b_info, b_info_in);
-
- rc = libxl__domain_build_info_setdefault(gc, b_info);
- if (rc) goto out;
-
- *need_memkb = b_info->target_memkb;
- switch (b_info->type) {
- case LIBXL_DOMAIN_TYPE_HVM:
- *need_memkb += b_info->shadow_memkb + LIBXL_HVM_EXTRA_MEMORY;
- if (libxl_defbool_val(b_info->device_model_stubdomain))
- *need_memkb += 32 * 1024;
- break;
- case LIBXL_DOMAIN_TYPE_PV:
- *need_memkb += b_info->shadow_memkb + LIBXL_PV_EXTRA_MEMORY;
- break;
- default:
- rc = ERROR_INVAL;
- goto out;
- }
- if (*need_memkb % (2 * 1024))
- *need_memkb += (2 * 1024) - (*need_memkb % (2 * 1024));
- rc = 0;
-out:
- GC_FREE;
- libxl_domain_build_info_dispose(b_info);
- return rc;
-
-}
-
-int libxl_domain_need_memory_0x040700(libxl_ctx *ctx,
- const libxl_domain_build_info *b_info_in,
- uint32_t *need_memkb)
-{
- uint64_t my_need_memkb;
- int rc;
-
- rc = libxl_domain_need_memory(ctx, b_info_in, &my_need_memkb);
- return libxl__memkb_64to32(ctx, rc, my_need_memkb, need_memkb);
-}
-
-int libxl_get_free_memory(libxl_ctx *ctx, uint64_t *memkb)
-{
- int rc = 0;
- libxl_physinfo info;
- GC_INIT(ctx);
-
- rc = libxl_get_physinfo(ctx, &info);
- if (rc < 0)
- goto out;
-
- *memkb = (info.free_pages + info.scrub_pages) * 4;
-
-out:
- GC_FREE;
- return rc;
-}
-
-int libxl_get_free_memory_0x040700(libxl_ctx *ctx, uint32_t *memkb)
-{
- uint64_t my_memkb;
- int rc;
-
- rc = libxl_get_free_memory(ctx, &my_memkb);
- return libxl__memkb_64to32(ctx, rc, my_memkb, memkb);
-}
-
-int libxl_wait_for_free_memory(libxl_ctx *ctx, uint32_t domid,
- uint64_t memory_kb, int wait_secs)
-{
- int rc = 0;
- libxl_physinfo info;
- GC_INIT(ctx);
-
- while (wait_secs > 0) {
- rc = libxl_get_physinfo(ctx, &info);
- if (rc < 0)
- goto out;
- if (info.free_pages * 4 >= memory_kb) {
- rc = 0;
- goto out;
- }
- wait_secs--;
- sleep(1);
- }
- rc = ERROR_NOMEM;
-
-out:
- GC_FREE;
- return rc;
-}
-
-int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs)
-{
- int rc = 0;
- uint64_t target_memkb = 0;
- uint64_t current_memkb, prev_memkb;
- libxl_dominfo info;
-
- rc = libxl_get_memory_target(ctx, domid, &target_memkb);
- if (rc < 0)
- return rc;
-
- libxl_dominfo_init(&info);
- prev_memkb = UINT64_MAX;
-
- do {
- sleep(2);
-
- libxl_dominfo_dispose(&info);
- libxl_dominfo_init(&info);
- rc = libxl_domain_info(ctx, &info, domid);
- if (rc < 0)
- goto out;
-
- current_memkb = info.current_memkb + info.outstanding_memkb;
-
- if (current_memkb > prev_memkb)
- {
- rc = ERROR_FAIL;
- goto out;
- }
- else if (current_memkb == prev_memkb)
- wait_secs -= 2;
- /* if current_memkb < prev_memkb loop for free as progress has
- * been made */
-
- prev_memkb = current_memkb;
- } while (wait_secs > 0 && current_memkb > target_memkb);
-
- if (current_memkb <= target_memkb)
- rc = 0;
- else
- rc = ERROR_FAIL;
-
-out:
- libxl_dominfo_dispose(&info);
- return rc;
-}
-
int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo)
{
xc_physinfo_t xcphysinfo = { 0 };
diff --git a/tools/libxl/libxl_mem.c b/tools/libxl/libxl_mem.c
new file mode 100644
index 0000000..f5d2530
--- /dev/null
+++ b/tools/libxl/libxl_mem.c
@@ -0,0 +1,601 @@
+/*
+ * Copyright 2009-2017 Citrix Ltd and other contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include "libxl_osdeps.h"
+
+#include "libxl_internal.h"
+#include "libxl_arch.h"
+
+/*
+ * Set the maximum memory size of the domain in the hypervisor. There is no
+ * change of the current memory size involved. The specified memory size can
+ * even be above the configured maxmem size of the domain, but the related
+ * Xenstore entry memory/static-max isn't modified!
+ */
+int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint64_t max_memkb)
+{
+ GC_INIT(ctx);
+ char *mem, *endptr;
+ uint64_t memorykb, size;
+ char *dompath = libxl__xs_get_dompath(gc, domid);
+ int rc = 1;
+ libxl__domain_userdata_lock *lock = NULL;
+ libxl_domain_config d_config;
+
+ libxl_domain_config_init(&d_config);
+
+ CTX_LOCK;
+
+ lock = libxl__lock_domain_userdata(gc, domid);
+ if (!lock) {
+ rc = ERROR_LOCK_FAIL;
+ goto out;
+ }
+
+ mem = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/memory/target", dompath));
+ if (!mem) {
+ LOGED(ERROR, domid, "Cannot get memory info from %s/memory/target",
+ dompath);
+ goto out;
+ }
+ memorykb = strtoull(mem, &endptr, 10);
+ if (*endptr != '\0') {
+ LOGED(ERROR, domid, "Invalid memory %s from %s/memory/target\n",
+ mem, dompath);
+ goto out;
+ }
+
+ if (max_memkb < memorykb) {
+ LOGED(ERROR, domid,
+ "memory_static_max must be greater than or or equal to
memory_dynamic_max");
+ goto out;
+ }
+
+ rc = libxl__get_domain_configuration(gc, domid, &d_config);
+ if (rc < 0) {
+ LOGE(ERROR, "unable to retrieve domain configuration");
+ goto out;
+ }
+
+ rc = libxl__arch_extra_memory(gc, &d_config.b_info, &size);
+ if (rc < 0) {
+ LOGE(ERROR, "Couldn't get arch extra constant memory size");
+ goto out;
+ }
+
+ rc = xc_domain_setmaxmem(ctx->xch, domid, max_memkb + size);
+ if (rc != 0) {
+ LOGED(ERROR, domid,
+ "xc_domain_setmaxmem domid=%d memkb=%"PRIu64" failed ""rc=%d\n",
+ domid, max_memkb + size, rc);
+ goto out;
+ }
+
+ rc = 0;
+out:
+ libxl_domain_config_dispose(&d_config);
+ if (lock) libxl__unlock_domain_userdata(lock);
+ CTX_UNLOCK;
+ GC_FREE;
+ return rc;
+}
+
+static int libxl__fill_dom0_memory_info(libxl__gc *gc, uint64_t *target_memkb,
+ uint64_t *max_memkb)
+{
+ int rc;
+ libxl_dominfo info;
+ libxl_physinfo physinfo;
+ char *target = NULL, *staticmax = NULL, *endptr = NULL;
+ char *target_path = "/local/domain/0/memory/target";
+ char *max_path = "/local/domain/0/memory/static-max";
+ xs_transaction_t t;
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+
+ libxl_dominfo_init(&info);
+
+retry_transaction:
+ t = xs_transaction_start(ctx->xsh);
+
+ target = libxl__xs_read(gc, t, target_path);
+ staticmax = libxl__xs_read(gc, t, max_path);
+ if (target && staticmax) {
+ rc = 0;
+ goto out;
+ }
+
+ if (target) {
+ *target_memkb = strtoull(target, &endptr, 10);
+ if (*endptr != '\0') {
+ LOGED(ERROR, 0, "Invalid memory target %s from %s\n", target,
+ target_path);
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ }
+
+ if (staticmax) {
+ *max_memkb = strtoull(staticmax, &endptr, 10);
+ if (*endptr != '\0') {
+ LOGED(ERROR, 0, "Invalid memory static-max %s from %s\n",
+ staticmax,
+ max_path);
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ }
+
+ libxl_dominfo_dispose(&info);
+ libxl_dominfo_init(&info);
+ rc = libxl_domain_info(ctx, &info, 0);
+ if (rc < 0)
+ goto out;
+
+ rc = libxl_get_physinfo(ctx, &physinfo);
+ if (rc < 0)
+ goto out;
+
+ if (target == NULL) {
+ libxl__xs_printf(gc, t, target_path, "%"PRIu64, info.current_memkb);
+ *target_memkb = info.current_memkb;
+ }
+ if (staticmax == NULL) {
+ libxl__xs_printf(gc, t, max_path, "%"PRIu64, info.max_memkb);
+ *max_memkb = info.max_memkb;
+ }
+
+ rc = 0;
+
+out:
+ if (!xs_transaction_end(ctx->xsh, t, 0)) {
+ if (errno == EAGAIN)
+ goto retry_transaction;
+ else
+ rc = ERROR_FAIL;
+ }
+
+ libxl_dominfo_dispose(&info);
+ return rc;
+}
+
+int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid,
+ int64_t target_memkb, int relative, int enforce)
+{
+ GC_INIT(ctx);
+ int rc, r, lrc, abort_transaction = 0;
+ uint64_t memorykb, size;
+ uint64_t 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);
+ xc_domaininfo_t info;
+ libxl_dominfo ptr;
+ char *uuid;
+ xs_transaction_t t;
+ libxl__domain_userdata_lock *lock;
+ libxl_domain_config d_config;
+
+ libxl_domain_config_init(&d_config);
+
+ CTX_LOCK;
+
+ lock = libxl__lock_domain_userdata(gc, domid);
+ if (!lock) {
+ rc = ERROR_LOCK_FAIL;
+ goto out_no_transaction;
+ }
+
+ rc = libxl__get_domain_configuration(gc, domid, &d_config);
+ if (rc < 0) {
+ LOGE(ERROR, "unable to retrieve domain configuration");
+ goto out_no_transaction;
+ }
+
+ rc = libxl__arch_extra_memory(gc, &d_config.b_info, &size);
+ if (rc < 0) {
+ LOGE(ERROR, "Couldn't get arch extra constant memory size");
+ goto out_no_transaction;
+ }
+
+retry_transaction:
+ t = xs_transaction_start(ctx->xsh);
+
+ target = libxl__xs_read(gc, t, GCSPRINTF("%s/memory/target", dompath));
+ if (!target && !domid) {
+ if (!xs_transaction_end(ctx->xsh, t, 1)) {
+ rc = ERROR_FAIL;
+ goto out_no_transaction;
+ }
+ lrc = libxl__fill_dom0_memory_info(gc, ¤t_target_memkb,
+ ¤t_max_memkb);
+ if (lrc < 0) { rc = ERROR_FAIL; goto out_no_transaction; }
+ goto retry_transaction;
+ } else if (!target) {
+ LOGED(ERROR, domid, "Cannot get target memory info from
%s/memory/target",
+ dompath);
+ abort_transaction = 1;
+ rc = ERROR_FAIL;
+ goto out;
+ } else {
+ current_target_memkb = strtoull(target, &endptr, 10);
+ if (*endptr != '\0') {
+ LOGED(ERROR, domid, "Invalid memory target %s from
%s/memory/target\n",
+ target, dompath);
+ abort_transaction = 1;
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ }
+ memmax = libxl__xs_read(gc, t, GCSPRINTF("%s/memory/static-max", dompath));
+ if (!memmax) {
+ LOGED(ERROR, domid, "Cannot get memory info from %s/memory/static-max",
+ dompath);
+ abort_transaction = 1;
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ memorykb = strtoull(memmax, &endptr, 10);
+ if (*endptr != '\0') {
+ LOGED(ERROR, domid, "Invalid max memory %s from
%s/memory/static-max\n",
+ memmax, dompath);
+ abort_transaction = 1;
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ videoram_s = libxl__xs_read(gc, t, GCSPRINTF("%s/memory/videoram",
+ dompath));
+ videoram = videoram_s ? atoi(videoram_s) : 0;
+
+ if (relative) {
+ if (target_memkb < 0 && llabs(target_memkb) > current_target_memkb)
+ new_target_memkb = 0;
+ else
+ new_target_memkb = current_target_memkb + target_memkb;
+ } else
+ new_target_memkb = target_memkb - videoram;
+ if (new_target_memkb > memorykb) {
+ LOGD(ERROR, domid,
+ "memory_dynamic_max must be less than or equal to"
+ " memory_static_max\n");
+ abort_transaction = 1;
+ rc = ERROR_INVAL;
+ goto out;
+ }
+
+ if (!domid && new_target_memkb < LIBXL_MIN_DOM0_MEM) {
+ LOGD(ERROR, domid,
+ "New target %"PRIu64" for dom0 is below the minimum threshold",
+ new_target_memkb);
+ abort_transaction = 1;
+ rc = ERROR_INVAL;
+ goto out;
+ }
+
+ if (enforce) {
+ memorykb = new_target_memkb + videoram;
+ r = xc_domain_setmaxmem(ctx->xch, domid, memorykb + size);
+ if (r != 0) {
+ LOGED(ERROR, domid,
+ "xc_domain_setmaxmem memkb=%"PRIu64" failed ""rc=%d\n",
+ memorykb + size,
+ r);
+ abort_transaction = 1;
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ }
+
+ r = xc_domain_set_pod_target(ctx->xch, domid,
+ (new_target_memkb + size) / 4, NULL, NULL, NULL);
+ if (r != 0) {
+ LOGED(ERROR, domid,
+ "xc_domain_set_pod_target memkb=%"PRIu64" failed rc=%d\n",
+ (new_target_memkb + size) / 4,
+ r);
+ abort_transaction = 1;
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ libxl__xs_printf(gc, t, GCSPRINTF("%s/memory/target", dompath),
+ "%"PRIu64, new_target_memkb);
+
+ r = xc_domain_getinfolist(ctx->xch, domid, 1, &info);
+ if (r != 1 || info.domain != domid) {
+ abort_transaction = 1;
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ libxl_dominfo_init(&ptr);
+ libxl__xcinfo2xlinfo(ctx, &info, &ptr);
+ uuid = libxl__uuid2string(gc, ptr.uuid);
+ libxl__xs_printf(gc, t, GCSPRINTF("/vm/%s/memory", uuid),
+ "%"PRIu64, new_target_memkb / 1024);
+ libxl_dominfo_dispose(&ptr);
+
+ rc = 0;
+out:
+ if (!xs_transaction_end(ctx->xsh, t, abort_transaction)
+ && !abort_transaction)
+ if (errno == EAGAIN)
+ goto retry_transaction;
+
+out_no_transaction:
+ libxl_domain_config_dispose(&d_config);
+ if (lock) libxl__unlock_domain_userdata(lock);
+ CTX_UNLOCK;
+ GC_FREE;
+ return rc;
+}
+
+/* out_target_memkb and out_max_memkb can be NULL */
+int libxl__get_memory_target(libxl__gc *gc, uint32_t domid,
+ 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);
+ uint64_t target_memkb, max_memkb;
+
+ target = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/memory/target",
+ dompath));
+ static_max = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/memory/static-max", dompath));
+
+ rc = ERROR_FAIL;
+ if ((!target || !static_max) && !domid) {
+ rc = libxl__fill_dom0_memory_info(gc, &target_memkb,
+ &max_memkb);
+ if (rc < 0)
+ goto out;
+ } else if (!target) {
+ LOGED(ERROR, domid, "Cannot get target memory info from
%s/memory/target",
+ dompath);
+ goto out;
+ } else if (!static_max) {
+ LOGED(ERROR, domid,
+ "Cannot get target memory info from %s/memory/static-max",
+ dompath);
+ goto out;
+ } else {
+ target_memkb = strtoull(target, &endptr, 10);
+ if (*endptr != '\0') {
+ LOGED(ERROR, domid, "Invalid memory target %s from
%s/memory/target\n",
+ target, dompath);
+ goto out;
+ }
+ max_memkb = strtoull(static_max, &endptr, 10);
+ if (*endptr != '\0') {
+ LOGED(ERROR, domid,
+ "Invalid memory target %s from %s/memory/static-max\n",
+ static_max,
+ dompath);
+ goto out;
+ }
+
+ }
+
+ if (out_target_memkb)
+ *out_target_memkb = target_memkb;
+
+ if (out_max_memkb)
+ *out_max_memkb = max_memkb;
+
+ rc = 0;
+
+out:
+ return rc;
+}
+
+static int libxl__memkb_64to32(libxl_ctx *ctx, int rc,
+ uint64_t val64, uint32_t *ptr32)
+{
+ GC_INIT(ctx);
+
+ if (rc)
+ goto out;
+
+ *ptr32 = val64;
+ if (*ptr32 == val64)
+ goto out;
+
+ LOGE(ERROR, "memory size %"PRIu64" too large for 32 bit value\n", val64);
+ rc = ERROR_FAIL;
+
+out:
+ GC_FREE;
+ return rc;
+}
+
+int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid,
+ uint64_t *out_target)
+{
+ GC_INIT(ctx);
+ int rc;
+
+ rc = libxl__get_memory_target(gc, domid, out_target, NULL);
+
+ GC_FREE;
+ return rc;
+}
+
+int libxl_get_memory_target_0x040700(
+ libxl_ctx *ctx, uint32_t domid, uint32_t *out_target)
+{
+ uint64_t my_out_target;
+ int rc;
+
+ rc = libxl_get_memory_target(ctx, domid, &my_out_target);
+ return libxl__memkb_64to32(ctx, rc, my_out_target, out_target);
+}
+
+int libxl_domain_need_memory(libxl_ctx *ctx,
+ const libxl_domain_build_info *b_info_in,
+ uint64_t *need_memkb)
+{
+ GC_INIT(ctx);
+ libxl_domain_build_info b_info[1];
+ int rc;
+
+ libxl_domain_build_info_init(b_info);
+ libxl_domain_build_info_copy(ctx, b_info, b_info_in);
+
+ rc = libxl__domain_build_info_setdefault(gc, b_info);
+ if (rc) goto out;
+
+ *need_memkb = b_info->target_memkb;
+ switch (b_info->type) {
+ case LIBXL_DOMAIN_TYPE_HVM:
+ *need_memkb += b_info->shadow_memkb + LIBXL_HVM_EXTRA_MEMORY;
+ if (libxl_defbool_val(b_info->device_model_stubdomain))
+ *need_memkb += 32 * 1024;
+ break;
+ case LIBXL_DOMAIN_TYPE_PV:
+ *need_memkb += b_info->shadow_memkb + LIBXL_PV_EXTRA_MEMORY;
+ break;
+ default:
+ rc = ERROR_INVAL;
+ goto out;
+ }
+ if (*need_memkb % (2 * 1024))
+ *need_memkb += (2 * 1024) - (*need_memkb % (2 * 1024));
+ rc = 0;
+out:
+ GC_FREE;
+ libxl_domain_build_info_dispose(b_info);
+ return rc;
+
+}
+
+int libxl_domain_need_memory_0x040700(libxl_ctx *ctx,
+ const libxl_domain_build_info *b_info_in,
+ uint32_t *need_memkb)
+{
+ uint64_t my_need_memkb;
+ int rc;
+
+ rc = libxl_domain_need_memory(ctx, b_info_in, &my_need_memkb);
+ return libxl__memkb_64to32(ctx, rc, my_need_memkb, need_memkb);
+}
+
+int libxl_get_free_memory(libxl_ctx *ctx, uint64_t *memkb)
+{
+ int rc = 0;
+ libxl_physinfo info;
+ GC_INIT(ctx);
+
+ rc = libxl_get_physinfo(ctx, &info);
+ if (rc < 0)
+ goto out;
+
+ *memkb = (info.free_pages + info.scrub_pages) * 4;
+
+out:
+ GC_FREE;
+ return rc;
+}
+
+int libxl_get_free_memory_0x040700(libxl_ctx *ctx, uint32_t *memkb)
+{
+ uint64_t my_memkb;
+ int rc;
+
+ rc = libxl_get_free_memory(ctx, &my_memkb);
+ return libxl__memkb_64to32(ctx, rc, my_memkb, memkb);
+}
+
+int libxl_wait_for_free_memory(libxl_ctx *ctx, uint32_t domid,
+ uint64_t memory_kb, int wait_secs)
+{
+ int rc = 0;
+ libxl_physinfo info;
+ GC_INIT(ctx);
+
+ while (wait_secs > 0) {
+ rc = libxl_get_physinfo(ctx, &info);
+ if (rc < 0)
+ goto out;
+ if (info.free_pages * 4 >= memory_kb) {
+ rc = 0;
+ goto out;
+ }
+ wait_secs--;
+ sleep(1);
+ }
+ rc = ERROR_NOMEM;
+
+out:
+ GC_FREE;
+ return rc;
+}
+
+int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs)
+{
+ int rc = 0;
+ uint64_t target_memkb = 0;
+ uint64_t current_memkb, prev_memkb;
+ libxl_dominfo info;
+
+ rc = libxl_get_memory_target(ctx, domid, &target_memkb);
+ if (rc < 0)
+ return rc;
+
+ libxl_dominfo_init(&info);
+ prev_memkb = UINT64_MAX;
+
+ do {
+ sleep(2);
+
+ libxl_dominfo_dispose(&info);
+ libxl_dominfo_init(&info);
+ rc = libxl_domain_info(ctx, &info, domid);
+ if (rc < 0)
+ goto out;
+
+ current_memkb = info.current_memkb + info.outstanding_memkb;
+
+ if (current_memkb > prev_memkb)
+ {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ else if (current_memkb == prev_memkb)
+ wait_secs -= 2;
+ /* if current_memkb < prev_memkb loop for free as progress has
+ * been made */
+
+ prev_memkb = current_memkb;
+ } while (wait_secs > 0 && current_memkb > target_memkb);
+
+ if (current_memkb <= target_memkb)
+ rc = 0;
+ else
+ rc = ERROR_FAIL;
+
+out:
+ libxl_dominfo_dispose(&info);
+ return rc;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |