Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Oct 2011 13:59:33 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r226212 - stable/9/usr.sbin/bsdinstall/partedit
Message-ID:  <201110101359.p9ADxXrw063685@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: nwhitehorn
Date: Mon Oct 10 13:59:33 2011
New Revision: 226212
URL: http://svn.freebsd.org/changeset/base/226212

Log:
  MFC r226083:
  Work around some behavior of gpart that I absolutely do not understand in
  order to make every operation of the partition editor fully revertable.
  Under *no circumstances* will it any longer touch the disks until the user
  presses Finish and confirms it.
  
  Approved by:	re (kib)

Modified:
  stable/9/usr.sbin/bsdinstall/partedit/diskeditor.c
  stable/9/usr.sbin/bsdinstall/partedit/gpart_ops.c
  stable/9/usr.sbin/bsdinstall/partedit/part_wizard.c
  stable/9/usr.sbin/bsdinstall/partedit/partedit.h
Directory Properties:
  stable/9/usr.sbin/bsdinstall/   (props changed)

Modified: stable/9/usr.sbin/bsdinstall/partedit/diskeditor.c
==============================================================================
--- stable/9/usr.sbin/bsdinstall/partedit/diskeditor.c	Mon Oct 10 13:58:33 2011	(r226211)
+++ stable/9/usr.sbin/bsdinstall/partedit/diskeditor.c	Mon Oct 10 13:59:33 2011	(r226212)
@@ -44,8 +44,8 @@ print_partedit_item(WINDOW *partitions, 
 
 	wattrset(partitions, selected ? item_selected_attr : item_attr);
 	wmove(partitions, y, MARGIN + items[item].indentation*2);
-	dlg_print_text(partitions, items[item].name, 8, &attr);
-	wmove(partitions, y, 15);
+	dlg_print_text(partitions, items[item].name, 10, &attr);
+	wmove(partitions, y, 17);
 	wattrset(partitions, item_attr);
 
 	humanize_number(sizetext, 7, items[item].size, "B", HN_AUTOSCALE,

Modified: stable/9/usr.sbin/bsdinstall/partedit/gpart_ops.c
==============================================================================
--- stable/9/usr.sbin/bsdinstall/partedit/gpart_ops.c	Mon Oct 10 13:58:33 2011	(r226211)
+++ stable/9/usr.sbin/bsdinstall/partedit/gpart_ops.c	Mon Oct 10 13:59:33 2011	(r226212)
@@ -365,39 +365,37 @@ gpart_partcode(struct gprovider *pp)
 }
 
 void
-gpart_destroy(struct ggeom *lg_geom, int force)
+gpart_destroy(struct ggeom *lg_geom)
 {
-	struct gprovider *pp;
 	struct gctl_req *r;
+	struct gprovider *pp;
 	const char *errstr;
+	int force = 1;
 
-	/* Begin with the hosing: delete all partitions */
+	/* Delete all child metadata */
 	LIST_FOREACH(pp, &lg_geom->lg_provider, lg_provider)
 		gpart_delete(pp);
 
+	/* Revert any local changes to get this geom into a pristine state */
+	r = gctl_get_handle();
+	gctl_ro_param(r, "class", -1, "PART");
+	gctl_ro_param(r, "arg0", -1, lg_geom->lg_name);
+	gctl_ro_param(r, "verb", -1, "undo");
+	gctl_issue(r); /* Ignore errors -- these are non-fatal */
+	gctl_free(r);
+
 	/* Now destroy the geom itself */
 	r = gctl_get_handle();
 	gctl_ro_param(r, "class", -1, "PART");
 	gctl_ro_param(r, "arg0", -1, lg_geom->lg_name);
 	gctl_ro_param(r, "flags", -1, GPART_FLAGS);
+	gctl_ro_param(r, "force", sizeof(force), &force);
 	gctl_ro_param(r, "verb", -1, "destroy");
 	errstr = gctl_issue(r);
 	if (errstr != NULL && errstr[0] != '\0') 
 		gpart_show_error("Error", NULL, errstr);
 	gctl_free(r);
 
-	/* If asked, commit the change */
-	if (force) {
-		r = gctl_get_handle();
-		gctl_ro_param(r, "class", -1, "PART");
-		gctl_ro_param(r, "arg0", -1, lg_geom->lg_name);
-		gctl_ro_param(r, "verb", -1, "commit");
-		errstr = gctl_issue(r);
-		if (errstr != NULL && errstr[0] != '\0') 
-			gpart_show_error("Error", NULL, errstr);
-		gctl_free(r);
-	}
-
 	/* And any metadata associated with the partition scheme itself */
 	delete_part_metadata(lg_geom->lg_name);
 }
@@ -439,28 +437,21 @@ gpart_edit(struct gprovider *pp)
 	geom = NULL;
 	LIST_FOREACH(cp, &pp->lg_consumers, lg_consumers)
 		if (strcmp(cp->lg_geom->lg_class->lg_name, "PART") == 0) {
-			char message[512];
-			/*
-			 * The PART object is a consumer, so the user wants to
-			 * edit the partition table. gpart doesn't really
-			 * support this, so we have to hose the whole table
-			 * first.
-			 */
-
-			sprintf(message, "Changing the partition scheme on "
-			    "this disk (%s) requires deleting all existing "
-			    "partitions on this drive. This will PERMANENTLY "
-			    "ERASE any data stored here. Are you sure you want "
-			    "to proceed?", cp->lg_geom->lg_name);
-			dialog_vars.defaultno = TRUE;
-			choice = dialog_yesno("Warning", message, 0, 0);
-			dialog_vars.defaultno = FALSE;
-
-			if (choice == 1) /* cancel */
+			/* Check for zombie geoms, treating them as blank */
+			scheme = NULL;
+			LIST_FOREACH(gc, &cp->lg_geom->lg_config, lg_config) {
+				if (strcmp(gc->lg_name, "scheme") == 0) {
+					scheme = gc->lg_val;
+					break;
+				}
+			}
+			if (scheme == NULL || strcmp(scheme, "(none)") == 0) {
+				gpart_partition(cp->lg_geom->lg_name, NULL);
 				return;
+			}
 
 			/* Destroy the geom and all sub-partitions */
-			gpart_destroy(cp->lg_geom, 0);
+			gpart_destroy(cp->lg_geom);
 
 			/* Now re-partition and return */
 			gpart_partition(cp->lg_geom->lg_name, NULL);
@@ -1004,7 +995,7 @@ gpart_delete(struct gprovider *pp)
 	struct gctl_req *r;
 	const char *errstr;
 	intmax_t idx;
-	int choice, is_partition;
+	int is_partition;
 
 	/* Is it a partition? */
 	is_partition = (strcmp(pp->lg_geom->lg_class->lg_name, "PART") == 0);
@@ -1017,32 +1008,21 @@ gpart_delete(struct gprovider *pp)
 			break;
 		}
 
-	/* Destroy all consumers */
+	/* If so, destroy all children */
 	if (geom != NULL) {
-		if (is_partition) {
-			char message[512];
-			/*
-			 * We have to actually really delete the sub-partition
-			 * tree so that the consumers will go away and the
-			 * partition can be deleted. Warn the user.
-			 */
-
-			sprintf(message, "Deleting this partition (%s) "
-			    "requires deleting all existing sub-partitions. "
-			    "This will PERMANENTLY ERASE any data stored here "
-			    "and CANNOT BE REVERTED. Are you sure you want to "
-			    "proceed?", cp->lg_geom->lg_name);
-			dialog_vars.defaultno = TRUE;
-			choice = dialog_yesno("Warning", message, 0, 0);
-			dialog_vars.defaultno = FALSE;
+		gpart_destroy(geom);
 
-			if (choice == 1) /* cancel */
-				return;
+		/* If this is a partition, revert it, so it can be deleted */
+		if (is_partition) {
+			r = gctl_get_handle();
+			gctl_ro_param(r, "class", -1, "PART");
+			gctl_ro_param(r, "arg0", -1, geom->lg_name);
+			gctl_ro_param(r, "verb", -1, "undo");
+			gctl_issue(r); /* Ignore non-fatal errors */
+			gctl_free(r);
 		}
-
-		gpart_destroy(geom, is_partition);
 	}
- 
+
 	/*
 	 * If this is not a partition, see if that is a problem, complain if
 	 * necessary, and return always, since we need not do anything further,

Modified: stable/9/usr.sbin/bsdinstall/partedit/part_wizard.c
==============================================================================
--- stable/9/usr.sbin/bsdinstall/partedit/part_wizard.c	Mon Oct 10 13:58:33 2011	(r226211)
+++ stable/9/usr.sbin/bsdinstall/partedit/part_wizard.c	Mon Oct 10 13:59:33 2011	(r226212)
@@ -254,7 +254,7 @@ query:
 		if (subchoice != 0)
 			goto query;
 
-		gpart_destroy(gpart, 1);
+		gpart_destroy(gpart);
 		gpart_partition(disk, default_scheme());
 		scheme = default_scheme();
 	}
@@ -267,7 +267,7 @@ query:
 			if (choice != 0)
 				goto query;
 
-			gpart_destroy(gpart, 1);
+			gpart_destroy(gpart);
 		}
 
 		gpart_partition(disk, default_scheme());

Modified: stable/9/usr.sbin/bsdinstall/partedit/partedit.h
==============================================================================
--- stable/9/usr.sbin/bsdinstall/partedit/partedit.h	Mon Oct 10 13:58:33 2011	(r226211)
+++ stable/9/usr.sbin/bsdinstall/partedit/partedit.h	Mon Oct 10 13:59:33 2011	(r226212)
@@ -58,7 +58,7 @@ int part_wizard(void);
 
 /* gpart operations */
 void gpart_delete(struct gprovider *pp);
-void gpart_destroy(struct ggeom *lg_geom, int force);
+void gpart_destroy(struct ggeom *lg_geom);
 void gpart_edit(struct gprovider *pp);
 void gpart_create(struct gprovider *pp, char *default_type, char *default_size,
     char *default_mountpoint, char **output, int interactive);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110101359.p9ADxXrw063685>