[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 24 of 24] xenpaging: libxl support
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |