[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |