]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Assemble.c
Remember to close directories when we are finished with them.
[thirdparty/mdadm.git] / Assemble.c
index c7cc385da98d6b1e9a26d8531e08a4cd573eb8c7..9c320c2d8aea7ceffb680b5b03a90e41b782b539 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;
                }
 
@@ -480,7 +481,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                } else
 #endif
                {
-                       struct supertype *tst = dup_super(st);;
+                       struct supertype *tst = dup_super(st);
                        int dfd;
                        dfd = dev_open(devname, O_RDWR|O_EXCL);
 
@@ -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,19 @@ 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) {
+                                       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,
+                                                           &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,
@@ -915,6 +945,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 +982,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.
                                         *