]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - util.c
Use new container_content rather than passing subarray to load_super.
[thirdparty/mdadm.git] / util.c
diff --git a/util.c b/util.c
index c93b0a7ab81b632fa743e66e54e7edd6ad2bcdbe..66c7f0b9d6ddfa5f26ccc3bc77d13a481c72fbac 100644 (file)
--- a/util.c
+++ b/util.c
@@ -320,6 +320,36 @@ int enough(int level, int raid_disks, int layout, int clean,
        }
 }
 
+int enough_fd(int fd)
+{
+       struct mdu_array_info_s array;
+       struct mdu_disk_info_s disk;
+       int avail_disks = 0;
+       int i;
+       char *avail;
+
+       if (ioctl(fd, GET_ARRAY_INFO, &array) != 0 ||
+           array.raid_disks <= 0)
+               return 0;
+       avail = calloc(array.raid_disks, 1);
+       for (i=0; i<array.raid_disks + array.nr_disks; i++) {
+               disk.number = i;
+               if (ioctl(fd, GET_DISK_INFO, &disk) != 0)
+                       continue;
+               if (! (disk.state & (1<<MD_DISK_SYNC)))
+                       continue;
+               if (disk.raid_disk < 0 || disk.raid_disk >= array.raid_disks)
+                       continue;
+               avail_disks++;
+               avail[disk.raid_disk] = 1;
+       }
+       /* This is used on an active array, so assume it is clean */
+       return enough(array.level, array.raid_disks, array.layout,
+                     1,
+                     avail, avail_disks);
+}
+
+
 const int uuid_match_any[4] = { ~0, ~0, ~0, ~0 };
 int same_uuid(int a[4], int b[4], int swapuuid)
 {
@@ -470,7 +500,7 @@ int check_raid(int fd, char *name)
        /* Looks like a raid array .. */
        fprintf(stderr, Name ": %s appears to be part of a raid array:\n",
                name);
-       st->ss->getinfo_super(st, &info);
+       st->ss->getinfo_super(st, &info, NULL);
        st->ss->free_super(st);
        crtime = info.array.ctime;
        level = map_num(pers, info.array.level);
@@ -997,12 +1027,12 @@ struct superswitch *superlist[] =
 {
        &super0, &super1,
        &super_ddf, &super_imsm,
-       &mbr,
+       &mbr, &gpt,
        NULL };
 
 #if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
 
-struct supertype *super_by_fd(int fd)
+struct supertype *super_by_fd(int fd, char **subarrayp)
 {
        mdu_array_info_t array;
        int vers;
@@ -1056,13 +1086,10 @@ struct supertype *super_by_fd(int fd)
                sysfs_free(sra);
        if (st) {
                st->sb = NULL;
-               if (subarray) {
-                       strncpy(st->subarray, subarray, 32);
-                       st->subarray[31] = 0;
-                       free(subarray);
-               } else
-                       st->subarray[0] = 0;
-       }
+               st->subarray[0] = 0;
+               *subarrayp = subarray;
+       } else
+               free(subarray);
        return st;
 }
 #endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */
@@ -1087,7 +1114,7 @@ struct supertype *dup_super(struct supertype *orig)
        return st;
 }
 
-struct supertype *guess_super(int fd)
+struct supertype *guess_super_type(int fd, enum guess_types guess_type)
 {
        /* try each load_super to find the best match,
         * and return the best superswitch
@@ -1102,11 +1129,15 @@ struct supertype *guess_super(int fd)
        for (i=0 ; superlist[i]; i++) {
                int rv;
                ss = superlist[i];
+               if (guess_type == guess_array && ss->add_to_super == NULL)
+                       continue;
+               if (guess_type == guess_partitions && ss->add_to_super != NULL)
+                       continue;
                memset(st, 0, sizeof(*st));
                rv = ss->load_super(st, fd, NULL);
                if (rv == 0) {
                        struct mdinfo info;
-                       st->ss->getinfo_super(st, &info);
+                       st->ss->getinfo_super(st, &info, NULL);
                        if (bestsuper == -1 ||
                            besttime < info.array.ctime) {
                                bestsuper = i;
@@ -1407,12 +1438,12 @@ int is_container_active(char *container)
 
 /* open_subarray - opens a subarray in a container
  * @dev: container device name
- * @st: supertype with only ->subarray set
+ * @st: empty supertype
  * @quiet: block reporting errors flag
  *
  * On success returns an fd to a container and fills in *st
  */
-int open_subarray(char *dev, struct supertype *st, int quiet)
+int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet)
 {
        struct mdinfo *mdi;
        int fd, err = 1;
@@ -1464,6 +1495,8 @@ int open_subarray(char *dev, struct supertype *st, int quiet)
                goto free_sysfs;
        }
 
+       strncpy(st->subarray, subarray, sizeof(st->subarray)-1);
+
        if (st->ss->load_super(st, fd, NULL)) {
                if (!quiet)
                        fprintf(stderr, Name ": Failed to find subarray-%s in %s\n",