summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
}