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>
This commit is contained in:
NeilBrown 2009-05-11 15:46:46 +10:00
parent 603f24a05f
commit 0ac91628b9
8 changed files with 132 additions and 25 deletions

View 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) {

View 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

View File

@ -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;
}

View File

@ -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:

34
mdadm.c
View File

@ -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();

View 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

10
mdadm.h
View File

@ -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);

View 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;
}