diff options
author | Neil Brown <neilb@suse.de> | 2005-08-04 06:41:12 +0200 |
---|---|---|
committer | Neil Brown <neilb@suse.de> | 2005-08-04 06:41:12 +0200 |
commit | f277ce367125882ea809f981172b8d5c0cc4d5c7 (patch) | |
tree | 9694dfe2d09a972eb38c0d33d8ba6a5153ccb2f6 | |
parent | Redhat 6.2 seems to require sys/time.h as well as time.h (diff) | |
download | mdadm-f277ce367125882ea809f981172b8d5c0cc4d5c7.tar.xz mdadm-f277ce367125882ea809f981172b8d5c0cc4d5c7.zip |
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 <neilb@cse.unsw.edu.au>
-rw-r--r-- | Assemble.c | 2 | ||||
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | Manage.c | 11 | ||||
-rw-r--r-- | bitmap.c | 4 | ||||
-rw-r--r-- | config.c | 4 | ||||
-rw-r--r-- | mdadm.h | 3 | ||||
-rw-r--r-- | super0.c | 5 | ||||
-rw-r--r-- | super1.c | 7 | ||||
-rw-r--r-- | util.c | 35 |
9 files changed, 55 insertions, 23 deletions
@@ -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); @@ -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. @@ -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); @@ -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", @@ -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 { @@ -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); @@ -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, }; @@ -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 }; @@ -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); |