ia64/xen-unstable

changeset 6966: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>
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;