svn commit: r213097 - head/sbin/geom/class/part

Andrey V. Elsukov ae at FreeBSD.org
Fri Sep 24 08:40:44 UTC 2010


Author: ae
Date: Fri Sep 24 08:40:43 2010
New Revision: 213097
URL: http://svn.freebsd.org/changeset/base/213097

Log:
  Implement "force" (-F) option for gpart destroy verb.
  This option doesn't passed to kernel and handled in user-space.
  With -F option gpart creates new "delete" request for each
  partition in table. Each request has flags="X" that disables
  auto-commit feature. Last request is the original "destroy" request.
  It has own flags and can have disabled or enabled auto-commit feature.
  If error is occurred when deleting partitions, then new "undo" request
  is created and all changes will be rolled back.
  
  Approved by:	kib (mentor)

Modified:
  head/sbin/geom/class/part/geom_part.c
  head/sbin/geom/class/part/gpart.8

Modified: head/sbin/geom/class/part/geom_part.c
==============================================================================
--- head/sbin/geom/class/part/geom_part.c	Fri Sep 24 07:52:07 2010	(r213096)
+++ head/sbin/geom/class/part/geom_part.c	Fri Sep 24 08:40:43 2010	(r213097)
@@ -67,6 +67,7 @@ static char ssize[32];
 #define	GPART_PARAM_BOOTCODE	"bootcode"
 #define	GPART_PARAM_INDEX	"index"
 #define	GPART_PARAM_PARTCODE	"partcode"
+#define	GPART_PARAM_FORCE	"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
 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, {
@@ -120,10 +123,11 @@ struct g_command PUBSYM(class_commands)[
 		G_OPT_SENTINEL },
 	    "-i index [-f flags] geom"
 	},
-	{ "destroy", 0, gpart_issue, {
+	{ "destroy", 0, gpart_destroy, {
+		{ 'F', GPART_PARAM_FORCE, NULL, G_TYPE_BOOL },
 		{ 'f', "flags", GPART_FLAGS, G_TYPE_STRING },
 		G_OPT_SENTINEL },
-	    "[-f flags] geom"
+	    "[-F] [-f flags] geom"
 	},
 	{ "modify", 0, gpart_issue, {
 		{ 'i', GPART_PARAM_INDEX, NULL, G_TYPE_NUMBER },
@@ -854,10 +858,104 @@ gpart_bootcode(struct gctl_req *req, uns
 }
 
 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;
+	intmax_t idx;
+
+	if (gctl_has_param(req, GPART_PARAM_FORCE)) {
+		val = gctl_get_int(req, GPART_PARAM_FORCE);
+		error = gctl_delete_param(req, GPART_PARAM_FORCE);
+		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, "arg0");
+		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);
+			idx = strtoimax(s, NULL, 0);
+			req2 = gctl_get_handle();
+			gctl_ro_param(req2, "class", -1, classp->lg_name);
+			gctl_ro_param(req2, "arg0", -1, gp->lg_name);
+			gctl_ro_param(req2, "verb", -1, "delete");
+			gctl_ro_param(req2, GPART_PARAM_INDEX,
+			    sizeof(intmax_t), &idx);
+			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, "arg0", -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;
 
@@ -883,17 +981,7 @@ gpart_issue(struct gctl_req *req, unsign
 		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:

Modified: head/sbin/geom/class/part/gpart.8
==============================================================================
--- head/sbin/geom/class/part/gpart.8	Fri Sep 24 07:52:07 2010	(r213096)
+++ head/sbin/geom/class/part/gpart.8	Fri Sep 24 08:40:43 2010	(r213097)
@@ -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 imple
 .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


More information about the svn-src-all mailing list