Stefano Stabellini
2010-Aug-27 13:49 UTC
[Xen-devel] [PATCH 0 of 9] v2: 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. The only changes compared to v1 are related to paths of xl.conf and the lockfile: the paths are now set from the system dependent global variables. Cheers, Stefano _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stefano.stabellini@eu.citrix.com
2010-Aug-27 13:53 UTC
[Xen-devel] [PATCH 1 of 9] libxl: Fix xcinfo2xlinfo to properly set max_memkb and target_memkb
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. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> diff -r eccfdeb41b80 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Tue Aug 24 18:42:59 2010 +0100 +++ b/tools/libxl/libxl.c Wed Aug 25 20:59:35 2010 +0100 @@ -539,7 +539,8 @@ static void xcinfo2xlinfo(const xc_domai else xlinfo->shutdown_reason = ~0; - xlinfo->max_memkb = PAGE_TO_MEMKB(xcinfo->tot_pages); + xlinfo->target_memkb = PAGE_TO_MEMKB(xcinfo->tot_pages); + xlinfo->max_memkb = PAGE_TO_MEMKB(xcinfo->max_pages); xlinfo->cpu_time = xcinfo->cpu_time; xlinfo->vcpu_max_id = xcinfo->max_vcpu_id; xlinfo->vcpu_online = xcinfo->nr_online_vcpus; diff -r eccfdeb41b80 tools/libxl/libxl.idl --- a/tools/libxl/libxl.idl Tue Aug 24 18:42:59 2010 +0100 +++ b/tools/libxl/libxl.idl Wed Aug 25 20:59:35 2010 +0100 @@ -36,6 +36,7 @@ libxl_dominfo = Struct("dominfo",[ Otherwise set to a value guaranteed not to clash with any valid SHUTDOWN_* constant."""), + ("target_memkb", uint64), ("max_memkb", uint64), ("cpu_time", uint64), ("vcpu_max_id", uint32), diff -r eccfdeb41b80 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Tue Aug 24 18:42:59 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Wed Aug 25 20:59:35 2010 +0100 @@ -2209,7 +2209,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].target_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-Aug-27 13:53 UTC
[Xen-devel] [PATCH 2 of 9] 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. Modify libxl_set_memory_target to use xenstore transactions. 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 990ff10b7b00 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Wed Aug 25 20:59:35 2010 +0100 +++ b/tools/libxl/libxl.c Wed Aug 25 21:01:36 2010 +0100 @@ -2751,56 +2751,243 @@ out: return rc; } +static int fill_dom0_memory_info(libxl_gc *gc, uint32_t *target_memkb) +{ + int rc; + libxl_dominfo 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 = libxl_domain_info(ctx, &info, 0); + if (rc < 0) + return rc; + + libxl_xs_write(gc, t, target_path, "%"PRIu32, (uint32_t) info.target_memkb); + libxl_xs_write(gc, t, max_path, "%"PRIu32, (uint32_t) info.max_memkb); + + *target_memkb = (uint32_t) info.target_memkb; + 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) { 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); + libxl_xs_write(&gc, t, libxl_sprintf(&gc, "%s/memory/static-max", 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) { + 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, 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_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 = 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 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"); + "invalid memory target %s from %s/memory/target\n", target, dompath); + abort = 1; goto out; } } - - videoram_s = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/videoram", dompath)); + 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; - libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/target", dompath), "%"PRIu32, target_memkb); - + 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) + 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) + 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 = 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; - rc = xc_domain_memory_set_pod_target(ctx->xch, domid, (target_memkb - videoram) / 4, NULL, NULL, NULL); + } 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); diff -r 990ff10b7b00 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Wed Aug 25 20:59:35 2010 +0100 +++ b/tools/libxl/libxl.h Wed Aug 25 21:01:36 2010 +0100 @@ -322,6 +322,8 @@ 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, 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-Aug-27 13:53 UTC
[Xen-devel] [PATCH 3 of 9] 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 a59fa4d54851 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Wed Aug 25 21:01:37 2010 +0100 +++ b/tools/libxl/libxl.c Thu Aug 26 19:06:04 2010 +0100 @@ -2755,9 +2755,11 @@ static int fill_dom0_memory_info(libxl_g { int rc; libxl_dominfo 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); @@ -2780,9 +2782,13 @@ retry_transaction: rc = libxl_domain_info(ctx, &info, 0); 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) info.target_memkb); libxl_xs_write(gc, t, max_path, "%"PRIu32, (uint32_t) info.max_memkb); + libxl_xs_write(gc, t, free_mem_slack_path, "%"PRIu32, (uint32_t) ((physinfo.total_pages * 4) - info.target_memkb)); *target_memkb = (uint32_t) info.target_memkb; rc = 0; @@ -2796,6 +2802,33 @@ out: return rc; } +int libxl_get_free_memory_slack(libxl_ctx *ctx, uint32_t *free_mem_slack) +{ + int rc; + libxl_gc gc = LIBXL_INIT_GC(ctx); + 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 = 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(ctx, XL_LOG_ERROR, + "invalid free_mem_slack %s from %s\n", free_mem_slack_s, free_mem_slack_path); + return ERROR_FAIL; + } + } + libxl_free_all(&gc); + return 0; +} + int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb, int enforce) { libxl_gc gc = LIBXL_INIT_GC(ctx); @@ -2994,6 +3027,90 @@ 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; + libxl_physinfo info; + uint32_t freemem_slack; + + rc = libxl_get_physinfo(ctx, &info); + if (rc < 0) + return rc; + rc = libxl_get_free_memory_slack(ctx, &freemem_slack); + if (rc < 0) + return rc; + + if ((info.free_pages + info.scrub_pages) * 4 > freemem_slack) + *memkb = (info.free_pages + info.scrub_pages) * 4 - freemem_slack; + else + *memkb = 0; + return 0; +} + +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; + + rc = libxl_get_free_memory_slack(ctx, &freemem_slack); + if (rc < 0) + return rc; + while (wait_secs > 0) { + rc = libxl_get_physinfo(ctx, &info); + if (rc < 0) + return rc; + if (info.free_pages * 4 - freemem_slack >= memory_kb) + return 0; + wait_secs--; + sleep(1); + } + return ERROR_NOMEM; +} + +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.target_memkb > target_memkb); + + if (info.target_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 a59fa4d54851 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Wed Aug 25 21:01:37 2010 +0100 +++ b/tools/libxl/libxl.h Thu Aug 26 19:06:04 2010 +0100 @@ -324,6 +324,12 @@ int libxl_domain_setmaxmem(libxl_ctx *ct 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_domain_need_memory(libxl_ctx *ctx, libxl_domain_build_info *b_info, + libxl_device_model_info *dm_info, uint32_t *need_memkb); +int libxl_get_free_memory(libxl_ctx *ctx, uint32_t *memkb); +int libxl_wait_for_free_memory(libxl_ctx *ctx, uint32_t domid, uint32_t memory_kb, int wait_secs); +int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs); +int libxl_get_free_memory_slack(libxl_ctx *ctx, uint32_t *free_mem_slack); 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 a59fa4d54851 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Wed Aug 25 21:01:37 2010 +0100 +++ b/tools/libxl/libxl_internal.h Thu Aug 26 19:06:04 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-Aug-27 13:53 UTC
[Xen-devel] [PATCH 4 of 9] 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 1276830b845f tools/libxl/libxl.c --- a/tools/libxl/libxl.c Thu Aug 26 18:55:46 2010 +0100 +++ b/tools/libxl/libxl.c Thu Aug 26 18:56:16 2010 +0100 @@ -2841,6 +2841,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); @@ -2948,6 +2954,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; + } videoram_s = libxl_xs_read(&gc, t, libxl_sprintf(&gc, "%s/memory/videoram", dompath)); videoram = videoram_s ? atoi(videoram_s) : 0; diff -r 1276830b845f tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Thu Aug 26 18:55:46 2010 +0100 +++ b/tools/libxl/libxl_internal.h Thu Aug 26 18:56:16 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-Aug-27 13:53 UTC
[Xen-devel] [PATCH 5 of 9] 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 00ef2205e0bc tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Thu Aug 26 17:04:25 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Thu Aug 26 17:27:56 2010 +0100 @@ -1066,39 +1066,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"); @@ -1254,6 +1235,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)); @@ -1399,18 +1382,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); @@ -1492,6 +1469,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); @@ -1506,7 +1489,6 @@ start: child1 = libxl_fork(&ctx); if (child1) { - int status; for (;;) { got_child = waitpid(child1, &status, 0); if (got_child == child1) break; @@ -1523,7 +1505,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); @@ -1599,6 +1582,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. @@ -1635,6 +1625,9 @@ 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-Aug-27 13:53 UTC
[Xen-devel] [PATCH 6 of 9] 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-Aug-27 13:53 UTC
[Xen-devel] [PATCH 7 of 9] 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-Aug-27 13:53 UTC
[Xen-devel] [PATCH 8 of 9] 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 673e09ce2549 tools/examples/xl.conf --- a/tools/examples/xl.conf Fri Aug 27 14:03:44 2010 +0100 +++ b/tools/examples/xl.conf Fri Aug 27 14:09:01 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 673e09ce2549 tools/libxl/xl.c --- a/tools/libxl/xl.c Fri Aug 27 14:03:44 2010 +0100 +++ b/tools/libxl/xl.c Fri Aug 27 14:09:01 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 673e09ce2549 tools/libxl/xl.h --- a/tools/libxl/xl.h Fri Aug 27 14:03:44 2010 +0100 +++ b/tools/libxl/xl.h Fri Aug 27 14:09:01 2010 +0100 @@ -92,5 +92,6 @@ extern xentoollog_logger_stdiostream *lo /* global options */ extern int autoballoon; +extern char *lockfile; #endif /* XL_H */ diff -r 673e09ce2549 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Fri Aug 27 14:03:44 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Fri Aug 27 14:09:01 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, ...) @@ -1209,6 +1269,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, 0); + 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; @@ -1367,6 +1469,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); @@ -1475,6 +1588,8 @@ start: goto error_out; } + release_lock(); + if (!paused) libxl_domain_unpause(&ctx, domid); @@ -1612,6 +1727,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-Aug-27 13:53 UTC
[Xen-devel] [PATCH 9 of 9] 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 d740144dfc1c tools/libxl/libxl.c --- a/tools/libxl/libxl.c Thu Aug 26 18:56:19 2010 +0100 +++ b/tools/libxl/libxl.c Thu Aug 26 18:56:47 2010 +0100 @@ -2865,11 +2865,12 @@ retry_transaction: libxl_xs_write(&gc, t, libxl_sprintf(&gc, "%s/memory/static-max", 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; @@ -2977,11 +2978,12 @@ retry_transaction: 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); + new_target_memkb -= videoram; + rc = xc_domain_memory_set_pod_target(ctx->xch, domid, 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 d740144dfc1c tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c Thu Aug 26 18:56:19 2010 +0100 +++ b/tools/libxl/libxl_dom.c Thu Aug 26 18:56:47 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->max_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"; @@ -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->max_memkb / 1024, (info->target_memkb - info->video_memkb) / 1024, libxl_abs_path(&gc, (char *)info->kernel.path, libxl_xenfirmwaredir_path())); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Christoph Egger
2010-Aug-27 15:17 UTC
Re: [Xen-devel] [PATCH 6 of 9] xl: add a global configuration file
On Friday 27 August 2010 15:53:24 stefano.stabellini@eu.citrix.com wrote:> 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>Acked-by: Christoph Egger <Christoph.Egger@amd.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-- ---to satisfy European Law for business letters: Advanced Micro Devices GmbH Einsteinring 24, 85609 Dornach b. Muenchen Geschaeftsfuehrer: Alberto Bozzo, Andrew Bowd Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Christoph Egger
2010-Aug-27 15:21 UTC
Re: [Xen-devel] [PATCH 7 of 9] introduce XEN_LOCK_DIR
On Friday 27 August 2010 15:53:25 stefano.stabellini@eu.citrix.com wrote:> 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>Acked-by: Christoph Egger <Christoph.Egger@amd.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-- ---to satisfy European Law for business letters: Advanced Micro Devices GmbH Einsteinring 24, 85609 Dornach b. Muenchen Geschaeftsfuehrer: Alberto Bozzo, Andrew Bowd Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Dan Magenheimer
2010-Aug-27 16:27 UTC
RE: [Xen-devel] [PATCH 0 of 9] v2: xl/libxl autoballooning
Hi Stefano -- I''m glad you have been working on this for xl since this dom0 capability is also the foundation for ensuring domain creation works properly when tmem is both enabled on Xen and enabled on one or more running guests. In that situation, tmem absorbs much (or even all) of the free memory in the system, much like dom0 starts with all the memory and must surrender it to start other guests. One big difference though is that dom0 doesn''t asynchronously grow and claim the memory back, which can happen with tmem. Tmem has functionality to cover this case though. I''m not able to work on this right now... it will probably be a few weeks before I can, due to various constraints. But since you have just implemented this, I''m sure it is fresh in your brain and you may be able to check or update your patch to ensure it will easily support tmem as well. Perhaps you can at least insert comments at the points where you think the tmem hooks would be necessary? Or if you insert actual code that works with tmem disabled, I can try/debug it later with tmem enabled? Either way would make it much easier for me to finish the job later. There are three important tmem concepts that apply here. They are: 1) freeable memory 2) tmem freeze/thaw 3) tmem flush All of these funnel through xc_tmem_control. Freeable memory (see tmem_query_freeable_mb in XendNode.py) is memory that tmem can immediately free when requested. The implementation only queries how much is available in MB. Tmem freeze guarantees that tmem will not absorb any additional memory until tmem thaw. Thus freeable memory can only increase during a freeze. (Note that if tmem is not frozen, "free", "freeable", and their sum may increase or decrease.) See TMEMC_FREEZE and TMEMC_THAW in xend/balloon.py. Note that it is critical that any freeze be soon paired with a matching thaw... tmem is essentially non- functional during freeze which can affect the performance of other guests. Tmem flush (see TMEMC_FLUSH in balloon.py) releases the amount of memory requested (or all available freeable memory if the request exceeds freeable memory). Ideally, freeable memory should be checked to ensure there is sufficient total memory for the domain before a flush is done... balloon.py does not currently implement this, so xend domain creation may unnecessarily flush memory useful for other guest domains, only to find out that there was insufficient total memory. So the algorithm for domain creation should be: 1) If there is enough free memory, create the domain. If successful, go to (8). If not, or creation fails due to insufficient memory... 2) Freeze tmem, if ret < 0 (tmem is disabled) goto (8) 3) Check total memory = free + freeable memory 4) If not enough total memory, go to (7) 5) Flush enough tmem memory to create the domain 6) Create the domain 7) Thaw tmem 8) Done Thanks, Dan> -----Original Message----- > From: Stefano Stabellini [mailto:stefano.stabellini@eu.citrix.com] > Sent: Friday, August 27, 2010 7:50 AM > To: xen-devel@lists.xensource.com > Subject: [Xen-devel] [PATCH 0 of 9] v2: 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. > > The only changes compared to v1 are related to paths of xl.conf and the > lockfile: the paths are now set from the system dependent global > variables. > > Cheers, > > Stefano > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Aug-27 17:51 UTC
RE: [Xen-devel] [PATCH 0 of 9] v2: xl/libxl autoballooning
On Fri, 27 Aug 2010, Dan Magenheimer wrote:> Hi Stefano -- > > I''m glad you have been working on this for xl since this dom0 > capability is also the foundation for ensuring domain creation works > properly when tmem is both enabled on Xen and enabled on one or more > running guests. In that situation, tmem absorbs much (or even > all) of the free memory in the system, much like dom0 starts > with all the memory and must surrender it to start other guests. > One big difference though is that dom0 doesn''t asynchronously > grow and claim the memory back, which can happen with tmem. > Tmem has functionality to cover this case though. > > I''m not able to work on this right now... it will probably > be a few weeks before I can, due to various constraints. But > since you have just implemented this, I''m sure it is fresh > in your brain and you may be able to check or update your > patch to ensure it will easily support tmem as well. > Perhaps you can at least insert comments at the points > where you think the tmem hooks would be necessary? Or if > you insert actual code that works with tmem disabled, > I can try/debug it later with tmem enabled? Either way > would make it much easier for me to finish the job later. >I think you''ll find very easy to add tmem support on top of this series because the way it works is very similar to what xend does now. In fact after trying few other approaches and throwing them away because either too hard or racy, I decided to go for the very simple "global lock" method. So right before building the domain in the create_domain function xl acquires a lock and calls freemem. Freemem is an xl function, very similar to the free function in balloon.py in xend, that calculates how much memory the new domain needs and frees it, using libxl memory management functions. Adding few libxl tmem calls in freemem should do the job. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel