]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
conf/assemble: new config line "auto".
authorNeilBrown <neilb@suse.de>
Mon, 11 May 2009 05:17:33 +0000 (15:17 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 11 May 2009 05:17:33 +0000 (15:17 +1000)
The line 'auto' in mdadm.conf can be used to disable assembly
of specific metadata types, or of all arrays.

This does not affect assembly of arrays listed in mdadm.conf
or on command line.

 auto -all

will disable all auto-assembly.

 auto -ddf

will cause mdadm to ignore ddf arrays that are not explicitly
mentioned, and auto assemble anything else it finds.

Signed-off-by: NeilBrown <neilb@suse.de>
Assemble.c
Incremental.c
config.c
mdadm.conf.5
mdadm.h
super1.c

index 47b8839e4835df1cf7461df07f6641e9ce577c3c..4966a79822045b19331497952f9f1ad37259e9dc 100644 (file)
@@ -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",
index 5849d39aa4d9e03ae4d1def8e8d17669464b1be5..7d6de981427663bf96574ca848f301dadce6e1d3 100644 (file)
@@ -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
index 66c3964ff3e7c579d6f9eba5e33b3b04dfbbe83d..0d5b3f9aac7a929e523224ef241ebdbf858cde67 100644 (file)
--- 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)
 {
index 7654f5f95b3e16567f79033df304e4b667071c06..f69c0b0f700d4b42b51b75670682c95f61a57cd9 100644 (file)
@@ -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 251f9a130436e3e360d9d436829c79167d774b8c..1f47be361d621c9a86f4c7ef93d5c1a71cb3041c 100644 (file)
--- 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);
index d1b8a9478ef86da4375177c59312c3c3ef19dbf6..679120ff3c9b3b1ad2177f27f9c6bb0a3f0df712 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -1652,5 +1652,5 @@ struct superswitch super1 = {
 #else
        .swapuuid = 1,
 #endif
-       .name = "1.0",
+       .name = "1.x",
 };