]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Allow homehost to be largely ignored when assembling arrays.
authorNeilBrown <neilb@suse.de>
Mon, 11 May 2009 05:46:46 +0000 (15:46 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 11 May 2009 05:46:46 +0000 (15:46 +1000)
If mdadm.conf contains
   HOMEHOST <ignore>
or commandline contains
   --homehost=<ignore>

then the check that array metadata mentions the given homehost is
replace by a check that the name recorded in the metadata is not
already used by some other array mentioned in mdadm.conf.

This allows more arrays to use their native name rather than having
an _NN suffix added.

This should only be used during boot time if all arrays required for
normal boot are listed in mdadm.conf.

If auto-assembly is used to find all array during boot, then the
HOMEHOST feature should be used to ensure there is no room for
confusion in choosing array names, and so it should not be set
to <ignore>.

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

index c079f6b34f4562abdee5621b611ca6b10f1be7ab..2c52f074dd540ea0fbdda9f3cdae35769cd322d6 100644 (file)
@@ -79,7 +79,7 @@ int Assemble(struct supertype *st, char *mddev,
             mddev_ident_t ident,
             mddev_dev_t devlist, char *backup_file,
             int readonly, int runstop,
-            char *update, char *homehost,
+            char *update, char *homehost, int require_homehost,
             int verbose, int force)
 {
        /*
@@ -509,6 +509,12 @@ int Assemble(struct supertype *st, char *mddev,
                name = content->text_version;
                trustworthy = METADATA;
        }
+
+       if (name[0] && trustworthy != LOCAL &&
+           ! require_homehost &&
+           conf_name_is_free(name))
+               trustworthy = LOCAL;
+
        mdfd = create_mddev(mddev, name, ident->autof, trustworthy,
                            chosen_name);
        if (mdfd < 0) {
index 8908eeced7efc8fb329000344f34821777905f79..c5ec6340e0efe5c9a4ae865ebee27de1a379eea8 100644 (file)
@@ -37,7 +37,8 @@ static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
                        char *array_name);
 
 int Incremental(char *devname, int verbose, int runstop,
-               struct supertype *st, char *homehost, int autof)
+               struct supertype *st, char *homehost, int require_homehost,
+               int autof)
 {
        /* Add this device to an array, creating the array if necessary
         * and starting the array if sensible or - if runstop>0 - if possible.
@@ -265,12 +266,16 @@ int Incremental(char *devname, int verbose, int runstop,
        else
                name_to_use = info.name;
 
-       if ((!name_to_use || name_to_use[0] == 0) &&
+       if (name_to_use[0] == 0 &&
            info.array.level == LEVEL_CONTAINER &&
            trustworthy == LOCAL) {
                name_to_use = info.text_version;
                trustworthy = METADATA;
        }
+       if (name_to_use[0] && trustworthy != LOCAL &&
+           ! require_homehost &&
+           conf_name_is_free(name_to_use))
+               trustworthy = LOCAL;
 
        /* 4/ Check if array exists.
         */
@@ -424,7 +429,7 @@ int Incremental(char *devname, int verbose, int runstop,
                if (runstop < 0)
                        return 0; /* don't try to assemble */
                rv = Incremental(chosen_name, verbose, runstop,
-                                NULL, homehost, autof);
+                                NULL, homehost, require_homehost, autof);
                if (rv == 1)
                        /* Don't fail the whole -I if a subarray didn't
                         * have enough devices to start yet
index 41428ae9f21a625a35508461b08f059562eff846..284896ed121190524247fb0c95cb89865ae0afb2 100644 (file)
--- a/config.c
+++ b/config.c
@@ -663,12 +663,15 @@ void programline(char *line)
 }
 
 static char *home_host = NULL;
+static int require_homehost = 1;
 void homehostline(char *line)
 {
        char *w;
 
        for (w=dl_next(line); w != line ; w=dl_next(w)) {
-               if (home_host == NULL)
+               if (strcasecmp(w, "<ignore>")==0)
+                       require_homehost = 0;
+               else if (home_host == NULL)
                        home_host = strdup(w);
                else
                        fprintf(stderr, Name ": excess host name on HOMEHOST line: %s - ignored\n",
@@ -788,9 +791,11 @@ char *conf_get_program(void)
        return alert_program;
 }
 
-char *conf_get_homehost(void)
+char *conf_get_homehost(int *require_homehostp)
 {
        load_conffile();
+       if (require_homehostp)
+               *require_homehostp = require_homehost;
        return home_host;
 }
 
@@ -953,3 +958,58 @@ int match_oneof(char *devices, char *devname)
     }
     return 0;
 }
+
+int devname_matches(char *name, char *match)
+{
+       /* See if the given array name matches the
+        * given match from config file.
+        *
+        * First strip and /dev/md/ or /dev/, then
+        * see if there might be a numeric match of
+        *  mdNN with NN
+        * then just strcmp
+        */
+       if (strncmp(name, "/dev/md/", 8) == 0)
+               name += 8;
+       else if (strncmp(name, "/dev/", 5) == 0)
+               name += 5;
+
+       if (strncmp(match, "/dev/md/", 8) == 0)
+               match += 8;
+       else if (strncmp(match, "/dev/", 5) == 0)
+               match += 5;
+
+
+       if (strncmp(name, "md", 2) == 0 &&
+           isdigit(name[2]))
+               name += 2;
+       if (strncmp(match, "md", 2) == 0 &&
+           isdigit(match[2]))
+               match += 2;
+
+       return (strcmp(name, match) == 0);
+}
+
+int conf_name_is_free(char *name)
+{
+       /* Check if this name is already take by an ARRAY entry in
+        * the config file.
+        * It can be taken either by a match on devname, name, or
+        * even super-minor.
+        */
+       mddev_ident_t dev;
+
+       load_conffile();
+       for (dev = mddevlist; dev; dev = dev->next) {
+               char nbuf[100];
+               if (dev->devname && devname_matches(name, dev->devname))
+                       return 0;
+               if (dev->name[0] && devname_matches(name, dev->name))
+                       return 0;
+               sprintf(nbuf, "%d", dev->super_minor);
+               if (dev->super_minor != UnSet &&
+                   devname_matches(name, nbuf))
+                       return 0;
+       }
+       return 1;
+}
diff --git a/mdadm.8 b/mdadm.8
index 04fea60dddf84f958482a352d46b59ee362a1df1..58270fa6608df23266f809da190bf59aa42d4fdc 100644 (file)
--- a/mdadm.8
+++ b/mdadm.8
@@ -357,7 +357,8 @@ When reporting information about an array, any array which is tagged
 for the given homehost will be reported as such.
 
 When using Auto-Assemble, only arrays tagged for the given homehost
-will be assembled.
+will be allowed to use 'local' names (i.e. not ending in '_' followed
+by a digit string).
 
 .SH For create, build, or grow:
 
diff --git a/mdadm.c b/mdadm.c
index 3245f0f7483ae722d162f026aa0709663e5fb800..74d230e392b0d97397d43c13a2253df5de3df73c 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -91,6 +91,7 @@ int main(int argc, char *argv[])
 
        char *homehost = NULL;
        char sys_hostname[256];
+       int require_homehost = 1;
        char *mailaddr = NULL;
        char *program = NULL;
        int delay = 0;
@@ -166,7 +167,10 @@ int main(int argc, char *argv[])
                        continue;
 
                case HomeHost:
-                       homehost = optarg;
+                       if (strcasecmp(optarg, "<ignore>") == 0)
+                               require_homehost = 0;
+                       else
+                               homehost = optarg;
                        continue;
 
                case ':':
@@ -1009,7 +1013,7 @@ int main(int argc, char *argv[])
        }
 
        if (homehost == NULL)
