Remove race for starting container devices.
This moves the lock handling out of Incremental_container() and relies on the caller holding the lock. This prevents conflict with a follow-on mdadm comment which may try and launch the device in parallel. This involves replacing a call to "Incremental" with an unrolled version with just the case that calls Incremental_container and so needs a call to ->load_container. Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
9c8c121881
commit
5fc8cff3a4
|
@ -139,10 +139,16 @@ int Incremental(char *devname, int verbose, int runstop,
|
|||
rv = st->ss->load_container(st, dfd, NULL);
|
||||
|
||||
close(dfd);
|
||||
if (!rv && st->ss->container_content)
|
||||
return Incremental_container(st, devname, homehost,
|
||||
verbose, runstop, autof,
|
||||
freeze_reshape);
|
||||
if (!rv && st->ss->container_content) {
|
||||
if (map_lock(&map))
|
||||
fprintf(stderr, Name ": failed to get "
|
||||
"exclusive lock on mapfile\n");
|
||||
rv = Incremental_container(st, devname, homehost,
|
||||
verbose, runstop, autof,
|
||||
freeze_reshape);
|
||||
map_unlock(&map);
|
||||
return rv;
|
||||
}
|
||||
|
||||
fprintf(stderr, Name ": %s is not part of an md array.\n",
|
||||
devname);
|
||||
|
@ -440,7 +446,6 @@ int Incremental(char *devname, int verbose, int runstop,
|
|||
if (info.array.level == LEVEL_CONTAINER) {
|
||||
int devnum = devnum; /* defined and used iff ->external */
|
||||
/* Try to assemble within the container */
|
||||
map_unlock(&map);
|
||||
sysfs_uevent(&info, "change");
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name
|
||||
|
@ -449,11 +454,15 @@ int Incremental(char *devname, int verbose, int runstop,
|
|||
wait_for(chosen_name, mdfd);
|
||||
if (st->ss->external)
|
||||
devnum = fd2devnum(mdfd);
|
||||
if (st->ss->load_container)
|
||||
rv = st->ss->load_container(st, mdfd, NULL);
|
||||
close(mdfd);
|
||||
sysfs_free(sra);
|
||||
rv = Incremental(chosen_name, verbose, runstop,
|
||||
NULL, homehost, require_homehost, autof,
|
||||
freeze_reshape);
|
||||
if (!rv)
|
||||
rv = Incremental_container(st, chosen_name, homehost,
|
||||
verbose, runstop, autof,
|
||||
freeze_reshape);
|
||||
map_unlock(&map);
|
||||
if (rv == 1)
|
||||
/* Don't fail the whole -I if a subarray didn't
|
||||
* have enough devices to start yet
|
||||
|
@ -1463,16 +1472,12 @@ static int Incremental_container(struct supertype *st, char *devname,
|
|||
trustworthy = FOREIGN;
|
||||
|
||||
list = st->ss->container_content(st, NULL);
|
||||
if (map_lock(&map))
|
||||
fprintf(stderr, Name ": failed to get exclusive lock on "
|
||||
"mapfile\n");
|
||||
/* do not assemble arrays that might have bad blocks */
|
||||
if (list && list->array.state & (1<<MD_SB_BBM_ERRORS)) {
|
||||
fprintf(stderr, Name ": BBM log found in metadata. "
|
||||
"Cannot activate array(s).\n");
|
||||
/* free container data and exit */
|
||||
sysfs_free(list);
|
||||
map_unlock(&map);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -1536,7 +1541,6 @@ static int Incremental_container(struct supertype *st, char *devname,
|
|||
fprintf(stderr, Name ": array %s/%s is "
|
||||
"explicitly ignored by mdadm.conf\n",
|
||||
match->container, match->member);
|
||||
map_unlock(&map);
|
||||
return 2;
|
||||
}
|
||||
if (match)
|
||||
|
@ -1552,7 +1556,6 @@ static int Incremental_container(struct supertype *st, char *devname,
|
|||
if (mdfd < 0) {
|
||||
fprintf(stderr, Name ": failed to open %s: %s.\n",
|
||||
chosen_name, strerror(errno));
|
||||
map_unlock(&map);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -1607,7 +1610,6 @@ static int Incremental_container(struct supertype *st, char *devname,
|
|||
close(sfd);
|
||||
}
|
||||
domain_free(domains);
|
||||
map_unlock(&map);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue