[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 4 of 4] xenpaging: initial libxl support
# HG changeset patch # User Olaf Hering <olaf@xxxxxxxxx> # Date 1320244864 -3600 # Node ID ab5406a5b1d01e3828f0dcd833f99b70e4fbad72 # Parent a51d4fab351d2d1a38b82cbd7ad925f76fce9e9a xenpaging: initial libxl support Add initial support to libxl for starting xenpaging. The patch adds three new config options: actmem=<int>, the amount of memory in MiB for the guest xenpaging_file=<string>, pagefile to use (optional) xenpaging_extra=[ 'string', 'string' ], additional args for xenpaging (optional) If 'actmem=' is not specified in config file, xenpaging will not start. If 'xenpaging_file=' is not specified in config file, /var/lib/xen/xenpaging/<domain_name>.<domaind_id>.paging is used. Signed-off-by: Olaf Hering <olaf@xxxxxxxxx> diff -r a51d4fab351d -r ab5406a5b1d0 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); diff -r a51d4fab351d -r ab5406a5b1d0 tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -429,6 +429,122 @@ 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->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->dom_path = dom_path; + buf_starting->pid_path = "xenpaging/xenpaging-pid"; + buf_starting->for_spawn = calloc(sizeof(libxl__spawn_starting), 1); + if (!buf_starting->for_spawn) { + rc = ERROR_NOMEM; + goto out; + } + + /* Assemble arguments for xenpaging */ + xp_args = flexarray_make(8, 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, "-d"); + 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) @@ -614,6 +730,16 @@ static int do_domain_create(libxl__gc *g goto error_out; } + if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM) { + ret = create_xenpaging(gc, d_config->dm_info.dom_name, domid, + &d_config->b_info); + if (ret) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, + "Failed to start xenpaging.\n"); + goto error_out; + } + } + *domid_out = domid; return 0; diff -r a51d4fab351d -r ab5406a5b1d0 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 a51d4fab351d -r ab5406a5b1d0 tools/libxl/libxl_memory.txt --- a/tools/libxl/libxl_memory.txt +++ b/tools/libxl/libxl_memory.txt @@ -1,28 +1,28 @@ /* === Domain memory breakdown: HVM guests ================================== - + +----------+ + - | | shadow | | - | +----------+ | - overhead | | extra | | - | | external | | - | +----------+ + | - | | extra | | | - | | internal | | | - + +----------+ + | | footprint - | | video | | | | - | +----------+ + + | | xen | - | | | | | | actual | maximum | - | | | | | | target | | - | | guest | | | build | | | - | | | | | start | | | - static | | | | | | | | - maximum | +----------+ | + + + + - | | | | - | | | | - | | balloon | | build - | | | | maximum - | | | | - + +----------+ + + + +----------+ + + | | shadow | | + | +----------+ | + overhead | | extra | | + | | external | | + | +----------+ + | + | | extra | | | + | | internal | | | + + +----------+ + | | footprint + | | video | | | | + | +----------+ + + + | | xen | + | | | | guest OS | | | actual | maximum | + | | guest | | real RAM | | | target | | + | | | | | | build | | | + | |----------+ + | | start + | | + static | | paging | | | | | + maximum | +----------+ | + + + + | | | | + | | | | + | | balloon | | build + | | | | maximum + | | | | + + +----------+ + extra internal = LIBXL_MAXMEM_CONSTANT @@ -34,6 +34,17 @@ libxl_domain_setmaxmem -> xen maximum libxl_set_memory_target -> actual target + build maximum = RAM as seen inside the virtual machine + Guest OS has to configure itself for this amount of memory + Increase/Decrease via memory hotplug of virtual hardware. + xl mem-max + build start = RAM usable by the guest OS + Guest OS sees balloon driver as memory hog + Increase/Decrease via commands to the balloon driver + xl mem-set + actual target = RAM allocated for the guest + Increase/Decrease via commands to paging daemon + xl mem-paging_target (?) === Domain memory breakdown: PV guests ================================== diff -r a51d4fab351d -r ab5406a5b1d0 tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -157,6 +157,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 +175,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 a51d4fab351d -r ab5406a5b1d0 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, @@ -620,6 +644,9 @@ static void parse_config_data(const char if (!xlu_cfg_get_long (config, "maxmem", &l)) b_info->max_memkb = l * 1024; + if (!xlu_cfg_get_long (config, "actmem", &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 +722,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: { diff -r a51d4fab351d -r ab5406a5b1d0 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 path to startup confirmation */ +#define WATCH_STARTUP "xenpaging/state" static char *watch_target_tot_pages; static char *dom_path; static char watch_token[16]; @@ -772,6 +774,20 @@ static int evict_pages(xenpaging_t *pagi return num; } +static void 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; + DPRINTF("confirming startup in %s\n", path); + xs_write(paging->xs_handle, XBT_NULL, path, "running", len); + free(path); +} + int main(int argc, char *argv[]) { struct sigaction act; @@ -830,6 +846,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 |