diff --git a/Assemble.c b/Assemble.c index c079f6b..2c52f07 100644 --- a/Assemble.c +++ b/Assemble.c @@ -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) { diff --git a/Incremental.c b/Incremental.c index 8908eec..c5ec634 100644 --- a/Incremental.c +++ b/Incremental.c @@ -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 diff --git a/config.c b/config.c index 41428ae..284896e 100644 --- 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, "")==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 04fea60..58270fa 100644 --- 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 3245f0f..74d230e 100644 --- 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, "") == 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, "")==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(); diff --git a/mdadm.conf.5 b/mdadm.conf.5 index 9876d27..7ef1765 100644 --- a/mdadm.conf.5 +++ b/mdadm.conf.5 @@ -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 -or a host name. +and +.BR . If .B 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 +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 d9bb4c9..645cf58 100644 --- 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); diff --git a/mdassemble.c b/mdassemble.c index e2baf05..45ff9c5 100644 --- a/mdassemble.c +++ b/mdassemble.c @@ -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; }