debuggers.hg

changeset 21184:5b8362505256

libxl: Provide libxl_domain_rename

Provide a new function libxl_domain_rename. It can check that the
domain being renamed has the expected name, to avoid races.

Use the new function to set the name during domain creation.

Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Apr 12 17:40:34 2010 +0100 (2010-04-12)
parents c031244c190e
children 86e82ab8d4de
files tools/libxl/libxl.c tools/libxl/libxl.h
line diff
     1.1 --- a/tools/libxl/libxl.c	Mon Apr 12 17:40:06 2010 +0100
     1.2 +++ b/tools/libxl/libxl.c	Mon Apr 12 17:40:34 2010 +0100
     1.3 @@ -82,7 +82,7 @@ int libxl_ctx_set_log(struct libxl_ctx *
     1.4  int libxl_domain_make(struct libxl_ctx *ctx, libxl_domain_create_info *info,
     1.5                         uint32_t *domid)
     1.6  {
     1.7 -    int flags, ret, i;
     1.8 +    int flags, ret, i, rc;
     1.9      char *uuid_string;
    1.10      char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"};
    1.11      char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers",
    1.12 @@ -146,7 +146,8 @@ retry_transaction:
    1.13  
    1.14      xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, strlen(vm_path));
    1.15      xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vss", dom_path), vss_path, strlen(vss_path));
    1.16 -    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", dom_path), info->name, strlen(info->name));
    1.17 +    rc = libxl_domain_rename(ctx, *domid, 0, info->name, t);
    1.18 +    if (rc) return rc;
    1.19  
    1.20      for (i = 0; i < ARRAY_SIZE(rw_paths); i++) {
    1.21          char *path = libxl_sprintf(ctx, "%s/%s", dom_path, rw_paths[i]);
    1.22 @@ -175,6 +176,84 @@ retry_transaction:
    1.23      return 0;
    1.24  }
    1.25  
    1.26 +int libxl_domain_rename(struct libxl_ctx *ctx, uint32_t domid,
    1.27 +                        const char *old_name, const char *new_name,
    1.28 +                        xs_transaction_t trans) {
    1.29 +    char *dom_path = 0;
    1.30 +    const char *name_path;
    1.31 +    char *got_old_name;
    1.32 +    unsigned int got_old_len;
    1.33 +    xs_transaction_t our_trans = 0;
    1.34 +    int rc;
    1.35 +
    1.36 +    dom_path = libxl_xs_get_dompath(ctx, domid);
    1.37 +    if (!dom_path) goto x_nomem;
    1.38 +
    1.39 +    name_path= libxl_sprintf(ctx, "%s/name", dom_path);
    1.40 +    if (!name_path) goto x_nomem;
    1.41 +
    1.42 + retry_transaction:
    1.43 +    if (!trans) {
    1.44 +        trans = our_trans = xs_transaction_start(ctx->xsh);
    1.45 +        if (!our_trans) {
    1.46 +            XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno,
    1.47 +                            "create xs transaction for domain (re)name");
    1.48 +            goto x_fail;
    1.49 +        }
    1.50 +    }
    1.51 +
    1.52 +    if (old_name) {
    1.53 +        got_old_name = xs_read(ctx->xsh, trans, name_path, &got_old_len);
    1.54 +        if (!got_old_name) {
    1.55 +            XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, "check old name"
    1.56 +                            " for domain %"PRIu32" allegedly named `%s'",
    1.57 +                            domid, old_name);
    1.58 +            goto x_fail;
    1.59 +        }
    1.60 +        if (strcmp(old_name, got_old_name)) {
    1.61 +            XL_LOG(ctx, XL_LOG_ERROR, "domain %"PRIu32" allegedly named "
    1.62 +                   "`%s' is actually named `%s' - racing ?",
    1.63 +                   domid, old_name, got_old_name);
    1.64 +            free(got_old_name);
    1.65 +            goto x_fail;
    1.66 +        }
    1.67 +        free(got_old_name);
    1.68 +    }
    1.69 +    if (!xs_write(ctx->xsh, trans, name_path,
    1.70 +                  new_name, strlen(new_name))) {
    1.71 +        XL_LOG(ctx, XL_LOG_ERROR, "failed to write new name `%s'"
    1.72 +               " for domain %"PRIu32" previously named `%s'",
    1.73 +               domid, new_name, old_name);
    1.74 +        goto x_fail;
    1.75 +    }
    1.76 +
    1.77 +    if (our_trans) {
    1.78 +        if (!xs_transaction_end(ctx->xsh, our_trans, 0)) {
    1.79 +            trans = our_trans = 0;
    1.80 +            if (errno != EAGAIN) {
    1.81 +                XL_LOG(ctx, XL_LOG_ERROR, "failed to commit new name `%s'"
    1.82 +                       " for domain %"PRIu32" previously named `%s'",
    1.83 +                       domid, new_name, old_name);
    1.84 +                goto x_fail;
    1.85 +            }
    1.86 +            XL_LOG(ctx, XL_LOG_DEBUG, "need to retry rename transaction"
    1.87 +                   " for domain %"PRIu32" (name_path=\"%s\", new_name=\"%s\")",
    1.88 +                   domid, name_path, new_name);
    1.89 +            goto retry_transaction;
    1.90 +        }
    1.91 +        our_trans = 0;
    1.92 +    }
    1.93 +
    1.94 +    rc = 0;
    1.95 + x_rc:
    1.96 +    if (dom_path) libxl_free(ctx, dom_path);
    1.97 +    if (our_trans) xs_transaction_end(ctx->xsh, our_trans, 1);
    1.98 +    return rc;
    1.99 +
   1.100 + x_fail:  rc = ERROR_FAIL;  goto x_rc;
   1.101 + x_nomem: rc = ERROR_NOMEM; goto x_rc;
   1.102 +}
   1.103 +
   1.104  int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state)
   1.105  {
   1.106      char **vments = NULL, **localents = NULL;
     2.1 --- a/tools/libxl/libxl.h	Mon Apr 12 17:40:06 2010 +0100
     2.2 +++ b/tools/libxl/libxl.h	Mon Apr 12 17:40:34 2010 +0100
     2.3 @@ -297,6 +297,12 @@ int libxl_free_waiter(libxl_waiter *wait
     2.4  int libxl_event_get_domain_death_info(struct libxl_ctx *ctx, uint32_t domid, libxl_event *event, xc_domaininfo_t *info);
     2.5  int libxl_event_get_disk_eject_info(struct libxl_ctx *ctx, uint32_t domid, libxl_event *event, libxl_device_disk *disk);
     2.6  
     2.7 +int libxl_domain_rename(struct libxl_ctx *ctx, uint32_t domid,
     2.8 +                        const char *old_name, const char *new_name,
     2.9 +                        xs_transaction_t trans);
    2.10 +  /* if old_name is NULL, any old name is OK; otherwise we check
    2.11 +   * transactionally that the domain has the old old name; if
    2.12 +   * trans is not 0 we use caller's transaction and caller must do retries */
    2.13  
    2.14  int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid);
    2.15  int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid);