[gparted] Only read partition table after not finding a whole disk file system (#771244)



commit 683dc9d1abd6a388e6f1eda7c7ba8465eb970756
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Thu Dec 22 11:00:05 2016 +0000

    Only read partition table after not finding a whole disk file system (#771244)
    
    ISO9660 images can contain embedded partitions which when encountered on
    whole disk drives causes libparted to report various warnings and
    errors.  For example on CentOS 6 with upgraded libparted 2.4 the
    following errors and warnings are encountered with various ISO images.
    (Deliberately using an older distribution with older blkid to avoid
    another issue with blkid addressed in the following patch).
    
    Libparted error message 1:
        # wget http://git.kernel.org/cgit/utils/util-linux/util-linux.git/plain/tests/ts/isosize/sample.iso.gz
        # dd if=/dev/zero bs=1M of=/dev/sdc
        # zcat sample.iso.gz | dd of=/dev/sdc
    
        # blkid -v
        blkid from util-linux-ng 2.17.2 (libblkid 2.17.0, 22-Mar-2010)
        # blkid | fgrep /dev/sdc
        /dev/sdc: LABEL="ARCH_201301" TYPE="iso9660"
    
        # ./gpartedbin /dev/sdc
        ======================
        libparted : 2.4
        ======================
        Invalid partition table - recursive partition on /dev/sdc.
    
        Libparted Error
        (-) Invalid partition table - recursive partition on /dev/sdc.
                                                 [ Cancel ] [ Ignore ]
    
    Libparted error message 2:
        # wget http://cdimage.debian.org/debian-cd/8.6.0/amd64/iso-cd/debian-8.6.0-amd64-netinst.iso
        # dd if=/dev/zero bs=1M of=/dev/sdc
        # dd if=debian-8.6.0-amd64-netinst.iso bs=1M of=/dev/sdc
    
        # blkid | fgrep /dev/sdc
        /dev/sdc: LABEL="Debian 8.6.0 amd64 1" TYPE="iso9660"
    
        # ./gpartedbin /dev/sdc
        ======================
        libparted : 2.4
        ======================
        /dev/sdc contains GPT signatures, indicating that it has a GPT
        table.  However, it does not have a valid fake msdos partition
        table, as it should.  Perhaps it was corrupted -- possibly by a
        program that doesn't understand GPT partition tables.  Or perhaps
        you deleted the GPT table, and are now using an msdos partition
        table.  Is this a GPT partition table?
    
        Libparted Warning
        /!\ /dev/sdc contains GPT signatures, indicating that it has a GPT
            table.  However, it does not have a valid fake msdos partition
            table, as it should.  Perhaps it was corrupted -- possibly by a
            program that doesn't understand GPT partition tables.  Or
            perhaps you deleted the GPT table, and are now using an msdos
            partition table.  Is this a GPT partition table?
                                                             [ Yes ] [ No ]
    
    These messages are because GParted is calling ped_disk_new() to attempt
    to read the partition table even before it has tried to recognise the
    ISO9660 file system on the whole disk drive.  Full call chain is:
        set_devices_thread()
            set_device_from_disk()
                get_device_and_disk()
                    get_disk()
                        ped_disk_new()
    
    Fix this by delaying the call to ped_disk_new() until after whole disk
    drive recognition has been performed.  Replace combined
    get_device_and_disk() with separate get_device() and only call
    get_disk() after no whole disk drive file system has been recognised.
    This is similar to how calibrate_partition() and
    erase_filesystem_signatures() are structured to also handle whole disk
    drive file systems.
    
    Bug 771244 - gparted does not recognize the iso9660 file system in
                 cloned Ubuntu USB boot drives

 src/GParted_Core.cc |  138 ++++++++++++++++++++++++++-------------------------
 1 files changed, 71 insertions(+), 67 deletions(-)
---
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index b0f8f2f..97a586a 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -873,7 +873,7 @@ void GParted_Core::set_device_from_disk( Device & device, const Glib::ustring &
 {
        PedDevice* lp_device = NULL;
        PedDisk* lp_disk = NULL;
-       if ( get_device_and_disk( device_path, lp_device, lp_disk, false, true ) )
+       if ( get_device( device_path, lp_device, true ) )
        {
                device.Reset();
 
@@ -909,80 +909,84 @@ void GParted_Core::set_device_from_disk( Device & device, const Glib::ustring &
                        device.max_prims = 1;
                        set_device_one_partition( device, lp_device, fstype, messages );
                }
-               // Partitioned drive (excluding "loop"), as recognised by libparted
-               else if ( lp_disk && lp_disk->type && lp_disk->type->name &&
-                         strcmp( lp_disk->type->name, "loop" ) != 0         )
+               // Partitioned drive
+               else if ( get_disk( lp_device, lp_disk, false ) )
                {
-                       device.disktype = lp_disk->type->name;
-                       device.max_prims = ped_disk_get_max_primary_partition_count( lp_disk );
-
-                       // Determine if partition naming is supported.
-                       if ( ped_disk_type_check_feature( lp_disk->type, PED_DISK_TYPE_PARTITION_NAME ) )
+                       // Partitioned drive (excluding "loop"), as recognised by libparted
+                       if ( lp_disk && lp_disk->type && lp_disk->type->name &&
+                            strcmp( lp_disk->type->name, "loop" ) != 0         )
                        {
-                               device.enable_partition_naming(
-                                               Utils::get_max_partition_name_length( device.disktype ) );
-                       }
+                               device.disktype = lp_disk->type->name;
+                               device.max_prims = ped_disk_get_max_primary_partition_count( lp_disk );
+
+                               // Determine if partition naming is supported.
+                               if ( ped_disk_type_check_feature( lp_disk->type, PED_DISK_TYPE_PARTITION_NAME 
) )
+                               {
+                                       device.enable_partition_naming(
+                                                       Utils::get_max_partition_name_length( device.disktype 
) );
+                               }
+
+                               set_device_partitions( device, lp_device, lp_disk );
 
-                       set_device_partitions( device, lp_device, lp_disk );
+                               if ( device.highest_busy )
+                               {
+                                       device.readonly = ! commit_to_os( lp_disk, 
SETTLE_DEVICE_PROBE_MAX_WAIT_SECONDS );
+                                       // Clear libparted messages.  Typically these are:
+                                       //     The kernel was unable to re-read the partition table...
+                                       libparted_messages.clear();
+                               }
+                       }
+                       // Drive just containing libparted "loop" signature and nothing
+                       // else.  (Actually any drive reported by libparted as "loop" but
+                       // not recognised by blkid on the whole disk device).
+                       else if ( lp_disk && lp_disk->type && lp_disk->type->name &&
+                                 strcmp( lp_disk->type->name, "loop" ) == 0         )
+                       {
+                               device.disktype = lp_disk->type->name;
+                               device.max_prims = 1;
 
-                       if ( device.highest_busy )
+                               // Create virtual partition covering the whole disk device
+                               // with unknown contents.
+                               Partition * partition_temp = new Partition();
+                               partition_temp->Set( device.get_path(),
+                                                    lp_device->path,
+                                                    1,
+                                                    TYPE_PRIMARY,
+                                                    true,
+                                                    FS_UNKNOWN,
+                                                    0LL,
+                                                    device.length - 1LL,
+                                                    device.sector_size,
+                                                    false,
+                                                    false );
+                               // Place unknown file system message in this partition.
+                               partition_temp->append_messages( messages );
+                               device.partitions.push_back_adopt( partition_temp );
+                       }
+                       // Unrecognised, unpartitioned drive.
+                       else
                        {
-                               device.readonly = ! commit_to_os( lp_disk, 
SETTLE_DEVICE_PROBE_MAX_WAIT_SECONDS );
-                               // Clear libparted messages.  Typically these are:
-                               //     The kernel was unable to re-read the partition table...
+                               device.disktype =
+                                       /* TO TRANSLATORS:  unrecognized
+                                        * means that the partition table for this disk
+                                        * device is unknown or not recognized.
+                                        */
+                                       _("unrecognized");
+                               device.max_prims = 1;
+
+                               Partition * partition_temp = new Partition();
+                               partition_temp->Set_Unallocated( device.get_path(),
+                                                                true,
+                                                                0LL,
+                                                                device.length - 1LL,
+                                                                device.sector_size,
+                                                                false );
+                               // Place libparted messages in this unallocated partition
+                               partition_temp->append_messages( libparted_messages );
                                libparted_messages.clear();
+                               device.partitions.push_back_adopt( partition_temp );
                        }
                }
-               // Drive just containing libparted "loop" signature and nothing else.
-               // (Actually any drive reported by libparted as "loop" but not recognised
-               // by blkid on the whole disk device).
-               else if ( lp_disk && lp_disk->type && lp_disk->type->name &&
-                         strcmp( lp_disk->type->name, "loop" ) == 0         )
-               {
-                       device.disktype = lp_disk->type->name;
-                       device.max_prims = 1;
-
-                       // Create virtual partition covering the whole disk device with
-                       // unknown contents.
-                       Partition * partition_temp = new Partition();
-                       partition_temp->Set( device.get_path(),
-                                            lp_device->path,
-                                            1,
-                                            TYPE_PRIMARY,
-                                            true,
-                                            FS_UNKNOWN,
-                                            0LL,
-                                            device.length - 1LL,
-                                            device.sector_size,
-                                            false,
-                                            false );
-                       // Place unknown file system message in this partition.
-                       partition_temp->append_messages( messages );
-                       device.partitions.push_back_adopt( partition_temp );
-               }
-               // Unrecognised, unpartitioned drive.
-               else
-               {
-                       device.disktype =
-                               /* TO TRANSLATORS:  unrecognized
-                                * means that the partition table for this disk device is
-                                * unknown or not recognized.
-                                */
-                               _("unrecognized");
-                       device.max_prims = 1;
-
-                       Partition * partition_temp = new Partition();
-                       partition_temp->Set_Unallocated( device.get_path(),
-                                                        true,
-                                                        0LL,
-                                                        device.length - 1LL,
-                                                        device.sector_size,
-                                                        false );
-                       // Place libparted messages in this unallocated partition
-                       partition_temp->append_messages( libparted_messages );
-                       libparted_messages.clear();
-                       device.partitions.push_back_adopt( partition_temp );
-               }
 
                destroy_device_and_disk( lp_device, lp_disk);
        }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]