Subject: [PATCH] parted: don't reload partition table on every command
From: Phillip Susi <[email-masked]>
To: [email-masked]
Date: Sun, 5 Jan 2014 23:03:55 -0500
List-Id: <debbugs-submit.debbugs.gnu.org>

gpt was using a static local variable to suppress repeatedly reporting
an error if you chose to ignore it.  This is incorrect as the variable is
global to all disks, and ignoring the error on one should not suppress its
reporting on another.  Moving the flag to the PedDisk object made it
effectively useless because parted was destroying the PedDisk and reloading
the partition table on every command.

Parted has been reworked to cache the PedDisk once loaded, and only discard
it when changing disks, or creating a new disklabel.
---
 NEWS                     |   5 +
 libparted/labels/gpt.c   |   7 +-
 parted/command.c         |   6 +-
 parted/command.h         |   6 +-
 parted/parted.c          | 257 +++++++++++++++++++++++------------------------
 parted/ui.c              |   8 +-
 parted/ui.h              |   8 +-
 tests/t3300-palo-prep.sh |   8 +-
 8 files changed, 153 insertions(+), 152 deletions(-)

diff --git a/NEWS b/NEWS
index bc948bd..39f91f3 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,11 @@ GNU parted NEWS                                    -*- outline -*-
 
 ** Bug Fixes
 
+  libparted: previously if you chose to ignore the warning about
+  the gpt thinking the disk was smaller than it appears to be on
+  on disk, subsequent warnings on other disks would be suppressed.
+  Now parted will warn once per disk.
+
   Fix filesystem detection on non 512 byte sector sizes
 
   Fix several bugs with loop labels ( whole disk filesystems )
diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c
index dce89b1..75b1ef8 100644
--- a/libparted/labels/gpt.c
+++ b/libparted/labels/gpt.c
@@ -695,7 +695,6 @@ _parse_header (PedDisk *disk, const GuidPartitionTableHeader_t *gpt,
   PedSector first_usable;
   PedSector last_usable;
   PedSector last_usable_if_grown, last_usable_min_default;
-  static int asked_already;
 
 #ifndef DISCOVER_ONLY
   if (PED_LE32_TO_CPU (gpt->Revision) > GPT_HEADER_REVISION_V1_02)
@@ -742,7 +741,7 @@ _parse_header (PedDisk *disk, const GuidPartitionTableHeader_t *gpt,
       || disk->dev->length < last_usable_if_grown)
     return 0;
 
-  if (!asked_already && last_usable < last_usable_if_grown)
+  if (last_usable < last_usable_if_grown)
     {
       PedExceptionOption q;
 
@@ -765,10 +764,6 @@ _parse_header (PedDisk *disk, const GuidPartitionTableHeader_t *gpt,
           last_usable = last_usable_if_grown;
           *update_needed = 1;
         }
-      else if (q != PED_EXCEPTION_UNHANDLED)
-        {
-          asked_already = 1;
-        }
     }
 
   ped_geometry_init (&gpt_disk_data->data_area, disk->dev,
diff --git a/parted/command.c b/parted/command.c
index e91c0c6..1b84e44 100644
--- a/parted/command.c
+++ b/parted/command.c
@@ -28,7 +28,7 @@
 
 Command*
 command_create (const StrList* names,
-		int (*method) (PedDevice** dev),
+		int (*method) (PedDevice** dev, PedDisk** disk),
 		const StrList* summary,
 		const StrList* help,
                 const int non_interactive)
@@ -134,7 +134,7 @@ command_print_help (Command* cmd)
 }
 
 int
-command_run (Command* cmd, PedDevice** dev)
+command_run (Command* cmd, PedDevice** dev, PedDisk** disk)
 {
-	return cmd->method (dev);
+	return cmd->method (dev, disk);
 }
diff --git a/parted/command.h b/parted/command.h
index fed7a23..6a6a075 100644
--- a/parted/command.h
+++ b/parted/command.h
@@ -24,14 +24,14 @@
 
 typedef struct {
 	StrList*	names;
-	int		(*method) (PedDevice** dev);
+	int		(*method) (PedDevice** dev, PedDisk** disk);
 	StrList*	summary;
 	StrList*	help;
         int             non_interactive:1;
 } Command;
 
 extern Command* command_create (const StrList* names,
-				int (*method) (PedDevice** dev),
+				int (*method) (PedDevice** dev, PedDisk** disk),
 				const StrList* summary,
 				const StrList* help,
                                 int non_interactive);
@@ -42,6 +42,6 @@ extern Command* command_get (Command** list, char* name);
 extern StrList* command_get_names (Command** list);
 extern void command_print_summary (Command* cmd);
 extern void command_print_help (Command* cmd);
-extern int command_run (Command* cmd, PedDevice** dev);
+extern int command_run (Command* cmd, PedDevice** dev, PedDisk** disk);
 
 #endif /* COMMAND_H_INCLUDED */
diff --git a/parted/parted.c b/parted/parted.c
index b20d432..5ff3dc7 100644
--- a/parted/parted.c
+++ b/parted/parted.c
@@ -176,7 +176,7 @@ static PedTimer* g_timer;
 static TimerContext timer_context;
 
 static int _print_list ();
-static void _done (PedDevice* dev);
+static void _done (PedDevice* dev, PedDisk *disk);
 static bool partition_align_check (PedDisk const *disk,
                         PedPartition const *part, enum AlignmentType a_type);
 
@@ -469,7 +469,7 @@ print_options_help ()
 }
 
 int
