struct mdinfo info;
char *avail;
int nextspare = 0;
+ int uuid_for_name = 0;
+
+ memset(&info, 0, sizeof(info));
if (get_linux_version() < 2004000)
old_linux = 1;
if (mdfd < 0) {
if (tst == NULL || tst->sb == NULL)
continue;
- if (update == NULL &&
- tst->ss->match_home(tst, homehost)==0) {
+ switch(tst->ss->match_home(tst, homehost))
+ {
+ case 1: /* happy with match. */
+ break;
+ case -1: /* cannot match */
+ uuid_for_name = 1;
+ break;
+ case 0: /* Doesn't match */
+ if (update)
+ /* We are changing the name*/
+ break;
if ((inargv && verbose >= 0) || verbose > 0)
- fprintf(stderr, Name ": %s is not built for host %s.\n",
+ fprintf(stderr, Name ": %s is not built for "
+ "host %s - using UUID for "
+ "device name.\n",
devname, homehost);
+
/* Auto-assemble, and this is not a usable host */
/* if update != NULL, we are updating the host
* name... */
- goto loop;
+ uuid_for_name = 1;
+ break;
}
}
/* If we are this far, then we are nearly commited to this device.
if (!tst || !tst->sb) {
fprintf(stderr, Name ": %s has no superblock - assembly aborted\n",
devname);
- st->ss->free_super(st);
+ if (st)
+ st->ss->free_super(st);
return 1;
}
if (homehost) {
int first = st->ss->match_home(st, homehost);
int last = tst->ss->match_home(tst, homehost);
- if (first+last == 1) {
+ if (first != last &&
+ (first == 1 || last == 1)) {
/* We can do something */
if (first) {/* just ignore this one */
if ((inargv && verbose >= 0) || verbose > 0)
tmpdev->used = 1;
loop:
- tst->ss->free_super(tst);
+ if (tst)
+ tst->ss->free_super(tst);
}
if (mdfd < 0) {
*/
mdu_array_info_t inf;
char *c;
- if (!st->sb) {
+ char nbuf[64];
+ if (!st || !st->sb) {
return 2;
}
st->ss->getinfo_super(st, &info);
- c = strchr(info.name, ':');
- if (c) c++; else c= info.name;
+ if (uuid_for_name)
+ c = fname_from_uuid(st, &info, nbuf, '-');
+ else {
+ c = strchr(info.name, ':');
+ if (c) c++; else c= info.name;
+ }
if (isdigit(*c) && ((ident->autof & 7)==4 || (ident->autof&7)==6))
/* /dev/md/d0 style for partitionable */
asprintf(&mddev, "/dev/md/d%s", c);
} else
#endif
{
- struct supertype *tst = dup_super(st);;
+ struct supertype *tst = dup_super(st);
int dfd;
dfd = dev_open(devname, O_RDWR|O_EXCL);
== devices[devcnt].i.events
&& (devices[best[i]].i.disk.minor
!= devices[devcnt].i.disk.minor)
- && st->ss->major == 0
- && info.array.level != -4) {
+ && st->ss == &super0
+ && info.array.level != LEVEL_MULTIPATH) {
/* two different devices with identical superblock.
* Could be a mis-detection caused by overlapping
* partitions. fail-safe.
devcnt++;
}
- if (update && strcmp(update, "byteorder")==0)
- st->minor_version = 90;
-
if (devcnt == 0) {
fprintf(stderr, Name ": no devices found for %s\n",
mddev);
- st->ss->free_super(st);
+ if (st)
+ st->ss->free_super(st);
if (must_close) close(mdfd);
return 1;
}
+ if (update && strcmp(update, "byteorder")==0)
+ st->minor_version = 90;
+
st->ss->getinfo_super(st, &info);
clean = info.array.state & 1;
continue;
}
tst = dup_super(st);
- if (tst->ss->load_super(st,fd, NULL)) {
+ if (tst->ss->load_super(tst,fd, NULL)) {
close(fd);
fprintf(stderr, Name ": RAID superblock disappeared from %s - not updating.\n",
devices[chosen_drive].devname);
return 1;
}
st->ss->getinfo_super(st, &info);
+#ifndef MDASSEMBLE
+ sysfs_init(&info, mdfd, 0);
+#endif
for (i=0; i<bestcnt; i++) {
int j = best[i];
unsigned int desired_state;
/* Almost ready to actually *do* something */
if (!old_linux) {
int rv;
- if ((vers % 100) >= 1) { /* can use different versions */
- mdu_array_info_t inf;
- memset(&inf, 0, sizeof(inf));
- inf.major_version = st->ss->major;
- inf.minor_version = st->minor_version;
- rv = ioctl(mdfd, SET_ARRAY_INFO, &inf);
- } else
- rv = ioctl(mdfd, SET_ARRAY_INFO, NULL);
+ rv = set_array_info(mdfd, st, &info);
if (rv) {
- fprintf(stderr, Name ": SET_ARRAY_INFO failed for %s: %s\n",
+ fprintf(stderr, Name ": failed to set array info for %s: %s\n",
mddev, strerror(errno));
if (must_close) close(mdfd);
return 1;
j = chosen_drive;
if (j >= 0 /* && devices[j].uptodate */) {
- if (ioctl(mdfd, ADD_NEW_DISK,
- &devices[j].i.disk)!=0) {
+ rv = add_disk(mdfd, st, &info, &devices[j].i);
+
+ if (rv) {
fprintf(stderr, Name ": failed to add "
"%s to %s: %s\n",
devices[j].devname,
i, mddev);
}
+ if (info.array.level == LEVEL_CONTAINER) {
+ if (verbose >= 0) {
+ fprintf(stderr, Name ": Container %s has been "
+ "assembled with %d drive%s",
+ mddev, okcnt, okcnt==1?"":"s");
+ if (okcnt < info.array.raid_disks)
+ fprintf(stderr, " (out of %d)",
+ info.array.raid_disks);
+ fprintf(stderr, "\n");
+ }
+ if (must_close)
+ close(mdfd);
+ return 0;
+ }
+
if (runstop == 1 ||
(runstop <= 0 &&
( enough(info.array.level, info.array.raid_disks,
/* There is a nasty race with 'mdadm --monitor'.
* If it opens this device before we close it,
* it gets an incomplete open on which IO
- * doesn't work and the capacity if wrong.
+ * doesn't work and the capacity is
+ * wrong.
* If we reopen (to check for layered devices)
* before --monitor closes, we loose.
*
"start the array while not clean "
"- consider --force.\n");
- if (must_close) close(mdfd);
+ if (must_close) {
+ ioctl(mdfd, STOP_ARRAY, NULL);
+ close(mdfd);
+ }
return 1;
}
if (runstop == -1) {
fprintf(stderr, " (use --run to insist).\n");
}
}
- if (must_close) close(mdfd);
+ if (must_close) {
+ ioctl(mdfd, STOP_ARRAY, NULL);
+ close(mdfd);
+ }
return 1;
} else {
/* The "chosen_drive" is a good choice, and if necessary, the superblock has