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

[Xen-changelog] Make xs_mkdir an xs_rm idempotent.



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID a5d67e3fbff1e2473b297b37c46f066bb0330a03
# Parent  3133e64d0462e1d84633e33c18b8e15bcf2efc82
Make xs_mkdir an xs_rm idempotent.
When modifying libxenstore to transparently restart when the daemon dies,
it became apparent that life is simpler when all commands can simply be
restarted.  So this patch makes a slight semantic change to xs_rm and xs_mkdir: 
xs_rm now succeeds if the file doesn't exist (as long as the parent exists),
and xs_mkdir succeeds if the directory already exists.
Noone should notice.
Signed-off-by: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r 3133e64d0462 -r a5d67e3fbff1 tools/xenstore/testsuite/02directory.test
--- a/tools/xenstore/testsuite/02directory.test Mon Sep 19 13:24:31 2005
+++ b/tools/xenstore/testsuite/02directory.test Mon Sep 19 14:25:29 2005
@@ -27,10 +27,8 @@
 expect contents2
 read /dir/test2
 
-# Creating dir over the top should fail.
-expect mkdir failed: File exists
+# Creating dir over the top should succeed.
 mkdir /dir
-expect mkdir failed: File exists
 mkdir /dir/test2
 
 # Mkdir implicitly creates directories.
diff -r 3133e64d0462 -r a5d67e3fbff1 tools/xenstore/testsuite/04rm.test
--- a/tools/xenstore/testsuite/04rm.test        Mon Sep 19 13:24:31 2005
+++ b/tools/xenstore/testsuite/04rm.test        Mon Sep 19 14:25:29 2005
@@ -1,5 +1,4 @@
-# Remove non-existant fails.
-expect rm failed: No such file or directory
+# Remove non-existant is OK, as long as parent exists
 rm /test
 expect rm failed: No such file or directory
 rm /dir/test
diff -r 3133e64d0462 -r a5d67e3fbff1 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Mon Sep 19 13:24:31 2005
+++ b/tools/xenstore/xenstored_core.c   Mon Sep 19 14:25:29 2005
@@ -961,6 +961,13 @@
        return dir;
 }
 
+static bool node_exists(struct connection *conn, const char *node)
+{
+       struct stat st;
+
+       return lstat(node_dir(conn->transaction, node), &st) == 0;
+}
+
 /* path, flags, data... */
 static void do_write(struct connection *conn, struct buffered_data *in)
 {
@@ -1050,7 +1057,6 @@
 static void do_mkdir(struct connection *conn, const char *node)
 {
        char *dir;
-       struct stat st;
 
        node = canonicalize(conn, node);
        if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_ENOENT_OK)) {
@@ -1066,9 +1072,9 @@
        if (transaction_block(conn, node))
                return;
 
-       /* Must not already exist. */
-       if (lstat(node_dir(conn->transaction, node), &st) == 0) {
-               send_error(conn, EEXIST);
+       /* If it already exists, fine. */
+       if (node_exists(conn, node)) {
+               send_ack(conn, XS_MKDIR);
                return;
        }
 
@@ -1089,6 +1095,15 @@
 
        node = canonicalize(conn, node);
        if (!check_node_perms(conn, node, XS_PERM_WRITE)) {
+               /* Didn't exist already?  Fine, if parent exists. */
+               if (errno == ENOENT) {
+                       if (node_exists(conn, get_parent(node))) {
+                               send_ack(conn, XS_RM);
+                               return;
+                       }
+                       /* Restore errno, just in case. */
+                       errno = ENOENT;
+               }
                send_error(conn, errno);
                return;
        }
diff -r 3133e64d0462 -r a5d67e3fbff1 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c       Mon Sep 19 13:24:31 2005
+++ b/tools/xenstore/xs.c       Mon Sep 19 14:25:29 2005
@@ -357,7 +357,7 @@
 }
 
 /* Create a new directory.
- * Returns false on failure.
+ * Returns false on failure, or success if it already exists.
  */
 bool xs_mkdir(struct xs_handle *h, const char *path)
 {
@@ -365,7 +365,7 @@
 }
 
 /* Destroy a file or directory (directories must be empty).
- * Returns false on failure.
+ * Returns false on failure, or success if it doesn't exist.
  */
 bool xs_rm(struct xs_handle *h, const char *path)
 {
diff -r 3133e64d0462 -r a5d67e3fbff1 tools/xenstore/xs.h
--- a/tools/xenstore/xs.h       Mon Sep 19 13:24:31 2005
+++ b/tools/xenstore/xs.h       Mon Sep 19 14:25:29 2005
@@ -59,12 +59,12 @@
              unsigned int len, int createflags);
 
 /* Create a new directory.
- * Returns false on failure.
+ * Returns false on failure, or success if it already exists.
  */
 bool xs_mkdir(struct xs_handle *h, const char *path);
 
 /* Destroy a file or directory (and children).
- * Returns false on failure.
+ * Returns false on failure, or success if it doesn't exist.
  */
 bool xs_rm(struct xs_handle *h, const char *path);
 
diff -r 3133e64d0462 -r a5d67e3fbff1 tools/xenstore/xs_random.c
--- a/tools/xenstore/xs_random.c        Mon Sep 19 13:24:31 2005
+++ b/tools/xenstore/xs_random.c        Mon Sep 19 14:25:29 2005
@@ -385,7 +385,7 @@
 
        make_dirs(parent_filename(dirname));
        if (mkdir(dirname, 0700) != 0)
-               return false;
+               return (errno == EEXIST);
 
        init_perms(dirname);
        return true;
@@ -401,8 +401,11 @@
                return false;
        }
 
-       if (lstat(filename, &st) != 0)
-               return false;
+       if (lstat(filename, &st) != 0) {
+               if (lstat(parent_filename(filename), &st) != 0)
+                       return false;
+               return true;
+       }
 
        if (!write_ok(info, path))
                return false;

_______________________________________________
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®.