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)
sprintf(nbuf, "/dev/md/%s", np);
nm = nbuf;
}
- if (stat(nm, &stb) == 0 &&
- S_ISBLK(stb.st_mode) &&
- major(stb.st_rdev) == (use_partitions ?
- get_mdp_major() : MD_MAJOR)) {
+ 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(stb.st_rdev) >> MdpMinorShift;
+ devnum = minor(stb2.st_rdev) >> MdpMinorShift;
else
- devnum = minor(stb.st_rdev);
+ devnum = minor(stb2.st_rdev);
if (mddev_busy(use_partitions ? (-1-devnum) : devnum))
devnum = -1;
}
/* - create the array */
/* - add the device */
struct mdinfo *sra;
+ struct mdinfo dinfo;
if (set_array_info(mdfd, st, &info) != 0) {
fprintf(stderr, Name ": failed to set array info for %s: %s\n",
return 2;
}
- info.disk.major = major(stb.st_rdev);
- info.disk.minor = minor(stb.st_rdev);
- if (add_disk(mdfd, st, &info, &info) != 0) {
+ dinfo = info;
+ dinfo.disk.major = major(stb.st_rdev);
+ dinfo.disk.minor = minor(stb.st_rdev);
+ if (add_disk(mdfd, st, &info, &dinfo) != 0) {
fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
devname, chosen_name, strerror(errno));
ioctl(mdfd, STOP_ARRAY, 0);
sysfs_free(sra);
return 2;
}
+ info.array.working_disks = 1;
sysfs_free(sra);
} else {
/* 5b/ if it does */
int err;
struct mdinfo *sra;
struct supertype *st2;
- struct mdinfo info2;
+ struct mdinfo info2, *d;
sra = sysfs_read(mdfd, devnum, (GET_DEVS | GET_STATE));
sprintf(dn, "%d:%d", sra->devs->disk.major,
}
info2.disk.major = major(stb.st_rdev);
info2.disk.minor = minor(stb.st_rdev);
+ /* add disk needs to know about containers */
+ if (st->ss->external)
+ sra->array.level = LEVEL_CONTAINER;
err = add_disk(mdfd, st2, sra, &info2);
if (err < 0 && errno == EBUSY) {
/* could be another device present with the same
close(mdfd);
return 2;
}
+ info.array.working_disks = 0;
+ for (d = sra->devs; d; d=d->next)
+ info.array.working_disks ++;
+
}
/* 6/ Make sure /var/run/mdadm.map contains this array. */
map_update(&map, devnum,
/* 7a/ if not, finish with success. */
if (info.array.level == LEVEL_CONTAINER) {
/* Try to assemble within the container */
+ close(mdfd);
+ if (verbose >= 0)
+ fprintf(stderr, Name
+ ": container %s now has %d devices\n",
+ chosen_name, info.array.working_disks);
return Incremental(chosen_name, verbose, runstop,
NULL, homehost, autof);
}
char chosen_name[1024];
int usepart = 1;
char *n;
- int working = 0;
+ int working = 0, preexist = 0;
+ struct map_ent *mp, *map = NULL;
if ((autof&7) == 3 || (autof&7) == 5)
usepart = 0;
- n = ra->name;
- if (*n == 'd')
- n++;
- if (*n) {
- devnum = strtoul(n, &n, 10);
- if (devnum >= 0 && (*n == 0 || *n == ' ')) {
- /* Use this devnum */
- usepart = (ra->name[0] == 'd');
- if (mddev_busy(usepart ? (-1-devnum) : devnum))
- devnum = -1;
- } else
- devnum = -1;
- }
+ mp = map_by_uuid(&map, ra->uuid);
+ if (mp)
+ devnum = mp->devnum;
+ else {
- if (devnum < 0) {
- char *nm = ra->name;
- 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))
+ n = ra->name;
+ if (*n == 'd')
+ n++;
+ if (*n && devnum < 0) {
+ devnum = strtoul(n, &n, 10);
+ if (devnum >= 0 && (*n == 0 || *n == ' ')) {
+ /* Use this devnum */
+ usepart = (ra->name[0] == 'd');
+ if (mddev_busy(usepart ? (-1-devnum) : devnum))
+ devnum = -1;
+ } else
devnum = -1;
}
- }
- if (devnum >= 0)
- devnum = usepart ? (-1-devnum) : devnum;
- else
- devnum = find_free_devnum(usepart);
- mdfd = open_mddev_devnum(NULL, devnum, ra->name,
+ if (devnum < 0) {
+ char *nm = ra->name;
+ 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 = open_mddev_devnum(mp ? mp->path : NULL, devnum, ra->name,
chosen_name, autof>>3);
if (mdfd < 0) {
for (dev = ra->devs; dev; dev = dev->next)
if (sysfs_add_disk(ra, dev) == 0)
working++;
-
- if (runstop > 0 || working >= ra->array.working_disks) {
+ else if (errno == EEXIST)
+ preexist++;
+ if (working == 0)
+ /* Nothing new, don't try to start */ ;
+ else if (runstop > 0 ||
+ (working + preexist) >= ra->array.working_disks) {
switch(ra->array.level) {
case LEVEL_LINEAR:
case LEVEL_MULTIPATH:
break;
}
sysfs_set_safemode(ra, ra->safe_mode_delay);
- if (verbose >= 0)
- printf("Started %s with %d devices\n",
- chosen_name, working);
+ if (verbose >= 0) {
+ fprintf(stderr, Name
+ "Started %s with %d devices",
+ chosen_name, working + preexist);
+ if (preexist)
+ fprintf(stderr, " (%d new)", working);
+ fprintf(stderr, "\n");
+ }
/* FIXME should have an O_EXCL and wait for read-auto */
} else
if (verbose >= 0)
- printf("%s assembled with %d devices but "
- "not started\n",
- chosen_name, working);
+ fprintf(stderr, Name
+ "%s assembled with %d devices but "
+ "not started\n",
+ chosen_name, working);
close(mdfd);
+ map_update(&map, devnum,
+ ra->text_version,
+ ra->uuid, chosen_name);
}
return 0;
}
*/
struct ddf_super *ddf = st->sb;
struct vcl *vcl = ddf->currentconf;
+ char *guid;
+ char buf[20];
+ struct sha1_ctx ctx;
- if (!vcl)
- memset(uuid, 0, sizeof (uuid));
- else {
- char buf[20];
- struct sha1_ctx ctx;
- sha1_init_ctx(&ctx);
- sha1_process_bytes(&vcl->conf.guid, DDF_GUID_LEN, &ctx);
- if (vcl->conf.sec_elmnt_count > 1)
- sha1_process_bytes(&vcl->conf.sec_elmnt_seq, 1, &ctx);
- sha1_finish_ctx(&ctx, buf);
- memcpy(uuid, buf, sizeof(uuid));
- }
+ if (vcl)
+ guid = vcl->conf.guid;
+ else
+ guid = ddf->anchor.guid;
+
+ sha1_init_ctx(&ctx);
+ sha1_process_bytes(guid, DDF_GUID_LEN, &ctx);
+ if (vcl && vcl->conf.sec_elmnt_count > 1)
+ sha1_process_bytes(&vcl->conf.sec_elmnt_seq, 1, &ctx);
+ sha1_finish_ctx(&ctx, buf);
+ memcpy(uuid, buf, 4*4);
}
static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info);
info->reshape_active = 0;
+ info->name[0] = 0;
info->array.major_version = -1;
info->array.minor_version = -2;
strcpy(info->text_version, "ddf");
info->safe_mode_delay = 0;
-// uuid_from_super_ddf(info->uuid, sbv);
+ uuid_from_super_ddf(st, info->uuid);
-// info->name[] ?? ;
}
static int rlq_to_layout(int rlq, int prl, int raiddisks);
st->subarray);
info->safe_mode_delay = 200;
-// info->name[] ?? ;
+ info->name[0] = 0;
}
this->array.size = this->component_size / 2;
this->container_member = i;
+ ddf->currentconf = vc;
+ uuid_from_super_ddf(st, this->uuid);
+ ddf->currentconf = NULL;
+
sprintf(this->text_version, "/%s/%d",
devnum2devname(st->container_dev),
this->container_member);