diff options
author | NeilBrown <neilb@suse.de> | 2012-10-04 08:34:20 +0200 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-10-04 08:34:20 +0200 |
commit | 7103b9b88d8c27989e17c80d7296eda97370dc1e (patch) | |
tree | 225ef68ca743ca2bdf6e70a7581ac82aebfa29db | |
parent | imsm: Allow to specify controller for --detail-platform. (diff) | |
download | mdadm-7103b9b88d8c27989e17c80d7296eda97370dc1e.tar.xz mdadm-7103b9b88d8c27989e17c80d7296eda97370dc1e.zip |
Handles spaces in array names better.
1/ When printing the "name=" entry for --brief output,
enclose name in quotes if it contains spaces etc.
Quotes are already supported for reading mdadm.conf
2/ When a name is used as a device name, translate spaces
and tabs to '_', as well as the current translation of
'/' to '-'.
Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r-- | Detail.c | 14 | ||||
-rw-r--r-- | lib.c | 68 | ||||
-rw-r--r-- | mapfile.c | 2 | ||||
-rw-r--r-- | mdadm.h | 2 | ||||
-rw-r--r-- | mdopen.c | 13 | ||||
-rw-r--r-- | super1.c | 19 |
6 files changed, 106 insertions, 12 deletions
@@ -206,8 +206,11 @@ int Detail(char *dev, struct context *c) printf("MD_UUID=%s\n", nbuf+5); mp = map_by_uuid(&map, info->uuid); if (mp && mp->path && - strncmp(mp->path, "/dev/md/", 8) == 0) - printf("MD_DEVNAME=%s\n", mp->path+8); + strncmp(mp->path, "/dev/md/", 8) == 0) { + printf("MD_DEVNAME="); + print_escape(mp->path+8); + putchar('\n'); + } if (st->ss->export_detail_super) st->ss->export_detail_super(st); @@ -220,8 +223,11 @@ int Detail(char *dev, struct context *c) printf("MD_UUID=%s\n", nbuf+5); } if (mp && mp->path && - strncmp(mp->path, "/dev/md/", 8) == 0) - printf("MD_DEVNAME=%s\n", mp->path+8); + strncmp(mp->path, "/dev/md/", 8) == 0) { + printf("MD_DEVNAME="); + print_escape(mp->path+8); + putchar('\n'); + } } goto out; } @@ -322,3 +322,71 @@ char *conf_word(FILE *file, int allow_key) } return word; } + +void print_quoted(char *str) +{ + /* Printf the string with surrounding quotes + * iff needed. + * If no space, tab, or quote - leave unchanged. + * Else print surrounded by " or ', swapping quotes + * when we find one that will cause confusion. + */ + + char first_quote = 0, q; + char *c; + + for (c = str; *c; c++) { + switch(*c) { + case '\'': + case '"': + first_quote = *c; + break; + case ' ': + case '\t': + first_quote = *c; + continue; + default: + continue; + } + break; + } + if (!first_quote) { + printf("%s", str); + return; + } + + if (first_quote == '"') + q = '\''; + else + q = '"'; + putchar(q); + for (c = str; *c; c++) { + if (*c == q) { + putchar(q); + q ^= '"' ^ '\''; + putchar(q); + } + putchar(*c); + } + putchar(q); +} + +void print_escape(char *str) +{ + /* print str, but change space and tab to '_' + * as is suitable for device names + */ + for (; *str ; str++) { + switch (*str) { + case ' ': + case '\t': + putchar('_'); + break; + case '/': + putchar('-'); + break; + default: + putchar(*str); + } + } +} @@ -422,7 +422,7 @@ void RebuildMap(void) * an MD_DEVNAME for udev. * The name needs to be unique both in /dev/md/ * and in this mapfile. - * It needs to match watch -I or -As would come + * It needs to match what -I or -As would come * up with. * That means: * Check if array is in mdadm.conf @@ -1196,6 +1196,8 @@ extern char *conf_get_program(void); extern char *conf_get_homehost(int *require_homehostp); extern char *conf_line(FILE *file); extern char *conf_word(FILE *file, int allow_key); +extern void print_quoted(char *str); +extern void print_escape(char *str); extern int conf_name_is_free(char *name); extern int conf_verify_devnames(struct mddev_ident *array_list); extern int devname_matches(char *name, char *match); @@ -286,8 +286,17 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, int cnlen; strncpy(cname, name, 200); cname[200] = 0; - while ((cp = strchr(cname, '/')) != NULL) - *cp = '-'; + for (cp = cname; *cp ; cp++) + switch (*cp) { + case '/': + *cp = '-'; + break; + case ' ': + case '\t': + *cp = '_'; + break; + } + if (trustworthy == LOCAL || (trustworthy == FOREIGN && strchr(cname, ':') != NULL)) { /* Only need suffix if there is a conflict */ @@ -485,7 +485,12 @@ static void brief_examine_super1(struct supertype *st, int verbose) else nm = NULL; - printf("ARRAY%s%s", nm ? " /dev/md/":"", nm); + printf("ARRAY "); + if (nm) { + printf("/dev/md/"); + print_escape(nm); + putchar(' '); + } if (verbose && c) printf(" level=%s", c); sb_offset = __le64_to_cpu(sb->super_offset); @@ -502,8 +507,10 @@ static void brief_examine_super1(struct supertype *st, int verbose) if ((i&3)==0 && i != 0) printf(":"); printf("%02x", sb->set_uuid[i]); } - if (sb->set_name[0]) - printf(" name=%.32s", sb->set_name); + if (sb->set_name[0]) { + printf(" name="); + print_quoted(sb->set_name); + } printf("\n"); } @@ -584,8 +591,10 @@ static void brief_detail_super1(struct supertype *st) struct mdp_superblock_1 *sb = st->sb; int i; - if (sb->set_name[0]) - printf(" name=%.32s", sb->set_name); + if (sb->set_name[0]) { + printf(" name="); + print_quoted(sb->set_name); + } printf(" UUID="); for (i=0; i<16; i++) { if ((i&3)==0 && i != 0) printf(":"); |