All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH 2 of 8] libxl: introduce libxl_set_relative_memory_target
Date: Fri, 27 Aug 2010 12:18:45 +0100	[thread overview]
Message-ID: <alpine.DEB.2.00.1008271215210.2545@kaball-desktop> (raw)

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);

             reply	other threads:[~2010-08-27 11:18 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-27 11:18 Stefano Stabellini [this message]
2010-08-31 17:25 ` [PATCH 2 of 8] libxl: introduce libxl_set_relative_memory_target Ian Jackson
2010-09-01 10:55   ` Stefano Stabellini
2010-09-01 18:01   ` Jeremy Fitzhardinge
2010-09-01 20:03     ` Dan Magenheimer
2010-09-01 21:17       ` Jeremy Fitzhardinge
2010-09-01 21:49         ` Dan Magenheimer
2010-09-02  9:15     ` Stefano Stabellini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.DEB.2.00.1008271215210.2545@kaball-desktop \
    --to=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.