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