Make -IRs and --run work properly for containers.

We really need to make sure assemble_container_content()
gets called to finished the assembly of these.

Reported-by: Francis Moreau <francis.moro@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2013-09-13 10:51:20 +10:00
parent a8b2563354
commit d5a4041647
5 changed files with 54 additions and 16 deletions

View File

@ -1817,7 +1817,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
working++;
} else if (errno == EEXIST)
preexist++;
if (working + expansion == 0)
if (working + expansion == 0 && c->runstop <= 0)
return 1;/* Nothing new, don't try to start */
map_update(&map, fd2devnm(mdfd),

View File

@ -44,7 +44,7 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
struct supertype *st, int verbose);
static int Incremental_container(struct supertype *st, char *devname,
struct context *c);
struct context *c, char *only);
int Incremental(char *devname, struct context *c,
struct supertype *st)
@ -138,7 +138,7 @@ int Incremental(char *devname, struct context *c,
if (map_lock(&map))
pr_err("failed to get "
"exclusive lock on mapfile\n");
rv = Incremental_container(st, devname, c);
rv = Incremental_container(st, devname, c, NULL);
map_unlock(&map);
return rv;
}
@ -478,7 +478,7 @@ int Incremental(char *devname, struct context *c,
close(mdfd);
sysfs_free(sra);
if (!rv)
rv = Incremental_container(st, chosen_name, c);
rv = Incremental_container(st, chosen_name, c, NULL);
map_unlock(&map);
if (rv == 1)
/* Don't fail the whole -I if a subarray didn't
@ -1278,7 +1278,7 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
return rv;
}
int IncrementalScan(int verbose, char *devnm)
int IncrementalScan(struct context *c, char *devnm)
{
/* look at every device listed in the 'map' file.
* If one is found that is not running then:
@ -1290,10 +1290,13 @@ int IncrementalScan(int verbose, char *devnm)
struct map_ent *me;
struct mddev_ident *devs, *mddev;
int rv = 0;
char container[32];
char *only = NULL;
map_read(&mapl);
devs = conf_get_ident(NULL);
restart:
for (me = mapl ; me ; me = me->next) {
mdu_array_info_t array;
mdu_bitmap_file_t bmf;
@ -1302,10 +1305,42 @@ int IncrementalScan(int verbose, char *devnm)
if (devnm && strcmp(devnm, me->devnm) != 0)
continue;
if (devnm && me->metadata[0] == '/') {
char *sl;
/* member array, need to work on container */
strncpy(container, me->metadata+1, 32);
container[31] = 0;
sl = strchr(container, '/');
if (sl)
*sl = 0;
only = devnm;
devnm = container;
goto restart;
}
mdfd = open_dev(me->devnm);
if (mdfd < 0)
continue;
if (!isdigit(me->metadata[0])) {
/* must be a container */
struct supertype *st = super_by_fd(mdfd, NULL);
int ret = 0;
struct map_ent *map = NULL;
if (st)
st->ignore_hw_compat = 1;
if (st && st->ss->load_container)
ret = st->ss->load_container(st, mdfd, NULL);
close(mdfd);
if (!ret && st->ss->container_content) {
if (map_lock(&map))
pr_err("failed to get exclusive lock on mapfile\n");
ret = Incremental_container(st, me->path, c, only);
map_unlock(&map);
}
if (ret)
rv = 1;
continue;
}
if (ioctl(mdfd, GET_ARRAY_INFO, &array) == 0 ||
errno != ENODEV) {
close(mdfd);
@ -1330,7 +1365,7 @@ int IncrementalScan(int verbose, char *devnm)
close(bmfd);
}
}
if (verbose >= 0) {
if (c->verbose >= 0) {
if (added == 0)
pr_err("Added bitmap %s to %s\n",
mddev->bitmap_file, me->path);
@ -1346,7 +1381,7 @@ int IncrementalScan(int verbose, char *devnm)
if (sra) {
if (sysfs_set_str(sra, NULL,
"array_state", "read-auto") == 0) {
if (verbose >= 0)
if (c->verbose >= 0)
pr_err("started array %s\n",
me->path ?: me->devnm);
} else {
@ -1387,7 +1422,7 @@ static char *container2devname(char *devname)
}
static int Incremental_container(struct supertype *st, char *devname,
struct context *c)
struct context *c, char *only)
{
/* Collect the contents of this container and for each
* array, choose a device name and assemble the array.
@ -1458,7 +1493,7 @@ static int Incremental_container(struct supertype *st, char *devname,
strcpy(chosen_name, mp->path);
else
strcpy(chosen_name, mp->devnm);
} else {
} else if (!only) {
/* Check in mdadm.conf for container == devname and
* member == ra->text_version after second slash.
@ -1515,6 +1550,8 @@ static int Incremental_container(struct supertype *st, char *devname,
trustworthy,
chosen_name);
}
if (only && (!mp || strcmp(mp->devnm, only) != 0))
continue;
if (mdfd < 0) {
pr_err("failed to open %s: %s.\n",

View File

@ -170,7 +170,7 @@ static void remove_devices(char *devnm, char *path)
free(path2);
}
int Manage_run(char *devname, int fd, int verbose)
int Manage_run(char *devname, int fd, struct context *c)
{
/* Run the array. Array must already be configured
* Requires >= 0.90.0
@ -187,7 +187,7 @@ int Manage_run(char *devname, int fd, int verbose)
return 1;
}
strcpy(nm, nmp);
return IncrementalScan(verbose, nm);
return IncrementalScan(c, nm);
}
int Manage_stop(char *devname, int fd, int verbose, int will_retry)

View File

@ -1293,7 +1293,7 @@ int main(int argc, char *argv[])
if (!rv && c.readonly < 0)
rv = Manage_ro(devlist->devname, mdfd, c.readonly);
if (!rv && c.runstop > 0)
rv = Manage_run(devlist->devname, mdfd, c.verbose);
rv = Manage_run(devlist->devname, mdfd, &c);
if (!rv && c.runstop < 0)
rv = Manage_stop(devlist->devname, mdfd, c.verbose, 0);
break;
@ -1535,7 +1535,7 @@ int main(int argc, char *argv[])
pr_err("--incremental --scan --fail not supported.\n");
break;
}
rv = IncrementalScan(c.verbose, NULL);
rv = IncrementalScan(&c, NULL);
}
if (!devlist) {
if (!rebuild_map && !c.scan) {
@ -1804,7 +1804,8 @@ static int misc_list(struct mddev_dev *devlist,
if (mdfd>=0) {
switch(dv->disposition) {
case 'R':
rv |= Manage_run(dv->devname, mdfd, c->verbose); break;
c->runstop = 1;
rv |= Manage_run(dv->devname, mdfd, c); break;
case 'S':
rv |= Manage_stop(dv->devname, mdfd, c->verbose, 0); break;
case 'o':

View File

@ -1171,7 +1171,7 @@ struct stat64;
extern int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s);
extern int Manage_ro(char *devname, int fd, int readonly);
extern int Manage_run(char *devname, int fd, int quiet);
extern int Manage_run(char *devname, int fd, struct context *c);
extern int Manage_stop(char *devname, int fd, int quiet,
int will_retry);
extern int Manage_subdevs(char *devname, int fd,
@ -1237,7 +1237,7 @@ extern int WaitClean(char *dev, int sock, int verbose);
extern int Incremental(char *devname, struct context *c,
struct supertype *st);
extern void RebuildMap(void);
extern int IncrementalScan(int verbose, char *devnm);
extern int IncrementalScan(struct context *c, char *devnm);
extern int IncrementalRemove(char *devname, char *path, int verbose);
extern int CreateBitmap(char *filename, int force, char uuid[16],
unsigned long chunksize, unsigned long daemon_sleep,