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]

Reply via email to