summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2005-08-04 04:41:12 +0000
committerNeil Brown <neilb@suse.de>2005-08-04 04:41:12 +0000
commitf277ce367125882ea809f981172b8d5c0cc4d5c7 (patch)
tree9694dfe2d09a972eb38c0d33d8ba6a5153ccb2f6
parent11018a4592680d0d9312c21bf7689bc8db55a609 (diff)
downloadmdadm-f277ce367125882ea809f981172b8d5c0cc4d5c7.tar.gz
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.c2
-rw-r--r--ChangeLog7
-rw-r--r--Manage.c11
-rw-r--r--bitmap.c4
-rw-r--r--config.c4
-rw-r--r--mdadm.h3
-rw-r--r--super0.c5
-rw-r--r--super1.c7
-rw-r--r--util.c35
9 files changed, 55 insertions, 23 deletions
diff --git a/Assemble.c b/Assemble.c
index 89086e3..20183ae 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 9fa9faa..0dfba4e 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 6f6f501..53accd7 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; 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);
diff --git a/bitmap.c b/bitmap.c
index c967af2..96a26f9 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 08a8ed1..40f33ac 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 4ad4d47..fa8ea69 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 7e1b58d..7ff5ff4 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 6bd5cec..3c24f34 100644
--- 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 8756d49..7621340 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);