When assembly arrays using incomplete detail, prefer arrays built for this host.
i.e. if assembling with --name or --super-minor, then if we find two different arrays with the same apparent identity, and one was built for 'this' host, then prefer that one instead of giving up in disgust. Signed-off-by: Neil Brown <neilb@suse.de>
This commit is contained in:
parent
811e6cbed7
commit
83b6208e89
40
Assemble.c
40
Assemble.c
|
@ -277,9 +277,11 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* If we are this far, then we are commited to this device.
|
||||
/* If we are this far, then we are nearly commited to this device.
|
||||
* If the super_block doesn't exist, or doesn't match others,
|
||||
* then we cannot continue
|
||||
* then we probably cannot continue
|
||||
* However if one of the arrays is for the homehost, and
|
||||
* the other isn't that can disambiguate.
|
||||
*/
|
||||
|
||||
if (!super) {
|
||||
|
@ -289,9 +291,37 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
st = tst; /* commit to this format, if haven't already */
|
||||
if (st->ss->compare_super(&first_super, super)) {
|
||||
if (st == NULL)
|
||||
st = tst;
|
||||
if (st->ss != tst->ss ||
|
||||
st->minor_version != tst->minor_version ||
|
||||
st->ss->compare_super(&first_super, super) != 0) {
|
||||
/* Some mismatch. If exactly one array matches this host,
|
||||
* we can resolve on that one
|
||||
*/
|
||||
if (homehost) {
|
||||
int first = st->ss->match_home(first_super, homehost);
|
||||
int last = tst->ss->match_home(super, homehost);
|
||||
if (first+last == 1) {
|
||||
/* We can do something */
|
||||
if (first) {/* just ignore this one */
|
||||
if ((inargv && verbose >= 0) || verbose > 0)
|
||||
fprintf(stderr, Name ": %s misses out due to wrong homehost\n",
|
||||
devname);
|
||||
continue;
|
||||
} else { /* reject all those sofar */
|
||||
mddev_dev_t td;
|
||||
if ((inargv && verbose >= 0) || verbose > 0)
|
||||
fprintf(stderr, Name ": %s overrides previous devices due to good homehost\n",
|
||||
devname);
|
||||
for (td=devlist; td != tmpdev; td=td->next)
|
||||
if (td->used == 1)
|
||||
td->used = 0;
|
||||
tmpdev->used = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(stderr, Name ": superblock on %s doesn't match others - assembly aborted\n",
|
||||
devname);
|
||||
free(super);
|
||||
|
|
1
mdadm.h
1
mdadm.h
|
@ -279,6 +279,7 @@ extern struct superswitch {
|
|||
void (*brief_detail_super)(void *sbv);
|
||||
void (*uuid_from_super)(int uuid[4], void *sbv);
|
||||
void (*getinfo_super)(struct mdinfo *info, void *sbv);
|
||||
int (*match_home)(void *sbv, char *homehost);
|
||||
int (*update_super)(struct mdinfo *info, void *sbv, char *update,
|
||||
char *devname, int verbose,
|
||||
int uuid_set, char *homehost);
|
||||
|
|
12
super0.c
12
super0.c
|
@ -269,6 +269,17 @@ static void brief_detail_super0(void *sbv)
|
|||
printf("%08x", sb->set_uuid0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int match_home0(void *sbv, char *homehost)
|
||||
{
|
||||
mdp_super_t *sb = sbv;
|
||||
unsigned char *hash = SHA1((unsigned char *)homehost,
|
||||
strlen(homehost),
|
||||
NULL);
|
||||
|
||||
return (memcmp(&sb->set_uuid2, hash, 8)==0);
|
||||
}
|
||||
|
||||
static void uuid_from_super0(int uuid[4], void * sbv)
|
||||
{
|
||||
mdp_super_t *super = sbv;
|
||||
|
@ -942,6 +953,7 @@ struct superswitch super0 = {
|
|||
.detail_super = detail_super0,
|
||||
.brief_detail_super = brief_detail_super0,
|
||||
#endif
|
||||
.match_home = match_home0,
|
||||
.uuid_from_super = uuid_from_super0,
|
||||
.getinfo_super = getinfo_super0,
|
||||
.update_super = update_super0,
|
||||
|
|
11
super1.c
11
super1.c
|
@ -357,6 +357,16 @@ static void brief_detail_super1(void *sbv)
|
|||
|
||||
#endif
|
||||
|
||||
static int match_home1(void *sbv, char *homehost)
|
||||
{
|
||||
struct mdp_superblock_1 *sb = sbv;
|
||||
int l = homehost ? strlen(homehost) : 0;
|
||||
|
||||
return (l > 0 && l < 32 &&
|
||||
sb->set_name[l] == ':' &&
|
||||
strncmp(sb->set_name, homehost, l) == 0);
|
||||
}
|
||||
|
||||
static void uuid_from_super1(int uuid[4], void * sbv)
|
||||
{
|
||||
struct mdp_superblock_1 *super = sbv;
|
||||
|
@ -1191,6 +1201,7 @@ struct superswitch super1 = {
|
|||
.detail_super = detail_super1,
|
||||
.brief_detail_super = brief_detail_super1,
|
||||
#endif
|
||||
.match_home = match_home1,
|
||||
.uuid_from_super = uuid_from_super1,
|
||||
.getinfo_super = getinfo_super1,
|
||||
.update_super = update_super1,
|
||||
|
|
Loading…
Reference in New Issue