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>
}
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);
-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
- 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.
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",
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;
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;
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);
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",
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] == '/') {
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 {
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 {
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);
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 ||
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;
.locate_bitmap = locate_bitmap0,
.write_bitmap = write_bitmap0,
.major = 0,
+ .swapuuid = 0,
};
*/
#include "mdadm.h"
-
+#include <endian.h>
#include "asm/byteorder.h"
/*
* The version-1 superblock :
.match_metadata_desc = match_metadata_desc1,
.avail_size = avail_size1,
.major = 1,
+#if __BYTE_ORDER == BIG_ENDIAN
+ .swapuuid = 0,
+#else
+ .swapuuid = 1,
+#endif
};
}
}
-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)
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;
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);