-do_help (PedDevice** dev)
+do_help (PedDevice** dev, PedDisk** disk)
 {
         if (command_line_get_word_count ()) {
                 char*   word = command_line_pop_word ();
@@ -484,26 +484,28 @@ do_help (PedDevice** dev)
 }
 
 static int
-do_mklabel (PedDevice** dev)
+do_mklabel (PedDevice** dev, PedDisk** diskp)
 {
         PedDisk*                disk;
         const PedDiskType*      type = NULL;
 
-        ped_exception_fetch_all ();
-        disk = ped_disk_new (*dev);
-        if (!disk) ped_exception_catch ();
-        ped_exception_leave_all ();
+        if (*diskp)
+                disk = *diskp;
+        else {
+                ped_exception_fetch_all ();
+                disk = ped_disk_new (*dev);
+                if (!disk) ped_exception_catch ();
+                ped_exception_leave_all ();
+        }
 
         if (!command_line_get_disk_type (_("New disk label type?"), &type))
                 goto error;
 
         if (disk) {
                 if (!_disk_warn_busy (disk))
-                        goto error_destroy_disk;
+                        goto error;
                 if (!opt_script_mode && !_disk_warn_loss (disk))
-                        goto error_destroy_disk;
-
-                ped_disk_destroy (disk);
+                        goto error;
         }
 
         disk = ped_disk_new_fresh (*dev, type);
@@ -512,15 +514,17 @@ do_mklabel (PedDevice** dev)
 
         if (!ped_disk_commit (disk))
                 goto error_destroy_disk;
-        ped_disk_destroy (disk);
 
         if ((*dev)->type != PED_DEVICE_FILE)
                 disk_is_modified = 1;
-
+        if (*diskp)
+                ped_disk_destroy (*diskp);
+        *diskp = disk;
         return 1;
 
 error_destroy_disk:
         ped_disk_destroy (disk);
+        *diskp = 0;
 error:
         return 0;
 }
@@ -598,7 +602,7 @@ _adjust_end_if_iec (PedSector* start, PedSector* end,
 }
 
 static int
-do_mkpart (PedDevice** dev)
+do_mkpart (PedDevice** dev, PedDisk** diskp)
 {
         PedDisk*                 disk;
         PedPartition*            part;
@@ -614,21 +618,26 @@ do_mkpart (PedDevice** dev)
         char                     *start_usr = NULL, *end_usr = NULL;
         char                     *start_sol = NULL, *end_sol = NULL;
 
-        disk = ped_disk_new (*dev);
+        if (*diskp)
+                disk = *diskp;
+        else {
+                disk = ped_disk_new (*dev);
+                *diskp = disk;
+        }
         if (!disk)
                 goto error;
 
         if (ped_disk_is_flag_available(disk, PED_DISK_CYLINDER_ALIGNMENT))
                 if (!ped_disk_set_flag(disk, PED_DISK_CYLINDER_ALIGNMENT,
                                        alignment == ALIGNMENT_CYLINDER))
-                        goto error_destroy_disk;
+                        goto error;
 
         if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED)) {
                 part_type = PED_PARTITION_NORMAL;
         } else {
                 if (!command_line_get_part_type (_("Partition type?"),
                                                 disk, &part_type))
-                        goto error_destroy_disk;
+                        goto error;
         }
 
         /* The undocumented feature that mkpart sometimes takes a
@@ -654,15 +663,15 @@ do_mkpart (PedDevice** dev)
         } else {
                 if (!command_line_get_fs_type (_("File system type?"),
                                                &fs_type))
-                        goto error_destroy_disk;
+                        goto error;
         }
         free (peek_word);
 
         if (!command_line_get_sector (_("Start?"), *dev, &start, &range_start, NULL))
-                goto error_destroy_disk;
+                goto error;
         char *end_input;
         if (!command_line_get_sector (_("End?"), *dev, &end, &range_end, &end_input))
-                goto error_destroy_disk;
+                goto error;
 
         _adjust_end_if_iec(&start, &end, range_end, end_input);
         free(end_input);
@@ -670,7 +679,7 @@ do_mkpart (PedDevice** dev)
         /* processing starts here */
         part = ped_partition_new (disk, part_type, fs_type, start, end);
         if (!part)
