summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-10-04 16:34:20 +1000
committerNeilBrown <neilb@suse.de>2012-10-18 15:38:55 +1100
commit5267ba06c27178ae641b0700526405791883bdcb (patch)
treea36077d6da3e3cdd7e098a297d8fefac81113b03
parent6f6809f609879bf18b24d3ed8b0e69686f942d20 (diff)
downloadmdadm-5267ba06c27178ae641b0700526405791883bdcb.tar.gz
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.c14
-rw-r--r--lib.c68
-rw-r--r--mapfile.c2
-rw-r--r--mdadm.h2
-rw-r--r--mdopen.c13
-rw-r--r--super1.c19
6 files changed, 106 insertions, 12 deletions
diff --git a/Detail.c b/Detail.c
index 67ddc80..07a00cb 100644
--- a/Detail.c
+++ b/Detail.c
@@ -206,8 +206,11 @@ int Detail(char *dev, int brief, int export, int test, char *homehost, char *pre
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, int brief, int export, int test, char *homehost, char *pre
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 c04f6a0..85513d7 100644
--- a/lib.c
+++ b/lib.c
@@ -325,3 +325,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);
+ }
+ }
+}
diff --git a/mapfile.c b/mapfile.c
index d416408..f549d4c 100644
--- 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 4cf34ab..216c31d 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1156,6 +1156,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);
diff --git a/mdopen.c b/mdopen.c
index fdae7f3..4ef9308 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -289,8 +289,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 */
diff --git a/super1.c b/super1.c
index fbc2e8f..63b5c17 100644
--- a/super1.c
+++ b/super1.c
@@ -468,7 +468,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);
@@ -485,8 +490,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");
}
@@ -548,8 +555,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(":");