From f277ce367125882ea809f981172b8d5c0cc4d5c7 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Thu, 4 Aug 2005 04:41:12 +0000 Subject: [PATCH] Assorted Fixes for multiple bugs. Assemble would crash, or just not work. A few other problem found by a new test-suite. Signed-off-by: Neil Brown --- Assemble.c | 2 +- ChangeLog | 7 +++++-- Manage.c | 11 ++++++----- bitmap.c | 4 ++-- config.c | 4 +++- mdadm.h | 3 ++- super0.c | 5 +++-- super1.c | 7 ++++++- util.c | 35 +++++++++++++++++++++++++++-------- 9 files changed, 55 insertions(+), 23 deletions(-) diff --git a/Assemble.c b/Assemble.c index 89086e38..20183ae1 100644 --- a/Assemble.c +++ b/Assemble.c @@ -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); diff --git a/ChangeLog b/ChangeLog index 9fa9faa2..0dfba4e9 100644 --- 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. diff --git a/Manage.c b/Manage.c index 6f6f501b..53accd7e 100644 --- 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; jmax_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; jmax_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); diff --git a/bitmap.c b/bitmap.c index c967af2f..96a26f9a 100644 --- 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", diff --git a/config.c b/config.c index 08a8ed1a..40f33ac5 100644 --- 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 4ad4d47d..fa8ea69b 100644 --- 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); diff --git a/super0.c b/super0.c index 7e1b58d9..7ff5ff42 100644 --- 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, }; diff --git a/super1.c b/super1.c index 6bd5ceca..3c24f348 100644 --- a/super1.c +++ b/super1.c @@ -28,7 +28,7 @@ */ #include "mdadm.h" - +#include #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 8756d499..7621340b 100644 --- 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); -- 2.39.2