-                goto error_destroy_disk;
+                goto error;
 
         snap_to_boundaries (&part->geom, NULL, disk, range_start, range_end);
 
@@ -778,16 +787,14 @@ do_mkpart (PedDevice** dev)
         free (part_name);  /* avoid double-free upon failure */
         part_name = NULL;
         if (!ped_partition_set_system (part, fs_type))
-                goto error_destroy_disk;
+                goto error;
         if (ped_partition_is_flag_available (part, PED_PARTITION_LBA))
                 ped_partition_set_flag (part, PED_PARTITION_LBA, 1);
 
         if (!ped_disk_commit (disk))
-                goto error_destroy_disk;
+                goto error;
 
         /* clean up */
-        ped_disk_destroy (disk);
-
         if (range_start != NULL)
                 ped_geometry_destroy (range_start);
         if (range_end != NULL)
@@ -807,10 +814,8 @@ error_remove_part:
         ped_disk_remove_partition (disk, part);
 error_destroy_simple_constraints:
         ped_partition_destroy (part);
-error_destroy_disk:
-        free (part_name);
-        ped_disk_destroy (disk);
 error:
+        free (part_name);
         if (range_start != NULL)
                 ped_geometry_destroy (range_start);
         if (range_end != NULL)
@@ -825,36 +830,33 @@ error:
 }
 
 static int
-do_name (PedDevice** dev)
+do_name (PedDevice** dev, PedDisk** disk)
 {
-        PedDisk*        disk;
         PedPartition*   part = NULL;
         char*           name;
 
-        disk = ped_disk_new (*dev);
+        if (!*disk)
+                *disk = ped_disk_new (*dev);
         if (!disk)
                 goto error;
 
-        if (!command_line_get_partition (_("Partition number?"), disk, &part))
-                goto error_destroy_disk;
+        if (!command_line_get_partition (_("Partition number?"), *disk, &part))
+                goto error;
 
         name = command_line_get_word (_("Partition name?"),
                         ped_partition_get_name (part), NULL, 0);
         if (!name)
-                goto error_destroy_disk;
+                goto error;
         if (!ped_partition_set_name (part, name))
                 goto error_free_name;
         free (name);
 
-        if (!ped_disk_commit (disk))
-                goto error_destroy_disk;
-        ped_disk_destroy (disk);
+        if (!ped_disk_commit (*disk))
+                goto error;
         return 1;
 
 error_free_name:
         free (name);
-error_destroy_disk:
-        ped_disk_destroy (disk);
 error:
         return 0;
 }
@@ -995,9 +997,8 @@ _print_disk_info (const PedDevice *dev, const PedDisk *disk)
 }
 
 static int
