summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Assemble.c7
-rw-r--r--Incremental.c9
-rw-r--r--config.c65
-rw-r--r--mdadm.conf.535
-rw-r--r--mdadm.h1
-rw-r--r--super1.c2
6 files changed, 116 insertions, 3 deletions
diff --git a/Assemble.c b/Assemble.c
index 47b8839..4966a79 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -263,6 +263,13 @@ int Assemble(struct supertype *st, char *mddev,
fprintf(stderr, Name ": no recogniseable superblock on %s\n",
devname);
tmpdev->used = 2;
+ } else if (auto_assem && st == NULL &&
+ !conf_test_metadata(tst->ss->name)) {
+ if (report_missmatch)
+ fprintf(stderr, Name ": %s has metadata type %s for which "
+ "auto-assembly is disabled\n",
+ devname, tst->ss->name);
+ tmpdev->used = 2;
} else if (tst->ss->load_super(tst,dfd, NULL)) {
if (report_missmatch)
fprintf( stderr, Name ": no RAID superblock on %s\n",
diff --git a/Incremental.c b/Incremental.c
index 5849d39..7d6de98 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -220,6 +220,15 @@ int Incremental(char *devname, int verbose, int runstop,
return 1;
}
+ if (!match && !conf_test_metadata(st->ss->name)) {
+ if (verbose >= 1)
+ fprintf(stderr, Name
+ ": %s has metadata type %s for which "
+ "auto-assembly is disabled\n",
+ devname, st->ss->name);
+ return 1;
+ }
+
/* 3a/ if not, check for homehost match. If no match, continue
* but don't trust the 'name' in the array. Thus a 'random' minor
* number will be assigned, and the device name will be based
diff --git a/config.c b/config.c
index 66c3964..0d5b3f9 100644
--- a/config.c
+++ b/config.c
@@ -56,7 +56,7 @@
* with a key word, and not be indented, or must start with a
* non-key-word and must be indented.
*
- * Keywords are DEVICE and ARRAY
+ * Keywords are DEVICE and ARRAY ... and several others.
* DEV{ICE} introduces some devices that might contain raid components.
* e.g.
* DEV style=0 /dev/sda* /dev/hd*
@@ -79,7 +79,8 @@
char DefaultConfFile[] = CONFFILE;
char DefaultAltConfFile[] = CONFFILE2;
-enum linetype { Devices, Array, Mailaddr, Mailfrom, Program, CreateDev, Homehost, LTEnd };
+enum linetype { Devices, Array, Mailaddr, Mailfrom, Program, CreateDev,
+ Homehost, AutoMode, LTEnd };
char *keywords[] = {
[Devices] = "devices",
[Array] = "array",
@@ -88,6 +89,7 @@ char *keywords[] = {
[Program] = "program",
[CreateDev]= "create",
[Homehost] = "homehost",
+ [AutoMode] = "auto",
[LTEnd] = NULL
};
@@ -639,6 +641,16 @@ void homehostline(char *line)
}
}
+static char *auto_options = NULL;
+void autoline(char *line)
+{
+ if (auto_options) {
+ fprintf(stderr, Name ": AUTO line may only be give once."
+ " Subsequent lines ignored\n");
+ return;
+ }
+ auto_options = line;
+}
int loaded = 0;
@@ -709,6 +721,9 @@ void load_conffile(void)
case Homehost:
homehostline(line);
break;
+ case AutoMode:
+ autoline(line);
+ break;
default:
fprintf(stderr, Name ": Unknown keyword %s\n", line);
}
@@ -832,6 +847,52 @@ int conf_test_dev(char *devname)
return 0;
}
+int conf_test_metadata(const char *version)
+{
+ /* Check if the given metadata version is allowed
+ * to be auto-assembled.
+ * The default is 'yes' but the 'auto' line might over-ride that.
+ * Word in auto_options are processed in order with the first
+ * match winning.
+ * word can be:
+ * +version - that version can be assembled
+ * -version - that version cannot be auto-assembled
+ * yes or +all - any other version can be assembled
+ * no or -all - no other version can be assembled.
+ */
+ char *w;
+ load_conffile();
+ if (!auto_options)
+ return 1;
+ for (w = dl_next(auto_options); w != auto_options; w = dl_next(w)) {
+ int rv;
+ if (strcasecmp(w, "yes") == 0)
+ return 1;
+ if (strcasecmp(w, "no") == 0)
+ return 0;
+ if (w[0] == '+')
+ rv = 1;
+ else if (w[0] == '-')
+ rv = 0;
+ else continue;
+
+ if (strcasecmp(w+1, "all") == 0)
+ return rv;
+ if (strcasecmp(w+1, version) == 0)
+ return rv;
+ /* allow '0' to match version '0.90'
+ * and 1 or 1.whatever to match version '1.x'
+ */
+ if (version[1] == '.' &&
+ strlen(w+1) == 1 &&
+ w[1] == version[0])
+ return rv;
+ if (version[1] == '.' && version[2] == 'x' &&
+ strncmp(w+1, version, 2) == 0)
+ return rv;
+ }
+ return 1;
+}
int match_oneof(char *devices, char *devname)
{
diff --git a/mdadm.conf.5 b/mdadm.conf.5
index 7654f5f..f69c0b0 100644
--- a/mdadm.conf.5
+++ b/mdadm.conf.5
@@ -339,6 +339,39 @@ When arrays are created, this host name will be stored in the
metadata. When arrays are assembled using auto-assembly, only arrays
with this host name stored in the metadata will be considered.
+.TP
+.B AUTO
+A list of names of metadata format can be given, each preceded by a
+plus or minus sign. Also the word
+.I all
+preceded by plus or minus is allowed and is usually last.
+
+When
+.I mdadm
+is auto-assembling an array, with via
+.I --assemble
+or
+.I --incremental
+and it finds metadata of a given type, it checks that metadata type
+against those listed in this line. The first match wins, where
+.I all
+matches anything.
+If a match is found that was preceded by a plus sign, the auto
+assembly is allowed. If the match was preceded by a minus sign, the
+auto assembly is disallowed. If no match is found, the auto assembly
+is allowed.
+
+This can be used to disable all auto-assembly (so that only arrays
+explicitly listed in mdadm.conf or on the command line are assembled),
+or to disable assembly of certain metadata types which might be
+handled by other software.
+
+The known metadata types are
+.BR 0.90 ,
+.BR 1.x ,
+.BR ddf ,
+.BR imsm .
+
.SH EXAMPLE
DEVICE /dev/sd[bcdjkl]1
.br
@@ -385,6 +418,8 @@ PROGRAM /usr/sbin/handle\-mdadm\-events
CREATE group=system mode=0640 auto=part\-8
.br
HOMEHOST <system>
+.br
+AUTO +1.x -all
.SH SEE ALSO
.BR mdadm (8),
diff --git a/mdadm.h b/mdadm.h
index 251f9a1..1f47be3 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -789,6 +789,7 @@ extern int parse_auto(char *str, char *msg, int config);
extern mddev_ident_t conf_get_ident(char *dev);
extern mddev_dev_t conf_get_devs(void);
extern int conf_test_dev(char *devname);
+extern int conf_test_metadata(const char *version);
extern struct createinfo *conf_get_create_info(void);
extern void set_conffile(char *file);
extern char *conf_get_mailaddr(void);
diff --git a/super1.c b/super1.c
index d1b8a94..679120f 100644
--- a/super1.c
+++ b/super1.c
@@ -1652,5 +1652,5 @@ struct superswitch super1 = {
#else
.swapuuid = 1,
#endif
- .name = "1.0",
+ .name = "1.x",
};