diff options
author | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-09-19 14:25:29 +0000 |
---|---|---|
committer | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-09-19 14:25:29 +0000 |
commit | 265d719ce5be2eb71d3a4433b27999350a85e0db (patch) | |
tree | bc212221201811e6237d11b6516168f51d5634e8 /tools/xenstore | |
parent | 9eed83921ee8405fb503348900c6d0e60557223d (diff) | |
download | xen-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.test | 4 | ||||
-rw-r--r-- | tools/xenstore/testsuite/04rm.test | 3 | ||||
-rw-r--r-- | tools/xenstore/xenstored_core.c | 23 | ||||
-rw-r--r-- | tools/xenstore/xs.c | 4 | ||||
-rw-r--r-- | tools/xenstore/xs.h | 4 | ||||
-rw-r--r-- | tools/xenstore/xs_random.c | 9 |
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; |