diff options
| -rw-r--r-- | sbin/geom/class/part/geom_part.c | 111 | ||||
| -rw-r--r-- | sbin/geom/class/part/gpart.8 | 5 |
2 files changed, 102 insertions, 14 deletions
diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c index 1baab4398cef..67d7472a8ef0 100644 --- a/sbin/geom/class/part/geom_part.c +++ b/sbin/geom/class/part/geom_part.c @@ -68,6 +68,7 @@ static char ssize[32]; static const char const bootcode_param[] = "bootcode"; static const char const index_param[] = "index"; static const char const partcode_param[] = "partcode"; +static const char const force_param[] = "force";
static struct gclass *find_class(struct gmesh *, const char *); static struct ggeom * find_geom(struct gclass *, const char *); @@ -84,6 +85,8 @@ static void gpart_show_geom(struct ggeom *, const char *); static int gpart_show_hasopt(struct gctl_req *, const char *, const char *); static void gpart_write_partcode(struct ggeom *, int, void *, ssize_t); static void gpart_write_partcode_vtoc8(struct ggeom *, int, void *); +static void gpart_destroy(struct gctl_req *, unsigned int);
+static void gpart_print_error(const char *);
struct g_command PUBSYM(class_commands)[] = { { "add", 0, gpart_issue, { @@ -118,7 +121,8 @@ struct g_command PUBSYM(class_commands)[] = { G_OPT_SENTINEL }, "geom", NULL }, - { "destroy", 0, gpart_issue, { + { "destroy", 0, gpart_destroy, {
+ { 'F', force_param, NULL, G_TYPE_BOOL },
{ 'f', "flags", flags, G_TYPE_STRING }, G_OPT_SENTINEL }, "geom", NULL }, @@ -853,10 +857,101 @@ gpart_bootcode(struct gctl_req *req, unsigned int fl) } static void +gpart_destroy(struct gctl_req *req, unsigned int fl)
+{
+ struct gmesh mesh;
+ struct gclass *classp;
+ struct gctl_req *req2;
+ struct ggeom *gp;
+ struct gprovider *pp;
+ const char *s;
+ int error, val;
+
+ if (gctl_has_param(req, force_param)) {
+ val = gctl_get_int(req, force_param);
+ error = gctl_delete_param(req, force_param);
+ if (error)
+ errc(EXIT_FAILURE, error, "internal error");
+ if (val == 0)
+ goto done;
+ s = gctl_get_ascii(req, "class");
+ if (s == NULL)
+ abort();
+ error = geom_gettree(&mesh);
+ if (error != 0)
+ errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
+ classp = find_class(&mesh, s);
+ if (classp == NULL) {
+ geom_deletetree(&mesh);
+ errx(EXIT_FAILURE, "Class %s not found.", s);
+ }
+ s = gctl_get_ascii(req, "geom");
+ if (s == NULL)
+ abort();
+ gp = find_geom(classp, s);
+ if (gp == NULL)
+ errx(EXIT_FAILURE, "No such geom: %s.", s);
+ val = 0;
+ LIST_FOREACH(pp, &gp->lg_provider, lg_provider){
+ s = find_provcfg(pp, "index");
+ if (s == NULL)
+ errx(EXIT_FAILURE, "Index not found for %s.",
+ pp->lg_name);
+ req2 = gctl_get_handle();
+ gctl_ro_param(req2, "class", -1, classp->lg_name);
+ gctl_ro_param(req2, "geom", -1, gp->lg_name);
+ gctl_ro_param(req2, "verb", -1, "delete");
+ gctl_ro_param(req2, index_param, -1, s);
+ gctl_ro_param(req2, "flags", -1, "X");
+ s = gctl_issue(req2);
+ if (s != NULL && s[0] != '\0') {
+ gpart_print_error(s);
+ gctl_free(req2);
+ if (val) { /* try to undo changes */
+ req2 = gctl_get_handle();
+ gctl_ro_param(req2, "verb", -1,
+ "undo");
+ gctl_ro_param(req2, "class", -1,
+ classp->lg_name);
+ gctl_ro_param(req2, "geom", -1,
+ gp->lg_name);
+ gctl_issue(req2);
+ gctl_free(req2);
+ }
+ geom_deletetree(&mesh);
+ exit(EXIT_FAILURE);
+ }
+ gctl_free(req2);
+ val = 1;
+ }
+ geom_deletetree(&mesh);
+ }
+done:
+ gpart_issue(req, fl);
+}
+
+static void
+gpart_print_error(const char *errstr)
+{
+ char *errmsg;
+ int error;
+
+ error = strtol(errstr, &errmsg, 0);
+ if (errmsg != errstr) {
+ while (errmsg[0] == ' ')
+ errmsg++;
+ if (errmsg[0] != '\0')
+ warnc(error, "%s", errmsg);
+ else
+ warnc(error, NULL);
+ } else
+ warnx("%s", errmsg);
+}
+
+static void
gpart_issue(struct gctl_req *req, unsigned int fl __unused) { char buf[4096]; - char *errmsg; const char *errstr; int error, status; @@ -878,17 +973,7 @@ gpart_issue(struct gctl_req *req, unsigned int fl __unused) goto done; } - error = strtol(errstr, &errmsg, 0); - if (errmsg != errstr) { - while (errmsg[0] == ' ') - errmsg++; - if (errmsg[0] != '\0') - warnc(error, "%s", errmsg); - else - warnc(error, NULL); - } else - warnx("%s", errmsg); - + gpart_print_error(errstr);
status = EXIT_FAILURE; done: diff --git a/sbin/geom/class/part/gpart.8 b/sbin/geom/class/part/gpart.8 index a8ccdd5fc8ad..60fb4632b21e 100644 --- a/sbin/geom/class/part/gpart.8 +++ b/sbin/geom/class/part/gpart.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 27, 2010 +.Dd Sep 24, 2010
.Dt GPART 8 .Os .Sh NAME @@ -118,6 +118,7 @@ utility: .\" ==== DESTROY ==== .Nm .Cm destroy +.Op Fl F
.Op Fl f Ar flags .Ar geom .\" ==== MODIFY ==== @@ -317,6 +318,8 @@ Destroy the partitioning scheme as implemented by geom .Pp Additional options include: .Bl -tag -width 10n +.It Fl F
+Forced destroying of the partition table even if it is not empty.
.It Fl f Ar flags Additional operational flags. See the section entitled |
