]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Assemble.c
mdmon: ping will wait for manage_mon to catch up.
[thirdparty/mdadm.git] / Assemble.c
index 79f091269e68f843cbf9bd03978b8c739f3cf80c..7efa2b8c8bfc4d0526e819f49b207266b9e49f79 100644 (file)
@@ -542,8 +542,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.
@@ -845,11 +845,29 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
        /* Almost ready to actually *do* something */
        if (!old_linux) {
                int rv;
+
+#ifndef MDASSEMBLE
+               struct mdinfo *sra;
+               if (st->ss->external) {
+                       char ver[100];
+                       strcat(strcpy(ver, "external:"), info.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;
+                       inf.major_version = info.array.major_version;
+                       inf.minor_version = info.array.minor_version;
                        rv = ioctl(mdfd, SET_ARRAY_INFO, &inf);
                } else
                        rv = ioctl(mdfd, SET_ARRAY_INFO, NULL);
@@ -895,8 +913,14 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                j = chosen_drive;
 
                        if (j >= 0 /* && devices[j].uptodate */) {
-                               if (ioctl(mdfd, ADD_NEW_DISK,
-                                         &devices[j].i.disk)!=0) {
+#ifndef MDASSEMBLE
+                               if (st->ss->external)
+                                       rv = sysfs_add_disk(sra, &devices[j].i);
+                               else
+#endif
+                                       rv = ioctl(mdfd, ADD_NEW_DISK,
+                                         &devices[j].i.disk);
+                               if (rv) {
                                        fprintf(stderr, Name ": failed to add "
                                                        "%s to %s: %s\n",
                                                devices[j].devname,
@@ -918,6 +942,21 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                        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,
@@ -940,7 +979,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                        /* 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.
                                         *