Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Nov 2005 17:33:50 -0800 (PST)
From:      Garry Belka <garry@NetworkPhysics.COM>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/89264: crash dump not implemented for RAID (ar) in 6.0
Message-ID:  <200511190133.jAJ1XoCN061610@focus5.fractal.networkphysics.com>
Resent-Message-ID: <200511190140.jAJ1eZJL022763@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         89264
>Category:       kern
>Synopsis:       crash dump not implemented for RAID (ar) in 6.0
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Nov 19 01:40:35 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Garry Belka
>Release:        FreeBSD 6.0-RELEASE i386
>Organization:
Network Physics
>Environment:
System: FreeBSD tempo 6.0-RELEASE i386 with ATA RAID1 configured:
ar0 consists of ad4 and ad6
	
>Description:
	dumpon /dev/ar0s1b fails because
dump support is not implemented in sys/dev/ata/ata-raid.c
	
>How-To-Repeat:
configure ar0 and do
dumpon /dev/ar0s1b
	
>Fix:
implement and enable ata_raid_dump()
patch below is an ar_dump() implementation from an older ATA code, 
modified for 6.0

--- ata_raid_dump.patch begins here ---
Index: ata-raid.c
===================================================================
RCS file: /u1/Repo/FreeBSD/sys/dev/ata/ata-raid.c,v
retrieving revision 1.11
diff -u -r1.11 ata-raid.c
--- ata-raid.c	5 Nov 2005 03:24:59 -0000	1.11
+++ ata-raid.c	19 Nov 2005 01:20:53 -0000
@@ -108,7 +108,7 @@
 
 /* device structures */
 static disk_strategy_t ata_raid_strategy;
-//static dumper_t ata_raid_dump;
+static dumper_t ata_raid_dump;
 
 static void
 ata_raid_attach(struct ar_softc *rdp, int writeback)
@@ -138,7 +138,7 @@
 	buffer[0] = '\0';
     rdp->disk = disk_alloc();
     rdp->disk->d_strategy = ata_raid_strategy;
-    //rdp->disk->d_dump = ata_raid_dump;
+    rdp->disk->d_dump = ata_raid_dump;
     rdp->disk->d_name = "ar";
     rdp->disk->d_sectorsize = DEV_BSIZE;
     rdp->disk->d_mediasize = (off_t)rdp->total_sectors * DEV_BSIZE;
@@ -228,6 +228,135 @@
 	break;
     }
     return error;
+}
+static int
+ata_raid_dump(void *arg, void *virtual, vm_offset_t physical,
+              off_t offset, size_t length)
+{
+#   define AD_SOFTC(ar_disk)  ((struct ad_softc *)device_get_ivars((ar_disk).dev))
+
+    struct disk *dp = arg;
+    struct ar_softc *rdp = dp->d_drv1;
+
+    struct disk *ap;
+    vm_offset_t pdata;
+    caddr_t vdata;
+    int blkno, count, chunk, error1, error2, lba, lbs, tmplba;
+    int drv = 0;
+
+    if (!rdp || !(rdp->status & AR_S_READY))
+        return ENXIO;
+
+    if (length == 0) {
+	for (drv = 0; drv < rdp->total_disks; drv++) {
+	    if (rdp->disks[drv].flags & AR_DF_ONLINE) {
+		ap = AD_SOFTC(rdp->disks[drv])->disk;
+		(void) ap->d_dump(ap, NULL, 0, 0, 0);
+	    }
+	}
+	return 0;
+    }
+    
+    blkno = offset / DEV_BSIZE;
+    vdata = virtual;
+    pdata = physical;
+    
+    for (count = howmany(length, DEV_BSIZE); count > 0; 
+	 count -= chunk, blkno += chunk, vdata += (chunk * DEV_BSIZE),
+	 pdata += (chunk * DEV_BSIZE)) {
+
+	switch (rdp->type) {
+	case AR_T_SPAN:
+	    lba = blkno;
+	    while (lba >= rdp->disks[drv].sectors)
+		lba -= rdp->disks[drv++].sectors;
+	    chunk = min(rdp->disks[drv].sectors - lba, count);
+	    break;
+	
+	case AR_T_RAID0:
+	case AR_T_RAID01:
+	    tmplba = blkno / rdp->interleave;
+	    chunk = blkno % rdp->interleave;
+	    if (blkno >= (rdp->total_sectors / (rdp->interleave * rdp->width)) *
+			 (rdp->interleave * rdp->width) ) {
+		lbs = (rdp->total_sectors - 
+		    ((rdp->total_sectors / (rdp->interleave * rdp->width)) *
+		     (rdp->interleave * rdp->width))) / rdp->width;
+		drv = (blkno - 
+		    ((rdp->total_sectors / (rdp->interleave * rdp->width)) *
+		     (rdp->interleave * rdp->width))) / lbs;
+		lba = ((tmplba / rdp->width) * rdp->interleave) +
+		      (blkno - ((tmplba / rdp->width) * rdp->interleave)) % lbs;
+		chunk = min(count, lbs);
+	    }
+	    else {
+		drv = tmplba % rdp->width;
+		lba = ((tmplba / rdp->width) * rdp->interleave) + chunk;
+		chunk = min(count, rdp->interleave - chunk);
+	    }
+	    break;
+	    
+	case AR_T_JBOD:
+	case AR_T_RAID1:
+	    drv = 0;
+	    lba = blkno;
+	    chunk = count;
+	    break;
+	    
+	default:
+	    printf("ar%d: unknown array type in ata_raid_dump\n", rdp->lun);
+	    return EIO;
+	}
+
+        /* offset on all but "first on HPTv2" */
+        if (!(drv == 0 && rdp->format == AR_F_HPTV2_RAID))
+            lba += rdp->offset_sectors;
+
+	switch (rdp->type) {
+	case AR_T_JBOD:
+	case AR_T_SPAN:
+	case AR_T_RAID0:
+	    if (rdp->disks[drv].flags & AR_DF_ONLINE) {
+		ap = AD_SOFTC(rdp->disks[drv])->disk;
+		error1 = ap->d_dump(ap, vdata, pdata,
+				    (off_t) lba * DEV_BSIZE,
+				    chunk * DEV_BSIZE);
+	    } else
+		error1 = EIO;
+	    if (error1)
+		return error1;
+	    break;
+
+	case AR_T_RAID1:
+	case AR_T_RAID01:
+	    if ((rdp->disks[drv].flags & AR_DF_ONLINE) ||
+		((rdp->status & AR_S_REBUILDING) && 
+		 (rdp->disks[drv].flags & AR_DF_SPARE))) {
+		ap = AD_SOFTC(rdp->disks[drv])->disk;
+		error1 = ap->d_dump(ap, vdata, pdata,
+				    (off_t) lba * DEV_BSIZE,
+				    chunk * DEV_BSIZE);
+	    } else
+		error1 = EIO;
+	    if ((rdp->disks[drv + rdp->width].flags & AR_DF_ONLINE) ||
+		((rdp->status & AR_S_REBUILDING) &&
+		 (rdp->disks[drv + rdp->width].flags & AR_DF_SPARE))) {
+		ap = AD_SOFTC(rdp->disks[drv + rdp->width])->disk;
+		error2 = ap->d_dump(ap, vdata, pdata,
+				    (off_t) lba * DEV_BSIZE,
+				    chunk * DEV_BSIZE);
+	    } else
+		error2 = EIO;
+	    if (error1 && error2)
+		return error1;
+	    break;
+	    
+	default:
+	    printf("ar%d: unknown array type in ata_raid_dump\n", rdp->lun);
+	    return EIO;
+	}
+    }
+    return 0;
 }
 
 static void
--- ata_raid_dump.patch ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200511190133.jAJ1XoCN061610>