Incremental: adjust to the new naming scheme.

--incremental now uses exactly the same create_mddev that
other code uses.
This commit is contained in:
NeilBrown 2008-11-04 20:50:38 +11:00
parent c4fe2d4f56
commit 215bb3f776
4 changed files with 54 additions and 264 deletions

View File

@ -209,7 +209,8 @@ int Assemble(struct supertype *st, char *mddev,
}
return Incremental_container(&container, ident->container,
verbose, runstop, ident->autof);
verbose, runstop, ident->autof,
LOCAL);
}
#endif
if (devlist == NULL)

View File

@ -48,7 +48,8 @@ int Incremental(char *devname, int verbose, int runstop,
* 2/ Find metadata, reject if none appropriate (check
* version/name from args)
* 3/ Check if there is a match in mdadm.conf
* 3a/ if not, check for homehost match. If no match, reject.
* 3a/ if not, check for homehost match. If no match, assemble as
* a 'foreign' array.
* 4/ Determine device number.
* - If in mdadm.conf with std name, use that
* - UUID in /var/run/mdadm.map use that
@ -85,9 +86,8 @@ int Incremental(char *devname, int verbose, int runstop,
int dfd, mdfd;
char *avail;
int active_disks;
int uuid_for_name = 0;
int trustworthy = FOREIGN;
char *name_to_use;
char nbuf[64];
struct createinfo *ci = conf_get_create_info();
@ -144,14 +144,6 @@ int Incremental(char *devname, int verbose, int runstop,
}
close (dfd);
if (st->ss->container_content && st->loaded_container) {
/* This is a pre-built container array, so we do something
* rather different.
*/
return Incremental_container(st, devname, verbose, runstop,
autof);
}
memset(&info, 0, sizeof(info));
st->ss->getinfo_super(st, &info);
/* 3/ Check if there is a match in mdadm.conf */
@ -218,28 +210,15 @@ int Incremental(char *devname, int verbose, int runstop,
* but don't trust the 'name' in the array. Thus a 'random' minor
* number will be assigned, and the device name will be based
* on that. */
if (!match) {
if (homehost == NULL ||
st->ss->match_home(st, homehost) != 1)
uuid_for_name = 1;
}
/* 4/ Determine device number. */
/* - If in mdadm.conf with std name, get number from name. */
/* - UUID in /var/run/mdadm.map get number from mapping */
/* - If name is suggestive, use that. unless in use with */
/* different uuid. */
/* - Choose a free, high number. */
/* - Use a partitioned device unless strong suggestion not to. */
/* e.g. auto=md */
mp = map_by_uuid(&map, info.uuid);
if (uuid_for_name && ! mp) {
name_to_use = fname_from_uuid(st, &info, nbuf, '-');
if (verbose >= 0)
fprintf(stderr, Name
": not found in mdadm.conf and not identified by homehost"
" - using uuid based name\n");
} else
if (match)
trustworthy = LOCAL;
else if (homehost == NULL ||
st->ss->match_home(st, homehost) != 1)
trustworthy = FOREIGN;
name_to_use = strchr(info.name, ':');
if (name_to_use)
name_to_use++;
else
name_to_use = info.name;
/* There are three possible sources for 'autof': command line,
@ -252,85 +231,35 @@ int Incremental(char *devname, int verbose, int runstop,
if (autof == 0)
autof = ci->autof;
if (match && (rv = is_standard(match->devname, &devnum))) {
devnum = (rv > 0) ? (-1-devnum) : devnum;
} else if (mp != NULL)
devnum = mp->devnum;
else {
/* Have to guess a bit. */
int use_partitions = 1;
char *np, *ep;
char *nm, nbuf[1024];
struct stat stb2;
if ((autof&7) == 3 || (autof&7) == 5)
use_partitions = 0;
if (st->ss->external)
use_partitions = 0;
np = strchr(name_to_use, ':');
if (np)
np++;
else
np = name_to_use;
devnum = strtoul(np, &ep, 10);
if (ep > np && *ep == 0) {
/* This is a number. Let check that it is unused. */
if (mddev_busy(use_partitions ? (-1-devnum) : devnum))
devnum = -1;
} else
devnum = -1;
if (match)
nm = match->devname;
else {
sprintf(nbuf, "/dev/md/%s", np);
nm = nbuf;
}
if (stat(nm, &stb2) == 0 &&
S_ISBLK(stb2.st_mode) &&
major(stb2.st_rdev) == (use_partitions ?
get_mdp_major() : MD_MAJOR)) {
if (use_partitions)
devnum = minor(stb2.st_rdev) >> MdpMinorShift;
else
devnum = minor(stb2.st_rdev);
if (mddev_busy(use_partitions ? (-1-devnum) : devnum))
devnum = -1;
}
if (devnum < 0) {
/* Haven't found anything yet, choose something free */
devnum = find_free_devnum(use_partitions);
if (devnum == NoMdDev) {
fprintf(stderr, Name
": No spare md devices!!\n");
return 2;
}
} else
devnum = use_partitions ? (-1-devnum) : devnum;
if (st->ss->container_content && st->loaded_container) {
/* This is a pre-built container array, so we do something
* rather different.
*/
return Incremental_container(st, devname, verbose, runstop,
autof, trustworthy);
}
/* 4/ Check is array exists.
*/
mp = map_by_uuid(&map, info.uuid);
if (mp)
mdfd = open_mddev(mp->path, 0);
else
mdfd = -1;
mdfd = create_mddev_devnum(match ? match->devname : mp ? mp->path : NULL,
devnum,
name_to_use,
chosen_name, autof >> 3);
if (mdfd < 0) {
fprintf(stderr, Name ": failed to open %s: %s.\n",
chosen_name, strerror(errno));
return 2;
}
sysfs_init(&info, mdfd, 0);
/* 5/ Find out if array already exists */
if (! mddev_busy(devnum)) {
/* 5a/ if it does not */
/* - choose a name, from mdadm.conf or 'name' field in array. */
/* - create the array */
/* - add the device */
struct mdinfo *sra;
struct mdinfo dinfo;
/* Couldn't find an existing array, maybe make a new one */
mdfd = create_mddev(mp ? mp->path : match ? match->devname : NULL,
info.name, autof, trustworthy, chosen_name);
if (mdfd < 0)
return 1;
sysfs_init(&info, mdfd, 0);
if (set_array_info(mdfd, st, &info) != 0) {
fprintf(stderr, Name ": failed to set array info for %s: %s\n",
chosen_name, strerror(errno));
@ -375,6 +304,9 @@ int Incremental(char *devname, int verbose, int runstop,
struct mdinfo *sra;
struct supertype *st2;
struct mdinfo info2, *d;
strcpy(chosen_name, mp->path);
sra = sysfs_read(mdfd, devnum, (GET_DEVS | GET_STATE));
sprintf(dn, "%d:%d", sra->devs->disk.major,
@ -430,7 +362,7 @@ int Incremental(char *devname, int verbose, int runstop,
}
/* 6/ Make sure /var/run/mdadm.map contains this array. */
map_update(&map, devnum,
map_update(&map, fd2devnum(mdfd),
info.text_version,
info.uuid, chosen_name);
@ -502,7 +434,7 @@ int Incremental(char *devname, int verbose, int runstop,
}
sra = sysfs_read(mdfd, devnum, 0);
if ((sra == NULL || active_disks >= info.array.working_disks)
&& uuid_for_name == 0)
&& trustworthy != FOREIGN)
rv = ioctl(mdfd, RUN_ARRAY, NULL);
else
rv = sysfs_set_str(sra, NULL,
@ -710,12 +642,11 @@ int IncrementalScan(int verbose)
devs = conf_get_ident(NULL);
for (me = mapl ; me ; me = me->next) {
char path[1024];
mdu_array_info_t array;
mdu_bitmap_file_t bmf;
struct mdinfo *sra;
int mdfd = create_mddev_devnum(me->path, me->devnum,
NULL, path, 0);
int mdfd = open_mddev(me->path, 0);
if (mdfd < 0)
continue;
if (ioctl(mdfd, GET_ARRAY_INFO, &array) == 0 ||
@ -772,7 +703,7 @@ int IncrementalScan(int verbose)
}
int Incremental_container(struct supertype *st, char *devname, int verbose,
int runstop, int autof)
int runstop, int autof, int trustworthy)
{
/* Collect the contents of this container and for each
* array, choose a device name and assemble the array.
@ -783,29 +714,14 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
for (ra = list ; ra ; ra = ra->next) {
struct mdinfo *dev, *sra;
int devnum = -1;
int mdfd;
char chosen_name[1024];
int usepart = 1;
char *n;
int working = 0, preexist = 0;
struct map_ent *mp, *map = NULL;
char nbuf[64];
char *name_to_use;
struct mddev_ident_s *match = NULL;
if ((autof&7) == 3 || (autof&7) == 5)
usepart = 0;
mp = map_by_uuid(&map, ra->uuid);
name_to_use = ra->name;
if (! name_to_use ||
! *name_to_use ||
(*devname != '/' || strncmp("UUID-", strrchr(devname,'/')+1,5) == 0)
)
name_to_use = fname_from_uuid(st, ra, nbuf, '-');
if (!mp) {
/* Check in mdadm.conf for devices == devname and
@ -850,57 +766,11 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
}
}
if (match && is_standard(match->devname, &devnum))
/* we have devnum now */;
else if (mp)
devnum = mp->devnum;
else if (is_standard(name_to_use, &devnum))
/* have devnum */;
else {
n = name_to_use;
if (*n == 'd')
n++;
if (*n && devnum < 0) {
devnum = strtoul(n, &n, 10);
if (devnum >= 0 && (*n == 0 || *n == ' ')) {
/* Use this devnum */
usepart = (name_to_use[0] == 'd');
if (mddev_busy(usepart ? (-1-devnum) : devnum))
devnum = -1;
} else
devnum = -1;
}
if (devnum < 0) {
char *nm = name_to_use;
char nbuf[1024];
struct stat stb;
if (strchr(nm, ':'))
nm = strchr(nm, ':')+1;
sprintf(nbuf, "/dev/md/%s", nm);
if (stat(nbuf, &stb) == 0 &&
S_ISBLK(stb.st_mode) &&
major(stb.st_rdev) == (usepart ?
get_mdp_major() : MD_MAJOR)){
if (usepart)
devnum = minor(stb.st_rdev)
>> MdpMinorShift;
else
devnum = minor(stb.st_rdev);
if (mddev_busy(usepart ? (-1-devnum) : devnum))
devnum = -1;
}
}
if (devnum >= 0)
devnum = usepart ? (-1-devnum) : devnum;
else
devnum = find_free_devnum(usepart);
}
mdfd = create_mddev_devnum(mp ? mp->path : match ? match->devname : NULL,
devnum, name_to_use,
chosen_name, autof>>3);
mdfd = create_mddev(match ? match->devname : NULL,
ra->name,
autof,
trustworthy,
chosen_name);
if (mdfd < 0) {
fprintf(stderr, Name ": failed to open %s: %s.\n",
@ -959,10 +829,10 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
": %s assembled with %d devices but "
"not started\n",
chosen_name, working);
close(mdfd);
map_update(&map, devnum,
map_update(&map, fd2devnum(mdfd),
ra->text_version,
ra->uuid, chosen_name);
close(mdfd);
}
return 0;
}

View File

@ -728,7 +728,8 @@ extern int WaitClean(char *dev, int verbose);
extern int Incremental(char *devname, int verbose, int runstop,
struct supertype *st, char *homehost, int autof);
extern int Incremental_container(struct supertype *st, char *devname,
int verbose, int runstop, int autof);
int verbose, int runstop, int autof,
int trustworthy);
extern void RebuildMap(void);
extern int IncrementalScan(int verbose);
@ -808,8 +809,6 @@ extern int create_mddev(char *dev, char *name, int autof, int trustworthy,
#define FOREIGN 2
#define METADATA 3
extern int open_mddev(char *dev, int report_errors);
extern int create_mddev_devnum(char *devname, int devnum, char *name,
char *chosen_name, int parts);
extern int open_container(int fd);
extern int mdmon_running(int devnum);

View File

@ -360,83 +360,3 @@ int open_mddev(char *dev, int report_errors)
}
return mdfd;
}
int create_mddev_devnum(char *devname, int devnum, char *name,
char *chosen_name, int parts)
{
/* Open the md device with number 'devnum', possibly using 'devname',
* possibly constructing a name with 'name', but in any case, copying
* the name into 'chosen_name'
*/
int major_num, minor_num;
struct stat stb;
int i;
struct createinfo *ci = conf_get_create_info();
if (devname)
strcpy(chosen_name, devname);
else if (name && *name && name[0] && strchr(name,'/') == NULL) {
char *n = strchr(name, ':');
if (n) n++; else n = name;
if (isdigit(*n) && devnum < 0)
sprintf(chosen_name, "/dev/md/d%s", n);
else
sprintf(chosen_name, "/dev/md/%s", n);
} else {
if (devnum >= 0)
sprintf(chosen_name, "/dev/md%d", devnum);
else
sprintf(chosen_name, "/dev/md/d%d", -1-devnum);
}
if (devnum >= 0) {
major_num = MD_MAJOR;
minor_num = devnum;
} else {
major_num = get_mdp_major();
minor_num = (-1-devnum) << 6;
}
if (stat(chosen_name, &stb) == 0) {
/* It already exists. Check it is right. */
if ( ! S_ISBLK(stb.st_mode) ||
stb.st_rdev != makedev(major_num, minor_num)) {
errno = EEXIST;
return -1;
}
} else {
/* special case: if --incremental is suggesting a name
* in /dev/md/, we make sure the directory exists.
*/
if (strncmp(chosen_name, "/dev/md/", 8) == 0) {
if (mkdir("/dev/md",0700)==0) {
if (chown("/dev/md", ci->uid, ci->gid))
perror("chown /dev/md");
if (chmod("/dev/md", ci->mode|
((ci->mode>>2) & 0111)))
perror("chmod /dev/md");
}
}
if (mknod(chosen_name, S_IFBLK | 0600,
makedev(major_num, minor_num)) != 0) {
return -1;
}
/* FIXME chown/chmod ?? */
}
/* Simple locking to avoid --incr being called for the same
* array multiple times in parallel.
*/
for (i = 0; i < 25 ; i++) {
int fd;
fd = open(chosen_name, O_RDWR|O_EXCL);
if (fd >= 0 || errno != EBUSY) {
if (devnum < 0)
make_parts(chosen_name, parts);
return fd;
}
usleep(200000);
}
return -1;
}