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>
This commit is contained in:
Neil Brown 2005-08-04 04:41:12 +00:00
parent 11018a4592
commit f277ce3671
9 changed files with 55 additions and 23 deletions

View 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);

View File

@ -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.

View File

@ -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);

View File

@ -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",

View File

@ -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 {

View File

@ -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);

View File

@ -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,
};

View File

@ -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
};

35
util.c
View File

@ -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);