]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Assorted Fixes for multiple bugs.
authorNeil Brown <neilb@suse.de>
Thu, 4 Aug 2005 04:41:12 +0000 (04:41 +0000)
committerNeil Brown <neilb@suse.de>
Thu, 4 Aug 2005 04:41:12 +0000 (04:41 +0000)
Assemble would crash, or just not work.
A few other problem found by a new test-suite.

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Assemble.c
ChangeLog
Manage.c
bitmap.c
config.c
mdadm.h
super0.c
super1.c
util.c

index 89086e38a6dba3ba6c98225a0db48a723b1426e4..20183ae12c3bdbe3653f0c1f2494e0c74dc49a2f 100644 (file)
@@ -219,7 +219,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                }
 
                if (ident->uuid_set &&
-                   (!super || same_uuid(info.uuid, ident->uuid)==0)) {
+                   (!super || same_uuid(info.uuid, ident->uuid, tst->ss->swapuuid)==0)) {
                        if (inargv || verbose)
                                fprintf(stderr, Name ": %s has wrong uuid.\n",
                                        devname);
index 9fa9faa28b9e1edbaf806bdaee0cb89ea74e86d1..0dfba4e9d45d8868ad9764097777032d0ab61b13 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,7 @@
-Changes Prior to this release
+Changes Prior to 2.0-devel-3 release
+    -   Assorted fixes for multiple bugs...
+       
+Changes Prior to 1.12.0 release
   Several of these are backported from the Debian package
     -   Don't use 'lstat' to check for blockdevices, use stat.
     -   Document --size=max option for --grow
@@ -32,7 +35,7 @@ Changes Prior to 1.10.0 release
     -   Open sub-devices with O_EXCL to detect if already in use
     -   Make sure superblock updates are flushed directly to disk.
        
-Changes Prior to 2.0-deve-1 release
+Changes Prior to 2.0-devel-1 release
     -   Support for version-1 superblock.  See --metadata option.
     -   Support for bitmap based intent logging.
     -   Minor fixes.
index 6f6f501bbefe1b7b02e410d277b51fb067ee2add..53accd7e9a1722013dc77d28408e3bc5ae0d913f 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -196,7 +196,7 @@ int Manage_subdevs(char *devname, int fd,
                        return 1;
                case 'a':
                        /* add the device - hot or cold */
-                       /* Make sure it isn' in use (in 2.6 or later) */
+                       /* Make sure it isn't in use (in 2.6 or later) */
                        tfd = open(dv->devname, O_RDONLY|O_EXCL);
                        if (tfd < 0) {
                                fprintf(stderr, Name ": Cannot open %s: %s\n",
@@ -228,7 +228,7 @@ int Manage_subdevs(char *devname, int fd,
                                        array.major_version, array.minor_version);
                                return 1;
                        }
-                       for (j=0; j<array.raid_disks+array.spare_disks+ array.failed_disks; j++) {
+                       for (j=0; j<st->max_devs; j++) {
                                char *dev;
                                int dfd;
                                disc.number = j;
@@ -253,7 +253,7 @@ int Manage_subdevs(char *devname, int fd,
                                fprintf(stderr, Name ": cannot find valid superblock in this array - HELP\n");
                                return 1;
                        }
-                       for (j=0; j<array.nr_disks; j++) {
+                       for (j=0; j< st->max_devs; j++) {
                                disc.number = j;
                                if (ioctl(fd, GET_DISK_INFO, &disc))
                                        break;
@@ -266,11 +266,12 @@ int Manage_subdevs(char *devname, int fd,
                        disc.minor = minor(stb.st_rdev);
                        disc.number =j;
                        disc.state = 0;
+                       st->ss->add_to_super(dsuper, &disc);
                        if (st->ss->write_init_super(st, dsuper, &disc, dv->devname))
                                return 1;
                        if (ioctl(fd,ADD_NEW_DISK, &disc)) {
-                               fprintf(stderr, Name ": add new device failed for %s: %s\n",
-                                       dv->devname, strerror(errno));
+                               fprintf(stderr, Name ": add new device failed for %s as %d: %s\n",
+                                       dv->devname, j, strerror(errno));
                                return 1;
                        }
                        fprintf(stderr, Name ": added %s\n", dv->devname);
index c967af2f802bbd745513f9e5892ac77619d267b0..96a26f9a96195446c6a35c6e28fcffd7a60b62f6 100644 (file)
--- a/bitmap.c
+++ b/bitmap.c
@@ -243,8 +243,8 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
        printf("           State : %s\n", bitmap_state(sb->state));
        printf("       Chunksize : %s\n", human_chunksize(sb->chunksize));
        printf("          Daemon : %ds flush period\n", sb->daemon_sleep);
-       printf("       Sync Size : %llu%s\n", sb->sync_size,
-                                       human_size(sb->sync_size * 1024));
+       printf("       Sync Size : %llu%s\n", sb->sync_size/2,
+                                       human_size(sb->sync_size * 512));
        if (brief)
                goto free_info;
        printf("          Bitmap : %llu bits (chunks), %llu dirty (%2.1f%%)\n",
index 08a8ed1aae71a650830615197f240eeb4836b3b6..40f33ac59afd90d79e9abbf15ab1e2dbdeab1dca 100644 (file)
--- a/config.c
+++ b/config.c
@@ -275,6 +275,8 @@ void arrayline(char *line)
        mis.spare_group = NULL;
        mis.autof = 0;
        mis.next = NULL;
+       mis.st = NULL;
+       mis.bitmap_fd = -1;
 
        for (w=dl_next(line); w!=line; w=dl_next(w)) {
                if (w[0] == '/') {
@@ -293,7 +295,7 @@ void arrayline(char *line)
                                        fprintf(stderr, Name ": bad uuid: %s\n", w);
                        }
                } else if (strncasecmp(w, "super-minor=", 12)==0 ) {
-                       if (mis.super_minor >= 0)
+                       if (mis.super_minor != UnSet)
                                fprintf(stderr, Name ": only specify super-minor once, %s ignored.\n",
                                        w);
                        else {
diff --git a/mdadm.h b/mdadm.h
index 4ad4d47dcf8375c1a5206ae5e0e3b65dd43fa10c..fa8ea69bcd7fa3692566bd993da11511c9a4ac6f 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -190,6 +190,7 @@ extern struct superswitch {
        void (*locate_bitmap)(struct supertype *st, int fd);
        int (*write_bitmap)(struct supertype *st, int fd, void *sbv);
        int major;
+       int swapuuid; /* true if uuid is bigending rather than hostendian */
 } super0, super1, *superlist[];
 
 struct supertype {
@@ -281,7 +282,7 @@ extern char *conf_word(FILE *file, int allow_key);
 extern void free_line(char *line);
 extern int match_oneof(char *devices, char *devname);
 extern void uuid_from_super(int uuid[4], mdp_super_t *super);
-extern int same_uuid(int a[4], int b[4]);
+extern int same_uuid(int a[4], int b[4], int swapuuid);
 /* extern int compare_super(mdp_super_t *first, mdp_super_t *second);*/
 extern unsigned long calc_csum(void *super, int bytes);
 extern int enough(int level, int raid_disks, int avail_disks);
index 7e1b58d9a143ea41408a029b9910bea66ad5dd3d..7ff5ff427cab070f3d88f9c4a89caf346c82cc32 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -500,7 +500,7 @@ static int compare_super0(void **firstp, void *secondv)
 
        uuid_from_super0(uuid1, first);
        uuid_from_super0(uuid2, second);
-       if (!same_uuid(uuid1, uuid2))
+       if (!same_uuid(uuid1, uuid2, 0))
                return 2;
        if (first->major_version != second->major_version ||
            first->minor_version != second->minor_version ||
@@ -638,7 +638,7 @@ static int add_internal_bitmap0(void *sbv, int chunk, int delay, unsigned long l
        bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MD_SB_BYTES);
 
        
-       min_chunk = 1024;
+       min_chunk = 4096; /* sub-page chunks don't work yet.. */
        while (bits > max_bits) {
                min_chunk *= 2;
                bits = (bits+1)/2;
@@ -767,4 +767,5 @@ struct superswitch super0 = {
        .locate_bitmap = locate_bitmap0,
        .write_bitmap = write_bitmap0,
        .major = 0,
+       .swapuuid = 0,
 };
index 6bd5ceca05c997b3cc0076d52e31da3834204045..3c24f3481553dc1b953e9da860064f34cf9f17cd 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -28,7 +28,7 @@
  */
 
 #include "mdadm.h"
-
+#include <endian.h>
 #include "asm/byteorder.h"
 /*
  * The version-1 superblock :
@@ -804,4 +804,9 @@ struct superswitch super1 = {
        .match_metadata_desc = match_metadata_desc1,
        .avail_size = avail_size1,
        .major = 1,
+#if __BYTE_ORDER == BIG_ENDIAN
+       .swapuuid = 0,
+#else
+       .swapuuid = 1,
+#endif
 };
diff --git a/util.c b/util.c
index 8756d499e64d06b56233cabae726f04dd144329d..7621340bc2b24d6f34abfc1758e930b4a1361f4f 100644 (file)
--- a/util.c
+++ b/util.c
@@ -140,14 +140,32 @@ int enough(int level, int raid_disks, int avail_disks)
        }
 }
 
-int same_uuid(int a[4], int b[4])
+int same_uuid(int a[4], int b[4], int swapuuid)
 {
-    if (a[0]==b[0] &&
-       a[1]==b[1] &&
-       a[2]==b[2] &&
-       a[3]==b[3])
-       return 1;
-    return 0;
+       if (swapuuid) {
+               /* parse uuids are hostendian.
+                * uuid's from some superblocks are big-ending
+                * if there is a difference, we need to swap.. 
+                */
+               unsigned char *ac = (unsigned char *)a;
+               unsigned char *bc = (unsigned char *)b;
+               int i;
+               for (i=0; i<16; i+= 4) {
+                       if (ac[i+0] != bc[i+3] ||
+                           ac[i+1] != bc[i+2] ||
+                           ac[i+2] != bc[i+1] ||
+                           ac[i+3] != bc[i+0])
+                               return 0;
+               }
+               return 1;
+       } else {
+               if (a[0]==b[0] &&
+                   a[1]==b[1] &&
+                   a[2]==b[2] &&
+                   a[3]==b[3])
+                       return 1;
+               return 0;
+       }
 }
 
 int check_ext2(int fd, char *name)
@@ -585,6 +603,7 @@ struct supertype *guess_super(int fd)
        for (i=0 ; superlist[i]; i++) {
                int rv;
                ss = superlist[i];
+               st->ss = NULL;
                rv = ss->load_super(st, fd, &sbp, NULL);
                if (rv == 0) {
                        struct mdinfo info;
@@ -594,12 +613,12 @@ struct supertype *guess_super(int fd)
                                bestsuper = i;
                                besttime = info.array.ctime;
                        }
-                       st->ss = NULL;
                        free(sbp);
                }
        }
        if (bestsuper != -1) {
                int rv;
+               st->ss = NULL;
                rv = superlist[bestsuper]->load_super(st, fd, &sbp, NULL);
                if (rv == 0) {
                        free(sbp);