aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenstore
diff options
context:
space:
mode:
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>2005-09-19 14:25:29 +0000
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>2005-09-19 14:25:29 +0000
commit265d719ce5be2eb71d3a4433b27999350a85e0db (patch)
treebc212221201811e6237d11b6516168f51d5634e8 /tools/xenstore
parent9eed83921ee8405fb503348900c6d0e60557223d (diff)
downloadxen-265d719ce5be2eb71d3a4433b27999350a85e0db.tar.gz
xen-265d719ce5be2eb71d3a4433b27999350a85e0db.tar.bz2
xen-265d719ce5be2eb71d3a4433b27999350a85e0db.zip
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>
Diffstat (limited to 'tools/xenstore')
-rw-r--r--tools/xenstore/testsuite/02directory.test4
-rw-r--r--tools/xenstore/testsuite/04rm.test3
-rw-r--r--tools/xenstore/xenstored_core.c23
-rw-r--r--tools/xenstore/xs.c4
-rw-r--r--tools/xenstore/xs.h4
-rw-r--r--tools/xenstore/xs_random.c9
6 files changed, 31 insertions, 16 deletions
diff --git a/tools/xenstore/testsuite/02directory.test b/tools/xenstore/testsuite/02directory.test
index 425026ffbe..fd57bb8b78 100644
--- a/tools/xenstore/testsuite/02directory.test
+++ b/tools/xenstore/testsuite/02directory.test
@@ -27,10 +27,8 @@ dir /dir
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 --git a/tools/xenstore/testsuite/04rm.test b/tools/xenstore/testsuite/04rm.test
index 186e9a9d75..bcc035bac2 100644
--- a/tools/xenstore/testsuite/04rm.test
+++ b/tools/xenstore/testsuite/04rm.test
@@ -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 --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 564b7dce38..f5e7d0c9f3 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -961,6 +961,13 @@ static char *tempdir(struct connection *conn,
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_write(struct connection *conn, struct buffered_data *in)
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 @@ static void do_mkdir(struct connection *conn, const char *node)
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 @@ static void do_rm(struct connection *conn, const char *node)
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 --git a/tools/xenstore/xs.c b/tools/xenstore/xs.c
index 9991cefc61..ad17e9d31a 100644
--- a/tools/xenstore/xs.c
+++ b/tools/xenstore/xs.c
@@ -357,7 +357,7 @@ bool xs_write(struct xs_handle *h, const char *path,
}
/* 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 @@ bool xs_mkdir(struct xs_handle *h, const char *path)
}
/* 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 --git a/tools/xenstore/xs.h b/tools/xenstore/xs.h
index 5999baaa00..98679eebd2 100644
--- a/tools/xenstore/xs.h
+++ b/tools/xenstore/xs.h
@@ -59,12 +59,12 @@ bool xs_write(struct xs_handle *h, const char *path, const void *data,
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 --git a/tools/xenstore/xs_random.c b/tools/xenstore/xs_random.c
index b8f39d36e7..7a2119ccf7 100644
--- a/tools/xenstore/xs_random.c
+++ b/tools/xenstore/xs_random.c
@@ -385,7 +385,7 @@ static bool file_mkdir(struct file_ops_info *info, const char *path)
make_dirs(parent_filename(dirname));
if (mkdir(dirname, 0700) != 0)
- return false;
+ return (errno == EEXIST);
init_perms(dirname);
return true;
@@ -401,8 +401,11 @@ static bool file_rm(struct file_ops_info *info, const char *path)
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;