WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-tools

[Xen-tools] Re: [PATCH] Make xs_rm and xs_mkdir idempotent

To: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
Subject: [Xen-tools] Re: [PATCH] Make xs_rm and xs_mkdir idempotent
From: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>
Date: Mon, 19 Sep 2005 15:25:40 +0100
Cc: Xen Tools <xen-tools@xxxxxxxxxxxxxxxxxxx>
Delivery-date: Mon, 19 Sep 2005 14:23:14 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1126916083.29203.8.camel@xxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-tools-request@lists.xensource.com?subject=help>
List-id: Xen control tools developers <xen-tools.lists.xensource.com>
List-post: <mailto:xen-tools@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-tools>, <mailto:xen-tools-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-tools>, <mailto:xen-tools-request@lists.xensource.com?subject=unsubscribe>
References: <1126916083.29203.8.camel@xxxxxxxxxxxxxxxxxxxxx>
Sender: xen-tools-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.4.1i
Thanks!

On Sat, Sep 17, 2005 at 10:14:43AM +1000, Rusty Russell wrote:
> # HG changeset patch
> # User Rusty Russell <rusty@xxxxxxxxxxxxxxx>
> # Node ID 90b4e122d3407c7d0e28e6391ca89d46d5a81e52
> # Parent  fd19e760932d095b23d38e67eaec24dd02ba3aba
> 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>
> 
> diff -r fd19e760932d -r 90b4e122d340 tools/xenstore/testsuite/02directory.test
> --- a/tools/xenstore/testsuite/02directory.test       Thu Sep 15 19:46:14 2005
> +++ b/tools/xenstore/testsuite/02directory.test       Fri Sep 16 05:01:11 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 fd19e760932d -r 90b4e122d340 tools/xenstore/testsuite/04rm.test
> --- a/tools/xenstore/testsuite/04rm.test      Thu Sep 15 19:46:14 2005
> +++ b/tools/xenstore/testsuite/04rm.test      Fri Sep 16 05:01:11 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 fd19e760932d -r 90b4e122d340 tools/xenstore/xenstored_core.c
> --- a/tools/xenstore/xenstored_core.c Thu Sep 15 19:46:14 2005
> +++ b/tools/xenstore/xenstored_core.c Fri Sep 16 05:01:11 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 fd19e760932d -r 90b4e122d340 tools/xenstore/xs.c
> --- a/tools/xenstore/xs.c     Thu Sep 15 19:46:14 2005
> +++ b/tools/xenstore/xs.c     Fri Sep 16 05:01:11 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 fd19e760932d -r 90b4e122d340 tools/xenstore/xs.h
> --- a/tools/xenstore/xs.h     Thu Sep 15 19:46:14 2005
> +++ b/tools/xenstore/xs.h     Fri Sep 16 05:01:11 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 fd19e760932d -r 90b4e122d340 tools/xenstore/xs_random.c
> --- a/tools/xenstore/xs_random.c      Thu Sep 15 19:46:14 2005
> +++ b/tools/xenstore/xs_random.c      Fri Sep 16 05:01:11 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;
> 
> -- 
> A bad analogy is like a leaky screwdriver -- Richard Braakman
> 
> 

_______________________________________________
Xen-tools mailing list
Xen-tools@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-tools

<Prev in Thread] Current Thread [Next in Thread>