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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to