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