[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] libxl: Provide libxl_domain_rename



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1271090434 -3600
# Node ID 5b8362505256165048210184d8183cf44035ad82
# Parent  c031244c190eec90f1d072dc3028fe874d56153d
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 -r c031244c190e -r 5b8362505256 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Mon Apr 12 17:40:06 2010 +0100
+++ b/tools/libxl/libxl.c       Mon Apr 12 17:40:34 2010 +0100
@@ -82,7 +82,7 @@ int libxl_domain_make(struct libxl_ctx *
 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]);
@@ -173,6 +174,84 @@ retry_transaction:
         if (errno == EAGAIN)
             goto 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)
diff -r c031244c190e -r 5b8362505256 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Mon Apr 12 17:40:06 2010 +0100
+++ b/tools/libxl/libxl.h       Mon Apr 12 17:40:34 2010 +0100
@@ -297,6 +297,12 @@ int libxl_event_get_domain_death_info(st
 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);

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.