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--