WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 05/16] 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@xxxxxxxxxxxxx>
---
 tools/libxl/libxl.c |   83 +++++++++++++++++++++++++++++++++++++++++++++++++-
 tools/libxl/libxl.h |    6 ++++
 2 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 87a51fa..4d80be5 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -82,7 +82,7 @@ int libxl_ctx_set_log(struct libxl_ctx *ctx, 
libxl_log_callback log_callback, vo
 int libxl_domain_make(struct libxl_ctx *ctx, libxl_domain_create_info *info,
                        uint32_t *domid)
 {
-    int flags, ret, i;
+    int flags, ret, i, rc;
     char *uuid_string;
     char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"};
     char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers",
@@ -146,7 +146,8 @@ retry_transaction:
 
     xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, 
strlen(vm_path));
     xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vss", dom_path), vss_path, 
strlen(vss_path));
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", dom_path), info->name, 
strlen(info->name));
+    rc = libxl_domain_rename(ctx, *domid, 0, info->name, t);
+    if (rc) return rc;
 
     for (i = 0; i < ARRAY_SIZE(rw_paths); i++) {
         char *path = libxl_sprintf(ctx, "%s/%s", dom_path, rw_paths[i]);
@@ -175,6 +176,84 @@ retry_transaction:
     return 0;
 }
 
+int libxl_domain_rename(struct libxl_ctx *ctx, uint32_t domid,
+                        const char *old_name, const char *new_name,
+                        xs_transaction_t trans) {
+    char *dom_path = 0;
+    const char *name_path;
+    char *got_old_name;
+    unsigned int got_old_len;
+    xs_transaction_t our_trans = 0;
+    int rc;
+
+    dom_path = libxl_xs_get_dompath(ctx, domid);
+    if (!dom_path) goto x_nomem;
+
+    name_path= libxl_sprintf(ctx, "%s/name", dom_path);
+    if (!name_path) goto x_nomem;
+
+ retry_transaction:
+    if (!trans) {
+        trans = our_trans = xs_transaction_start(ctx->xsh);
+        if (!our_trans) {
+            XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno,
+                            "create xs transaction for domain (re)name");
+            goto x_fail;
+        }
+    }
+
+    if (old_name) {
+        got_old_name = xs_read(ctx->xsh, trans, name_path, &got_old_len);
+        if (!got_old_name) {
+            XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, "check old name"
+                            " for domain %"PRIu32" allegedly named `%s'",
+                            domid, old_name);
+            goto x_fail;
+        }
+        if (strcmp(old_name, got_old_name)) {
+            XL_LOG(ctx, XL_LOG_ERROR, "domain %"PRIu32" allegedly named "
+                   "`%s' is actually named `%s' - racing ?",
+                   domid, old_name, got_old_name);
+            free(got_old_name);
+            goto x_fail;
+        }
+        free(got_old_name);
+    }
+    if (!xs_write(ctx->xsh, trans, name_path,
+                  new_name, strlen(new_name))) {
+        XL_LOG(ctx, XL_LOG_ERROR, "failed to write new name `%s'"
+               " for domain %"PRIu32" previously named `%s'",
+               domid, new_name, old_name);
+        goto x_fail;
+    }
+
+    if (our_trans) {
+        if (!xs_transaction_end(ctx->xsh, our_trans, 0)) {
+            trans = our_trans = 0;
+            if (errno != EAGAIN) {
+                XL_LOG(ctx, XL_LOG_ERROR, "failed to commit new name `%s'"
+                       " for domain %"PRIu32" previously named `%s'",
+                       domid, new_name, old_name);
+                goto x_fail;
+            }
+            XL_LOG(ctx, XL_LOG_DEBUG, "need to retry rename transaction"
+                   " for domain %"PRIu32" (name_path=\"%s\", new_name=\"%s\")",
+                   domid, name_path, new_name);
+            goto retry_transaction;
+        }
+        our_trans = 0;
+    }
+
+    rc = 0;
+ x_rc:
+    if (dom_path) libxl_free(ctx, dom_path);
+    if (our_trans) xs_transaction_end(ctx->xsh, our_trans, 1);
+    return rc;
+
+ x_fail:  rc = ERROR_FAIL;  goto x_rc;
+ x_nomem: rc = ERROR_NOMEM; goto x_rc;
+}
+
 int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, 
uint32_t domid, libxl_domain_build_state *state)
 {
     char **vments = NULL, **localents = NULL;
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 959d9f5..fea552b 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -297,6 +297,12 @@ int libxl_free_waiter(libxl_waiter *waiter);
 int libxl_event_get_domain_death_info(struct libxl_ctx *ctx, uint32_t domid, 
libxl_event *event, xc_domaininfo_t *info);
 int libxl_event_get_disk_eject_info(struct libxl_ctx *ctx, uint32_t domid, 
libxl_event *event, libxl_device_disk *disk);
 
+int libxl_domain_rename(struct libxl_ctx *ctx, uint32_t domid,
+                        const char *old_name, const char *new_name,
+                        xs_transaction_t trans);
+  /* if old_name is NULL, any old name is OK; otherwise we check
+   * transactionally that the domain has the old old name; if
+   * trans is not 0 we use caller's transaction and caller must do retries */
 
 int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid);
 int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid);
-- 
1.5.6.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel