summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2007-10-21 00:04:23 +0000
committermarcel <marcel@FreeBSD.org>2007-10-21 00:04:23 +0000
commitdf8581071ad1f4d73459a3000bdbb8959dd6c5d3 (patch)
treeb827e218436feb289e956c6007b512dfc0fd2ea6 /sbin
parent51d643caa6efc11780104da450ee36a818170f81 (diff)
downloadFreeBSD-src-df8581071ad1f4d73459a3000bdbb8959dd6c5d3.zip
FreeBSD-src-df8581071ad1f4d73459a3000bdbb8959dd6c5d3.tar.gz
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.
Diffstat (limited to 'sbin')
-rw-r--r--sbin/geom/class/part/geom_part.c184
-rw-r--r--sbin/geom/class/part/gpart.827
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 ce9dfb3..30db6c0 100644
--- a/sbin/geom/class/part/geom_part.c
+++ b/sbin/geom/class/part/geom_part.c
@@ -31,8 +31,8 @@ __FBSDID("$FreeBSD$");
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
+#include <err.h>
#include <fcntl.h>
-#include <readpassphrase.h>
#include <string.h>
#include <strings.h>
#include <libgeom.h>
@@ -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 f98aefa..1f664ca 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
OpenPOWER on IntegriCloud