bug-parted
[Top][All Lists]
Advanced

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

Re: Problem with GPT partition after LUN resized (parted-1.7.0)


From: Darren Lavender
Subject: Re: Problem with GPT partition after LUN resized (parted-1.7.0)
Date: Mon, 14 Aug 2006 14:06:46 +0100

Following on from my earlier bug report:

> Problem with GPT partition after LUN resized
> 
> parted-1.7.0  (platform ia64)


I have discovered the root cause and fixed both problem #1 & #2, perhaps
the fixes suggested below can be reviewed/considered for inclusion in to
the parted/libparted???


> ##### PROBLEM DETAILS #####
> 
> 
> I observe several problems with parted v1.7.0 after having 
> resized a LUN on ia64 (SLES8):
> 
> 
> ### PROBLEM #1:
> 
> An exception when parted recognises that the backup GPT header is not
> in the correct place and tries to move it:
> 

> ...........
> 
> Assertion (n > 0) at exception.c:112 in function ped_log2() failed.
> 
> Ignore/Cancel? Ignore                                                     
>                                                                           
> 
> You found a bug in GNU Parted! Here's what you have to do:


This assertion problem is found in command_line_get_ex_opt() of
parted-1.7.0/parted/ui.c and can be addressed via the following patch: 

royce:~ # diff -Naur parted-1.7.0.old/parted/ui.c parted-1.7.0/parted/ui.c
--- parted-1.7.0.old/parted/ui.c        2006-05-15 02:49:53.000000000 -0700
+++ parted-1.7.0/parted/ui.c    2006-08-14 13:50:10.000000000 -0700
@@ -1027,13 +1027,13 @@
 
        opt = PED_EXCEPTION_OPTION_FIRST;
        while (1) {
-               opt = option_get_next (options, opt);
                if (strcmp (opt_name,
                            ped_exception_get_option_string (opt)) == 0)
                        break;
                if (strcmp (opt_name,
                            _(ped_exception_get_option_string (opt))) == 0)
                        break;
+               opt = option_get_next (options, opt);
        }
        free (opt_name);
        return opt;
royce:~ # 


The problem occurs because we prematurely advance the options, thereby
missing the one we're after.  After making the above change the
assertion error is no longer observed.



> ### PROBLEM #2:
> 
> Having relocated the GPT headers, I cannot utilise the additional
> space made available in the resized LUN.

.......

> So although the header was relocated parted made no attempt to 
> modify the LastUsableLBA field, hence the newly available space 
> is not available for a new partition or resizing.  Should this 
> not have been adjusted to 25165790 ?
> 
> Am I missing some technical reason for why this did not happen 
> or is it simply an oversight/defect?

This problem occurs because when the backup GPT is not located at the
end of the disk we assume it is corrupt, we could in fact locate it from
the data in the first header, but that's a different story.  Anyway,
when moving the header we simply don't consider the fact that the device
has grown and that we could utilise the newly allocated space.  

The code I introduce now gives the user the option of updating the
LastUsableLBA so that the space can be utilised, or they can ignore the
fact that the disk has changed size and leave the LastUsableLBA alone. 

The code modified is in:

parted-1.7.0/libparted/labels/gpt.c:_parse_header():


royce:~ # diff -Naur  parted-1.7.0.old/libparted/labels/gpt.c 
parted-1.7.0/libparted/labels/gpt.c
--- parted-1.7.0.old/libparted/labels/gpt.c     2006-05-15 02:19:34.000000000 
-0700
+++ parted-1.7.0/libparted/labels/gpt.c 2006-08-14 13:56:45.000000000 -0700
@@ -612,6 +612,7 @@
        GPTDiskData* gpt_disk_data = disk->disk_specific;
        PedSector first_usable;
        PedSector last_usable;
+       PedSector last_usable_if_grown;
 
        PED_ASSERT (_header_is_valid (disk->dev, gpt), return 0);
 
@@ -633,11 +634,47 @@
 
        first_usable = PED_CPU_TO_LE64 (gpt->FirstUsableLBA);
        last_usable = PED_CPU_TO_LE64 (gpt->LastUsableLBA);
+
+/* Need to check whether the volume has grown, the LastUsableLBA is
+   normally set to disk->dev->length - 2 - ptes_size, where ptes_size
+   is the number of entries * size of each entry / sector size.
+   If the volume has grown, offer the user the chance to use the new
+   space or continue with the current usable area.
+*/
+   
+       last_usable_if_grown 
+               = PED_CPU_TO_LE64 (disk->dev->length - 2 - 
+               ((PedSector)(PED_CPU_TO_LE32(gpt->NumberOfPartitionEntries)) * 
+               (PedSector)(PED_CPU_TO_LE32(gpt->SizeOfPartitionEntry)) / 
+               disk->dev->sector_size));
+
+
        PED_ASSERT (last_usable > first_usable, return 0);
        PED_ASSERT (last_usable <= disk->dev->length, return 0);
+
+       PED_ASSERT (last_usable_if_grown > first_usable, return 0);
+       PED_ASSERT (last_usable_if_grown <= disk->dev->length, return 0);
+
+       if ( last_usable < last_usable_if_grown ) {
+
+               if (ped_exception_throw (
+                       PED_EXCEPTION_ERROR,
+                       PED_EXCEPTION_FIX | PED_EXCEPTION_IGNORE,
+                       _("The disk appears to have grown in size, you "
+                       "can fix the GPT to use the newly allocated space "
+                       "or continue with the current setting? "))
+                       == PED_EXCEPTION_FIX) {
+
+
+                               last_usable = last_usable_if_grown;
+
+               }
+       }
+
        ped_geometry_init (&gpt_disk_data->data_area, disk->dev,
                           first_usable, last_usable - first_usable + 1);
 
+
        gpt_disk_data->entry_count
                = PED_CPU_TO_LE32 (gpt->NumberOfPartitionEntries);
        PED_ASSERT (gpt_disk_data->entry_count > 0, return 0);
royce:~ # 


With this code in place, the user is prompted to update the GPT if the
current LastUsableLBA does not match where we think it should be for a
volume of this size with gpt->NumberOfPartitionEntries, eg:



royce:~/parted-1.7.0 # parted /dev/vgparted/lvol1 
GNU Parted 1.7.0
Using /dev/vgparted/lvol1
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print                                                            
Error: The backup GPT table is not at the end of the disk, as it should be.
This might mean that another operating system believes the disk is smaller.
Fix, by moving the backup to the end (and removing the old backup)?
Fix/Cancel? f                                                             
Error: The disk appears to have grown in size, you can fix the GPT to use the
newly allocated space or continue with the current setting? 
Fix/Ignore? f                                                             

Disk /dev/vgparted/lvol1: 1887MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system  Name     Flags
 1      17.4kB  512MB   512MB                primary       
 2      512MB   1536MB  1024MB               primary       

(parted) q                                                                
Information: Don't forget to update /etc/fstab, if necessary.        



I have performed some rudimentary testing and the fixes appear to work.
Nevertheless, further close review would not be shunned!







reply via email to

[Prev in Thread] Current Thread [Next in Thread]