debuggers.hg

changeset 22244:4b00f89e15f1

libxl: add a "relative" parameter to libxl_set_memory_target

Introduce a relative parameter to flag that target_memkb is a relative
amount of memory. The first time we are reading/writing dom0 memory
target, fill the informations in xenstore if they are missing.

Introduce libxl_get_memory_target.

[fixed up for conflicts with libxl__ naming policy changes -iwj]

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
date Wed Sep 22 17:37:09 2010 +0100 (2010-09-22)
parents a0044f16d3df
children 7659c107b2f3
files tools/libxl/libxl.c tools/libxl/libxl.h tools/libxl/xl_cmdimpl.c
line diff
     1.1 --- a/tools/libxl/libxl.c	Wed Sep 22 17:31:45 2010 +0100
     1.2 +++ b/tools/libxl/libxl.c	Wed Sep 22 17:37:09 2010 +0100
     1.3 @@ -2774,13 +2774,61 @@ out:
     1.4      return rc;
     1.5  }
     1.6  
     1.7 -int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t
     1.8 -        target_memkb, int enforce)
     1.9 +static int libxl__fill_dom0_memory_info(libxl__gc *gc, uint32_t *target_memkb)
    1.10 +{
    1.11 +    int rc;
    1.12 +    libxl_dominfo info;
    1.13 +    char *target = NULL, *endptr = NULL;
    1.14 +    char *target_path = "/local/domain/0/memory/target";
    1.15 +    char *max_path = "/local/domain/0/memory/static-max";
    1.16 +    xs_transaction_t t;
    1.17 +    libxl_ctx *ctx = libxl__gc_owner(gc);
    1.18 +
    1.19 +retry_transaction:
    1.20 +    t = xs_transaction_start(ctx->xsh);
    1.21 +
    1.22 +    target = libxl__xs_read(gc, t, target_path);
    1.23 +    if (target) {
    1.24 +        *target_memkb = strtoul(target, &endptr, 10);
    1.25 +        if (*endptr != '\0') {
    1.26 +            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
    1.27 +                    "invalid memory target %s from %s\n", target, target_path);
    1.28 +            rc = ERROR_FAIL;
    1.29 +            goto out;
    1.30 +        }
    1.31 +        rc = 0;
    1.32 +        goto out;
    1.33 +    }
    1.34 +
    1.35 +    rc = libxl_domain_info(ctx, &info, 0);
    1.36 +    if (rc < 0)
    1.37 +        return rc;
    1.38 +
    1.39 +    libxl__xs_write(gc, t, target_path, "%"PRIu32,
    1.40 +            (uint32_t) info.current_memkb);
    1.41 +    libxl__xs_write(gc, t, max_path, "%"PRIu32,
    1.42 +            (uint32_t) info.max_memkb);
    1.43 +
    1.44 +    *target_memkb = (uint32_t) info.current_memkb;
    1.45 +    rc = 0;
    1.46 +
    1.47 +out:
    1.48 +    if (!xs_transaction_end(ctx->xsh, t, 0))
    1.49 +        if (errno == EAGAIN)
    1.50 +            goto retry_transaction;
    1.51 +
    1.52 +
    1.53 +    return rc;
    1.54 +}
    1.55 +
    1.56 +int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid,
    1.57 +        int32_t target_memkb, int relative, int enforce)
    1.58  {
    1.59      libxl__gc gc = LIBXL_INIT_GC(ctx);
    1.60      int rc = 1, abort = 0;
    1.61 -    uint32_t videoram = 0;
    1.62 -    char *videoram_s = NULL;
    1.63 +    uint32_t memorykb = 0, videoram = 0;
    1.64 +    uint32_t current_target_memkb = 0, new_target_memkb = 0;
    1.65 +    char *memmax, *endptr, *videoram_s = NULL, *target = NULL;
    1.66      char *dompath = libxl__xs_get_dompath(&gc, domid);
    1.67      xc_domaininfo_t info;
    1.68      libxl_dominfo ptr;
    1.69 @@ -2790,35 +2838,92 @@ int libxl_set_memory_target(libxl_ctx *c
    1.70  retry_transaction:
    1.71      t = xs_transaction_start(ctx->xsh);
    1.72  
    1.73 -    videoram_s = libxl__xs_read(&gc, t, libxl__sprintf(&gc, "%s/memory/videoram",
    1.74 -                dompath));
    1.75 -    videoram = videoram_s ? atoi(videoram_s) : 0;
    1.76 -
    1.77 -    if (enforce) {
    1.78 -        rc = xc_domain_setmaxmem(ctx->xch, domid, target_memkb +
    1.79 -                LIBXL_MAXMEM_CONSTANT);
    1.80 -        if (rc != 0) {
    1.81 +    target = libxl__xs_read(&gc, t, libxl__sprintf(&gc,
    1.82 +                "%s/memory/target", dompath));
    1.83 +    if (!target && !domid) {
    1.84 +        xs_transaction_end(ctx->xsh, t, 1);
    1.85 +        rc = libxl__fill_dom0_memory_info(&gc, &current_target_memkb);
    1.86 +        if (rc < 0) {
    1.87 +            abort = 1;
    1.88 +            goto out;
    1.89 +        }
    1.90 +        goto retry_transaction;
    1.91 +    } else if (!target) {
    1.92 +        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
    1.93 +                "cannot get target memory info from %s/memory/target\n",
    1.94 +                dompath);
    1.95 +        abort = 1;
    1.96 +        goto out;
    1.97 +    } else {
    1.98 +        current_target_memkb = strtoul(target, &endptr, 10);
    1.99 +        if (*endptr != '\0') {
   1.100              LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
   1.101 -                    "xc_domain_setmaxmem domid=%d memkb=%d failed "
   1.102 -                    "rc=%d\n", domid, target_memkb + LIBXL_MAXMEM_CONSTANT, rc);
   1.103 +                    "invalid memory target %s from %s/memory/target\n",
   1.104 +                    target, dompath);
   1.105              abort = 1;
   1.106              goto out;
   1.107          }
   1.108      }
   1.109 -
   1.110 -    rc = xc_domain_memory_set_pod_target(ctx->xch, domid, (target_memkb -
   1.111 -                videoram) / 4, NULL, NULL, NULL);
   1.112 +    memmax = libxl__xs_read(&gc, t, libxl__sprintf(&gc,
   1.113 +                "%s/memory/static-max", dompath));
   1.114 +    if (!memmax) {
   1.115 +        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
   1.116 +                "cannot get memory info from %s/memory/static-max\n",
   1.117 +                dompath);
   1.118 +        abort = 1;
   1.119 +        goto out;
   1.120 +    }
   1.121 +    memorykb = strtoul(memmax, &endptr, 10);
   1.122 +    if (*endptr != '\0') {
   1.123 +        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
   1.124 +                "invalid max memory %s from %s/memory/static-max\n",
   1.125 +                memmax, dompath);
   1.126 +        abort = 1;
   1.127 +        goto out;
   1.128 +    }
   1.129 +
   1.130 +    if (relative)
   1.131 +        new_target_memkb = current_target_memkb + target_memkb;
   1.132 +    else
   1.133 +        new_target_memkb = target_memkb;
   1.134 +    if (new_target_memkb > memorykb) {
   1.135 +        LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
   1.136 +                "memory_dynamic_max must be less than or equal to"
   1.137 +                " memory_static_max\n");
   1.138 +        abort = 1;
   1.139 +        goto out;
   1.140 +    }
   1.141 +
   1.142 +    videoram_s = libxl__xs_read(&gc, t, libxl__sprintf(&gc,
   1.143 +                "%s/memory/videoram", dompath));
   1.144 +    videoram = videoram_s ? atoi(videoram_s) : 0;
   1.145 +
   1.146 +    if (enforce) {
   1.147 +        memorykb = new_target_memkb;
   1.148 +        rc = xc_domain_setmaxmem(ctx->xch, domid, memorykb +
   1.149 +                LIBXL_MAXMEM_CONSTANT);
   1.150 +        if (rc != 0) {
   1.151 +            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
   1.152 +                    "xc_domain_setmaxmem domid=%d memkb=%d failed "
   1.153 +                    "rc=%d\n", domid, memorykb + LIBXL_MAXMEM_CONSTANT, rc);
   1.154 +            abort = 1;
   1.155 +            goto out;
   1.156 +        }
   1.157 +    }
   1.158 +
   1.159 +    rc = xc_domain_memory_set_pod_target(ctx->xch, domid,
   1.160 +            (new_target_memkb - videoram) / 4, NULL, NULL, NULL);
   1.161      if (rc != 0) {
   1.162          LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
   1.163                  "xc_domain_memory_set_pod_target domid=%d, memkb=%d "
   1.164 -                "failed rc=%d\n", domid, (target_memkb - videoram) / 4,
   1.165 +                "failed rc=%d\n", domid, (new_target_memkb - videoram) / 4,
   1.166                  rc);
   1.167          abort = 1;
   1.168          goto out;
   1.169      }
   1.170  
   1.171 -    libxl__xs_write(&gc, t, libxl__sprintf(&gc, "%s/memory/target", dompath),
   1.172 -            "%"PRIu32, target_memkb);
   1.173 +    libxl__xs_write(&gc, t, libxl__sprintf(&gc, "%s/memory/target",
   1.174 +                dompath), "%"PRIu32, new_target_memkb);
   1.175      rc = xc_domain_getinfolist(ctx->xch, domid, 1, &info);
   1.176      if (rc != 1 || info.domain != domid) {
   1.177          abort = 1;
   1.178 @@ -2826,8 +2931,8 @@ retry_transaction:
   1.179      }
   1.180      xcinfo2xlinfo(&info, &ptr);
   1.181      uuid = libxl__uuid2string(&gc, ptr.uuid);
   1.182 -    libxl__xs_write(&gc, t, libxl__sprintf(&gc, "/vm/%s/memory", uuid), "%"PRIu32,
   1.183 -            target_memkb / 1024);
   1.184 +    libxl__xs_write(&gc, t, libxl__sprintf(&gc, "/vm/%s/memory", uuid),
   1.185 +            "%"PRIu32, new_target_memkb / 1024);
   1.186  
   1.187  out:
   1.188      if (!xs_transaction_end(ctx->xsh, t, abort) && !abort)
   1.189 @@ -2838,6 +2943,42 @@ out:
   1.190      return rc;
   1.191  }
   1.192  
   1.193 +int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t *out_target)
   1.194 +{
   1.195 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   1.196 +    int rc = 1;
   1.197 +    char *target = NULL, *endptr = NULL;
   1.198 +    char *dompath = libxl__xs_get_dompath(&gc, domid);
   1.199 +    uint32_t target_memkb;
   1.200 +
   1.201 +    target = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc,
   1.202 +                "%s/memory/target", dompath));
   1.203 +    if (!target && !domid) {
   1.204 +        rc = libxl__fill_dom0_memory_info(&gc, &target_memkb);
   1.205 +        if (rc < 0)
   1.206 +            goto out;
   1.207 +    } else if (!target) {
   1.208 +        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
   1.209 +                "cannot get target memory info from %s/memory/target\n",
   1.210 +                dompath);
   1.211 +        goto out;
   1.212 +    } else {
   1.213 +        target_memkb = strtoul(target, &endptr, 10);
   1.214 +        if (*endptr != '\0') {
   1.215 +            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
   1.216 +                    "invalid memory target %s from %s/memory/target\n",
   1.217 +                    target, dompath);
   1.218 +            goto out;
   1.219 +        }
   1.220 +    }
   1.221 +    *out_target = target_memkb;
   1.222 +    rc = 0;
   1.223 +
   1.224 +out:
   1.225 +    libxl__free_all(&gc);
   1.226 +    return rc;
   1.227 +}
   1.228 +
   1.229  int libxl_button_press(libxl_ctx *ctx, uint32_t domid, libxl_button button)
   1.230  {
   1.231      int rc = -1;
     2.1 --- a/tools/libxl/libxl.h	Wed Sep 22 17:31:45 2010 +0100
     2.2 +++ b/tools/libxl/libxl.h	Wed Sep 22 17:37:09 2010 +0100
     2.3 @@ -332,7 +332,8 @@ int libxl_domain_unpause(libxl_ctx *ctx,
     2.4  int libxl_domain_core_dump(libxl_ctx *ctx, uint32_t domid, const char *filename);
     2.5  
     2.6  int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb);
     2.7 -int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb, int enforce);
     2.8 +int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, int32_t target_memkb, int relative, int enforce);
     2.9 +int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t *out_target);
    2.10  
    2.11  int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass);
    2.12  int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num, libxl_console_constype type);
     3.1 --- a/tools/libxl/xl_cmdimpl.c	Wed Sep 22 17:31:45 2010 +0100
     3.2 +++ b/tools/libxl/xl_cmdimpl.c	Wed Sep 22 17:37:09 2010 +0100
     3.3 @@ -1767,7 +1767,7 @@ static void set_memory_target(char *p, c
     3.4          exit(3);
     3.5      }
     3.6  
     3.7 -    libxl_set_memory_target(&ctx, domid, memorykb, /* enforce */ 1);
     3.8 +    libxl_set_memory_target(&ctx, domid, memorykb, 0, /* enforce */ 1);
     3.9  }
    3.10  
    3.11  int main_memset(int argc, char **argv)