direct-io.hg

changeset 7387:bb127c984f74

Added --tidy flag to xenstore-rm that recursively removes any empty directories
left by the primary removal.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Sat Oct 15 12:52:38 2005 +0100 (2005-10-15)
parents fd7b8b051466
children a0ec7370eec0
files tools/xenstore/xenstore_client.c
line diff
     1.1 --- a/tools/xenstore/xenstore_client.c	Sat Oct 15 09:32:10 2005 +0100
     1.2 +++ b/tools/xenstore/xenstore_client.c	Sat Oct 15 12:52:38 2005 +0100
     1.3 @@ -24,15 +24,32 @@ usage(const char *progname)
     1.4      errx(1, "Usage: %s [-h] [-p] [-s] key [...]", progname);
     1.5  #elif defined(CLIENT_write)
     1.6      errx(1, "Usage: %s [-h] [-s] key value [...]", progname);
     1.7 -#elif defined(CLIENT_rm) || defined(CLIENT_exists) || defined(CLIENT_list)
     1.8 +#elif defined(CLIENT_rm)
     1.9 +    errx(1, "Usage: %s [-h] [-s] [-t] key [...]", progname);
    1.10 +#elif defined(CLIENT_exists) || defined(CLIENT_list)
    1.11      errx(1, "Usage: %s [-h] [-s] key [...]", progname);
    1.12  #endif
    1.13  }
    1.14  
    1.15  
    1.16 +#if defined(CLIENT_rm)
    1.17 +static int
    1.18 +do_rm(char * path, struct xs_handle *xsh, struct xs_transaction_handle *xth)
    1.19 +{
    1.20 +    if (xs_rm(xsh, xth, path)) {
    1.21 +        return 0;
    1.22 +    }
    1.23 +    else {
    1.24 +        warnx("could not remove path %s", path);
    1.25 +        return 1;
    1.26 +    }
    1.27 +}
    1.28 +#endif
    1.29 +
    1.30 +
    1.31  static int
    1.32  perform(int optind, int argc, char **argv, struct xs_handle *xsh,
    1.33 -        struct xs_transaction_handle *xth, int prefix)
    1.34 +        struct xs_transaction_handle *xth, int prefix, int tidy)
    1.35  {
    1.36      while (optind < argc) {
    1.37  #if defined(CLIENT_read)
    1.38 @@ -54,10 +71,49 @@ perform(int optind, int argc, char **arg
    1.39  	}
    1.40  	optind += 2;
    1.41  #elif defined(CLIENT_rm)
    1.42 -	if (!xs_rm(xsh, xth, argv[optind])) {
    1.43 -	    warnx("could not remove path %s", argv[optind]);
    1.44 -	    return 1;
    1.45 -	}
    1.46 +        /* Remove the specified path.  If the tidy flag is set, then also
    1.47 +           remove any containing directories that are both empty and have no
    1.48 +           value attached, and repeat, recursing all the way up to the root if
    1.49 +           necessary.
    1.50 +        */
    1.51 +
    1.52 +        char *path = argv[optind];
    1.53 +
    1.54 +        if (tidy) {
    1.55 +            /* Copy path, because we can't modify argv because we will need it
    1.56 +               again if xs_transaction_end gives us EAGAIN. */
    1.57 +            char *p = malloc(strlen(path) + 1);
    1.58 +            strcpy(p, path);
    1.59 +            path = p;
    1.60 +
    1.61 +        again:
    1.62 +            if (do_rm(path, xsh, xth)) {
    1.63 +                return 1;
    1.64 +            }
    1.65 +
    1.66 +            char *slash = strrchr(p, '/');
    1.67 +            if (slash) {
    1.68 +                char *val;
    1.69 +                *slash = '\0';
    1.70 +                val = xs_read(xsh, xth, p, NULL);
    1.71 +                if (val && strlen(val) == 0) {
    1.72 +                    unsigned int num;
    1.73 +                    char ** list = xs_directory(xsh, xth, p, &num);
    1.74 +
    1.75 +                    if (list && num == 0) {
    1.76 +                        goto again;
    1.77 +                    }
    1.78 +                }
    1.79 +            }
    1.80 +
    1.81 +            free(path);
    1.82 +        }
    1.83 +        else {
    1.84 +            if (do_rm(path, xsh, xth)) {
    1.85 +                return 1;
    1.86 +            }
    1.87 +        }
    1.88 +
    1.89  	optind++;
    1.90  #elif defined(CLIENT_exists)
    1.91  	char *val = xs_read(xsh, xth, argv[optind], NULL);
    1.92 @@ -94,21 +150,26 @@ main(int argc, char **argv)
    1.93      struct xs_transaction_handle *xth;
    1.94      int ret = 0, socket = 0;
    1.95      int prefix = 0;
    1.96 +    int tidy = 0;
    1.97  
    1.98      while (1) {
    1.99  	int c, index = 0;
   1.100  	static struct option long_options[] = {
   1.101  	    {"help", 0, 0, 'h'},
   1.102 +            {"socket", 0, 0, 's'},
   1.103  #if defined(CLIENT_read) || defined(CLIENT_list)
   1.104  	    {"prefix", 0, 0, 'p'},
   1.105 +#elif defined(CLIENT_rm)
   1.106 +            {"tidy",   0, 0, 't'},
   1.107  #endif
   1.108 -            {"socket", 0, 0, 's'},
   1.109  	    {0, 0, 0, 0}
   1.110  	};
   1.111  
   1.112  	c = getopt_long(argc, argv, "hs"
   1.113  #if defined(CLIENT_read) || defined(CLIENT_list)
   1.114  			"p"
   1.115 +#elif defined(CLIENT_rm)
   1.116 +                        "t"
   1.117  #endif
   1.118  			, long_options, &index);
   1.119  	if (c == -1)
   1.120 @@ -125,6 +186,10 @@ main(int argc, char **argv)
   1.121  	case 'p':
   1.122  	    prefix = 1;
   1.123  	    break;
   1.124 +#elif defined(CLIENT_rm)
   1.125 +	case 't':
   1.126 +	    tidy = 1;
   1.127 +	    break;
   1.128  #endif
   1.129  	}
   1.130      }
   1.131 @@ -149,7 +214,7 @@ main(int argc, char **argv)
   1.132      if (xth == NULL)
   1.133  	errx(1, "couldn't start transaction");
   1.134  
   1.135 -    ret = perform(optind, argc, argv, xsh, xth, prefix);
   1.136 +    ret = perform(optind, argc, argv, xsh, xth, prefix, tidy);
   1.137  
   1.138      if (!xs_transaction_end(xsh, xth, ret)) {
   1.139  	if (ret == 0 && errno == EAGAIN)