diff options
| author | Simon J. Gerraty <sjg@FreeBSD.org> | 2014-04-28 07:50:45 +0000 |
|---|---|---|
| committer | Simon J. Gerraty <sjg@FreeBSD.org> | 2014-04-28 07:50:45 +0000 |
| commit | 3b8f08459569bf0faa21473e5cec2491e95c9349 (patch) | |
| tree | 80f45dd81ca716bcd7ca9674581e1fc40b93cd34 /sbin/geom | |
| parent | 9d2ab4a62d6733c45958627ac113bdbd818d1e2a (diff) | |
| parent | b2ba55951383498f252746f618d513139da06e8e (diff) | |
Notes
Diffstat (limited to 'sbin/geom')
| -rw-r--r-- | sbin/geom/Makefile | 2 | ||||
| -rw-r--r-- | sbin/geom/class/eli/geom_eli.c | 2 | ||||
| -rw-r--r-- | sbin/geom/class/mirror/geom_mirror.c | 109 | ||||
| -rw-r--r-- | sbin/geom/class/mirror/gmirror.8 | 33 | ||||
| -rw-r--r-- | sbin/geom/class/part/geom_part.c | 49 | ||||
| -rw-r--r-- | sbin/geom/class/part/gpart.8 | 27 |
6 files changed, 210 insertions, 12 deletions
diff --git a/sbin/geom/Makefile b/sbin/geom/Makefile index 88b82404e107..ced58425c657 100644 --- a/sbin/geom/Makefile +++ b/sbin/geom/Makefile @@ -9,7 +9,7 @@ PROG= geom SRCS= geom.c geom_label.c geom_part.c subr.c -NO_MAN= +MAN= WARNS?= 2 CFLAGS+=-I${.CURDIR} -I${.CURDIR}/core -DSTATIC_GEOM_CLASSES diff --git a/sbin/geom/class/eli/geom_eli.c b/sbin/geom/class/eli/geom_eli.c index 3eee6f249b54..7df4d905f4bc 100644 --- a/sbin/geom/class/eli/geom_eli.c +++ b/sbin/geom/class/eli/geom_eli.c @@ -789,7 +789,7 @@ eli_init(struct gctl_req *req) if (val == 0) md.md_sectorsize = secsize; else { - if (val < 0 || (val % secsize) != 0) { + if (val < 0 || (val % secsize) != 0 || !powerof2(val)) { gctl_error(req, "Invalid sector size."); return; } diff --git a/sbin/geom/class/mirror/geom_mirror.c b/sbin/geom/class/mirror/geom_mirror.c index 9f0acc67aea3..30f5f8494556 100644 --- a/sbin/geom/class/mirror/geom_mirror.c +++ b/sbin/geom/class/mirror/geom_mirror.c @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> +#include <err.h> #include <errno.h> #include <paths.h> #include <stdio.h> @@ -53,6 +54,7 @@ static void mirror_activate(struct gctl_req *req); static void mirror_clear(struct gctl_req *req); static void mirror_dump(struct gctl_req *req); static void mirror_label(struct gctl_req *req); +static void mirror_resize(struct gctl_req *req, unsigned flags); struct g_command class_commands[] = { { "activate", G_FLAG_VERBOSE, mirror_main, G_NULL_OPTS, @@ -80,6 +82,13 @@ struct g_command class_commands[] = { { "deactivate", G_FLAG_VERBOSE, NULL, G_NULL_OPTS, "[-v] name prov ..." }, + { "destroy", G_FLAG_VERBOSE, NULL, + { + { 'f', "force", NULL, G_TYPE_BOOL }, + G_OPT_SENTINEL + }, + "[-fv] name ..." + }, { "dump", 0, mirror_main, G_NULL_OPTS, "prov ..." }, @@ -112,6 +121,13 @@ struct g_command class_commands[] = { { "remove", G_FLAG_VERBOSE, NULL, G_NULL_OPTS, "[-v] name prov ..." }, + { "resize", G_FLAG_VERBOSE, mirror_resize, + { + { 's', "size", "*", G_TYPE_STRING }, + G_OPT_SENTINEL + }, + "[-s size] [-v] name" + }, { "stop", G_FLAG_VERBOSE, NULL, { { 'f', "force", NULL, G_TYPE_BOOL }, @@ -376,3 +392,96 @@ mirror_activate(struct gctl_req *req) printf("Provider %s activated.\n", path); } } + +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 void +mirror_resize(struct gctl_req *req, unsigned flags __unused) +{ + struct gmesh mesh; + struct gclass *classp; + struct ggeom *gp; + struct gprovider *pp; + struct gconsumer *cp; + off_t size; + int error, nargs; + const char *name; + char ssize[30]; + + nargs = gctl_get_int(req, "nargs"); + if (nargs < 1) { + gctl_error(req, "Too few arguments."); + return; + } + error = geom_gettree(&mesh); + if (error) + errc(EXIT_FAILURE, error, "Cannot get GEOM tree"); + name = gctl_get_ascii(req, "class"); + if (name == NULL) + abort(); + classp = find_class(&mesh, name); + if (classp == NULL) + errx(EXIT_FAILURE, "Class %s not found.", name); + name = gctl_get_ascii(req, "arg0"); + if (name == NULL) + abort(); + gp = find_geom(classp, name); + if (gp == NULL) + errx(EXIT_FAILURE, "No such geom: %s.", name); + pp = LIST_FIRST(&gp->lg_provider); + if (pp == NULL) + errx(EXIT_FAILURE, "Provider of geom %s not found.", name); + size = pp->lg_mediasize; + name = gctl_get_ascii(req, "size"); + if (name == NULL) + errx(EXIT_FAILURE, "The size is not specified."); + if (*name == '*') { +#define CSZ(c) ((c)->lg_provider->lg_mediasize - \ + (c)->lg_provider->lg_sectorsize) + /* Find the maximum possible size */ + LIST_FOREACH(cp, &gp->lg_consumer, lg_consumer) { + if (CSZ(cp) > size) + size = CSZ(cp); + } + LIST_FOREACH(cp, &gp->lg_consumer, lg_consumer) { + if (CSZ(cp) < size) + size = CSZ(cp); + } +#undef CSZ + if (size == pp->lg_mediasize) + errx(EXIT_FAILURE, + "Cannot expand provider %s\n", + pp->lg_name); + } else { + error = g_parse_lba(name, pp->lg_sectorsize, &size); + if (error) + errc(EXIT_FAILURE, error, "Invalid size param"); + size *= pp->lg_sectorsize; + } + snprintf(ssize, sizeof(ssize), "%ju", (uintmax_t)size); + gctl_change_param(req, "size", -1, ssize); + geom_deletetree(&mesh); + gctl_issue(req); +} diff --git a/sbin/geom/class/mirror/gmirror.8 b/sbin/geom/class/mirror/gmirror.8 index 58ff8afcbc4c..bca5bdba9749 100644 --- a/sbin/geom/class/mirror/gmirror.8 +++ b/sbin/geom/class/mirror/gmirror.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 8, 2009 +.Dd December 27, 2013 .Dt GMIRROR 8 .Os .Sh NAME @@ -60,6 +60,11 @@ .Ar name .Ar prov ... .Nm +.Cm resize +.Op Fl v +.Op Fl s Ar size +.Ar name +.Nm .Cm insert .Op Fl hiv .Op Fl p Ar priority @@ -81,6 +86,10 @@ .Ar name .Ar prov ... .Nm +.Cm destroy +.Op Fl fv +.Ar name ... +.Nm .Cm forget .Op Fl v .Ar name ... @@ -193,6 +202,16 @@ balance algorithm. Rebuild the given mirror components forcibly. If autosynchronization was not turned off for the given device, this command should be unnecessary. +.It Cm resize +Change the size of the given mirror. +.Pp +Additional options include: +.Bl -tag -width ".Fl s Ar size" +.It Fl s Ar size +New size of the mirror is expressed in logical block numbers. +This option can be omitted, then it will be automatically calculated to +maximum available size. +.El .It Cm insert Add the given component(s) to the existing mirror. .Pp @@ -212,6 +231,14 @@ Activate the given component(s), which were marked as inactive before. .It Cm deactivate Mark the given component(s) as inactive, so it will not be automatically connected to the mirror. +.It Cm destroy +Stop the given mirror and clear metadata on all its components. +.Pp +Additional options include: +.Bl -tag -width ".Fl f" +.It Fl f +Stop the given mirror even if it is opened. +.El .It Cm forget Forget about components which are not connected. This command is useful when a disk has failed and cannot be reconnected, preventing the @@ -300,9 +327,7 @@ gmirror activate data da1 .Sh NOTES Doing kernel dumps to .Nm -providers. -.Pp -This is possible, but some conditions have to be met. +providers is possible, but some conditions have to be met. First of all, a kernel dump will go only to one component and .Nm always chooses the component with the highest priority. diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c index 9b3e0e5e451b..ee4b2a939f82 100644 --- a/sbin/geom/class/part/geom_part.c +++ b/sbin/geom/class/part/geom_part.c @@ -364,7 +364,11 @@ gpart_autofill_resize(struct gctl_req *req) } offset = (pp->lg_stripeoffset / pp->lg_sectorsize) % alignment; - last = (off_t)strtoimax(find_geomcfg(gp, "last"), NULL, 0); + s = find_geomcfg(gp, "last"); + if (s == NULL) + errx(EXIT_FAILURE, "Final block not found for geom %s", + gp->lg_name); + last = (off_t)strtoimax(s, NULL, 0); LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { s = find_provcfg(pp, "index"); if (s == NULL) @@ -450,8 +454,19 @@ gpart_autofill(struct gctl_req *req) if (s == NULL) abort(); gp = find_geom(cp, s); - if (gp == NULL) - errx(EXIT_FAILURE, "No such geom: %s.", s); + if (gp == NULL) { + if (g_device_path(s) == NULL) { + errx(EXIT_FAILURE, "No such geom %s.", s); + } else { + /* + * We don't free memory allocated by g_device_path() as + * we are about to exit. + */ + errx(EXIT_FAILURE, + "No partitioning scheme found on geom %s. Create one first using 'gpart create'.", + s); + } + } pp = LIST_FIRST(&gp->lg_consumer)->lg_provider; if (pp == NULL) errx(EXIT_FAILURE, "Provider for geom %s not found.", s); @@ -502,8 +517,16 @@ gpart_autofill(struct gctl_req *req) if (size > alignment) size = ALIGNDOWN(size, alignment); - first = (off_t)strtoimax(find_geomcfg(gp, "first"), NULL, 0); - last = (off_t)strtoimax(find_geomcfg(gp, "last"), NULL, 0); + s = find_geomcfg(gp, "first"); + if (s == NULL) + errx(EXIT_FAILURE, "Starting block not found for geom %s", + gp->lg_name); + first = (off_t)strtoimax(s, NULL, 0); + s = find_geomcfg(gp, "last"); + if (s == NULL) + errx(EXIT_FAILURE, "Final block not found for geom %s", + gp->lg_name); + last = (off_t)strtoimax(s, NULL, 0); grade = ~0ULL; a_first = ALIGNUP(first + offset, alignment); last = ALIGNDOWN(last + offset, alignment); @@ -587,12 +610,22 @@ gpart_show_geom(struct ggeom *gp, const char *element, int show_providers) int idx, wblocks, wname, wmax; scheme = find_geomcfg(gp, "scheme"); + if (scheme == NULL) + errx(EXIT_FAILURE, "Scheme not found for geom %s", gp->lg_name); s = find_geomcfg(gp, "first"); + if (s == NULL) + errx(EXIT_FAILURE, "Starting block not found for geom %s", + gp->lg_name); first = (off_t)strtoimax(s, NULL, 0); s = find_geomcfg(gp, "last"); + if (s == NULL) + errx(EXIT_FAILURE, "Final block not found for geom %s", + gp->lg_name); last = (off_t)strtoimax(s, NULL, 0); wblocks = strlen(s); s = find_geomcfg(gp, "state"); + if (s == NULL) + errx(EXIT_FAILURE, "State not found for geom %s", gp->lg_name); if (s != NULL && *s != 'C') s = NULL; wmax = strlen(gp->lg_name); @@ -748,6 +781,8 @@ gpart_backup(struct gctl_req *req, unsigned int fl __unused) abort(); pp = LIST_FIRST(&gp->lg_consumer)->lg_provider; s = find_geomcfg(gp, "last"); + if (s == NULL) + abort(); wblocks = strlen(s); wtype = 0; LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { @@ -757,6 +792,8 @@ gpart_backup(struct gctl_req *req, unsigned int fl __unused) wtype = i; } s = find_geomcfg(gp, "entries"); + if (s == NULL) + abort(); windex = strlen(s); printf("%s %s\n", scheme, s); LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { @@ -1177,6 +1214,8 @@ gpart_bootcode(struct gctl_req *req, unsigned int fl) if (gp == NULL) errx(EXIT_FAILURE, "No such geom: %s.", s); s = find_geomcfg(gp, "scheme"); + if (s == NULL) + errx(EXIT_FAILURE, "Scheme not found for geom %s", gp->lg_name); vtoc8 = 0; if (strcmp(s, "VTOC8") == 0) vtoc8 = 1; diff --git a/sbin/geom/class/part/gpart.8 b/sbin/geom/class/part/gpart.8 index 3ce79a847213..194a19fdf46a 100644 --- a/sbin/geom/class/part/gpart.8 +++ b/sbin/geom/class/part/gpart.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 1, 2013 +.Dd April 2, 2014 .Dt GPART 8 .Os .Sh NAME @@ -557,6 +557,16 @@ Interface (EFI). In such cases, the GPT partitioning scheme is used and the actual partition type for the system partition can also be specified as .Qq Li "!c12a7328-f81f-11d2-ba4b-00a0c93ec93b" . +.It Cm fat16 +A partition that contains a FAT16 filesystem. +The scheme-specific type is +.Qq Li "!6" +for MBR. +.It Cm fat32 +A partition that contains a FAT32 filesystem. +The scheme-specific type is +.Qq Li "!11" +for MBR. .It Cm freebsd A .Fx @@ -620,6 +630,16 @@ A partition that is sub-partitioned by a Master Boot Record (MBR). This type is known as .Qq Li "!024dee41-33e7-11d3-9d69-0008c781f39f" by GPT. +.It Cm ms-basic-data +A basic data partition (BDP) for Microsoft operating systems. +In the GPT this type is the equivalent to partition types +.Cm fat16 , fat32 +and +.Cm ntfs +in MBR. +The scheme-specific type is +.Qq Li "!ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" +for GPT. .It Cm ms-ldm-data A partition that contains Logical Disk Manager (LDM) volumes. The scheme-specific types are @@ -632,6 +652,11 @@ A partition that contains Logical Disk Manager (LDM) database. The scheme-specific type is .Qq Li "!5808c8aa-7e8f-42e0-85d2-e1e90434cfb3" for GPT. +.It Cm ntfs +A partition that contains a NTFS or exFAT filesystem. +The scheme-specific type is +.Qq Li "!7" +for MBR. .El .Sh ATTRIBUTES The scheme-specific attributes for EBR: |
