Package: quik Version: 2.1-6 Tags: patch quik-2.1-6 segfaults when a spare/faulty device is present in a RAID1 md mirror. The attached patch solves the problem
diff -Naur quik-2.1.orig/include/quik_md.h quik-2.1/include/quik_md.h --- quik-2.1.orig/include/quik_md.h 2005-09-04 12:19:10.000000000 +0200 +++ quik-2.1/include/quik_md.h 2005-09-04 12:00:40.000000000 +0200 @@ -40,6 +40,14 @@ /* From md_p.h */ #define MD_SB_DISKS 27 +/* + * Device "operational" state bits + */ +#define MD_DISK_FAULTY 0 /* disk is faulty / operational */ +#define MD_DISK_ACTIVE 1 /* disk is running or spare disk */ +#define MD_DISK_SYNC 2 /* disk is in sync with the raid set */ +#define MD_DISK_REMOVED 3 /* disk is in sync with the raid set */ + #include <linux/raid/md_u.h> struct devmap { @@ -62,7 +70,7 @@ int add_dev(const char *, const struct stat *, int, struct FTW *); int digit_offset (const char *); -//void fatal (const char *); +/* void fatal (const char *); */ typedef struct dev_info { char * bootdev; /* Physical device, e.g. /dev/hda */ @@ -85,8 +93,8 @@ int rlevel; } mdev_info_t; -#define BOOTDEV(dev,i) ((dev)->devs[(i)]->bootdev) -#define SPART(dev,i) ((dev)->devs[(i)]->spart) +#define BOOTDEV(dev,i) (((dev)->devs[(i)]) ? (dev)->devs[(i)]->bootdev : NULL) +#define SPART(dev,i) (((dev)->devs[(i)]) ? (dev)->devs[(i)]->spart : NULL) dev_info_t * new_dev_info (unsigned char); void free_dev_info (dev_info_t *); diff -Naur quik-2.1.orig/quik/quik.c quik-2.1/quik/quik.c --- quik-2.1.orig/quik/quik.c 2005-09-04 12:19:10.000000000 +0200 +++ quik-2.1/quik/quik.c 2005-09-04 12:06:37.000000000 +0200 @@ -129,15 +129,15 @@ close(fd); for (i=0; i<devs->ndevs; i++) { - if (devs->devs[i]->bootdev) { /* Handle "missing" raid devices */ + if (BOOTDEV(devs,i)) { /* Handle "missing" and spare raid devices */ partno = part_from_dev(SPART(devs,i)); if (partno == 0) fatal("Can't determine partition number for %s", SPART(devs,i)); upart = 0; mp = (struct mac_partition *) buff; md = (struct mac_driver_desc *) buff; - if ((fd = open(devs->devs[i]->bootdev, O_RDONLY)) == -1) - fatal("Can't open %s", BOOTDEV(devs, i)); + if ((fd = open(BOOTDEV(devs,i), O_RDONLY)) == -1) + fatal("Can't open %s", BOOTDEV(devs,i)); if (read(fd, buff, sizeof (buff)) != sizeof (buff)) fatal("Error reading %s (block 0)", BOOTDEV(devs, i)); if (md->signature != MAC_DRIVER_MAGIC) @@ -184,43 +184,46 @@ off_t seek_offset; for (i=0; i<devs->ndevs; i++) { - if (devs->devs[i]->part_block == 0) - return; - if (verbose) + if (devs->devs[i]) { + if (devs->devs[i]->part_block == 0) + return; + if (verbose) printf("Making %s bootable (map entry %d)\n", SPART(devs, i), devs->devs[i]->part_block); - if (devs->devs[i]->first_bootable > 0 - && devs->devs[i]->first_bootable < devs->devs[i]->part_block) - fprintf(stderr, "Warning: prior partition (entry %d) is bootable\n", - devs->devs[i]->first_bootable); - if ((fd = open(BOOTDEV(devs,i), O_RDWR)) < 0) + if (devs->devs[i]->first_bootable > 0 + && devs->devs[i]->first_bootable < devs->devs[i]->part_block) + fprintf(stderr, "Warning: prior partition (entry %d) is bootable\n", + devs->devs[i]->first_bootable); + if ((fd = open(BOOTDEV(devs,i), O_RDWR)) < 0) fatal("Cannot open %s for writing\n", BOOTDEV(devs,i)); - seek_offset = (off_t)devs->devs[i]->part_block * devs->devs[i]->secsize; - lseek(fd, seek_offset, 0); - if (read(fd, buff, sizeof(buff)) != sizeof(buff)) { - close(fd); - fatal("Error reading partition map entry %d from %s\n", - devs->devs[i]->part_block, - BOOTDEV(devs,i)); - } - mp = (struct mac_partition *) buff; - mp->status |= STATUS_BOOTABLE; - mp->boot_start = 0; - mp->boot_size = 1024; - mp->boot_load = FIRST_BASE; - mp->boot_load2 = 0; - mp->boot_entry = FIRST_BASE; - mp->boot_entry2 = 0; - strncpy(mp->processor, "PowerPC", sizeof(mp->processor)); - if (lseek(fd, seek_offset, 0) < 0 - || write(fd, buff, sizeof(buff)) != sizeof(buff)) { - close(fd); - fatal("Couldn't make %s%d bootable: write error\n", - BOOTDEV(devs,i), - devs->devs[i]->part_block); - } + + seek_offset = (off_t)devs->devs[i]->part_block * devs->devs[i]->secsize; + lseek(fd, seek_offset, 0); + if (read(fd, buff, sizeof(buff)) != sizeof(buff)) { + close(fd); + fatal("Error reading partition map entry %d from %s\n", + devs->devs[i]->part_block, + BOOTDEV(devs,i)); + } + mp = (struct mac_partition *) buff; + mp->status |= STATUS_BOOTABLE; + mp->boot_start = 0; + mp->boot_size = 1024; + mp->boot_load = FIRST_BASE; + mp->boot_load2 = 0; + mp->boot_entry = FIRST_BASE; + mp->boot_entry2 = 0; + strncpy(mp->processor, "PowerPC", sizeof(mp->processor)); + if (lseek(fd, seek_offset, 0) < 0 + || write(fd, buff, sizeof(buff)) != sizeof(buff)) { + close(fd); + fatal("Couldn't make %s%d bootable: write error\n", + BOOTDEV(devs,i), + devs->devs[i]->part_block); + } close(fd); + } } } diff -Naur quik-2.1.orig/quik/quik_md.c quik-2.1/quik/quik_md.c --- quik-2.1.orig/quik/quik_md.c 2005-09-04 12:19:10.000000000 +0200 +++ quik-2.1/quik/quik_md.c 2005-09-04 11:56:23.000000000 +0200 @@ -61,6 +61,7 @@ /* From quik.c */ void fatal(char *fmt,...) __attribute__ ((noreturn)); +extern int verbose; mdev_info_t * md_get_info (const char * device) { @@ -78,14 +79,14 @@ fatal("Couldn't get array info for device %s\n", device); } - out = new_mdev_info(array.raid_disks); + out = new_mdev_info(array.nr_disks); out->rlevel = array.level; /* Not needed for the moment */ c = map_num(pers, array.level); /* fprintf(stderr, "ARRAY %s level=%s num-devices=%d\n", - md_dev, c?c:"unknown", array.raid_disks); */ + device, c?c:"unknown", array.nr_disks); */ /* Get devices */ for (d=0; d < MD_SB_DISKS; d++) { @@ -94,11 +95,21 @@ int o; disk.number = d; if (ioctl(mdev_fd, GET_DISK_INFO, &disk) < 0) { continue; } + if (d > array.raid_disks && disk.major == 0 && disk.minor == 0) { continue; } if ((dv=map_dev(disk.major, disk.minor))) { + /* Ignore spare & faulty devices */ + if (disk.state == 0 || (disk.state & (1<<MD_DISK_FAULTY))) { + if (verbose) + printf("Ignoring spare or faulty device %s\n", dv); + free_dev_info(out->devs[i]); + out->devs[i]=NULL; + continue; + } + out->devs[i]->spart = (char *) malloc(strlen(dv)+1); strcpy(out->devs[i]->spart, dv); o = digit_offset(out->devs[i]->spart); Simon -- Simon Vallet [EMAIL PROTECTED] -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]