-               homehost = conf_get_homehost();
+               homehost = conf_get_homehost(&require_homehost);
        if (homehost == NULL || strcmp(homehost, "<system>")==0) {
                if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
                        sys_hostname[sizeof(sys_hostname)-1] = 0;
@@ -1049,12 +1053,16 @@ int main(int argc, char *argv[])
                                        array_ident->autof = autof;
                                rv |= Assemble(ss, devlist->devname, array_ident,
                                               NULL, backup_file,
-                                              readonly, runstop, update, homehost, verbose-quiet, force);
+                                              readonly, runstop, update,
+                                              homehost, require_homehost,
+                                              verbose-quiet, force);
                        }
                } else if (!scan)
                        rv = Assemble(ss, devlist->devname, &ident,
                                      devlist->next, backup_file,
-                                     readonly, runstop, update, homehost, verbose-quiet, force);
+                                     readonly, runstop, update,
+                                     homehost, require_homehost,
+                                     verbose-quiet, force);
                else if (devs_found>0) {
                        if (update && devs_found > 1) {
                                fprintf(stderr, Name ": can only update a single array at a time\n");
@@ -1076,7 +1084,9 @@ int main(int argc, char *argv[])
                                        array_ident->autof = autof;
                                rv |= Assemble(ss, dv->devname, array_ident,
                                               NULL, backup_file,
-                                              readonly, runstop, update, homehost, verbose-quiet, force);
+                                              readonly, runstop, update,
+                                              homehost, require_homehost,
+                                              verbose-quiet, force);
                        }
                } else {
                        mddev_ident_t array_list =  conf_get_ident(NULL);
@@ -1104,7 +1114,9 @@ int main(int argc, char *argv[])
                                rv |= Assemble(ss, array_list->devname,
                                               array_list,
                                               NULL, NULL,
-                                              readonly, runstop, NULL, homehost, verbose-quiet, force);
+                                              readonly, runstop, NULL,
+                                              homehost, require_homehost,
+                                              verbose-quiet, force);
                                cnt++;
                        }
                        if (homehost && cnt == 0) {
@@ -1122,7 +1134,9 @@ int main(int argc, char *argv[])
                                                rv2 = Assemble(ss, NULL,
                                                               &ident,
                                                               devlist, NULL,
-                                                              readonly, runstop, NULL, homehost, verbose-quiet, force);
+                                                              readonly, runstop, NULL,
+                                                              homehost, require_homehost,
+                                                              verbose-quiet, force);
                                                if (rv2==0) {
                                                        cnt++;
                                                        acnt++;
@@ -1143,7 +1157,9 @@ int main(int argc, char *argv[])
                                                        rv2 = Assemble(ss, NULL,
                                                                       &ident,
                                                                       NULL, NULL,
-                                                                      readonly, runstop, "homehost", homehost, verbose-quiet, force);
+                                                                      readonly, runstop, "homehost",
+                                                                      homehost, require_homehost,
+                                                                      verbose-quiet, force);
                                                        if (rv2==0) {
                                                                cnt++;
                                                                acnt++;
@@ -1410,7 +1426,7 @@ int main(int argc, char *argv[])
                        break;
                }
                rv = Incremental(devlist->devname, verbose-quiet, runstop,
-                                ss, homehost, autof);
+                                ss, homehost, require_homehost, autof);
                break;
        case AUTODETECT:
                autodetect();
