debuggers.hg
changeset 6982:a5d67e3fbff1
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@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
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@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author | cl349@firebug.cl.cam.ac.uk |
---|---|
date | Mon Sep 19 14:25:29 2005 +0000 (2005-09-19) |
parents | 3133e64d0462 |
children | f7a7f8f2e6e4 |
files | tools/xenstore/testsuite/02directory.test tools/xenstore/testsuite/04rm.test tools/xenstore/xenstored_core.c tools/xenstore/xs.c tools/xenstore/xs.h tools/xenstore/xs_random.c |
line diff
1.1 --- a/tools/xenstore/testsuite/02directory.test Mon Sep 19 13:24:31 2005 +0000 1.2 +++ b/tools/xenstore/testsuite/02directory.test Mon Sep 19 14:25:29 2005 +0000 1.3 @@ -27,10 +27,8 @@ dir /dir 1.4 expect contents2 1.5 read /dir/test2 1.6 1.7 -# Creating dir over the top should fail. 1.8 -expect mkdir failed: File exists 1.9 +# Creating dir over the top should succeed. 1.10 mkdir /dir 1.11 -expect mkdir failed: File exists 1.12 mkdir /dir/test2 1.13 1.14 # Mkdir implicitly creates directories.
2.1 --- a/tools/xenstore/testsuite/04rm.test Mon Sep 19 13:24:31 2005 +0000 2.2 +++ b/tools/xenstore/testsuite/04rm.test Mon Sep 19 14:25:29 2005 +0000 2.3 @@ -1,5 +1,4 @@ 2.4 -# Remove non-existant fails. 2.5 -expect rm failed: No such file or directory 2.6 +# Remove non-existant is OK, as long as parent exists 2.7 rm /test 2.8 expect rm failed: No such file or directory 2.9 rm /dir/test
3.1 --- a/tools/xenstore/xenstored_core.c Mon Sep 19 13:24:31 2005 +0000 3.2 +++ b/tools/xenstore/xenstored_core.c Mon Sep 19 14:25:29 2005 +0000 3.3 @@ -961,6 +961,13 @@ static char *tempdir(struct connection * 3.4 return dir; 3.5 } 3.6 3.7 +static bool node_exists(struct connection *conn, const char *node) 3.8 +{ 3.9 + struct stat st; 3.10 + 3.11 + return lstat(node_dir(conn->transaction, node), &st) == 0; 3.12 +} 3.13 + 3.14 /* path, flags, data... */ 3.15 static void do_write(struct connection *conn, struct buffered_data *in) 3.16 { 3.17 @@ -1050,7 +1057,6 @@ static void do_write(struct connection * 3.18 static void do_mkdir(struct connection *conn, const char *node) 3.19 { 3.20 char *dir; 3.21 - struct stat st; 3.22 3.23 node = canonicalize(conn, node); 3.24 if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_ENOENT_OK)) { 3.25 @@ -1066,9 +1072,9 @@ static void do_mkdir(struct connection * 3.26 if (transaction_block(conn, node)) 3.27 return; 3.28 3.29 - /* Must not already exist. */ 3.30 - if (lstat(node_dir(conn->transaction, node), &st) == 0) { 3.31 - send_error(conn, EEXIST); 3.32 + /* If it already exists, fine. */ 3.33 + if (node_exists(conn, node)) { 3.34 + send_ack(conn, XS_MKDIR); 3.35 return; 3.36 } 3.37 3.38 @@ -1089,6 +1095,15 @@ static void do_rm(struct connection *con 3.39 3.40 node = canonicalize(conn, node); 3.41 if (!check_node_perms(conn, node, XS_PERM_WRITE)) { 3.42 + /* Didn't exist already? Fine, if parent exists. */ 3.43 + if (errno == ENOENT) { 3.44 + if (node_exists(conn, get_parent(node))) { 3.45 + send_ack(conn, XS_RM); 3.46 + return; 3.47 + } 3.48 + /* Restore errno, just in case. */ 3.49 + errno = ENOENT; 3.50 + } 3.51 send_error(conn, errno); 3.52 return; 3.53 }
4.1 --- a/tools/xenstore/xs.c Mon Sep 19 13:24:31 2005 +0000 4.2 +++ b/tools/xenstore/xs.c Mon Sep 19 14:25:29 2005 +0000 4.3 @@ -357,7 +357,7 @@ bool xs_write(struct xs_handle *h, const 4.4 } 4.5 4.6 /* Create a new directory. 4.7 - * Returns false on failure. 4.8 + * Returns false on failure, or success if it already exists. 4.9 */ 4.10 bool xs_mkdir(struct xs_handle *h, const char *path) 4.11 { 4.12 @@ -365,7 +365,7 @@ bool xs_mkdir(struct xs_handle *h, const 4.13 } 4.14 4.15 /* Destroy a file or directory (directories must be empty). 4.16 - * Returns false on failure. 4.17 + * Returns false on failure, or success if it doesn't exist. 4.18 */ 4.19 bool xs_rm(struct xs_handle *h, const char *path) 4.20 {
5.1 --- a/tools/xenstore/xs.h Mon Sep 19 13:24:31 2005 +0000 5.2 +++ b/tools/xenstore/xs.h Mon Sep 19 14:25:29 2005 +0000 5.3 @@ -59,12 +59,12 @@ bool xs_write(struct xs_handle *h, const 5.4 unsigned int len, int createflags); 5.5 5.6 /* Create a new directory. 5.7 - * Returns false on failure. 5.8 + * Returns false on failure, or success if it already exists. 5.9 */ 5.10 bool xs_mkdir(struct xs_handle *h, const char *path); 5.11 5.12 /* Destroy a file or directory (and children). 5.13 - * Returns false on failure. 5.14 + * Returns false on failure, or success if it doesn't exist. 5.15 */ 5.16 bool xs_rm(struct xs_handle *h, const char *path); 5.17
6.1 --- a/tools/xenstore/xs_random.c Mon Sep 19 13:24:31 2005 +0000 6.2 +++ b/tools/xenstore/xs_random.c Mon Sep 19 14:25:29 2005 +0000 6.3 @@ -385,7 +385,7 @@ static bool file_mkdir(struct file_ops_i 6.4 6.5 make_dirs(parent_filename(dirname)); 6.6 if (mkdir(dirname, 0700) != 0) 6.7 - return false; 6.8 + return (errno == EEXIST); 6.9 6.10 init_perms(dirname); 6.11 return true; 6.12 @@ -401,8 +401,11 @@ static bool file_rm(struct file_ops_info 6.13 return false; 6.14 } 6.15 6.16 - if (lstat(filename, &st) != 0) 6.17 - return false; 6.18 + if (lstat(filename, &st) != 0) { 6.19 + if (lstat(parent_filename(filename), &st) != 0) 6.20 + return false; 6.21 + return true; 6.22 + } 6.23 6.24 if (!write_ok(info, path)) 6.25 return false;