From c83e7f0d4cd3377060285d6b14f5fa286fdd76f6 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 21 Oct 2007 00:04:23 +0000 Subject: [PATCH] Add the show command to print the partition information ala gpt(8). Update the manpage accordingly. While here, mention the MBR scheme and add a bugs section. With this commit gpt(8) can be obsoleted. --- sbin/geom/class/part/geom_part.c | 184 ++++++++++++++++++++++++++++++- sbin/geom/class/part/gpart.8 | 27 ++++- 2 files changed, 205 insertions(+), 6 deletions(-) diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c index ce9dfb39526d..30db6c00d07d 100644 --- a/sbin/geom/class/part/geom_part.c +++ b/sbin/geom/class/part/geom_part.c @@ -31,8 +31,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include -#include #include #include #include @@ -49,6 +49,8 @@ uint32_t version = 0; static char optional[] = ""; static char flags[] = "C"; +static void gpart_show(struct gctl_req *, unsigned); + struct g_command class_commands[] = { { "add", 0, NULL, { { 'b', "start", NULL, G_TYPE_STRING }, @@ -86,6 +88,186 @@ struct g_command class_commands[] = { G_OPT_SENTINEL }, "geom", NULL }, + { "show", 0, gpart_show, G_NULL_OPTS, "[geom ...]", NULL }, { "undo", 0, NULL, G_NULL_OPTS, "geom", NULL }, G_CMD_SENTINEL }; + +static struct gclass * +find_class(struct gmesh *mesh, const char *name) +{ + struct gclass *classp; + + LIST_FOREACH(classp, &mesh->lg_class, lg_class) { + if (strcmp(classp->lg_name, name) == 0) + return (classp); + } + return (NULL); +} + +static struct ggeom * +find_geom(struct gclass *classp, const char *name) +{ + struct ggeom *gp; + + LIST_FOREACH(gp, &classp->lg_geom, lg_geom) { + if (strcmp(gp->lg_name, name) == 0) + return (gp); + } + return (NULL); +} + +static const char * +find_geomcfg(struct ggeom *gp, const char *cfg) +{ + struct gconfig *gc; + + LIST_FOREACH(gc, &gp->lg_config, lg_config) { + if (!strcmp(gc->lg_name, cfg)) + return (gc->lg_val); + } + return (NULL); +} + +static const char * +find_provcfg(struct gprovider *pp, const char *cfg) +{ + struct gconfig *gc; + + LIST_FOREACH(gc, &pp->lg_config, lg_config) { + if (!strcmp(gc->lg_name, cfg)) + return (gc->lg_val); + } + return (NULL); +} + +static struct gprovider * +find_provider(struct ggeom *gp, unsigned long long minsector) +{ + struct gprovider *pp, *bestpp; + unsigned long long offset; + unsigned long long sector, bestsector; + + bestpp = NULL; + LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { + offset = atoll(find_provcfg(pp, "offset")); + sector = offset / pp->lg_sectorsize; + if (sector < minsector) + continue; + if (bestpp != NULL && sector >= bestsector) + continue; + bestpp = pp; + bestsector = sector; + } + return (bestpp); +} + +static const char * +fmtsize(long double rawsz) +{ + static char buf[32]; + static const char *sfx[] = { "B", "KB", "MB", "GB", "TB" }; + long double sz; + int sfxidx; + + sfxidx = 0; + sz = (long double)rawsz; + while (sfxidx < 4 && sz > 1099.0) { + sz /= 1000; + sfxidx++; + } + + sprintf(buf, "%.1Lf%s", sz, sfx[sfxidx]); + return (buf); +} + +static void +gpart_show_geom(struct ggeom *gp) +{ + struct gprovider *pp; + const char *s, *scheme; + unsigned long long first, last, sector, end; + unsigned long long offset, length, secsz; + int idx, wblocks, wname; + + scheme = find_geomcfg(gp, "scheme"); + s = find_geomcfg(gp, "first"); + first = atoll(s); + s = find_geomcfg(gp, "last"); + last = atoll(s); + wblocks = strlen(s); + wname = strlen(gp->lg_name); + pp = LIST_FIRST(&gp->lg_consumer)->lg_provider; + secsz = pp->lg_sectorsize; + printf("=>%*llu %*llu %*s %s (%s)\n", + wblocks, first, wblocks, (last - first + 1), + wname, gp->lg_name, + scheme, fmtsize(pp->lg_mediasize)); + + while ((pp = find_provider(gp, first)) != NULL) { + s = find_provcfg(pp, "offset"); + offset = atoll(s); + sector = offset / secsz; + s = find_provcfg(pp, "length"); + length = atoll(s); + s = find_provcfg(pp, "index"); + idx = atoi(s); + end = sector + length / secsz; + if (first < sector) { + printf(" %*llu %*llu %*s - free - (%s)\n", + wblocks, first, wblocks, sector - first, + wname, "", + fmtsize((sector - first) * secsz)); + } + printf(" %*llu %*llu %*d %s (%s)\n", + wblocks, sector, wblocks, end - sector, + wname, idx, + find_provcfg(pp, "type"), fmtsize(pp->lg_mediasize)); + first = end; + } + if (first <= last) { + printf(" %*llu %*llu %*s - free - (%s)\n", + wblocks, first, wblocks, last - first + 1, + wname, "", + fmtsize((last - first + 1) * secsz)); + } + printf("\n"); +} + +static void +gpart_show(struct gctl_req *req, unsigned fl __unused) +{ + struct gmesh mesh; + struct gclass *classp; + struct ggeom *gp; + const char *name; + int error, i, nargs; + + name = gctl_get_ascii(req, "class"); + if (name == NULL) + abort(); + error = geom_gettree(&mesh); + if (error != 0) + errc(EXIT_FAILURE, error, "Cannot get GEOM tree"); + classp = find_class(&mesh, name); + if (classp == NULL) { + geom_deletetree(&mesh); + errx(EXIT_FAILURE, "Class %s not found.", name); + } + nargs = gctl_get_int(req, "nargs"); + if (nargs > 0) { + for (i = 0; i < nargs; i++) { + name = gctl_get_ascii(req, "arg%d", i); + gp = find_geom(classp, name); + if (gp != NULL) + gpart_show_geom(gp); + else + errx(EXIT_FAILURE, "No such geom: %s.", name); + } + } else { + LIST_FOREACH(gp, &classp->lg_geom, lg_geom) { + gpart_show_geom(gp); + } + } + geom_deletetree(&mesh); +} diff --git a/sbin/geom/class/part/gpart.8 b/sbin/geom/class/part/gpart.8 index f98aefa9a25e..1f664ca5ec24 100644 --- a/sbin/geom/class/part/gpart.8 +++ b/sbin/geom/class/part/gpart.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 15, 2007 +.Dd Oct 20, 2007 .Dt GPART 8 .Os .Sh NAME @@ -37,12 +37,15 @@ lines in your kernel configuration file: .Bd -ragged -offset indent .Cd "options GEOM_PART_APM" .Cd "options GEOM_PART_GPT" +.Cd "options GEOM_PART_MBR" .Ed .Pp The GEOM_PART_APM option adds support for the Apple Partition Map (APM) -found on Apple Macintosh computers, and the GEOM_PART_GPT option adds -support for the GUID Partition Table (GPT) found on Intel Itanium -computers and Intel-based Macintosh computers. +found on Apple Macintosh computers. +The GEOM_PART_GPT option adds support for the GUID Partition Table (GPT) +found on Intel Itanium computers and Intel-based Macintosh computers. +The GEOM_PART_MBR option adds support for the Master Boot Record (MBR) +found on PCs and used on many removable media. .Pp Usage of the .Xr gpart 8 @@ -88,6 +91,10 @@ utility: .Op Fl t Ar type .Op Fl f Ar flags .Ar geom +.\" ==== SHOW ==== +.Nm +.Cm show +.Op Ar geom ... .\" ==== UNDO ==== .Nm .Cm undo @@ -223,6 +230,10 @@ Additional operational flags. See the section entitled "Operational flags" below for a discussion about its use. .El +.\" ==== SHOW ==== +.It Cm show +Show the current partition information of the specified geoms +or all geoms if none are specified. .\" ==== UNDO ==== .It Cm undo Revert any pending changes. @@ -254,7 +265,7 @@ A FreeBSD partition that uses the BSD disklabel to sub-divide the partition into file systems. This is a legacy partition type and should not be used for the APM or GPT schemes. -The scheme-specific types are "!FreeBSD" for APM, and +The scheme-specific types are "!165" for MBR, "!FreeBSD" for APM, and "!516e7cb4-6ecf-11d6-8ff8-00022d09712b" for GPT. .It freebsd-swap A FreeBSD partition dedicated to swap space. @@ -304,5 +315,11 @@ The .Nm utility appeared in .Fx 7.0 . +.Sh BUGS +The MBR partitioning scheme cannot yet be used to create a bootable +MBR. +.Pp +Support for the PC98 or Sun partitioning schemes is not yet present. +The BSD disklabel is also not supported yet. .Sh AUTHORS .An Marcel Moolenaar Aq marcel@FreeBSD.org