index 9876d279dc38af4f852494264c0e84a70b3b8d84..7ef1765a840b63e4ee11a9921a497f325aaaebf5 100644 (file)
@@ -333,18 +333,32 @@ The
 line gives a default value for the
 .B --homehost=
 option to mdadm.  There should be exactly one other word on the line.
-It should either exactly
+It should either be a host name, or one of the special words
 .B <system>
-or a host name.
+and
+.BR <ignore> .
 If
 .B <system>
 is given, then the
 .BR gethostname ( 2 )
 systemcall is used to get the host name.
-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.
 
+If
+.B <ignore>
+is given, then a flag is set so that when arrays are being
+auto-assemble the checking of the recorded
+.I homehost
+is disabled.
+
+When arrays are created, this host name will be stored in the
+metadata.  When arrays are assembled using auto-assembly, arrays which
+do not record the correct homehost name in their metadata will be
+assembled using a 'foreign' name.  A 'foreign' name alway ends with a
+digit string (possibly preceded by an underscore) to differentiate it
+from any possible local name. e.g.
+.B /dev/md/1_1
+or
+.BR /dev/md/home0 .
 .TP
 .B AUTO
 A list of names of metadata format can be given, each preceded by a
diff --git a/mdadm.h b/mdadm.h
index d9bb4c9c0052eb365e7193db59a6cea285676eeb..645cf589c2a36a6ddf516ac80037cc7c6bfb9a8e 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -724,7 +724,7 @@ extern int Assemble(struct supertype *st, char *mddev,
                    mddev_ident_t ident,
                    mddev_dev_t devlist, char *backup_file,
                    int readonly, int runstop,
-                   char *update, char *homehost,
+                   char *update, char *homehost, int require_homehost,
                    int verbose, int force);
 
 extern int Build(char *mddev, int chunk, int level, int layout,
@@ -755,7 +755,8 @@ extern int Wait(char *dev);
 extern int WaitClean(char *dev, int verbose);
 
 extern int Incremental(char *devname, int verbose, int runstop,
-                      struct supertype *st, char *homehost, int autof);
+                      struct supertype *st, char *homehost, int require_homehost,
+                      int autof);
 extern int Incremental_container(struct supertype *st, char *devname,
                                 int verbose, int runstop, int autof,
                                 int trustworthy);
@@ -795,9 +796,12 @@ extern void set_conffile(char *file);
 extern char *conf_get_mailaddr(void);
 extern char *conf_get_mailfrom(void);
 extern char *conf_get_program(void);
-extern char *conf_get_homehost(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 int conf_name_is_free(char *name);
+extern int devname_matches(char *name, char *match);
+
 extern void free_line(char *line);
 extern int match_oneof(char *devices, char *devname);
 extern void uuid_from_super(int uuid[4], mdp_super_t *super);
index e2baf055b558e00881b4be83e3aa467879be1a12..45ff9c57526af875f7048366a0edda2b1a3debb2 100644 (file)
@@ -111,7 +111,8 @@ int main(int argc, char *argv[]) {
                                close(mdfd);
                        rv |= Assemble(array_list->st, array_list->devname,
                                       array_list, NULL, NULL,
-                                      readonly, runstop, NULL, NULL, verbose, force);
+                                      readonly, runstop, NULL, NULL, 0,
+                                      verbose, force);
                }
        return rv;
 }