From 53705e35aec166897e4e19f7d0c0b9391d2db0bd Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Tue, 23 Apr 2002 19:54:02 +0000 Subject: [PATCH] Implement the GEOMGETCONF ioctl which returns vital stats for the current device in XML in an sbuf. Sponsored by: DARPA & NAI Labs --- sys/geom/geom.h | 4 ++++ sys/geom/geom_bsd.c | 33 +++++++++++++++++++++------------ sys/geom/geom_dev.c | 18 +++++++++++++++++- sys/geom/geom_slice.c | 2 +- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/sys/geom/geom.h b/sys/geom/geom.h index d707a349afd..ab99c508fef 100644 --- a/sys/geom/geom.h +++ b/sys/geom/geom.h @@ -42,6 +42,8 @@ #include #include #include +#include +#include #ifndef _KERNEL /* @@ -284,4 +286,6 @@ extern struct sx topology_lock; #endif /* _KERNEL */ +#define GEOMGETCONF _IOWR('G', 0, struct sbuf) + #endif /* _GEOM_GEOM_H_ */ diff --git a/sys/geom/geom_bsd.c b/sys/geom/geom_bsd.c index 419998adf15..22d56b9d389 100644 --- a/sys/geom/geom_bsd.c +++ b/sys/geom/geom_bsd.c @@ -60,6 +60,7 @@ #define BSD_CLASS_NAME "BSD-class" struct g_bsd_softc { + off_t labeloffset; struct disklabel ondisk; struct disklabel inram; }; @@ -226,11 +227,13 @@ g_bsd_lesum(struct disklabel *dl, u_char *p) } static int -g_bsd_i386(struct g_slicer *gsp, struct g_consumer *cp, int secsize, struct disklabel *dl) +g_bsd_i386(struct g_slicer *gsp, struct g_consumer *cp, int secsize, struct g_bsd_softc *ms) { int error; u_char *buf; + struct disklabel *dl; + dl = &ms->ondisk; buf = g_read_data(cp, secsize * 1, secsize, &error); if (buf == NULL || error != 0) return(ENOENT); @@ -242,16 +245,21 @@ g_bsd_i386(struct g_slicer *gsp, struct g_consumer *cp, int secsize, struct disk else error = ENOENT; g_free(buf); - gsp->frontstuff = 16 * secsize; + if (error == 0) { + gsp->frontstuff = 16 * secsize; + ms->labeloffset = secsize * 1; + } return(error); } static int -g_bsd_alpha(struct g_slicer *gsp, struct g_consumer *cp, int secsize, struct disklabel *dl) +g_bsd_alpha(struct g_slicer *gsp, struct g_consumer *cp, int secsize, struct g_bsd_softc *ms) { int error; u_char *buf; + struct disklabel *dl; + dl = &ms->ondisk; buf = g_read_data(cp, 0, secsize, &error); if (buf == NULL || error != 0) return(ENOENT); @@ -263,7 +271,10 @@ g_bsd_alpha(struct g_slicer *gsp, struct g_consumer *cp, int secsize, struct dis else error = ENOENT; g_free(buf); - gsp->frontstuff = 16 * secsize; + if (error == 0) { + gsp->frontstuff = 16 * secsize; + ms->labeloffset = 64; + } return(error); } @@ -295,17 +306,15 @@ g_bsd_start(struct bio *bp) static void g_bsd_dumpconf(struct sbuf *sb, char *indent, struct g_geom *gp, struct g_consumer *cp __unused, struct g_provider *pp) { -#if 0 - struct g_mbr_softc *ms; + struct g_bsd_softc *ms; struct g_slicer *gsp; gsp = gp->softc; ms = gsp->softc; - if (pp != NULL) { - sbuf_printf(sb, "%s%d\n", - indent, ms->type[pp->index]); + if (pp == NULL && cp == NULL) { + sbuf_printf(sb, "%s%lld\n", + indent, ms->labeloffset); } -#endif g_slice_dumpconf(sb, indent, gp, cp, pp); } @@ -352,9 +361,9 @@ g_bsd_taste(struct g_class *mp, struct g_provider *pp, int flags) printf("g_error %d Mediasize is %lld bytes\n", error, (long long)mediasize); } - error = g_bsd_i386(gsp, cp, secsize, &ms->ondisk); + error = g_bsd_i386(gsp, cp, secsize, ms); if (error) - error = g_bsd_alpha(gsp, cp, secsize, &ms->ondisk); + error = g_bsd_alpha(gsp, cp, secsize, ms); if (error) break; dl = &ms->ondisk; diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index b845b0698c1..d74113bebd4 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #define CDEV_MAJOR 4 @@ -238,15 +239,19 @@ g_dev_close(dev_t dev, int flags, int fmt, struct thread *td) static int g_dev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td) { - struct g_geom *gp; + struct g_geom *gp, *gp2; struct g_consumer *cp; + struct g_provider *pp2; struct g_kerneldump kd; int i, error; u_int u; struct g_ioctl *gio; + struct sbuf *usb, *sb; gp = dev->si_drv1; cp = dev->si_drv2; + pp2 = cp->provider; + gp2 = pp2->geom; error = 0; DROP_GIANT(); @@ -282,6 +287,17 @@ g_dev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td) if (!error) dev->si_flags |= SI_DUMPDEV; break; + case GEOMGETCONF: + /* we bogusly pass cp to avoid getting any consumers listed */ + sb = g_conf_specific(gp2->class, gp2, pp2, cp); + usb = (struct sbuf *)data; + if (usb->s_size - 1 < sbuf_len(sb)) + error = ENOMEM; + else + error = copyout(sbuf_data(sb), usb->s_buf, sbuf_len(sb) + 1); + if (!error) + usb->s_len = sbuf_len(sb); + break; default: gio = g_malloc(sizeof *gio, M_WAITOK); gio->cmd = cmd; diff --git a/sys/geom/geom_slice.c b/sys/geom/geom_slice.c index ac05fa6c7c1..dc8d3abd94a 100644 --- a/sys/geom/geom_slice.c +++ b/sys/geom/geom_slice.c @@ -203,7 +203,7 @@ g_slice_dumpconf(struct sbuf *sb, char *indent, struct g_geom *gp, struct g_cons gsp = gp->softc; mp = gsp->softc; - if (gp != NULL) { + if (gp != NULL && (pp == NULL && cp == NULL)) { sbuf_printf(sb, "%s%llu\n", indent, (unsigned long long)gsp->frontstuff); } -- 2.45.2