Stefano Stabellini
2010-Sep-01 13:38 UTC
[Xen-devel] [PATCH 0 of 11] v3: xl/libxl autoballooning
Hi all, this patch series adds some new memory management functions to libxl that are used by xl to autoballoon dom0 down by the amount of memory needed by the new domain build. In order to avoid conflicts with other xl instances during the memory accounting operation I am introducing a global filelock. I am also introducing a global configuration file for xl to enable/disable autoballooning. Changes compares to v2: - removed max_memkb from libxl_dominfo, added current_memkb instead; - the changes to instroduce a xenstore transaction in libxl_set_memory_target have been moved to a separate patch; - the "enforce" parameter to libxl memory target functions has been removed; - get_free_memory_slack has been made static; - few comments have been added to libxl.h regarding the new memory related functions; - code style fixes to avoid lines longer than 80 chars. Cheers, Stefano _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stefano.stabellini@eu.citrix.com
2010-Sep-01 13:41 UTC
[Xen-devel] [PATCH 1 of 11] libxl: remove max_memkb, add current_memkb to libxl_dominfo
currently xcinfo2xlinfo reads tot_pages and uses that data to calculate max_memkb, while tot_pages is the memory currently used by the domain and max_pages is the theoretical maximum. Remove max_memkb from libxl_dominfo, add current_memkb instead. Make max_memkb completely opaque to the users, therefore remove max_memkb from libxl_domain_build_info and remove libxl_domain_setmaxmem too. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> diff -r ae0cd4e5cc01 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Wed Sep 01 10:19:14 2010 +0100 +++ b/tools/libxl/libxl.c Wed Sep 01 11:48:09 2010 +0100 @@ -543,7 +543,7 @@ static void xcinfo2xlinfo(const xc_domai else xlinfo->shutdown_reason = ~0; - xlinfo->max_memkb = PAGE_TO_MEMKB(xcinfo->tot_pages); + xlinfo->current_memkb = PAGE_TO_MEMKB(xcinfo->tot_pages); xlinfo->cpu_time = xcinfo->cpu_time; xlinfo->vcpu_max_id = xcinfo->max_vcpu_id; xlinfo->vcpu_online = xcinfo->nr_online_vcpus; @@ -1511,8 +1511,7 @@ static int libxl_create_stubdom(libxl_ct memset(&b_info, 0x00, sizeof(libxl_domain_build_info)); b_info.max_vcpus = 1; - b_info.max_memkb = 32 * 1024; - b_info.target_memkb = b_info.max_memkb; + b_info.target_memkb = 32 * 1024; b_info.kernel.path = libxl_abs_path(&gc, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path()); b_info.u.pv.cmdline = libxl_sprintf(&gc, " -d %d", info->domid); b_info.u.pv.ramdisk.path = ""; @@ -2721,39 +2720,6 @@ int libxl_device_vfb_hard_shutdown(libxl /******************************************************************************/ -int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t max_memkb) -{ - libxl_gc gc = LIBXL_INIT_GC(ctx); - char *mem, *endptr; - uint32_t memorykb; - char *dompath = libxl_xs_get_dompath(&gc, domid); - int rc = 1; - - mem = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/target", dompath)); - if (!mem) { - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot get memory info from %s/memory/target\n", dompath); - goto out; - } - memorykb = strtoul(mem, &endptr, 10); - if (*endptr != ''\0'') { - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "invalid memory %s from %s/memory/target\n", mem, dompath); - goto out; - } - - if (max_memkb < memorykb) { - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "memory_static_max must be greater than or or equal to memory_dynamic_max\n"); - goto out; - } - - if (domid != 0) - libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/static-max", dompath), "%"PRIu32, max_memkb); - - rc = 0; -out: - libxl_free_all(&gc); - return rc; -} - int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb, int enforce) { libxl_gc gc = LIBXL_INIT_GC(ctx); diff -r ae0cd4e5cc01 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Wed Sep 01 10:19:14 2010 +0100 +++ b/tools/libxl/libxl.h Wed Sep 01 11:48:09 2010 +0100 @@ -320,7 +320,6 @@ int libxl_domain_unpause(libxl_ctx *ctx, 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, uint32_t target_memkb, int enforce); int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass); diff -r ae0cd4e5cc01 tools/libxl/libxl.idl --- a/tools/libxl/libxl.idl Wed Sep 01 10:19:14 2010 +0100 +++ b/tools/libxl/libxl.idl Wed Sep 01 11:48:09 2010 +0100 @@ -36,7 +36,7 @@ libxl_dominfo = Struct("dominfo",[ Otherwise set to a value guaranteed not to clash with any valid SHUTDOWN_* constant."""), - ("max_memkb", uint64), + ("current_memkb", uint64), ("cpu_time", uint64), ("vcpu_max_id", uint32), ("vcpu_online", uint32), @@ -91,7 +91,6 @@ libxl_domain_build_info = Struct("domain ("max_vcpus", integer), ("cur_vcpus", integer), ("tsc_mode", integer), - ("max_memkb", uint32), ("target_memkb", uint32), ("video_memkb", uint32), ("shadow_memkb", uint32), diff -r ae0cd4e5cc01 tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c Wed Sep 01 10:19:14 2010 +0100 +++ b/tools/libxl/libxl_dom.c Wed Sep 01 11:48:09 2010 +0100 @@ -65,8 +65,8 @@ int build_pre(libxl_ctx *ctx, uint32_t d xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus); xc_domain_setmaxmem(ctx->xch, domid, info->target_memkb + LIBXL_MAXMEM_CONSTANT); xc_domain_set_memmap_limit(ctx->xch, domid, - (info->hvm) ? info->max_memkb : - (info->max_memkb + info->u.pv.slack_memkb)); + (info->hvm) ? info->target_memkb : + (info->target_memkb + info->u.pv.slack_memkb)); xc_domain_set_tsc_info(ctx->xch, domid, info->tsc_mode, 0, 0, 0); if ( info->disable_migrate ) xc_domain_disable_migrate(ctx->xch, domid); @@ -98,7 +98,7 @@ int build_post(libxl_ctx *ctx, uint32_t ents = libxl_calloc(&gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *)); ents[0] = "memory/static-max"; - ents[1] = libxl_sprintf(&gc, "%d", info->max_memkb); + ents[1] = libxl_sprintf(&gc, "%d", info->target_memkb); ents[2] = "memory/target"; ents[3] = libxl_sprintf(&gc, "%d", info->target_memkb); ents[4] = "memory/videoram"; @@ -230,7 +230,7 @@ int build_hvm(libxl_ctx *ctx, uint32_t d ret = xc_hvm_build_target_mem( ctx->xch, domid, - (info->max_memkb - info->video_memkb) / 1024, + (info->target_memkb - info->video_memkb) / 1024, (info->target_memkb - info->video_memkb) / 1024, libxl_abs_path(&gc, (char *)info->kernel.path, libxl_xenfirmwaredir_path())); diff -r ae0cd4e5cc01 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Wed Sep 01 10:19:14 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Wed Sep 01 11:48:09 2010 +0100 @@ -265,8 +265,7 @@ static void init_build_info(libxl_domain { memset(b_info, ''\0'', sizeof(*b_info)); b_info->max_vcpus = 1; - b_info->max_memkb = 32 * 1024; - b_info->target_memkb = b_info->max_memkb; + b_info->target_memkb = 32 * 1024; b_info->disable_migrate = 0; if (c_info->hvm) { b_info->shadow_memkb = 0; /* Set later */ @@ -428,7 +427,6 @@ static void printf_info(int domid, printf("\t(domain_build_info)\n"); printf("\t(max_vcpus %d)\n", b_info->max_vcpus); printf("\t(tsc_mode %d)\n", b_info->tsc_mode); - printf("\t(max_memkb %d)\n", b_info->max_memkb); printf("\t(target_memkb %d)\n", b_info->target_memkb); printf("\t(nomigrate %d)\n", b_info->disable_migrate); @@ -627,10 +625,8 @@ static void parse_config_data(const char b_info->cur_vcpus = (1 << l) - 1; } - if (!xlu_cfg_get_long (config, "memory", &l)) { - b_info->max_memkb = l * 1024; - b_info->target_memkb = b_info->max_memkb; - } + if (!xlu_cfg_get_long (config, "memory", &l)) + b_info->target_memkb = l * 1024; if (xlu_cfg_get_string (config, "on_poweroff", &buf)) buf = "destroy"; @@ -666,7 +662,7 @@ static void parse_config_data(const char * calculation depends on those values. */ b_info->shadow_memkb = !xlu_cfg_get_long(config, "shadow_memory", &l) ? l * 1024 - : libxl_get_required_shadow_memory(b_info->max_memkb, + : libxl_get_required_shadow_memory(b_info->target_memkb, b_info->max_vcpus); if (!xlu_cfg_get_long (config, "nomigrate", &l)) @@ -1708,7 +1704,7 @@ static int set_memory_max(char *p, char exit(3); } - rc = libxl_domain_setmaxmem(&ctx, domid, memorykb); + rc = libxl_set_memory_target(&ctx, domid, memorykb, 1); return rc; } @@ -2209,7 +2205,7 @@ static void list_domains(int verbose, co printf("%-40s %5d %5lu %5d %c%c%c%c%c%c %8.1f", domname, info[i].domid, - (unsigned long) (info[i].max_memkb / 1024), + (unsigned long) (info[i].current_memkb / 1024), info[i].vcpu_online, info[i].running ? ''r'' : ''-'', info[i].blocked ? ''b'' : ''-'', _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stefano.stabellini@eu.citrix.com
2010-Sep-01 13:41 UTC
[Xen-devel] [PATCH 2 of 11] libxl: use transactions in libxl_set_memory_target
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> diff -r be24166159b0 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Wed Sep 01 12:53:24 2010 +0100 +++ b/tools/libxl/libxl.c Wed Sep 01 13:04:16 2010 +0100 @@ -2720,58 +2720,68 @@ int libxl_device_vfb_hard_shutdown(libxl /******************************************************************************/ -int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb, int enforce) +int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t + target_memkb, int enforce) { libxl_gc gc = LIBXL_INIT_GC(ctx); - int rc = 1; - uint32_t memorykb = 0, videoram = 0; - char *memmax, *endptr, *videoram_s = NULL; + int rc = 1, abort = 0; + uint32_t videoram = 0; + char *videoram_s = NULL; char *dompath = libxl_xs_get_dompath(&gc, domid); xc_domaininfo_t info; libxl_dominfo ptr; char *uuid; - - if (domid) { - memmax = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/static-max", dompath)); - if (!memmax) { + xs_transaction_t t; + +retry_transaction: + t = xs_transaction_start(ctx->xsh); + + videoram_s = libxl_xs_read(&gc, t, libxl_sprintf(&gc, "%s/memory/videoram", + dompath)); + videoram = videoram_s ? atoi(videoram_s) : 0; + + if (enforce) { + rc = xc_domain_setmaxmem(ctx->xch, domid, target_memkb + + LIBXL_MAXMEM_CONSTANT); + if (rc != 0) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, - "cannot get memory info from %s/memory/static-max\n", dompath); + "xc_domain_setmaxmem domid=%d memkb=%d failed " + "rc=%d\n", domid, target_memkb + LIBXL_MAXMEM_CONSTANT, rc); + abort = 1; goto out; } - memorykb = strtoul(memmax, &endptr, 10); - if (*endptr != ''\0'') { - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, - "invalid max memory %s from %s/memory/static-max\n", memmax, dompath); - goto out; - } - - if (target_memkb > memorykb) { - XL_LOG(ctx, XL_LOG_ERROR, - "memory_dynamic_max must be less than or equal to memory_static_max\n"); - goto out; - } + libxl_xs_write(&gc, t, libxl_sprintf(&gc, "%s/memory/static-max", + dompath), "%"PRIu32, target_memkb); } - videoram_s = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/videoram", dompath)); - videoram = videoram_s ? atoi(videoram_s) : 0; - - libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/target", dompath), "%"PRIu32, target_memkb); - + rc = xc_domain_memory_set_pod_target(ctx->xch, domid, (target_memkb - + videoram) / 4, NULL, NULL, NULL); + if (rc != 0) { + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, + "xc_domain_memory_set_pod_target domid=%d, memkb=%d " + "failed rc=%d\n", domid, (target_memkb - videoram) / 4, + rc); + abort = 1; + goto out; + } + + libxl_xs_write(&gc, t, libxl_sprintf(&gc, "%s/memory/target", dompath), + "%"PRIu32, target_memkb); rc = xc_domain_getinfolist(ctx->xch, domid, 1, &info); - if (rc != 1 || info.domain != domid) + if (rc != 1 || info.domain != domid) { + abort = 1; goto out; + } xcinfo2xlinfo(&info, &ptr); uuid = libxl_uuid2string(&gc, ptr.uuid); - libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "/vm/%s/memory", uuid), "%"PRIu32, target_memkb / 1024); - - if (enforce || !domid) - memorykb = target_memkb; - rc = xc_domain_setmaxmem(ctx->xch, domid, memorykb + LIBXL_MAXMEM_CONSTANT); - if (rc != 0) - goto out; - rc = xc_domain_memory_set_pod_target(ctx->xch, domid, (target_memkb - videoram) / 4, NULL, NULL, NULL); + libxl_xs_write(&gc, t, libxl_sprintf(&gc, "/vm/%s/memory", uuid), "%"PRIu32, + target_memkb / 1024); out: + if (!xs_transaction_end(ctx->xsh, t, abort) && !abort) + if (errno == EAGAIN) + goto retry_transaction; + libxl_free_all(&gc); return rc; } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stefano.stabellini@eu.citrix.com
2010-Sep-01 13:41 UTC
[Xen-devel] [PATCH 3 of 11] libxl: introduce libxl_set_relative_memory_target
Introduce libxl_set_relative_memory_target to modify the memory target of a domain by a relative amount of memory in a single xenstore transaction. The first time we are reading/writing dom0 memory target, fill the informations in xenstore if they are missing. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> diff -r 2731a625a7b1 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Wed Sep 01 12:53:24 2010 +0100 +++ b/tools/libxl/libxl.c Wed Sep 01 12:53:53 2010 +0100 @@ -2720,6 +2720,53 @@ int libxl_device_vfb_hard_shutdown(libxl /******************************************************************************/ +static int libxl__fill_dom0_memory_info(libxl_gc *gc, uint32_t *target_memkb) +{ + int rc; + xc_domaininfo_t info; + char *target = NULL, *endptr = NULL; + char *target_path = "/local/domain/0/memory/target"; + char *max_path = "/local/domain/0/memory/static-max"; + xs_transaction_t t; + libxl_ctx *ctx = libxl_gc_owner(gc); + +retry_transaction: + t = xs_transaction_start(ctx->xsh); + + target = libxl_xs_read(gc, t, target_path); + if (target) { + *target_memkb = strtoul(target, &endptr, 10); + if (*endptr != ''\0'') { + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, + "invalid memory target %s from %s\n", target, target_path); + rc = ERROR_FAIL; + goto out; + } + rc = 0; + goto out; + } + + rc = xc_domain_getinfolist(ctx->xch, 0, 1, &info); + if (rc < 0) + return rc; + + libxl_xs_write(gc, t, target_path, "%"PRIu32, + (uint32_t) PAGE_TO_MEMKB(info.tot_pages)); + libxl_xs_write(gc, t, max_path, "%"PRIu32, + (uint32_t) PAGE_TO_MEMKB(info.max_pages)); + + *target_memkb = (uint32_t) PAGE_TO_MEMKB(info.tot_pages); + rc = 0; + +out: + if (!xs_transaction_end(ctx->xsh, t, 0)) + if (errno == EAGAIN) + goto retry_transaction; + + + return rc; +} + int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb, int enforce) { @@ -2787,6 +2834,163 @@ out: return rc; } +int libxl_set_relative_memory_target(libxl_ctx *ctx, uint32_t domid, + int32_t relative_target_memkb, int enforce) +{ + libxl_gc gc = LIBXL_INIT_GC(ctx); + int rc = 1, abort = 0; + uint32_t memorykb = 0, videoram = 0, target_memkb = 0, new_target_memkb = 0; + char *memmax, *endptr, *videoram_s = NULL, *target = NULL; + char *dompath = libxl_xs_get_dompath(&gc, domid); + xc_domaininfo_t info; + libxl_dominfo ptr; + char *uuid; + xs_transaction_t t; + +retry_transaction: + t = xs_transaction_start(ctx->xsh); + + target = libxl_xs_read(&gc, t, libxl_sprintf(&gc, + "%s/memory/target", dompath)); + if (!target && !domid) { + xs_transaction_end(ctx->xsh, t, 1); + rc = libxl__fill_dom0_memory_info(&gc, &target_memkb); + if (rc < 0) { + abort = 1; + goto out; + } + goto retry_transaction; + } else if (!target) { + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, + "cannot get target memory info from %s/memory/target\n", + dompath); + abort = 1; + goto out; + } else { + target_memkb = strtoul(target, &endptr, 10); + if (*endptr != ''\0'') { + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, + "invalid memory target %s from %s/memory/target\n", + target, dompath); + abort = 1; + goto out; + } + } + memmax = libxl_xs_read(&gc, t, libxl_sprintf(&gc, + "%s/memory/static-max", dompath)); + if (!memmax) { + XL_LOG_ERRNO(ctx, XL_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'') { + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, + "invalid max memory %s from %s/memory/static-max\n", + memmax, dompath); + abort = 1; + goto out; + } + + new_target_memkb = target_memkb + relative_target_memkb; + if (new_target_memkb > memorykb) { + XL_LOG(ctx, XL_LOG_ERROR, + "memory_dynamic_max must be less than or equal to" + " memory_static_max\n"); + 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; + + if (enforce) { + memorykb = new_target_memkb; + rc = xc_domain_setmaxmem(ctx->xch, domid, memorykb + + LIBXL_MAXMEM_CONSTANT); + if (rc != 0) { + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, + "xc_domain_setmaxmem domid=%d memkb=%d failed " + "rc=%d\n", domid, memorykb + LIBXL_MAXMEM_CONSTANT, rc); + abort = 1; + goto out; + } + libxl_xs_write(&gc, t, libxl_sprintf(&gc, + "%s/memory/static-max", dompath), "%"PRIu32, + memorykb); + } + + rc = xc_domain_memory_set_pod_target(ctx->xch, domid, + (new_target_memkb - videoram) / 4, NULL, NULL, NULL); + if (rc != 0) { + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, + "xc_domain_memory_set_pod_target domid=%d, memkb=%d " + "failed rc=%d\n", domid, (new_target_memkb - videoram) / 4, + rc); + abort = 1; + goto out; + } + + libxl_xs_write(&gc, t, libxl_sprintf(&gc, "%s/memory/target", + dompath), "%"PRIu32, new_target_memkb); + rc = xc_domain_getinfolist(ctx->xch, domid, 1, &info); + if (rc != 1 || info.domain != domid) { + abort = 1; + goto out; + } + xcinfo2xlinfo(&info, &ptr); + uuid = libxl_uuid2string(&gc, ptr.uuid); + libxl_xs_write(&gc, t, libxl_sprintf(&gc, "/vm/%s/memory", uuid), + "%"PRIu32, new_target_memkb / 1024); + +out: + if (!xs_transaction_end(ctx->xsh, t, abort) && !abort) + if (errno == EAGAIN) + goto retry_transaction; + + libxl_free_all(&gc); + return rc; +} + +int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t *out_target) +{ + libxl_gc gc = LIBXL_INIT_GC(ctx); + int rc = 1; + char *target = NULL, *endptr = NULL; + char *dompath = libxl_xs_get_dompath(&gc, domid); + uint32_t target_memkb; + + target = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, + "%s/memory/target", dompath)); + if (!target && !domid) { + rc = libxl__fill_dom0_memory_info(&gc, &target_memkb); + if (rc < 0) + goto out; + } else if (!target) { + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, + "cannot get target memory info from %s/memory/target\n", + dompath); + goto out; + } else { + target_memkb = strtoul(target, &endptr, 10); + if (*endptr != ''\0'') { + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, + "invalid memory target %s from %s/memory/target\n", + target, dompath); + goto out; + } + } + *out_target = target_memkb; + rc = 0; + +out: + libxl_free_all(&gc); + return rc; +} + int libxl_button_press(libxl_ctx *ctx, uint32_t domid, libxl_button button) { int rc = -1; diff -r 2731a625a7b1 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Wed Sep 01 12:53:24 2010 +0100 +++ b/tools/libxl/libxl.h Wed Sep 01 12:53:53 2010 +0100 @@ -321,6 +321,8 @@ int libxl_domain_unpause(libxl_ctx *ctx, int libxl_domain_core_dump(libxl_ctx *ctx, uint32_t domid, const char *filename); int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb, int enforce); +int libxl_set_relative_memory_target(libxl_ctx *ctx, uint32_t domid, int32_t relative_target_memkb, int enforce); +int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t *out_target); 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); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stefano.stabellini@eu.citrix.com
2010-Sep-01 13:41 UTC
[Xen-devel] [PATCH 4 of 11] Remove "enforce" parameter to libxl memory target functions
Always assume that the user wants to enforce the memory target for all domains but dom0. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> diff -r 1e423427f2aa tools/libxl/libxl.c --- a/tools/libxl/libxl.c Wed Sep 01 13:04:20 2010 +0100 +++ b/tools/libxl/libxl.c Wed Sep 01 13:07:32 2010 +0100 @@ -2767,8 +2767,8 @@ out: return rc; } -int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t - target_memkb, int enforce) +int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, + uint32_t target_memkb) { libxl_gc gc = LIBXL_INIT_GC(ctx); int rc = 1, abort = 0; @@ -2787,7 +2787,7 @@ retry_transaction: dompath)); videoram = videoram_s ? atoi(videoram_s) : 0; - if (enforce) { + if (domid) { rc = xc_domain_setmaxmem(ctx->xch, domid, target_memkb + LIBXL_MAXMEM_CONSTANT); if (rc != 0) { @@ -2834,7 +2834,7 @@ out: } int libxl_set_relative_memory_target(libxl_ctx *ctx, uint32_t domid, - int32_t relative_target_memkb, int enforce) + int32_t relative_target_memkb) { libxl_gc gc = LIBXL_INIT_GC(ctx); int rc = 1, abort = 0; @@ -2906,7 +2906,7 @@ retry_transaction: "%s/memory/videoram", dompath)); videoram = videoram_s ? atoi(videoram_s) : 0; - if (enforce) { + if (domid) { memorykb = new_target_memkb; rc = xc_domain_setmaxmem(ctx->xch, domid, memorykb + LIBXL_MAXMEM_CONSTANT); diff -r 1e423427f2aa tools/libxl/libxl.h --- a/tools/libxl/libxl.h Wed Sep 01 13:04:20 2010 +0100 +++ b/tools/libxl/libxl.h Wed Sep 01 13:07:32 2010 +0100 @@ -320,8 +320,8 @@ int libxl_domain_unpause(libxl_ctx *ctx, int libxl_domain_core_dump(libxl_ctx *ctx, uint32_t domid, const char *filename); -int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb, int enforce); -int libxl_set_relative_memory_target(libxl_ctx *ctx, uint32_t domid, int32_t relative_target_memkb, int enforce); +int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb); +int libxl_set_relative_memory_target(libxl_ctx *ctx, uint32_t domid, int32_t relative_target_memkb); int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t *out_target); int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass); diff -r 1e423427f2aa tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Wed Sep 01 13:04:20 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Wed Sep 01 13:07:32 2010 +0100 @@ -1704,7 +1704,7 @@ static int set_memory_max(char *p, char exit(3); } - rc = libxl_set_memory_target(&ctx, domid, memorykb, 1); + rc = libxl_set_memory_target(&ctx, domid, memorykb); return rc; } @@ -1754,7 +1754,7 @@ static void set_memory_target(char *p, c exit(3); } - libxl_set_memory_target(&ctx, domid, memorykb, /* enforce */ 1); + libxl_set_memory_target(&ctx, domid, memorykb); } int main_memset(int argc, char **argv) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stefano.stabellini@eu.citrix.com
2010-Sep-01 13:41 UTC
[Xen-devel] [PATCH 5 of 11] libxl: adds few more memory operations
libxl_get_free_memory_slack: calculate the amount of memory that should be left free in the system and write it on xenstore. 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. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> diff -r d3596b6319e8 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Wed Sep 01 13:07:32 2010 +0100 +++ b/tools/libxl/libxl.c Wed Sep 01 13:08:02 2010 +0100 @@ -2724,9 +2724,11 @@ static int libxl__fill_dom0_memory_info( { int rc; xc_domaininfo_t 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); @@ -2750,10 +2752,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) PAGE_TO_MEMKB(info.tot_pages)); libxl_xs_write(gc, t, max_path, "%"PRIu32, (uint32_t) PAGE_TO_MEMKB(info.max_pages)); + libxl_xs_write(gc, t, free_mem_slack_path, "%"PRIu32, + (uint32_t) PAGE_TO_MEMKB(physinfo.total_pages - info.tot_pages)); *target_memkb = (uint32_t) PAGE_TO_MEMKB(info.tot_pages); rc = 0; @@ -2767,6 +2775,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'') { + XL_LOG_ERRNO(gc->owner, XL_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, uint32_t target_memkb) { @@ -2990,6 +3025,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; diff -r d3596b6319e8 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Wed Sep 01 13:07:32 2010 +0100 +++ b/tools/libxl/libxl.h Wed Sep 01 13:08:02 2010 +0100 @@ -323,6 +323,15 @@ int libxl_domain_core_dump(libxl_ctx *ct int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb); int libxl_set_relative_memory_target(libxl_ctx *ctx, uint32_t domid, int32_t relative_target_memkb); 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); diff -r d3596b6319e8 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Wed Sep 01 13:07:32 2010 +0100 +++ b/tools/libxl/libxl_internal.h Wed Sep 01 13:08:02 2010 +0100 @@ -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])) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stefano.stabellini@eu.citrix.com
2010-Sep-01 13:41 UTC
[Xen-devel] [PATCH 6 of 11] libxl: introduce the concept of dom0 minimum memory
Introduce a minimum value for the memory assigned to dom0. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> diff -r 101149a58c1d tools/libxl/libxl.c --- a/tools/libxl/libxl.c Wed Sep 01 13:04:21 2010 +0100 +++ b/tools/libxl/libxl.c Wed Sep 01 13:04:50 2010 +0100 @@ -2815,6 +2815,12 @@ int libxl_set_memory_target(libxl_ctx *c char *uuid; xs_transaction_t t; + if (!domid && target_memkb < LIBXL_MIN_DOM0_MEM) { + XL_LOG(ctx, XL_LOG_ERROR, + "new target for dom0 is below the minimum threshold\n"); + return ERROR_NOMEM; + } + retry_transaction: t = xs_transaction_start(ctx->xsh); @@ -2967,6 +2973,12 @@ retry_transaction: abort = 1; goto out; } + if (!domid && new_target_memkb < LIBXL_MIN_DOM0_MEM) { + XL_LOG(ctx, XL_LOG_ERROR, + "new target for dom0 is below the minimum threshold\n"); + abort = 1; + goto out; + } libxl_xs_write(&gc, t, libxl_sprintf(&gc, "%s/memory/target", dompath), "%"PRIu32, new_target_memkb); diff -r 101149a58c1d tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Wed Sep 01 13:04:21 2010 +0100 +++ b/tools/libxl/libxl_internal.h Wed Sep 01 13:04:50 2010 +0100 @@ -43,6 +43,7 @@ #define LIBXL_MAXMEM_CONSTANT 1024 #define LIBXL_PV_EXTRA_MEMORY 1024 #define LIBXL_HVM_EXTRA_MEMORY 2048 +#define LIBXL_MIN_DOM0_MEM (128*1024) #define QEMU_SIGNATURE "QemuDeviceModelRecord" #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stefano.stabellini@eu.citrix.com
2010-Sep-01 13:41 UTC
[Xen-devel] [PATCH 7 of 11] xl: do not continue in the child and exec xenconsole in the parent
Currenctly console_autoconnect spawns a child that continues building the domain while the parent exec''s xenconsole; this patch inverts the logic. As a consequence autoconnect_console needs to be called twice: once for pv guests at the beginning and once for hvm guests at the end. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> diff -r f762d7922ff0 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Wed Sep 01 12:35:40 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Wed Sep 01 12:37:25 2010 +0100 @@ -1062,39 +1062,20 @@ static void *xrealloc(void *ptr, size_t return r; } -static int autoconnect_console(int hvm) +static pid_t autoconnect_console(void) { - int status, options; - pid_t pid, r; - - /* - * Fork for xenconsole. We exec xenconsole in the foreground - * process allowing it to retain the tty. xl continues in the - * child. The xenconsole client uses a xenstore watch to wait for - * the console to be setup so there is no race. - */ + pid_t pid; + pid = fork(); if (pid < 0) { perror("unable to fork xenconsole"); return ERROR_FAIL; - } else if (pid == 0) - return 0; - - /* - * In the PV case we only catch failure of the create process, in - * the HVM case we also wait for the creation process to be - * completed so that the stubdom is already up and running and we - * can connect to it. - */ - if (hvm) - options = 0; - else - options = WNOHANG; + } else if (pid > 0) + return pid; + + libxl_ctx_postfork(&ctx); + sleep(1); - r = waitpid(pid, &status, options); - if (r > 0 && WIFEXITED(status) && WEXITSTATUS(status) != 0) - _exit(WEXITSTATUS(status)); - libxl_primary_console_exec(&ctx, domid); /* Do not return. xl continued in child process */ fprintf(stderr, "Unable to attach console\n"); @@ -1250,6 +1231,8 @@ static int create_domain(struct domain_c int config_len = 0; int restore_fd = -1; struct save_file_header hdr; + pid_t child_console_pid = -1; + int status = 0; memset(&d_config, 0x00, sizeof(d_config)); memset(&dm_info, 0x00, sizeof(dm_info)); @@ -1395,18 +1378,12 @@ start: goto error_out; } - if (dom_info->console_autoconnect) { - ret = autoconnect_console(d_config.c_info.hvm); - if (ret) + if (dom_info->console_autoconnect && !d_config.c_info.hvm) { + child_console_pid = autoconnect_console(); + if (child_console_pid < 0) goto error_out; } - /* - * Do not attempt to reconnect if we come round again due to a - * guest reboot -- the stdin/out will be disconnected by then. - */ - dom_info->console_autoconnect = 0; - ret = libxl_run_bootloader(&ctx, &d_config.b_info, d_config.num_disks > 0 ? &d_config.disks[0] : NULL, domid); if (ret) { fprintf(stderr, "failed to run bootloader: %d\n", ret); @@ -1488,6 +1465,12 @@ start: for (i = 0; i < d_config.num_pcidevs; i++) libxl_device_pci_add(&ctx, domid, &d_config.pcidevs[i]); + if (dom_info->console_autoconnect && d_config.c_info.hvm) { + child_console_pid = autoconnect_console(); + if (child_console_pid < 0) + goto error_out; + } + if (!paused) libxl_domain_unpause(&ctx, domid); @@ -1502,7 +1485,6 @@ start: child1 = libxl_fork(&ctx); if (child1) { - int status; for (;;) { got_child = waitpid(child1, &status, 0); if (got_child == child1) break; @@ -1519,7 +1501,8 @@ start: ret = ERROR_FAIL; goto error_out; } - return domid; /* caller gets success in parent */ + ret = domid; + goto waitpid_out; } rc = libxl_ctx_postfork(&ctx); @@ -1595,6 +1578,13 @@ start: libxl_free_waiter(w2); free(w1); free(w2); + + /* + * Do not attempt to reconnect if we come round again due to a + * guest reboot -- the stdin/out will be disconnected by then. + */ + dom_info->console_autoconnect = 0; + /* * XXX FIXME: If this sleep is not there then domain * re-creation fails sometimes. @@ -1631,6 +1621,10 @@ out: free(config_data); +waitpid_out: + if (child_console_pid > 0 && + waitpid(child_console_pid, &status, 0) < 0 && errno == EINTR) + goto waitpid_out; return ret; } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stefano.stabellini@eu.citrix.com
2010-Sep-01 13:41 UTC
[Xen-devel] [PATCH 8 of 11] xl: add a global configuration file
Add a global configuration file: /etc/xen/xl.conf; the only option currently parsed is autoballoon that is 1 by default. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> diff -r 434f3315185a tools/examples/Makefile --- a/tools/examples/Makefile Fri Aug 27 12:43:18 2010 +0100 +++ b/tools/examples/Makefile Fri Aug 27 14:09:51 2010 +0100 @@ -21,6 +21,7 @@ XEN_CONFIGS += xmexample.nbd XEN_CONFIGS += xmexample.vti XEN_CONFIGS += xend-pci-quirks.sxp XEN_CONFIGS += xend-pci-permissive.sxp +XEN_CONFIGS += xl.conf .PHONY: all all: diff -r 434f3315185a tools/examples/xl.conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/examples/xl.conf Fri Aug 27 14:09:51 2010 +0100 @@ -0,0 +1,5 @@ +## Global XL config file ## + +# automatically balloon down dom0 when xen doesn''t have enough free +# memory to create a domain +autoballon=1 diff -r 434f3315185a tools/libxl/xl.c --- a/tools/libxl/xl.c Fri Aug 27 12:43:18 2010 +0100 +++ b/tools/libxl/xl.c Fri Aug 27 14:09:51 2010 +0100 @@ -29,18 +29,49 @@ #include "libxl.h" #include "libxl_utils.h" +#include "libxlutil.h" #include "xl.h" xentoollog_logger_stdiostream *logger; +int autoballoon = 1; static xentoollog_level minmsglevel = XTL_PROGRESS; +static void parse_global_config(const char *configfile, + const char *configfile_data, + int configfile_len) +{ + long l; + XLU_Config *config; + int e; + + config = xlu_cfg_init(stderr, configfile); + if (!config) { + fprintf(stderr, "Failed to allocate for configuration\n"); + exit(1); + } + + e = xlu_cfg_readdata(config, configfile_data, configfile_len); + if (e) { + fprintf(stderr, "Failed to parse config file: %s\n", strerror(e)); + exit(1); + } + + if (!xlu_cfg_get_long (config, "autoballoon", &l)) + autoballoon = l; + + xlu_cfg_destroy(config); +} + int main(int argc, char **argv) { int opt = 0; char *cmd = 0; struct cmd_spec *cspec; int ret; + char *config_file; + void *config_data = 0; + int config_len = 0; while ((opt = getopt(argc, argv, "+v")) >= 0) { switch (opt) { @@ -69,6 +100,21 @@ int main(int argc, char **argv) exit(1); } + /* Read global config file options */ + ret = asprintf(&config_file, "%s/xl.conf", libxl_xen_config_dir_path()); + if (ret < 0) { + fprintf(stderr, "memory allocation failed ret=%d, errno=%d\n", ret, errno); + exit(1); + } + + ret = libxl_read_file_contents(&ctx, config_file, + &config_data, &config_len); + if (ret) + fprintf(stderr, "Failed to read config file: %s: %s\n", + config_file, strerror(errno)); + parse_global_config(config_file, config_data, config_len); + free(config_file); + /* Reset options for per-command use of getopt. */ argv += optind; argc -= optind; diff -r 434f3315185a tools/libxl/xl.h --- a/tools/libxl/xl.h Fri Aug 27 12:43:18 2010 +0100 +++ b/tools/libxl/xl.h Fri Aug 27 14:09:51 2010 +0100 @@ -90,4 +90,7 @@ struct cmd_spec *cmdtable_lookup(const c extern libxl_ctx ctx; extern xentoollog_logger_stdiostream *logger; +/* global options */ +extern int autoballoon; + #endif /* XL_H */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stefano.stabellini@eu.citrix.com
2010-Sep-01 13:41 UTC
[Xen-devel] [PATCH 9 of 11] introduce XEN_LOCK_DIR
Introduce a OS dependent global variable XEN_LOCK_DIR that points at the system directory that contains lock files. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> diff -r 29dbbdc79759 Config.mk --- a/Config.mk Fri Aug 27 14:17:58 2010 +0100 +++ b/Config.mk Fri Aug 27 14:23:13 2010 +0100 @@ -114,6 +114,7 @@ define buildmakevars2file-closure echo "XENFIRMWAREDIR=\"$(XENFIRMWAREDIR)\"" >> $(1); \ echo "XEN_CONFIG_DIR=\"$(XEN_CONFIG_DIR)\"" >> $(1); \ echo "XEN_SCRIPT_DIR=\"$(XEN_SCRIPT_DIR)\"" >> $(1) + echo "XEN_LOCK_DIR=\"$(XEN_LOCK_DIR)\"" >> $(1) endef ifeq ($(debug),y) diff -r 29dbbdc79759 config/NetBSD.mk --- a/config/NetBSD.mk Fri Aug 27 14:17:58 2010 +0100 +++ b/config/NetBSD.mk Fri Aug 27 14:23:13 2010 +0100 @@ -7,4 +7,10 @@ LIBLEAFDIR_x86_64 = lib LIBEXEC = $(PREFIX)/libexec PRIVATE_BINDIR = $(BINDIR) +ifeq ($(PREFIX),/usr) +XEN_LOCK_DIR = /var/lib +else +XEN_LOCK_DIR = $(PREFIX)/var/lib +endif + WGET = ftp diff -r 29dbbdc79759 config/StdGNU.mk --- a/config/StdGNU.mk Fri Aug 27 14:17:58 2010 +0100 +++ b/config/StdGNU.mk Fri Aug 27 14:23:13 2010 +0100 @@ -45,8 +45,10 @@ PRIVATE_BINDIR = $(PRIVATE_PREFIX)/bin ifeq ($(PREFIX),/usr) CONFIG_DIR = /etc +XEN_LOCK_DIR = /var/lock else CONFIG_DIR = $(PREFIX)/etc +XEN_LOCK_DIR = $(PREFIX)/var/lock endif SYSCONFIG_DIR = $(CONFIG_DIR)/sysconfig diff -r 29dbbdc79759 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Fri Aug 27 14:17:58 2010 +0100 +++ b/tools/libxl/libxl.h Fri Aug 27 14:23:13 2010 +0100 @@ -495,6 +495,7 @@ const char *libxl_private_bindir_path(vo const char *libxl_xenfirmwaredir_path(void); const char *libxl_xen_config_dir_path(void); const char *libxl_xen_script_dir_path(void); +const char *libxl_lock_dir_path(void); #endif /* LIBXL_H */ diff -r 29dbbdc79759 tools/libxl/libxl_paths.c --- a/tools/libxl/libxl_paths.c Fri Aug 27 14:17:58 2010 +0100 +++ b/tools/libxl/libxl_paths.c Fri Aug 27 14:23:13 2010 +0100 @@ -60,3 +60,7 @@ const char *libxl_xen_script_dir_path(vo return XEN_SCRIPT_DIR; } +const char *libxl_lock_dir_path(void) +{ + return XEN_LOCK_DIR; +} _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stefano.stabellini@eu.citrix.com
2010-Sep-01 13:41 UTC
[Xen-devel] [PATCH 10 of 11] xl: free memory before building a domain
Free the needed amount of memory before proceeding with the domain build. Use a filelock to prevent other xl instances from conflicting during this operation. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> diff -r 234527e61859 tools/examples/xl.conf --- a/tools/examples/xl.conf Wed Sep 01 13:08:07 2010 +0100 +++ b/tools/examples/xl.conf Wed Sep 01 13:08:56 2010 +0100 @@ -3,3 +3,6 @@ # automatically balloon down dom0 when xen doesn''t have enough free # memory to create a domain autoballon=1 + +# full path of the lockfile used by xl during domain creation +#lockfile="/var/lock/xl" diff -r 234527e61859 tools/libxl/xl.c --- a/tools/libxl/xl.c Wed Sep 01 13:08:07 2010 +0100 +++ b/tools/libxl/xl.c Wed Sep 01 13:08:56 2010 +0100 @@ -34,6 +34,7 @@ xentoollog_logger_stdiostream *logger; int autoballoon = 1; +char *lockfile; static xentoollog_level minmsglevel = XTL_PROGRESS; @@ -44,6 +45,7 @@ static void parse_global_config(const ch long l; XLU_Config *config; int e; + const char *buf; config = xlu_cfg_init(stderr, configfile); if (!config) { @@ -60,6 +62,16 @@ static void parse_global_config(const ch if (!xlu_cfg_get_long (config, "autoballoon", &l)) autoballoon = l; + if (!xlu_cfg_get_string (config, "lockfile", &buf)) + lockfile = strdup(buf); + else { + e = asprintf(&lockfile, "%s/xl", (char *)libxl_lock_dir_path()); + if (e < 0) { + fprintf(stderr, "asprintf memory allocation failed\n"); + exit(1); + } + } + xlu_cfg_destroy(config); } diff -r 234527e61859 tools/libxl/xl.h --- a/tools/libxl/xl.h Wed Sep 01 13:08:07 2010 +0100 +++ b/tools/libxl/xl.h Wed Sep 01 13:08:56 2010 +0100 @@ -92,5 +92,6 @@ extern xentoollog_logger_stdiostream *lo /* global options */ extern int autoballoon; +extern char *lockfile; #endif /* XL_H */ diff -r 234527e61859 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Wed Sep 01 13:08:07 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Wed Sep 01 13:08:56 2010 +0100 @@ -68,6 +68,7 @@ libxl_ctx ctx; /* when we operate on a domain, it is this one: */ static uint32_t domid; static const char *common_domname; +static int fd_lock = -1; static const char savefileheader_magic[32]@@ -234,6 +235,65 @@ static void find_domain(const char *p) common_domname = was_name ? p : libxl_domid_to_name(&ctx, domid); } +static int acquire_lock(void) +{ + int rc; + struct flock fl; + + /* lock already acquired */ + if (fd_lock >= 0) + return ERROR_INVAL; + + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fd_lock = open(lockfile, O_WRONLY|O_CREAT, S_IWUSR); + if (fd_lock < 0) { + fprintf(stderr, "cannot open the lockfile %s errno=%d\n", lockfile, errno); + return ERROR_FAIL; + } +get_lock: + rc = fcntl(fd_lock, F_SETLKW, &fl); + if (rc < 0 && errno == EINTR) + goto get_lock; + if (rc < 0) { + fprintf(stderr, "cannot acquire lock %s errno=%d\n", lockfile, errno); + rc = ERROR_FAIL; + } else + rc = 0; + return rc; +} + +static int release_lock(void) +{ + int rc; + struct flock fl; + + /* lock not acquired */ + if (fd_lock < 0) + return ERROR_INVAL; + +release_lock: + fl.l_type = F_UNLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + + rc = fcntl(fd_lock, F_SETLKW, &fl); + if (rc < 0 && errno == EINTR) + goto release_lock; + if (rc < 0) { + fprintf(stderr, "cannot release lock %s, errno=%d\n", lockfile, errno); + rc = ERROR_FAIL; + } else + rc = 0; + close(fd_lock); + fd_lock = -1; + + return rc; +} + #define LOG(_f, _a...) dolog(__FILE__, __LINE__, __func__, _f "\n", ##_a) static void dolog(const char *file, int line, const char *func, char *fmt, ...) @@ -1205,6 +1265,48 @@ struct domain_create { char **migration_domname_r; }; +static int freemem(libxl_domain_build_info *b_info, libxl_device_model_info *dm_info) +{ + int rc, retries = 3; + uint32_t need_memkb, free_memkb; + + if (!autoballoon) + return 0; + + rc = libxl_domain_need_memory(&ctx, b_info, dm_info, &need_memkb); + if (rc < 0) + return rc; + + do { + rc = libxl_get_free_memory(&ctx, &free_memkb); + if (rc < 0) + return rc; + + if (free_memkb >= need_memkb) + return 0; + + rc = libxl_set_relative_memory_target(&ctx, 0, free_memkb - need_memkb); + if (rc < 0) + return rc; + + rc = libxl_wait_for_free_memory(&ctx, domid, need_memkb, 10); + if (!rc) + return 0; + else if (rc != ERROR_NOMEM) + return rc; + + /* the memory target has been reached but the free memory is still + * not enough: loop over again */ + rc = libxl_wait_for_memory_target(&ctx, 0, 1); + if (rc < 0) + return rc; + + retries--; + } while (retries > 0); + + return ERROR_NOMEM; +} + static int create_domain(struct domain_create *dom_info) { struct domain_config d_config; @@ -1363,6 +1465,17 @@ static int create_domain(struct domain_c start: domid = 0; + rc = acquire_lock(); + if (rc < 0) + goto error_out; + + ret = freemem(&d_config.b_info, &dm_info); + if (ret < 0) { + fprintf(stderr, "failed to free memory for the domain\n"); + ret = ERROR_FAIL; + goto error_out; + } + ret = libxl_domain_make(&ctx, &d_config.c_info, &domid); if (ret) { fprintf(stderr, "cannot make domain: %d\n", ret); @@ -1471,6 +1584,8 @@ start: goto error_out; } + release_lock(); + if (!paused) libxl_domain_unpause(&ctx, domid); @@ -1608,6 +1723,7 @@ start: } error_out: + release_lock(); if (domid) libxl_domain_destroy(&ctx, domid, 0); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stefano.stabellini@eu.citrix.com
2010-Sep-01 13:41 UTC
[Xen-devel] [PATCH 11 of 11] libxl: proper accounting for the videoram
Remove the videoram from the memory target of the domains consistently, leave the total amount of memory in maxmem. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> diff -r d008be183166 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Wed Sep 01 12:42:37 2010 +0100 +++ b/tools/libxl/libxl.c Wed Sep 01 12:44:36 2010 +0100 @@ -2836,12 +2836,13 @@ retry_transaction: dompath), "%"PRIu32, target_memkb); } - rc = xc_domain_memory_set_pod_target(ctx->xch, domid, (target_memkb - - videoram) / 4, NULL, NULL, NULL); + target_memkb -= videoram; + rc = xc_domain_memory_set_pod_target(ctx->xch, domid, target_memkb / 4, + NULL, NULL, NULL); if (rc != 0) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_domain_memory_set_pod_target domid=%d, memkb=%d " - "failed rc=%d\n", domid, (target_memkb - videoram) / 4, + "failed rc=%d\n", domid, target_memkb / 4, rc); abort = 1; goto out; @@ -2963,12 +2964,13 @@ retry_transaction: memorykb); } + new_target_memkb -= videoram; rc = xc_domain_memory_set_pod_target(ctx->xch, domid, - (new_target_memkb - videoram) / 4, NULL, NULL, NULL); + new_target_memkb / 4, NULL, NULL, NULL); if (rc != 0) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_domain_memory_set_pod_target domid=%d, memkb=%d " - "failed rc=%d\n", domid, (new_target_memkb - videoram) / 4, + "failed rc=%d\n", domid, new_target_memkb / 4, rc); abort = 1; goto out; diff -r d008be183166 tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c Wed Sep 01 12:42:37 2010 +0100 +++ b/tools/libxl/libxl_dom.c Wed Sep 01 12:44:36 2010 +0100 @@ -100,7 +100,7 @@ int build_post(libxl_ctx *ctx, uint32_t ents[0] = "memory/static-max"; ents[1] = libxl_sprintf(&gc, "%d", info->target_memkb); ents[2] = "memory/target"; - ents[3] = libxl_sprintf(&gc, "%d", info->target_memkb); + ents[3] = libxl_sprintf(&gc, "%d", info->target_memkb - info->video_memkb); ents[4] = "memory/videoram"; ents[5] = libxl_sprintf(&gc, "%d", info->video_memkb); ents[6] = "domid"; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel