mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
libxl: add few more memory operations
libxl_domain_need_memory: calculate how much memory a domain needs in order to be built and start correctly. libxl_get_free_memory: calculate the total free memory in the system. libxl_wait_for_free_memory: wait for a certain amount of memory to become free in the system. libxl_wait_for_memory_target: wait for a domain to reach its memory target. [fixed up for conflicts with libxl__ naming policy changes -iwj] Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
This commit is contained in:
1 parent
038955aa3b
commit
7010e9b7e4
3 files changed
+142
No files matched your search
@@ -2778,9 +2778,11 @@ static int libxl__fill_dom0_memory_info(libxl__gc *gc, uint32_t *target_memkb)
|
||||
{
|
||||
int rc;
|
||||
libxl_dominfo info;
|
||||
libxl_physinfo physinfo;
|
||||
char *target = NULL, *endptr = NULL;
|
||||
char *target_path = "/local/domain/0/memory/target";
|
||||
char *max_path = "/local/domain/0/memory/static-max";
|
||||
char *free_mem_slack_path = "/local/domain/0/memory/freemem-slack";
|
||||
xs_transaction_t t;
|
||||
libxl_ctx *ctx = libxl__gc_owner(gc);
|
||||
|
||||
@@ -2804,10 +2806,16 @@ retry_transaction:
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = libxl_get_physinfo(ctx, &physinfo);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
libxl__xs_write(gc, t, target_path, "%"PRIu32,
|
||||
(uint32_t) info.current_memkb);
|
||||
libxl__xs_write(gc, t, max_path, "%"PRIu32,
|
||||
(uint32_t) info.max_memkb);
|
||||
libxl__xs_write(gc, t, free_mem_slack_path, "%"PRIu32, (uint32_t)
|
||||
(PAGE_TO_MEMKB(physinfo.total_pages) - info.current_memkb));
|
||||
|
||||
*target_memkb = (uint32_t) info.current_memkb;
|
||||
rc = 0;
|
||||
@@ -2821,6 +2829,33 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* returns how much memory should be left free in the system */
|
||||
static int libxl__get_free_memory_slack(libxl__gc *gc, uint32_t *free_mem_slack)
|
||||
{
|
||||
int rc;
|
||||
char *free_mem_slack_path = "/local/domain/0/memory/freemem-slack";
|
||||
char *free_mem_slack_s, *endptr;
|
||||
uint32_t target_memkb;
|
||||
|
||||
retry:
|
||||
free_mem_slack_s = libxl__xs_read(gc, XBT_NULL, free_mem_slack_path);
|
||||
if (!free_mem_slack_s) {
|
||||
rc = libxl__fill_dom0_memory_info(gc, &target_memkb);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
goto retry;
|
||||
} else {
|
||||
*free_mem_slack = strtoul(free_mem_slack_s, &endptr, 10);
|
||||
if (*endptr != '\0') {
|
||||
LIBXL__LOG_ERRNO(gc->owner, LIBXL__LOG_ERROR,
|
||||
"invalid free_mem_slack %s from %s\n",
|
||||
free_mem_slack_s, free_mem_slack_path);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid,
|
||||
int32_t target_memkb, int relative, int enforce)
|
||||
{
|
||||
@@ -2979,6 +3014,102 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int libxl_domain_need_memory(libxl_ctx *ctx, libxl_domain_build_info *b_info,
|
||||
libxl_device_model_info *dm_info, uint32_t *need_memkb)
|
||||
{
|
||||
*need_memkb = b_info->target_memkb;
|
||||
if (b_info->hvm) {
|
||||
*need_memkb += b_info->shadow_memkb + LIBXL_HVM_EXTRA_MEMORY;
|
||||
if (strstr(dm_info->device_model, "stubdom-dm"))
|
||||
*need_memkb += 32 * 1024;
|
||||
} else
|
||||
*need_memkb += LIBXL_PV_EXTRA_MEMORY;
|
||||
if (*need_memkb % (2 * 1024))
|
||||
*need_memkb += (2 * 1024) - (*need_memkb % (2 * 1024));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxl_get_free_memory(libxl_ctx *ctx, uint32_t *memkb)
|
||||
{
|
||||
int rc = 0;
|
||||
libxl_physinfo info;
|
||||
uint32_t freemem_slack;
|
||||
libxl__gc gc = LIBXL_INIT_GC(ctx);
|
||||
|
||||
rc = libxl_get_physinfo(ctx, &info);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
rc = libxl__get_free_memory_slack(&gc, &freemem_slack);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
|
||||
if ((info.free_pages + info.scrub_pages) * 4 > freemem_slack)
|
||||
*memkb = (info.free_pages + info.scrub_pages) * 4 - freemem_slack;
|
||||
else
|
||||
*memkb = 0;
|
||||
|
||||
out:
|
||||
libxl__free_all(&gc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int libxl_wait_for_free_memory(libxl_ctx *ctx, uint32_t domid, uint32_t
|
||||
memory_kb, int wait_secs)
|
||||
{
|
||||
int rc = 0;
|
||||
libxl_physinfo info;
|
||||
uint32_t freemem_slack;
|
||||
libxl__gc gc = LIBXL_INIT_GC(ctx);
|
||||
|
||||
rc = libxl__get_free_memory_slack(&gc, &freemem_slack);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
while (wait_secs > 0) {
|
||||
rc = libxl_get_physinfo(ctx, &info);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
if (info.free_pages * 4 - freemem_slack >= memory_kb) {
|
||||
rc = 0;
|
||||
goto out;
|
||||
}
|
||||
wait_secs--;
|
||||
sleep(1);
|
||||
}
|
||||
rc = ERROR_NOMEM;
|
||||
|
||||
out:
|
||||
libxl__free_all(&gc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs)
|
||||
{
|
||||
int rc = 0;
|
||||
uint32_t target_memkb = 0;
|
||||
libxl_dominfo info;
|
||||
|
||||
do {
|
||||
wait_secs--;
|
||||
sleep(1);
|
||||
|
||||
rc = libxl_get_memory_target(ctx, domid, &target_memkb);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
|
||||
rc = libxl_domain_info(ctx, &info, domid);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
} while (wait_secs > 0 && info.current_memkb > target_memkb);
|
||||
|
||||
if (info.current_memkb <= target_memkb)
|
||||
rc = 0;
|
||||
else
|
||||
rc = ERROR_FAIL;
|
||||
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxl_button_press(libxl_ctx *ctx, uint32_t domid, libxl_button button)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
@@ -334,6 +334,15 @@ int libxl_domain_core_dump(libxl_ctx *ctx, uint32_t domid, const char *filename)
|
||||
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);
|
||||
/* how much free memory in the system a domain needs to be built */
|
||||
int libxl_domain_need_memory(libxl_ctx *ctx, libxl_domain_build_info *b_info,
|
||||
libxl_device_model_info *dm_info, uint32_t *need_memkb);
|
||||
/* how much free memory is available in the system */
|
||||
int libxl_get_free_memory(libxl_ctx *ctx, uint32_t *memkb);
|
||||
/* wait for a given amount of memory to be free in the system */
|
||||
int libxl_wait_for_free_memory(libxl_ctx *ctx, uint32_t domid, uint32_t memory_kb, int wait_secs);
|
||||
/* wait for the memory target of a domain to be reached */
|
||||
int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs);
|
||||
|
||||
int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass);
|
||||
int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num, libxl_console_constype type);
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#define LIBXL_XENCONSOLE_LIMIT 1048576
|
||||
#define LIBXL_XENCONSOLE_PROTOCOL "vt100"
|
||||
#define LIBXL_MAXMEM_CONSTANT 1024
|
||||
#define LIBXL_PV_EXTRA_MEMORY 1024
|
||||
#define LIBXL_HVM_EXTRA_MEMORY 2048
|
||||
#define QEMU_SIGNATURE "QemuDeviceModelRecord"
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||