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>
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)