]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - util.c
util: correctly parse shorter linux version numbers.
[thirdparty/mdadm.git] / util.c
diff --git a/util.c b/util.c
index 1056ae4a299992ef2957484db61bcefce4868e64..55d171a0bc5e80a06deccaa7f704e571b0156f03 100644 (file)
--- a/util.c
+++ b/util.c
@@ -146,16 +146,16 @@ int get_linux_version()
 {
        struct utsname name;
        char *cp;
-       int a,b,c;
+       int a = 0, b = 0,c = 0;
        if (uname(&name) <0)
                return -1;
 
        cp = name.release;
        a = strtoul(cp, &cp, 10);
-       if (*cp != '.') return -1;
-       b = strtoul(cp+1, &cp, 10);
-       if (*cp != '.') return -1;
-       c = strtoul(cp+1, NULL, 10);
+       if (*cp == '.')
+               b = strtoul(cp+1, &cp, 10);
+       if (*cp == '.')
+               c = strtoul(cp+1, &cp, 10);
 
        return (a*1000000)+(b*1000)+c;
 }
@@ -370,10 +370,14 @@ int enough_fd(int fd)
            array.raid_disks <= 0)
                return 0;
        avail = calloc(array.raid_disks, 1);
-       for (i=0; i<array.raid_disks + array.nr_disks; i++) {
+       for (i=0; i < 1024 && array.nr_disks > 0; i++) {
                disk.number = i;
                if (ioctl(fd, GET_DISK_INFO, &disk) != 0)
                        continue;
+               if (disk.major == 0 && disk.minor == 0)
+                       continue;
+               array.nr_disks--;
+
                if (! (disk.state & (1<<MD_DISK_SYNC)))
                        continue;
                if (disk.raid_disk < 0 || disk.raid_disk >= array.raid_disks)
@@ -1115,9 +1119,8 @@ int must_be_container(int fd)
 static int get_gpt_last_partition_end(int fd, unsigned long long *endofpart)
 {
        struct GPT gpt;
-       unsigned char buf[512];
        unsigned char empty_gpt_entry[16]= {0};
-       struct GPT_part_entry *part;
+       struct GPT_part_entry part;
        unsigned long long curr_part_end;
        unsigned all_partitions, entry_size;
        unsigned part_nr;
@@ -1125,8 +1128,9 @@ static int get_gpt_last_partition_end(int fd, unsigned long long *endofpart)
        *endofpart = 0;
 
        BUILD_BUG_ON(sizeof(gpt) != 512);
-       /* read GPT header */
+       /* skip protective MBR */
        lseek(fd, 512, SEEK_SET);
+       /* read GPT header */
        if (read(fd, &gpt, 512) != 512)
                return 0;
 
@@ -1143,28 +1147,19 @@ static int get_gpt_last_partition_end(int fd, unsigned long long *endofpart)
            entry_size > 512)
                return -1;
 
-       /* read first GPT partition entries */
-       if (read(fd, buf, 512) != 512)
-               return 0;
-
-       part = (struct GPT_part_entry*)buf;
-
        for (part_nr=0; part_nr < all_partitions; part_nr++) {
+               /* read partition entry */
+               if (read(fd, &part, entry_size) != (ssize_t)entry_size)
+                       return 0;
+
                /* is this valid partition? */
-               if (memcmp(part->type_guid, empty_gpt_entry, 16) != 0) {
+               if (memcmp(part.type_guid, empty_gpt_entry, 16) != 0) {
                        /* check the last lba for the current partition */
-                       curr_part_end = __le64_to_cpu(part->ending_lba);
+                       curr_part_end = __le64_to_cpu(part.ending_lba);
                        if (curr_part_end > *endofpart)
                                *endofpart = curr_part_end;
                }
 
-               part = (struct GPT_part_entry*)((unsigned char*)part + entry_size);
-
-               if ((unsigned char *)part >= buf + 512) {
-                       if (read(fd, buf, 512) != 512)
-                               return 0;
-                       part = (struct GPT_part_entry*)buf;
-               }
        }
        return 1;
 }
@@ -1256,10 +1251,13 @@ int check_partitions(int fd, char *dname, unsigned long long freesize,
 void get_one_disk(int mdfd, mdu_array_info_t *ainf, mdu_disk_info_t *disk)
 {
        int d;
+
        ioctl(mdfd, GET_ARRAY_INFO, ainf);
-       for (d = 0 ; d < ainf->raid_disks + ainf->nr_disks ; d++)
-               if (ioctl(mdfd, GET_DISK_INFO, disk) == 0)
+       for (d = 0 ; d < 1024 ; d++) {
+               if (ioctl(mdfd, GET_DISK_INFO, disk) == 0 &&
+                   (disk->major || disk->minor))
                        return;
+       }
 }
 
 int open_container(int fd)