# HG changeset patch
# User Olaf Hering <olaf@xxxxxxxxx>
# Date 1317656695 -7200
# Node ID c37a41cf0bf05f183a9b167f307591ec69e770e4
# Parent 5dd8e13e8222486bc09894dc3245c28a7e654d0a
xenpaging: libxl support
Add support to libxl for starting xenpaging.
Its a huge patch and should be spit into totmem= and the actual xenpaging
change.
The patch adds three new config options:
totmem=<int> , the number of pages
xenpaging_file=<string>, pagefile to use
xenpaging_extra=[ 'string', 'string' ], additional optional args for xenpaging
xl gets a new 'mem-tot_pages' command which modifies xenstore
"memory/target-tot_pages" to notify the pager of a new target number and it
instructs the xl monitor process to start the pager if the totmem= option was
not in the config file.
Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -626,6 +626,21 @@ out:
return rc;
}
+int libxl_wait_for_target_tot_pages(libxl_ctx *ctx, uint32_t domid,
libxl_waiter *waiter)
+{
+ libxl__gc gc = LIBXL_INIT_GC(ctx);
+ int rc = -1;
+ if (asprintf(&waiter->path, "%s/memory/target-tot_pages",
libxl__xs_get_dompath(&gc, domid)) < 0)
+ goto out;
+ if (asprintf(&waiter->token, "%d", LIBXL_EVENT_TYPE_XENPAGING) < 0)
+ goto out;
+ if (xs_watch(ctx->xsh, waiter->path, waiter->token) == true)
+ rc = 0;
+out:
+ libxl__free_all(&gc);
+ return rc;
+}
+
int libxl_get_event(libxl_ctx *ctx, libxl_event *event)
{
unsigned int num;
@@ -2035,6 +2050,112 @@ out:
return rc;
}
+int libxl_set_memory_tot_pages(libxl_ctx *ctx, uint32_t domid,
+ int32_t tot_pages_memkb, int relative)
+{
+ libxl__gc gc;
+ int rc, abort = 0;
+ uint32_t memorykb, videoram;
+ uint32_t current_target_memkb = 0;
+ uint32_t current_tot_pages_memkb, new_tot_pages_memkb;
+ char *memmax, *endptr, *videoram_s, *target, *tot_pages;
+ char *dompath;
+ xs_transaction_t t;
+
+ if (domid == 0) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot set tot_pages for dom0.\n");
+ return ERROR_INVAL;
+ }
+
+ gc = LIBXL_INIT_GC(ctx);
+ dompath = libxl__xs_get_dompath(&gc, domid);
+
+retry_transaction:
+ rc = 1;
+ t = xs_transaction_start(ctx->xsh);
+
+ target = libxl__xs_read(&gc, t, libxl__sprintf(&gc,
+ "%s/memory/target", dompath));
+ if (!target) {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+ "cannot get target memory info from %s/memory/target\n",
+ dompath);
+ abort = 1;
+ goto out;
+ } else {
+ current_target_memkb = strtoul(target, &endptr, 10);
+ if (*endptr != '\0') {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+ "invalid memory target %s from %s/memory/target\n",
+ target, dompath);
+ abort = 1;
+ goto out;
+ }
+ }
+
+ videoram_s = libxl__xs_read(&gc, t, libxl__sprintf(&gc,
+ "%s/memory/videoram", dompath));
+ videoram = videoram_s ? atoi(videoram_s) : 0;
+
+ current_tot_pages_memkb = current_target_memkb + videoram;
+ tot_pages = libxl__xs_read(&gc, t, libxl__sprintf(&gc,
+ "%s/memory/target-tot_pages", dompath));
+ if (tot_pages) {
+ current_tot_pages_memkb = strtoul(tot_pages, &endptr, 10);
+ if (*endptr != '\0') {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+ "invalid tot_pages %s from %s/memory/target-tot_pages\n",
+ tot_pages, dompath);
+ abort = 1;
+ goto out;
+ }
+ }
+ memmax = libxl__xs_read(&gc, t, libxl__sprintf(&gc,
+ "%s/memory/static-max", dompath));
+ if (!memmax) {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+ "cannot get memory info from %s/memory/static-max\n",
+ dompath);
+ abort = 1;
+ goto out;
+ }
+ memorykb = strtoul(memmax, &endptr, 10);
+ if (*endptr != '\0') {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+ "invalid max memory %s from %s/memory/static-max\n",
+ memmax, dompath);
+ abort = 1;
+ goto out;
+ }
+
+ if (relative) {
+ if (tot_pages_memkb < 0 && abs(tot_pages_memkb) >
current_tot_pages_memkb)
+ new_tot_pages_memkb = 0;
+ else
+ new_tot_pages_memkb = current_tot_pages_memkb + tot_pages_memkb;
+ } else
+ new_tot_pages_memkb = tot_pages_memkb;
+ if (new_tot_pages_memkb > memorykb) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+ "memory_dynamic_max must be less than or equal to"
+ " memory_static_max\n");
+ abort = 1;
+ goto out;
+ }
+
+ libxl__xs_write(&gc, t, libxl__sprintf(&gc, "%s/memory/target-tot_pages",
+ dompath), "%"PRIu32, new_tot_pages_memkb);
+
+ rc = 0;
+out:
+ if (!xs_transaction_end(ctx->xsh, t, abort) && !abort)
+ if (errno == EAGAIN)
+ goto retry_transaction;
+
+ libxl__free_all(&gc);
+ 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)
{
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -261,6 +261,7 @@ int libxl_init_dm_info(libxl_ctx *ctx,
typedef int (*libxl_console_ready)(libxl_ctx *ctx, uint32_t domid, void *priv);
int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config,
libxl_console_ready cb, void *priv, uint32_t *domid);
int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config,
libxl_console_ready cb, void *priv, uint32_t *domid, int restore_fd);
+int libxl__create_xenpaging(libxl_ctx *ctx, libxl_domain_config *d_config,
uint32_t domid, char *path);
void libxl_domain_config_destroy(libxl_domain_config *d_config);
int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info,
uint32_t domid, int fd);
@@ -312,6 +313,8 @@ int libxl_get_wait_fd(libxl_ctx *ctx, in
int libxl_wait_for_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_waiter
*waiter);
/* waiter is a preallocated array of num_disks libxl_waiter elements */
int libxl_wait_for_disk_ejects(libxl_ctx *ctx, uint32_t domid,
libxl_device_disk *disks, int num_disks, libxl_waiter *waiter);
+/* waiter is allocated by the caller */
+int libxl_wait_for_target_tot_pages(libxl_ctx *ctx, uint32_t domid,
libxl_waiter *waiter);
int libxl_get_event(libxl_ctx *ctx, libxl_event *event);
int libxl_stop_waiting(libxl_ctx *ctx, libxl_waiter *waiter);
int libxl_free_event(libxl_event *event);
@@ -352,6 +355,7 @@ int libxl_domain_core_dump(libxl_ctx *ct
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_set_memory_tot_pages(libxl_ctx *ctx, uint32_t domid, int32_t
tot_pages_memkb, int relative);
/* 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);
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl_create.c
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -429,6 +429,121 @@ retry_transaction:
return rc;
}
+static int create_xenpaging(libxl__gc *gc, char *dom_name, uint32_t domid,
+ libxl_domain_build_info *b_info)
+{
+ libxl__spawner_starting *buf_starting;
+ libxl_string_list xpe = b_info->u.hvm.xenpaging_extra;
+ int i, rc;
+ char *logfile;
+ int logfile_w, null;
+ char *path, *dom_path, *value;
+ char **args;
+ char *xp;
+ flexarray_t *xp_args;
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+
+ /* Nothing to do */
+ if (b_info->target_memkb == b_info->tot_memkb)
+ return 0;
+
+ /* Check if paging is already enabled */
+ dom_path = libxl__xs_get_dompath(gc, domid);
+ if (!dom_path ) {
+ rc = ERROR_NOMEM;
+ goto out;
+ }
+ path = libxl__sprintf(gc, "%s/xenpaging/state", dom_path);
+ if (!path ) {
+ rc = ERROR_NOMEM;
+ goto out;
+ }
+ value = xs_read(ctx->xsh, XBT_NULL, path, NULL);
+ rc = value && strcmp(value, "running") == 0;
+ free(value);
+ /* Already running, nothing to do */
+ if (rc)
+ return 0;
+
+ /* Check if xenpaging is present */
+ xp = libxl__abs_path(gc, "xenpaging", libxl_libexec_path());
+ if (access(xp, X_OK) < 0) {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "%s is not executable", xp);
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ /* Initialise settings for child */
+ buf_starting = calloc(sizeof(*buf_starting), 1);
+ if (!buf_starting) {
+ rc = ERROR_NOMEM;
+ goto out;
+ }
+ buf_starting->domid = domid;
+ buf_starting->for_spawn = calloc(sizeof(libxl__spawn_starting), 1);
+ buf_starting->dom_path = dom_path;
+ buf_starting->pid_path = "xenpaging/xenpaging-pid";
+ if (!buf_starting->for_spawn) {
+ rc = ERROR_NOMEM;
+ goto out;
+ }
+
+ /* Assemble arguments for xenpaging */
+ xp_args = flexarray_make(5, 1);
+ if (!xp_args) {
+ rc = ERROR_NOMEM;
+ goto out;
+ }
+ /* Set executable path */
+ flexarray_append(xp_args, xp);
+
+ /* Append pagefile option */
+ flexarray_append(xp_args, "-f");
+ if (b_info->u.hvm.xenpaging_file)
+ flexarray_append(xp_args, b_info->u.hvm.xenpaging_file);
+ else
+ flexarray_append(xp_args, libxl__sprintf(gc, "%s/%s.%u.paging",
+ libxl_xenpaging_dir_path(), dom_name, domid));
+
+ /* Set maximum amount of memory xenpaging should handle */
+ flexarray_append(xp_args, "-m");
+ flexarray_append(xp_args, libxl__sprintf(gc, "%d", b_info->max_memkb));
+
+ /* Append extra args for pager */
+ for (i = 0; xpe && xpe[i]; i++)
+ flexarray_append(xp_args, xpe[i]);
+ /* Append domid for pager */
+ flexarray_append(xp_args, libxl__sprintf(gc, "%u", domid));
+ flexarray_append(xp_args, NULL);
+ args = (char **) flexarray_contents(xp_args);
+
+ /* Initialise logfile */
+ libxl_create_logfile(ctx, libxl__sprintf(gc, "xenpaging-%s", dom_name),
+ &logfile);
+ logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644);
+ free(logfile);
+ null = open("/dev/null", O_RDONLY);
+
+ /* Spawn the child */
+ rc = libxl__spawn_spawn(gc, buf_starting->for_spawn, "xenpaging",
+ libxl_spawner_record_pid, buf_starting);
+ if (rc < 0)
+ goto out_close;
+ if (!rc) { /* inner child */
+ setsid();
+ /* Finally run xenpaging */
+ libxl__exec(null, logfile_w, logfile_w, xp, args);
+ }
+ rc = libxl__spawn_confirm_offspring_startup(gc, 5, "xenpaging", path,
+ "running", buf_starting);
+out_close:
+ close(null);
+ close(logfile_w);
+ free(args);
+out:
+ return rc;
+}
+
static int do_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
libxl_console_ready cb, void *priv,
uint32_t *domid_out, int restore_fd)
@@ -641,3 +756,32 @@ int libxl_domain_create_restore(libxl_ct
libxl__free_all(&gc);
return rc;
}
+
+int libxl__create_xenpaging(libxl_ctx *ctx, libxl_domain_config *d_config,
+ uint32_t domid, char *path)
+{
+ libxl__gc gc = LIBXL_INIT_GC(ctx);
+ char *value, *endptr;
+ uint32_t new_tot_pages;
+ int rc;
+
+ if (d_config->c_info.type != LIBXL_DOMAIN_TYPE_HVM)
+ return 0;
+
+ value = xs_read(ctx->xsh, XBT_NULL, path, NULL);
+ if (!value)
+ return 0;
+ new_tot_pages = strtoul(value, &endptr, 10);
+ free(value);
+ if (*endptr != '\0') {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Invalid value in %s", path);
+ return 0;
+ }
+ d_config->b_info.tot_memkb = new_tot_pages;
+
+ rc = create_xenpaging(&gc, d_config->dm_info.dom_name, domid,
&d_config->b_info);
+ if (rc < 0)
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to start xenpaging:
%d", rc);
+ libxl__free_all(&gc);
+ return rc;
+}
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -108,7 +108,7 @@ int libxl__build_post(libxl__gc *gc, uin
if (info->cpuid != NULL)
libxl_cpuid_set(ctx, domid, info->cpuid);
- ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *));
+ ents = libxl__calloc(gc, 14 + (info->max_vcpus * 2) + 2, sizeof(char *));
ents[0] = "memory/static-max";
ents[1] = libxl__sprintf(gc, "%d", info->max_memkb);
ents[2] = "memory/target";
@@ -121,9 +121,11 @@ int libxl__build_post(libxl__gc *gc, uin
ents[9] = libxl__sprintf(gc, "%"PRIu32, state->store_port);
ents[10] = "store/ring-ref";
ents[11] = libxl__sprintf(gc, "%lu", state->store_mfn);
+ ents[12] = "memory/target-tot_pages";
+ ents[13] = libxl__sprintf(gc, "%d", info->tot_memkb);
for (i = 0; i < info->max_vcpus; i++) {
- ents[12+(i*2)] = libxl__sprintf(gc, "cpu/%d/availability", i);
- ents[12+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 <<
i)))
+ ents[14+(i*2)] = libxl__sprintf(gc, "cpu/%d/availability", i);
+ ents[14+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 <<
i)))
? "offline" : "online";
}
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl_types.idl
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -78,6 +78,7 @@ libxl_action_on_shutdown = Enumeration("
libxl_event_type = Enumeration("event_type", [
(1, "DOMAIN_DEATH"),
(2, "DISK_EJECT"),
+ (3, "XENPAGING"),
])
libxl_button = Enumeration("button", [
@@ -157,6 +158,7 @@ libxl_domain_build_info = Struct("domain
("tsc_mode", integer),
("max_memkb", uint32),
("target_memkb", uint32),
+ ("tot_memkb", uint32),
("video_memkb", uint32),
("shadow_memkb", uint32),
("disable_migrate", bool),
@@ -174,6 +176,8 @@ libxl_domain_build_info = Struct("domain
("vpt_align", bool),
("timer_mode", integer),
("nested_hvm", bool),
+ ("xenpaging_file", string),
+ ("xenpaging_extra", libxl_string_list),
])),
("pv", Struct(None, [("kernel", libxl_file_reference),
("slack_memkb", uint32),
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/xl.h
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -54,6 +54,7 @@ int main_vcpupin(int argc, char **argv);
int main_vcpuset(int argc, char **argv);
int main_memmax(int argc, char **argv);
int main_memset(int argc, char **argv);
+int main_mem_tot_pages(int argc, char **argv);
int main_sched_credit(int argc, char **argv);
int main_domid(int argc, char **argv);
int main_domname(int argc, char **argv);
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -346,6 +346,7 @@ static void printf_info(int domid,
printf("\t\t\t(firmware %s)\n", b_info->u.hvm.firmware);
printf("\t\t\t(video_memkb %d)\n", b_info->video_memkb);
printf("\t\t\t(shadow_memkb %d)\n", b_info->shadow_memkb);
+ printf("\t\t\t(tot_memkb %d)\n", b_info->tot_memkb);
printf("\t\t\t(pae %d)\n", b_info->u.hvm.pae);
printf("\t\t\t(apic %d)\n", b_info->u.hvm.apic);
printf("\t\t\t(acpi %d)\n", b_info->u.hvm.acpi);
@@ -380,6 +381,7 @@ static void printf_info(int domid,
printf("\t\t\t(spicedisable_ticketing %d)\n",
dm_info->spicedisable_ticketing);
printf("\t\t\t(spiceagent_mouse %d)\n", dm_info->spiceagent_mouse);
+ printf("\t\t\t(xenpaging_file %s)\n", b_info->u.hvm.xenpaging_file);
printf("\t\t)\n");
break;
case LIBXL_DOMAIN_TYPE_PV:
@@ -515,6 +517,28 @@ static void parse_disk_config(XLU_Config
parse_disk_config_multistring(config, 1, &spec, disk);
}
+static void parse_xenpaging_extra(const XLU_Config *config, libxl_string_list
*xpe)
+{
+ XLU_ConfigList *args;
+ libxl_string_list l;
+ const char *val;
+ int nr_args = 0, i;
+
+ if (xlu_cfg_get_list(config, "xenpaging_extra", &args, &nr_args, 1))
+ return;
+
+ l = xmalloc(sizeof(char*)*(nr_args + 1));
+ if (!l)
+ return;
+
+ l[nr_args] = NULL;
+ for (i = 0; i < nr_args; i++) {
+ val = xlu_cfg_get_listitem(args, i);
+ l[i] = val ? strdup(val) : NULL;
+ }
+ *xpe = l;
+}
+
static void parse_config_data(const char *configfile_filename_report,
const char *configfile_data,
int configfile_len,
@@ -615,11 +639,15 @@ static void parse_config_data(const char
if (!xlu_cfg_get_long (config, "memory", &l)) {
b_info->max_memkb = l * 1024;
b_info->target_memkb = b_info->max_memkb;
+ b_info->tot_memkb = b_info->max_memkb;
}
if (!xlu_cfg_get_long (config, "maxmem", &l))
b_info->max_memkb = l * 1024;
+ if (!xlu_cfg_get_long (config, "totmem", &l))
+ b_info->tot_memkb = l * 1024;
+
if (xlu_cfg_get_string (config, "on_poweroff", &buf))
buf = "destroy";
if (!parse_action_on_shutdown(buf, &d_config->on_poweroff)) {
@@ -695,6 +723,10 @@ static void parse_config_data(const char
b_info->u.hvm.timer_mode = l;
if (!xlu_cfg_get_long (config, "nestedhvm", &l))
b_info->u.hvm.nested_hvm = l;
+
+ xlu_cfg_replace_string (config, "xenpaging_file",
&b_info->u.hvm.xenpaging_file);
+ parse_xenpaging_extra(config, &b_info->u.hvm.xenpaging_extra);
+
break;
case LIBXL_DOMAIN_TYPE_PV:
{
@@ -1356,7 +1388,7 @@ static int create_domain(struct domain_c
int fd, i;
int need_daemon = daemonize;
int ret, rc;
- libxl_waiter *w1 = NULL, *w2 = NULL;
+ libxl_waiter *w1 = NULL, *w2 = NULL, *w3;
void *config_data = 0;
int config_len = 0;
int restore_fd = -1;
@@ -1606,8 +1638,10 @@ start:
d_config.c_info.name, domid, (long)getpid());
w1 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter) * d_config.num_disks);
w2 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter));
+ w3 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter));
libxl_wait_for_disk_ejects(ctx, domid, d_config.disks, d_config.num_disks,
w1);
libxl_wait_for_domain_death(ctx, domid, w2);
+ libxl_wait_for_target_tot_pages(ctx, domid, w3);
libxl_get_wait_fd(ctx, &fd);
while (1) {
int ret;
@@ -1649,8 +1683,10 @@ start:
for (i = 0; i < d_config.num_disks; i++)
libxl_free_waiter(&w1[i]);
libxl_free_waiter(w2);
+ libxl_free_waiter(w3);
free(w1);
free(w2);
+ free(w3);
/*
* Do not attempt to reconnect if we come round again
due to a
@@ -1688,6 +1724,9 @@ start:
libxl_device_disk_destroy(&disk);
}
break;
+ case LIBXL_EVENT_TYPE_XENPAGING:
+ libxl__create_xenpaging(ctx, &d_config, domid, event.path);
+ break;
}
libxl_free_event(&event);
}
@@ -1872,6 +1911,36 @@ int main_memset(int argc, char **argv)
return 0;
}
+static void set_memory_tot_pages(const char *p, const char *mem)
+{
+ long long int memorykb;
+
+ find_domain(p);
+
+ memorykb = parse_mem_size_kb(mem);
+ if (memorykb == -1) {
+ fprintf(stderr, "invalid memory size: %s\n", mem);
+ exit(3);
+ }
+
+ libxl_set_memory_tot_pages(ctx, domid, memorykb, 0);
+}
+
+int main_mem_tot_pages(int argc, char **argv)
+{
+ int opt = 0;
+ const char *p = NULL, *mem;
+
+ if ((opt = def_getopt(argc, argv, "", "mem-totpages", 2)) != -1)
+ return opt;
+
+ p = argv[optind];
+ mem = argv[optind + 1];
+
+ set_memory_tot_pages(p, mem);
+ return 0;
+}
+
static void cd_insert(const char *dom, const char *virtdev, char *phys)
{
libxl_device_disk disk; /* we don't free disk's contents */
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -158,6 +158,11 @@ struct cmd_spec cmd_table[] = {
"Set the current memory usage for a domain",
"<Domain> <MemMB['b'[bytes]|'k'[KB]|'m'[MB]|'g'[GB]|'t'[TB]]>",
},
+ { "mem-totpages",
+ &main_mem_tot_pages, 0,
+ "Set the how much memory is assigned to a domain",
+ "<Domain> <MemMB['b'[bytes]|'k'[KB]|'m'[MB]|'g'[GB]|'t'[TB]]>",
+ },
{ "button-press",
&main_button_press, 0,
"Indicate an ACPI button press to the domain",
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -40,6 +40,8 @@
/* Defines number of mfns a guest should use at a time, in KiB */
#define WATCH_TARGETPAGES "memory/target-tot_pages"
+/* Defines startup confirmation */
+#define WATCH_STARTUP "xenpaging/state"
static char *watch_target_tot_pages;
static char *dom_path;
static char watch_token[16];
@@ -777,6 +779,22 @@ static int evict_pages(xenpaging_t *pagi
return num;
}
+static int xenpaging_confirm_startup(xenpaging_t *paging)
+{
+ xc_interface *xch = paging->xc_handle;
+ char *path;
+ int len;
+
+ len = asprintf(&path, "%s/%s", dom_path, WATCH_STARTUP);
+ if ( len < 0 )
+ return -1;
+ DPRINTF("confirm startup '%s'\n", path);
+ len = xs_write(paging->xs_handle, XBT_NULL, path, "running", len);
+ DPRINTF("confirm startup returned %d\n", len);
+ free(path);
+ return 0;
+}
+
int main(int argc, char *argv[])
{
struct sigaction act;
@@ -835,6 +853,9 @@ int main(int argc, char *argv[])
/* listen for page-in events to stop pager */
create_page_in_thread(paging);
+ /* Confirm startup to caller */
+ xenpaging_confirm_startup(paging);
+
/* Swap pages in and out */
while ( 1 )
{
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|