]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Assemble.c
Can now mostly assemble DDF arrays
[thirdparty/mdadm.git] / Assemble.c
index c7cc385da98d6b1e9a26d8531e08a4cd573eb8c7..f10491b63f48b2c7849aaebf7c94c13ddea3f32c 100644 (file)
@@ -315,7 +315,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                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;
                }
 
@@ -842,6 +843,24 @@ 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:"), 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));
@@ -892,8 +911,26 @@ 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) {
+                                       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);
+                               if (rv) {
                                        fprintf(stderr, Name ": failed to add "
                                                        "%s to %s: %s\n",
                                                devices[j].devname,
@@ -915,6 +952,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,
@@ -937,7 +989,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.
                                         *