-do_print (PedDevice** dev)
+do_print (PedDevice** dev, PedDisk** disk)
 {
-        PedDisk*        disk = NULL;
         Table*          table;
         int             has_extended;
         int             has_name;
@@ -1039,22 +1040,23 @@ do_print (PedDevice** dev)
         }
 
         if (!has_devices_arg && !has_list_arg) {
-                disk = ped_disk_new (*dev);
+                if (!*disk)
+                        *disk = ped_disk_new (*dev);
                 /* Returning NULL here is an indication of failure, when in
                    script mode.  Otherwise (interactive mode) it may indicate
                    a real error, but it may also indicate that the user
                    declined when asked to perform some operation.  FIXME:
                    what this really needs is an API change, but a reliable
                    exit code is less important in interactive mode.  */
-                if (disk == NULL && opt_script_mode)
+                if (*disk == NULL && opt_script_mode)
                         ok = 0;
         }
 
-        if (disk &&
-            ped_disk_is_flag_available(disk, PED_DISK_CYLINDER_ALIGNMENT))
-                if (!ped_disk_set_flag(disk, PED_DISK_CYLINDER_ALIGNMENT,
+        if (*disk &&
+            ped_disk_is_flag_available(*disk, PED_DISK_CYLINDER_ALIGNMENT))
+                if (!ped_disk_set_flag(*disk, PED_DISK_CYLINDER_ALIGNMENT,
                                        alignment == ALIGNMENT_CYLINDER))
-                        goto error_destroy_disk;
+                        return 0;
 
         if (has_devices_arg) {
                 char*           dev_name;
@@ -1087,24 +1089,23 @@ do_print (PedDevice** dev)
         else if (has_list_arg)
                 return _print_list ();
 
-        else if (disk && has_num_arg) {
+        else if (*disk && has_num_arg) {
                 PedPartition*   part = NULL;
                 int             status = 0;
-                if (command_line_get_partition ("", disk, &part))
+                if (command_line_get_partition ("", *disk, &part))
                         status = partition_print (part);
-                ped_disk_destroy (disk);
                 return status;
         }
 
-        _print_disk_info (*dev, disk);
-        if (!disk)
+        _print_disk_info (*dev, *disk);
+        if (!*disk)
                 goto nopt;
         if (!opt_machine_mode)
                 putchar ('\n');
 
-        has_extended = ped_disk_type_check_feature (disk->type,
+        has_extended = ped_disk_type_check_feature ((*disk)->type,
                                          PED_DISK_TYPE_EXTENDED);
-        has_name = ped_disk_type_check_feature (disk->type,
+        has_name = ped_disk_type_check_feature ((*disk)->type,
                                          PED_DISK_TYPE_PARTITION_NAME);
 
         PedPartition* part;
@@ -1134,8 +1135,8 @@ do_print (PedDevice** dev)
 
             table_add_row_from_strlist (table, row1);
 
-            for (part = ped_disk_next_partition (disk, NULL); part;
-                 part = ped_disk_next_partition (disk, part)) {
+            for (part = ped_disk_next_partition (*disk, NULL); part;
+                 part = ped_disk_next_partition (*disk, part)) {
 
                     if ((!has_free_arg && !ped_partition_is_active(part)) ||
                         part->type & PED_PARTITION_METADATA)
@@ -1210,8 +1211,8 @@ do_print (PedDevice** dev)
 
         } else {
 
-            for (part = ped_disk_next_partition (disk, NULL); part;
-                 part = ped_disk_next_partition (disk, part)) {
+            for (part = ped_disk_next_partition (*disk, NULL); part;
+                 part = ped_disk_next_partition (*disk, part)) {
 
                 if ((!has_free_arg && !ped_partition_is_active(part)) ||
                         part->type & PED_PARTITION_METADATA)
@@ -1259,13 +1260,8 @@ do_print (PedDevice** dev)
             }
         }
 
-        ped_disk_destroy (disk);
-
         return ok;
 
-error_destroy_disk:
-        ped_disk_destroy (disk);
-        return 0;
 nopt:
         return ok;
 }
@@ -1274,11 +1270,15 @@ static int
 _print_list ()
 {
         PedDevice *current_dev = NULL;
+        PedDisk *disk = 0;
 
         ped_device_probe_all();
 
         while ((current_dev = ped_device_get_next(current_dev))) {
-                do_print (&current_dev);
+                do_print (&current_dev, &disk);
+                if (disk)
+                        ped_disk_destroy (disk);
+                disk = 0;
                 putchar ('\n');
         }
 
@@ -1286,9 +1286,9 @@ _print_list ()
 }
 
 static int
-do_quit (PedDevice** dev)
+do_quit (PedDevice** dev, PedDisk **disk)
 {
-        _done (*dev);
+        _done (*dev, *disk);
         exit (EXIT_SUCCESS);
 }
 
@@ -1434,7 +1434,7 @@ error_remove_partition:
 }
 
 static int
-do_rescue (PedDevice** dev)
+do_rescue (PedDevice** dev, PedDisk** diskp)
 {
         PedDisk*                disk;
         PedSector               start = 0, end = 0;
@@ -1442,6 +1442,10 @@ do_rescue (PedDevice** dev)
         PedGeometry             probe_start_region;
         PedGeometry             probe_end_region;
 
+        if (*diskp) {
+                ped_disk_destroy (*diskp);
+                *diskp = 0;
+        }
         disk = ped_disk_new (*dev);
         if (!disk)
                 goto error;
@@ -1478,37 +1482,34 @@ error:
 }
 
 static int
-do_rm (PedDevice** dev)
+do_rm (PedDevice** dev, PedDisk** disk)
 {
-        PedDisk*                disk;
         PedPartition*           part = NULL;
 
-        disk = ped_disk_new (*dev);
-        if (!disk)
+        if (!*disk)
+                *disk = ped_disk_new (*dev);
+        if (!*disk)
                 goto error;
 
-        if (!command_line_get_partition (_("Partition number?"), disk, &part))
-                goto error_destroy_disk;
+        if (!command_line_get_partition (_("Partition number?"), *disk, &part))
+                goto error;
         if (!_partition_warn_busy (part))
-                goto error_destroy_disk;
+                goto error;
 
-        ped_disk_delete_partition (disk, part);
-        ped_disk_commit (disk);
-        ped_disk_destroy (disk);
+        ped_disk_delete_partition (*disk, part);
+        ped_disk_commit (*disk);
 
         if ((*dev)->type != PED_DEVICE_FILE)
                 disk_is_modified = 1;
 
         return 1;
 
-error_destroy_disk:
-        ped_disk_destroy (disk);
 error:
         return 0;
 }
 
 static int
-do_select (PedDevice** dev)
+do_select (PedDevice** dev, PedDisk** disk)
 {
         PedDevice*      new_dev = *dev;
 
@@ -1518,6 +1519,10 @@ do_select (PedDevice** dev)
                 return 0;
 
         ped_device_close (*dev);
+        if (*disk) {
+                ped_disk_destroy (*disk);
+                *disk = 0;
+        }
         *dev = new_dev;
         print_using_dev (*dev);
         return 1;
@@ -1548,26 +1553,25 @@ partition_align_check (PedDisk const *disk, PedPartition const *part,
 }
 
 static int
-do_align_check (PedDevice **dev)
+do_align_check (PedDevice **dev, PedDisk** disk)
 {
-  PedDisk *disk = ped_disk_new (*dev);
-  if (!disk)
+  if (!*disk)
+    *disk = ped_disk_new (*dev);
+  if (!*disk)
     goto error;
 
   enum AlignmentType align_type = PA_OPTIMUM;
   PedPartition *part = NULL;
 
   if (!command_line_get_align_type (_("alignment type(min/opt)"), &align_type))
-    goto error_destroy_disk;
-  if (!command_line_get_partition (_("Partition number?"), disk, &part))
-    goto error_destroy_disk;
+    goto error;
+  if (!command_line_get_partition (_("Partition number?"), *disk, &part))
+    goto error;
 
-  bool aligned = partition_align_check (disk, part, align_type);
+  bool aligned = partition_align_check (*disk, part, align_type);
   if (!opt_script_mode)
     printf(aligned ? _("%d aligned\n") : _("%d not aligned\n"), part->num);
 
-  ped_disk_destroy (disk);
-
   if (opt_script_mode)
     return aligned ? 1 : 0;
 
@@ -1575,115 +1579,107 @@ do_align_check (PedDevice **dev)
      with the other modes.  */
   return 1;
 
-error_destroy_disk:
-  ped_disk_destroy (disk);
 error:
   return 0;
 }
 
 static int
-do_disk_set (PedDevice** dev)
+do_disk_set (PedDevice** dev, PedDisk** disk)
 {
-    PedDisk*    disk;
     PedDiskFlag flag;
     int         state;
 
-    disk = ped_disk_new (*dev);
+    if (!*disk)
+            *disk = ped_disk_new (*dev);
     if (!disk)
         goto error;
 
-    if (!command_line_get_disk_flag (_("Flag to Invert?"), disk, &flag))
-        goto error_destroy_disk;
-    state = (ped_disk_get_flag (disk, flag) == 0 ? 1 : 0);
+    if (!command_line_get_disk_flag (_("Flag to Invert?"), *disk, &flag))
+        goto error;
+    state = (ped_disk_get_flag (*disk, flag) == 0 ? 1 : 0);
 
     if (!is_toggle_mode) {
         if (!command_line_get_state (_("New state?"), &state))
-            goto error_destroy_disk;
+            goto error;
     }
 
-    if (!ped_disk_set_flag (disk, flag, state))
-        goto error_destroy_disk;
-    if (!ped_disk_commit (disk))
-        goto error_destroy_disk;
-    ped_disk_destroy (disk);
+    if (!ped_disk_set_flag (*disk, flag, state))
+        goto error;
+    if (!ped_disk_commit (*disk))
+        goto error;
 
     if ((*dev)->type != PED_DEVICE_FILE)
         disk_is_modified = 1;
 
     return 1;
 
-error_destroy_disk:
-    ped_disk_destroy (disk);
 error:
     return 0;
 }
 
 static int
-do_set (PedDevice** dev)
+do_set (PedDevice** dev, PedDisk **disk)
 {
-        PedDisk*                disk;
         PedPartition*           part = NULL;
         PedPartitionFlag        flag;
         int                     state;
 
-        disk = ped_disk_new (*dev);
-        if (!disk)
+        if (*disk == 0)
+                *disk = ped_disk_new (*dev);
+        if (!*disk)
                 goto error;
 
-        if (!command_line_get_partition (_("Partition number?"), disk, &part))
-                goto error_destroy_disk;
+        if (!command_line_get_partition (_("Partition number?"), *disk, &part))
+                goto error;
         if (!command_line_get_part_flag (_("Flag to Invert?"), part, &flag))
-                goto error_destroy_disk;
+                goto error;
         state = (ped_partition_get_flag (part, flag) == 0 ? 1 : 0);
 
         if (!is_toggle_mode) {
                 if (!command_line_get_state (_("New state?"), &state))
-		            goto error_destroy_disk;
+                        goto error;
         }
 
         if (!ped_partition_set_flag (part, flag, state))
-	        	goto error_destroy_disk;
-    	if (!ped_disk_commit (disk))
-	        	goto error_destroy_disk;
-    	ped_disk_destroy (disk);
+                goto error;
+        if (!ped_disk_commit (*disk))
+                goto error;
 
         if ((*dev)->type != PED_DEVICE_FILE)
                 disk_is_modified = 1;
 
-	    return 1;
+        return 1;
 
-error_destroy_disk:
-        ped_disk_destroy (disk);
 error:
         return 0;
 }
 
 static int
-do_disk_toggle (PedDevice **dev)
+do_disk_toggle (PedDevice **dev, PedDisk** disk)
 {
     int result;
 
     is_toggle_mode = 1;
-    result = do_disk_set (dev);
+    result = do_disk_set (dev, disk);
     is_toggle_mode = 0;
 
     return result;
 }
 
 static int
-do_toggle (PedDevice **dev)
+do_toggle (PedDevice **dev, PedDisk** disk)
 {
         int result;
 
         is_toggle_mode = 1;
-        result = do_set (dev);
+        result = do_set (dev, disk);
         is_toggle_mode = 0;
 
         return result;
 }
 
 static int
-do_unit (PedDevice** dev)
+do_unit (PedDevice** dev, PedDisk** disk)
 {
         PedUnit unit = ped_unit_get_default ();
         if (!command_line_get_unit (_("Unit?"), &unit))
@@ -2131,8 +2127,10 @@ return NULL;
 }
 
 static void
-_done (PedDevice* dev)
+_done (PedDevice* dev, PedDisk* disk)
 {
+if (disk)
+        ped_disk_destroy (disk);
 if (dev->boot_dirty && dev->type != PED_DEVICE_FILE) {
         ped_exception_throw (
                 PED_EXCEPTION_WARNING,
@@ -2159,6 +2157,7 @@ int
 main (int argc, char** argv)
 {
         PedDevice*      dev;
+	PedDisk*        disk = 0;
         int             status;
 
         set_program_name (argv[0]);
@@ -2169,11 +2168,11 @@ main (int argc, char** argv)
                 return 1;
 
         if (argc || opt_script_mode)
-                status = non_interactive_mode (&dev, commands, argc, argv);
+                status = non_interactive_mode (&dev, &disk, commands, argc, argv);
         else
-                status = interactive_mode (&dev, commands);
+                status = interactive_mode (&dev, &disk, commands);
 
-        _done (dev);
+        _done (dev, disk);
 
         return !status;
 }
diff --git a/parted/ui.c b/parted/ui.c
index 786deed..e0355ff 100644
--- a/parted/ui.c
+++ b/parted/ui.c
@@ -1557,7 +1557,7 @@ print_using_dev (PedDevice* dev)
 }
 
 int
-interactive_mode (PedDevice** dev, Command* cmd_list[])
+interactive_mode (PedDevice** dev, PedDisk** disk, Command* cmd_list[])
 {
         StrList*    list;
         StrList*    command_names = command_get_names (cmd_list);
@@ -1590,7 +1590,7 @@ interactive_mode (PedDevice** dev, Command* cmd_list[])
                         cmd = command_get (commands, word);
                         free (word);
                         if (cmd) {
-                                if (!command_run (cmd, dev))
+                                if (!command_run (cmd, dev, disk))
                                         command_line_flush ();
                         } else
                                 print_commands_help ();
@@ -1602,7 +1602,7 @@ interactive_mode (PedDevice** dev, Command* cmd_list[])

 int
-non_interactive_mode (PedDevice** dev, Command* cmd_list[],
+non_interactive_mode (PedDevice** dev, PedDisk **disk, Command* cmd_list[],
                       int argc, char* argv[])
 {
         int         i;
@@ -1633,7 +1633,7 @@ non_interactive_mode (PedDevice** dev, Command* cmd_list[],
                         goto error;
                 }
 
-                if (!command_run (cmd, dev))
+                if (!command_run (cmd, dev, disk))
                         goto error;
         }
         return 1;
diff --git a/parted/ui.h b/parted/ui.h
index 3c6ebc0..260ce37 100644
--- a/parted/ui.h
+++ b/parted/ui.h
@@ -31,9 +31,11 @@ extern const char *prog_name;
 
 extern int init_ui ();
 extern int init_readline ();
-extern int non_interactive_mode (PedDevice** dev, Command* cmd_list[],
-				 int argc, char* argv[]);
-extern int interactive_mode (PedDevice** dev, Command* cmd_list[]);
+extern int non_interactive_mode (PedDevice** dev, PedDisk **disk,
+				 Command* cmd_list[], int argc,
+				 char* argv[]);
+extern int interactive_mode (PedDevice** dev, PedDisk **disk,
+			     Command* cmd_list[]);
 extern void done_ui ();
 
 extern int screen_width ();
diff --git a/tests/t3300-palo-prep.sh b/tests/t3300-palo-prep.sh
index 4050414..88b2c55 100755
--- a/tests/t3300-palo-prep.sh
+++ b/tests/t3300-palo-prep.sh
@@ -20,9 +20,9 @@
 ss=$sector_size_
 
 cat > exp <<EOF || framework_failure
-1:2048s:4095s:2048s:::palo;
-1:2048s:4095s:2048s:::prep;
-1:2048s:4095s:2048s:::palo;
+1:2048s:4095s:2048s:ext2::lba, palo;
+1:2048s:4095s:2048s:ext2::lba, prep;
+1:2048s:4095s:2048s:ext2::lba, palo;
 EOF
 
 dev=dev-file
@@ -37,7 +37,7 @@ parted -m -s $dev mklabel msdos \
   set 1 palo on u s print \
     > out 2> err || fail=1
 
-grep -E '^1:2048s:4095s:2048s:::p...;$' out > k; mv k out
+grep -E '^1:2048s:4095s:2048s:ext2::lba, p...;$' out > k; mv k out
 
 compare exp out || fail=1
 
-- 
1.8.3.2