Use load_container in Incremental assembly.
We more clearly separate out -I on a container, and use load_container in that case and load_super only for true members. This removes another use of loaded_container. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
3a97f21010
commit
47c74f3f50
108
Incremental.c
108
Incremental.c
|
@ -41,8 +41,8 @@ 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,
|
||||
int verbose, int runstop, int autof,
|
||||
int trustworthy);
|
||||
char *homehost,
|
||||
int verbose, int runstop, int autof);
|
||||
|
||||
static struct mddev_ident_s *search_mdstat(struct supertype *st,
|
||||
struct mdinfo *info,
|
||||
|
@ -99,13 +99,51 @@ int Incremental(char *devname, int verbose, int runstop,
|
|||
int dfd = -1, mdfd = -1;
|
||||
char *avail;
|
||||
int active_disks;
|
||||
int trustworthy = FOREIGN;
|
||||
int trustworthy;
|
||||
char *name_to_use;
|
||||
mdu_array_info_t ainf;
|
||||
struct dev_policy *policy = NULL;
|
||||
unsigned long long size;
|
||||
|
||||
struct createinfo *ci = conf_get_create_info();
|
||||
|
||||
if (stat(devname, &stb) < 0) {
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name ": stat failed for %s: %s.\n",
|
||||
devname, strerror(errno));
|
||||
return rv;
|
||||
}
|
||||
if ((stb.st_mode & S_IFMT) != S_IFBLK) {
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name ": %s is not a block device.\n",
|
||||
devname);
|
||||
return rv;
|
||||
}
|
||||
dfd = dev_open(devname, O_RDONLY|O_EXCL);
|
||||
if (dfd < 0) {
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name ": cannot open %s: %s.\n",
|
||||
devname, strerror(errno));
|
||||
return rv;
|
||||
}
|
||||
/* If the device is a container, we do something very different */
|
||||
if (get_dev_size(dfd, devname, &size) == 0)
|
||||
goto out;
|
||||
if (size == 0) {
|
||||
if (!st)
|
||||
st = super_by_fd(dfd, NULL);
|
||||
if (st)
|
||||
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);
|
||||
|
||||
fprintf(stderr, Name ": %s is not part of an md array.\n",
|
||||
devname);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* 1/ Check if device is permitted by mdadm.conf */
|
||||
|
||||
|
@ -120,13 +158,6 @@ int Incremental(char *devname, int verbose, int runstop,
|
|||
/* 2/ Find metadata, reject if none appropriate (check
|
||||
* version/name from args) */
|
||||
|
||||
dfd = dev_open(devname, O_RDONLY|O_EXCL);
|
||||
if (dfd < 0) {
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name ": cannot open %s: %s.\n",
|
||||
devname, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
if (fstat(dfd, &stb) < 0) {
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name ": fstat failed for %s: %s.\n",
|
||||
|
@ -217,25 +248,6 @@ int Incremental(char *devname, int verbose, int runstop,
|
|||
if (autof == 0)
|
||||
autof = ci->autof;
|
||||
|
||||
if (st->ss->container_content && st->loaded_container) {
|
||||
if ((runstop > 0 && info.container_enough >= 0) ||
|
||||
info.container_enough > 0)
|
||||
/* pass */;
|
||||
else {
|
||||
if (verbose)
|
||||
fprintf(stderr, Name ": not enough devices to start the container\n");
|
||||
rv = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* This is a pre-built container array, so we do something
|
||||
* rather different.
|
||||
*/
|
||||
rv = Incremental_container(st, devname, verbose, runstop,
|
||||
autof, trustworthy);
|
||||
goto out;
|
||||
}
|
||||
|
||||
name_to_use = info.name;
|
||||
if (name_to_use[0] == 0 &&
|
||||
info.array.level == LEVEL_CONTAINER &&
|
||||
|
@ -1205,17 +1217,49 @@ static char *container2devname(char *devname)
|
|||
return mdname;
|
||||
}
|
||||
|
||||
static int Incremental_container(struct supertype *st, char *devname, int verbose,
|
||||
int runstop, int autof, int trustworthy)
|
||||
static int Incremental_container(struct supertype *st, char *devname,
|
||||
char *homehost, int verbose,
|
||||
int runstop, int autof)
|
||||
{
|
||||
/* Collect the contents of this container and for each
|
||||
* array, choose a device name and assemble the array.
|
||||
*/
|
||||
|
||||
struct mdinfo *list = st->ss->container_content(st, NULL);
|
||||
struct mdinfo *list;
|
||||
struct mdinfo *ra;
|
||||
struct map_ent *map = NULL;
|
||||
struct mdinfo info;
|
||||
int trustworthy;
|
||||
struct mddev_ident_s *match;
|
||||
int rv = 0;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
st->ss->getinfo_super(st, &info, NULL);
|
||||
|
||||
if ((runstop > 0 && info.container_enough >= 0) ||
|
||||
info.container_enough > 0)
|
||||
/* pass */;
|
||||
else {
|
||||
if (verbose)
|
||||
fprintf(stderr, Name ": not enough devices to start the container\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
match = search_mdstat(st, &info, devname, verbose, &rv);
|
||||
if (match == NULL && rv == 2)
|
||||
return rv;
|
||||
|
||||
/* Need to compute 'trustworthy' */
|
||||
if (match)
|
||||
trustworthy = LOCAL;
|
||||
else if (st->ss->match_home(st, homehost) == 1)
|
||||
trustworthy = LOCAL;
|
||||
else if (st->ss->match_home(st, "any") == 1)
|
||||
trustworthy = LOCAL;
|
||||
else
|
||||
trustworthy = FOREIGN;
|
||||
|
||||
list = st->ss->container_content(st, NULL);
|
||||
if (map_lock(&map))
|
||||
fprintf(stderr, Name ": failed to get exclusive lock on "
|
||||
"mapfile\n");
|
||||
|
|
|
@ -2875,8 +2875,8 @@ static int load_super_ddf_all(struct supertype *st, int fd,
|
|||
st->ss = &super_ddf;
|
||||
st->minor_version = 0;
|
||||
st->max_devs = 512;
|
||||
st->container_dev = fd2devnum(fd);
|
||||
}
|
||||
st->container_dev = fd2devnum(fd);
|
||||
st->loaded_container = 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue