Subject: Re: Dumping to wedges
To: None <tech-kern@NetBSD.org>
From: Martin Husemann <martin@duskware.de>
List: tech-kern
Date: 08/15/2006 03:07:17
--fUYQa+Pmc3FrFX/N
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Mon, Aug 14, 2006 at 10:12:18PM +0200, Martin Husemann wrote:
> Besides wedges not autoconfiguring the dump device (which is pretty easy to
> solve and testable w/o writing a dump all over your disk ;-})

Here is a complete patch, including the autoconfig parts.
I haven't tried writing a kernel dump with it yet.

Comments?

Martin

--fUYQa+Pmc3FrFX/N
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=patch

Index: dev/dkwedge/dk.c
===================================================================
RCS file: /cvsroot/src/sys/dev/dkwedge/dk.c,v
retrieving revision 1.16
diff -u -r1.16 dk.c
--- dev/dkwedge/dk.c	21 Jul 2006 16:48:48 -0000	1.16
+++ dev/dkwedge/dk.c	15 Aug 2006 01:02:10 -0000
@@ -875,6 +875,35 @@
 }
 
 /*
+ * dkwedge_find_swap	[exported function]
+ *
+ *	Find the next wedge with type swap on the same parent disk.
+ */
+struct device *
+dkwedge_find_swap(struct device *dev)
+{
+	struct dkwedge_softc *sc, *w;
+	int unit;
+
+	unit = device_unit(dev);
+	if (unit >= ndkwedges)
+		return NULL;
+
+	KASSERT(dkwedges != NULL);
+
+	sc = dkwedges[unit];
+	if (sc == NULL)
+		return NULL;
+
+	LIST_FOREACH(w, &sc->sc_parent->dk_wedges, sc_plink) {
+		if (strcmp(w->sc_ptype, DKW_PTYPE_SWAP) == 0)
+			return w->sc_dev;
+	}
+
+	return NULL;
+}
+
+/*
  * dkopen:		[devsw entry point]
  *
  *	Open a wedge.
@@ -1253,7 +1282,37 @@
 static int
 dkdump(dev_t dev, daddr_t blkno, caddr_t va, size_t size)
 {
+	struct dkwedge_softc *sc = dkwedge_lookup(dev);
+	const struct bdevsw *bdev;
+	int rv = 0;
+
+	if (sc == NULL)
+		return (-1);
+	
+	if (sc->sc_state != DKW_STATE_RUNNING)
+		return (ENXIO);
+
+	(void) lockmgr(&sc->sc_dk.dk_openlock, LK_EXCLUSIVE, NULL);
+	(void) lockmgr(&sc->sc_parent->dk_rawlock, LK_EXCLUSIVE, NULL);
+
+	/* Our content type is static, no need to open the device. */
+
+	if (strcmp(sc->sc_ptype, DKW_PTYPE_SWAP) != 0) {
+		rv = ENXIO;
+		goto out;
+	}
+	if (blkno + size > sc->sc_size) {
+		rv = EINVAL;
+		goto out;
+	}
+
+	bdev = bdevsw_lookup(sc->sc_pdev);
+	rv = (*bdev->d_dump)(sc->sc_pdev, blkno+sc->sc_offset, va,
+	    size);
+
+out:
+	(void) lockmgr(&sc->sc_parent->dk_rawlock, LK_RELEASE, NULL);
+	(void) lockmgr(&sc->sc_dk.dk_openlock, LK_RELEASE, NULL);
 
-	/* XXX */
-	return (ENXIO);
+	return rv;
 }
Index: kern/kern_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_subr.c,v
retrieving revision 1.141
diff -u -r1.141 kern_subr.c
--- kern/kern_subr.c	12 Aug 2006 21:46:03 -0000	1.141
+++ kern/kern_subr.c	15 Aug 2006 01:02:10 -0000
@@ -108,6 +108,7 @@
 #include <sys/ktrace.h>
 #include <sys/ptrace.h>
 #include <sys/fcntl.h>
+#include <sys/disk.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -1059,8 +1060,9 @@
 	 *
 	 *	(c) If dumpspec is not set, the dump device is
 	 *	    wildcarded or unspecified.  If the root device
-	 *	    is DV_IFNET, punt.  Otherwise, use partition b
-	 *	    of the root device.
+	 *	    is a wedge, use the first "swap" wedge.
+	 *	    If the root device is DV_IFNET, punt.
+	 *	    Otherwise, use partition b of the root device.
 	 */
 
 	if (boothowto & RB_ASKNAME) {		/* (a) */
@@ -1091,9 +1093,14 @@
 			goto nodumpdev;
 		}
 	} else {				/* (c) */
-		if (DEV_USES_PARTITIONS(rootdv) == 0)
+		if (device_is_a(rootdv, "dk")) {
+			dumpdv = dkwedge_find_swap(rootdv);
+			if (dumpdv == NULL)
+				goto nodumpdev;
+			dumpdev = makedev(major(rootdev), device_unit(dumpdv));
+		} else if (DEV_USES_PARTITIONS(rootdv) == 0) {
 			goto nodumpdev;
-		else {
+		} else {
 			dumpdv = rootdv;
 			dumpdev = MAKEDISKDEV(major(rootdev),
 			    device_unit(dumpdv), 1);
Index: sys/disk.h
===================================================================
RCS file: /cvsroot/src/sys/sys/disk.h,v
retrieving revision 1.36
diff -u -r1.36 disk.h
--- sys/disk.h	21 Apr 2006 13:53:30 -0000	1.36
+++ sys/disk.h	15 Aug 2006 01:02:10 -0000
@@ -300,6 +300,7 @@
 int	dkwedge_add(struct dkwedge_info *);
 int	dkwedge_del(struct dkwedge_info *);
 void	dkwedge_delall(struct disk *);
+struct device *	dkwedge_find_swap(struct device *);
 int	dkwedge_list(struct disk *, struct dkwedge_list *, struct lwp *);
 void	dkwedge_discover(struct disk *);
 void	dkwedge_set_bootwedge(struct device *, daddr_t, uint64_t);

--fUYQa+Pmc3FrFX/N--