X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;ds=sidebyside;f=Assemble.c;h=a73e101ed047e75c139ab48b84a70f0c15270df2;hb=ff54de6e47163944185f231700e72d3122b58f4c;hp=ed40e579bb9fcffc1455f8d758b312745110890f;hpb=30e1b9a585ea667a3d79edd4e4ca2bf5692c2ab9;p=thirdparty%2Fmdadm.git diff --git a/Assemble.c b/Assemble.c index ed40e579..a73e101e 100644 --- a/Assemble.c +++ b/Assemble.c @@ -139,6 +139,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, 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; @@ -294,15 +297,28 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, 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. @@ -337,7 +353,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, 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) @@ -367,7 +384,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, tmpdev->used = 1; loop: - tst->ss->free_super(tst); + if (tst) + tst->ss->free_super(tst); } if (mdfd < 0) { @@ -377,12 +395,17 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, */ 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); @@ -541,8 +564,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, == 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. @@ -568,17 +591,18 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, 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; @@ -654,7 +678,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, 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); @@ -734,6 +758,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, return 1; } st->ss->getinfo_super(st, &info); +#ifndef MDASSEMBLE + sysfs_init(&info, mdfd, 0); +#endif for (i=0; iss->external) { - char ver[100]; - strcat(strcpy(ver, "external:"), st->ss->text_version); - sra = sysfs_read(mdfd, 0, 0); - if ((vers % 100) < 2 || - sra == NULL || - sysfs_set_str(sra, NULL, "metadata_version", - ver) < 0) { - fprintf(stderr, Name ": This kernel does not " - "support external metadata.\n"); - return 1; - } - rv = sysfs_set_array(sra, &info); - } else -#endif - 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; @@ -911,25 +913,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, j = chosen_drive; if (j >= 0 /* && devices[j].uptodate */) { -#ifndef MDASSEMBLE - if (st->ss->external) { - int fd = dev_open(devices[j].devname, - O_RDONLY); - if (fd < 0) - rv = 1; - else { - devices[j].i.disk.number = - devices[j].i.disk.raid_disk; - st->ss->getinfo_super_n(st, - &devices[j].i); - rv = sysfs_add_disk(sra, fd, - &devices[j].i); - close(fd); - } - } else -#endif - rv = ioctl(mdfd, ADD_NEW_DISK, - &devices[j].i.disk); + rv = add_disk(mdfd, st, &info, &devices[j].i); + if (rv) { fprintf(stderr, Name ": failed to add " "%s to %s: %s\n", @@ -1027,7 +1012,10 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, "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) { @@ -1061,7 +1049,10 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, 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