From 26b322134bc1a467057c05882af7450ef640bed7 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sun, 1 Mar 2020 02:33:24 +0000 Subject: [PATCH 1/2] Allow dumping to cgd(4) on a dk(4). (Technically this also allows dumping to a dk(4) on which there happens to be a cgd(4) configured, but I'm not sure how to distinguish that case here. So don't do that!) --- sys/dev/dkwedge/dk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/dkwedge/dk.c b/sys/dev/dkwedge/dk.c index 9492cf0d88ca..29af0c5e2345 100644 --- a/sys/dev/dkwedge/dk.c +++ b/sys/dev/dkwedge/dk.c @@ -1622,7 +1622,8 @@ dkdump(dev_t dev, daddr_t blkno, void *va, size_t size) /* Our content type is static, no need to open the device. */ if (strcmp(sc->sc_ptype, DKW_PTYPE_SWAP) != 0 && - strcmp(sc->sc_ptype, DKW_PTYPE_RAID) != 0) { + strcmp(sc->sc_ptype, DKW_PTYPE_RAID) != 0 && + strcmp(sc->sc_ptype, DKW_PTYPE_CGD) != 0) { rv = ENXIO; goto out; } From a7f3f6699a9fb4ceaa6e9be9f842f388751880c4 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sun, 1 Mar 2020 02:37:59 +0000 Subject: [PATCH 2/2] Add a flag to dk_dump for virtual disk devices. If a disk is backed by a physical medium other than itself, such as cgd(4), then it passes DK_DUMP_RECURIVE to disable the recursion detection for dk_dump. If, however, a device represents a physical medium on its own, such as wd(4), then it passes 0 instead. --- sys/arch/xen/xen/xbd_xenbus.c | 2 +- sys/dev/ata/wd.c | 2 +- sys/dev/cgd.c | 2 +- sys/dev/dksubr.c | 8 +++++--- sys/dev/dkvar.h | 4 +++- sys/dev/ld.c | 2 +- sys/dev/raidframe/rf_netbsdkintf.c | 2 +- sys/dev/scsipi/sd.c | 2 +- 8 files changed, 14 insertions(+), 10 deletions(-) diff --git a/sys/arch/xen/xen/xbd_xenbus.c b/sys/arch/xen/xen/xbd_xenbus.c index 5976988dde20..df35d3b8d993 100644 --- a/sys/arch/xen/xen/xbd_xenbus.c +++ b/sys/arch/xen/xen/xbd_xenbus.c @@ -930,7 +930,7 @@ xbddump(dev_t dev, daddr_t blkno, void *va, size_t size) DPRINTF(("xbddump(%d, %" PRId64 ", %p, %lu)\n", dev, blkno, va, (unsigned long)size)); - return dk_dump(&sc->sc_dksc, dev, blkno, va, size); + return dk_dump(&sc->sc_dksc, dev, blkno, va, size, 0); } static int diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c index be12f307ac5f..82b43f20f030 100644 --- a/sys/dev/ata/wd.c +++ b/sys/dev/ata/wd.c @@ -1570,7 +1570,7 @@ wddump(dev_t dev, daddr_t blkno, void *va, size_t size) return (ENXIO); dksc = &wd->sc_dksc; - return dk_dump(dksc, dev, blkno, va, size); + return dk_dump(dksc, dev, blkno, va, size, 0); } static int diff --git a/sys/dev/cgd.c b/sys/dev/cgd.c index 46512e0bbbf0..2ed4506191f8 100644 --- a/sys/dev/cgd.c +++ b/sys/dev/cgd.c @@ -770,7 +770,7 @@ cgddump(dev_t dev, daddr_t blkno, void *va, size_t size) DPRINTF_FOLLOW(("cgddump(0x%"PRIx64", %" PRId64 ", %p, %lu)\n", dev, blkno, va, (unsigned long)size)); GETCGD_SOFTC(cs, dev); - return dk_dump(&cs->sc_dksc, dev, blkno, va, size); + return dk_dump(&cs->sc_dksc, dev, blkno, va, size, DK_DUMP_RECURSIVE); } /* diff --git a/sys/dev/dksubr.c b/sys/dev/dksubr.c index 90ba04166efc..8d354a019d82 100644 --- a/sys/dev/dksubr.c +++ b/sys/dev/dksubr.c @@ -761,7 +761,7 @@ static volatile int dk_dumping = 0; /* ARGSUSED */ int dk_dump(struct dk_softc *dksc, dev_t dev, - daddr_t blkno, void *vav, size_t size) + daddr_t blkno, void *vav, size_t size, int flags) { const struct dkdriver *dkd = dksc->sc_dkdev.dk_driver; struct disk_geom *dg = &dksc->sc_dkdev.dk_geom; @@ -784,7 +784,8 @@ dk_dump(struct dk_softc *dksc, dev_t dev, /* ensure that we are not already dumping */ if (dk_dumping) return EFAULT; - dk_dumping = 1; + if ((flags & DK_DUMP_RECURSIVE) == 0) + dk_dumping = 1; if (dkd->d_dumpblocks == NULL) { DPRINTF(DKDB_DUMP, ("%s: no dumpblocks\n", __func__)); @@ -863,7 +864,8 @@ dk_dump(struct dk_softc *dksc, dev_t dev, va += nblk * lp->d_secsize; } - dk_dumping = 0; + if ((flags & DK_DUMP_RECURSIVE) == 0) + dk_dumping = 0; return 0; } diff --git a/sys/dev/dkvar.h b/sys/dev/dkvar.h index 0be2cd0d47c8..84e8a8eae391 100644 --- a/sys/dev/dkvar.h +++ b/sys/dev/dkvar.h @@ -83,6 +83,8 @@ struct dk_softc { ((_dksc)->sc_dkdev.dk_bopenmask & (_pmask) && \ ((_dksc)->sc_dkdev.dk_copenmask & (_pmask)))) +#define DK_DUMP_RECURSIVE __BIT(0) /* this is a virtual disk */ + /* * Functions that are exported to the pseudo disk implementations: */ @@ -106,7 +108,7 @@ int dk_size(struct dk_softc *, dev_t); int dk_ioctl(struct dk_softc *, dev_t, u_long, void *, int, struct lwp *); int dk_dump(struct dk_softc *, dev_t, - daddr_t, void *, size_t); + daddr_t, void *, size_t, int); void dk_getdisklabel(struct dk_softc *, dev_t); void dk_getdefaultlabel(struct dk_softc *, struct disklabel *); diff --git a/sys/dev/ld.c b/sys/dev/ld.c index c07477c4b95d..1923d9c5a214 100644 --- a/sys/dev/ld.c +++ b/sys/dev/ld.c @@ -507,7 +507,7 @@ lddump(dev_t dev, daddr_t blkno, void *va, size_t size) if ((sc->sc_flags & LDF_ENABLED) == 0) return (ENODEV); - return dk_dump(dksc, dev, blkno, va, size); + return dk_dump(dksc, dev, blkno, va, size, 0); } static int diff --git a/sys/dev/raidframe/rf_netbsdkintf.c b/sys/dev/raidframe/rf_netbsdkintf.c index d9a7c7ba4699..0225ec43624f 100644 --- a/sys/dev/raidframe/rf_netbsdkintf.c +++ b/sys/dev/raidframe/rf_netbsdkintf.c @@ -663,7 +663,7 @@ raiddump(dev_t dev, daddr_t blkno, void *va, size_t size) */ blkno += RF_PROTECTED_SECTORS; - return dk_dump(dksc, dev, blkno, va, size); + return dk_dump(dksc, dev, blkno, va, size, DK_DUMP_RECURSIVE); } static int diff --git a/sys/dev/scsipi/sd.c b/sys/dev/scsipi/sd.c index d8812542a4fc..655f6ce81972 100644 --- a/sys/dev/scsipi/sd.c +++ b/sys/dev/scsipi/sd.c @@ -1192,7 +1192,7 @@ sddump(dev_t dev, daddr_t blkno, void *va, size_t size) if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) return (ENXIO); - return dk_dump(dksc, dev, blkno, va, size); + return dk_dump(dksc, dev, blkno, va, size, 0); } static int