summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-05-11 15:46:46 +1000
committerNeilBrown <neilb@suse.de>2009-05-11 15:46:46 +1000
commit0ac91628b93b31636979b637c1ac7258064dea4e (patch)
tree88971a9e037c1519a8db205e8d6d1338ddfe8131
parent603f24a05f48063a7239e323e2aeab497cb0feb6 (diff)
downloadmdadm-0ac91628b93b31636979b637c1ac7258064dea4e.tar.gz
mdadm-0ac91628b93b31636979b637c1ac7258064dea4e.tar.xz
mdadm-0ac91628b93b31636979b637c1ac7258064dea4e.zip
Allow homehost to be largely ignored when assembling arrays.
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>
-rw-r--r--Assemble.c8
-rw-r--r--Incremental.c11
-rw-r--r--config.c64
-rw-r--r--mdadm.83
-rw-r--r--mdadm.c34
-rw-r--r--mdadm.conf.524
-rw-r--r--mdadm.h10
-rw-r--r--mdassemble.c3
8 files changed, 132 insertions, 25 deletions
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, "<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 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, "<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();
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 <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 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;
}