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. MFC after: 3 days
This commit is contained in:
parent
2b03effa01
commit
f36a5e0f34
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=226083
@ -44,8 +44,8 @@ print_partedit_item(WINDOW *partitions, struct partedit_item *items,
|
||||
|
||||
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,
|
||||
|
@ -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) {
|
||||
gpart_destroy(geom);
|
||||
|
||||
/* If this is a partition, revert it, so it can be deleted */
|
||||
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;
|
||||
|
||||
if (choice == 1) /* cancel */
|
||||
return;
|
||||
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,
|
||||
|
@ -254,7 +254,7 @@ wizard_partition(struct gmesh *mesh, const char *disk)
|
||||
if (subchoice != 0)
|
||||
goto query;
|
||||
|
||||
gpart_destroy(gpart, 1);
|
||||
gpart_destroy(gpart);
|
||||
gpart_partition(disk, default_scheme());
|
||||
scheme = default_scheme();
|
||||
}
|
||||
@ -267,7 +267,7 @@ wizard_partition(struct gmesh *mesh, const char *disk)
|
||||
if (choice != 0)
|
||||
goto query;
|
||||
|
||||
gpart_destroy(gpart, 1);
|
||||
gpart_destroy(gpart);
|
||||
}
|
||||
|
||||
gpart_partition(disk, default_scheme());
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user