[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 24 of 24] xenpaging: libxl support


  • To: xen-devel@xxxxxxxxxxxxxxxxxxx
  • From: Olaf Hering <olaf@xxxxxxxxx>
  • Date: Mon, 03 Oct 2011 17:55:01 +0200
  • Delivery-date: Mon, 03 Oct 2011 09:08:54 -0700
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.