diff options
author | pjd <pjd@FreeBSD.org> | 2006-03-08 08:27:33 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2006-03-08 08:27:33 +0000 |
commit | 1c595687a8848b43bbbe289321caa315bc8fc740 (patch) | |
tree | a140b7acaecedceb2012b7c499a15e877f05dfe5 /sys/geom/mirror | |
parent | f1947eff71c8ad93627629ada8b60773f7f344e1 (diff) | |
download | FreeBSD-src-1c595687a8848b43bbbe289321caa315bc8fc740.zip FreeBSD-src-1c595687a8848b43bbbe289321caa315bc8fc740.tar.gz |
Allow to dump kernel to gmirror providers.
Some conditions have to be met to make it work properly. This will be
described in the manual page.
MFC after: 3 days
Diffstat (limited to 'sys/geom/mirror')
-rw-r--r-- | sys/geom/mirror/g_mirror.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index ce6ea5d..559272f 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -985,6 +985,38 @@ g_mirror_sync_done(struct bio *bp) } static void +g_mirror_kernel_dump(struct bio *bp) +{ + struct g_mirror_softc *sc; + struct g_mirror_disk *disk; + struct bio *cbp; + struct g_kerneldump *gkd; + + /* + * We configure dumping to the first component, because this component + * will be used for reading with 'prefer' balance algorithm. + * If the component with the higest priority is currently disconnected + * we will not be able to read the dump after the reboot if it will be + * connected and synchronized later. Can we do something better? + */ + sc = bp->bio_to->geom->softc; + disk = LIST_FIRST(&sc->sc_disks); + + gkd = (struct g_kerneldump *)bp->bio_data; + if (gkd->length > bp->bio_to->mediasize) + gkd->length = bp->bio_to->mediasize; + cbp = g_clone_bio(bp); + if (cbp == NULL) { + g_io_deliver(bp, ENOMEM); + return; + } + cbp->bio_done = g_std_done; + g_io_request(cbp, disk->d_consumer); + G_MIRROR_DEBUG(1, "Kernel dump will go to %s.", + g_mirror_get_diskname(disk)); +} + +static void g_mirror_start(struct bio *bp) { struct g_mirror_softc *sc; @@ -1005,6 +1037,11 @@ g_mirror_start(struct bio *bp) case BIO_DELETE: break; case BIO_GETATTR: + if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) { + g_mirror_kernel_dump(bp); + return; + } + /* FALLTHROUGH */ default: g_io_deliver(bp, EOPNOTSUPP); return; |