]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Handles spaces in array names better.
authorNeilBrown <neilb@suse.de>
Thu, 4 Oct 2012 06:34:20 +0000 (16:34 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 4 Oct 2012 06:34:20 +0000 (16:34 +1000)
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>
Detail.c
lib.c
mapfile.c
mdadm.h
mdopen.c
super1.c

index 9bf2061895d1c4f68ab2b3ef74032ddde9c19a23..8ca3a962f8e87c26520ee3c3fd44dc5b7ccc4fd2 100644 (file)
--- a/Detail.c
+++ b/Detail.c
@@ -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;
        }
diff --git a/lib.c b/lib.c
index 082cff56a190d8fa1893087bc35b192d8f0bce6d..dc32c561faa9b9b63978981195ee35bc6ef684c3 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -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);
+               }
+       }
+}
index 6712733ffa651030ace480e50f4b908c106b3838..34ebdb54f7ee567e112d3346587ce4a7c2745b47 100644 (file)
--- a/mapfile.c
+++ b/mapfile.c
@@ -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 
diff --git a/mdadm.h b/mdadm.h
index 1390be8dcec1e43b575e0e3cf6e3b41716cc6262..6980bfb8195e9e014ccb62464f86c227bd1a9360 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -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);
index 58e359aa01b7c64d82e38155219c51f7d56a3bda..61eda8120a3b670e4d628fa0aad6e3ffc20eaddf 100644 (file)
--- a/mdopen.c
+++ b/mdopen.c
@@ -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 */
index 3ace6fc797a1fc6a1f88b866ec2a1dfa333fdfe9..96d5b1b016a67715310f05c8e3cc81b1a9eb55d6 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -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(":");