OpenSolaris

Printable Version Enter a New Search
Bug ID 6690824
Synopsis fdisk(1M) corrupts Solaris VTOC, if there is Linux swap primary partition defined
State 10-Fix Delivered (Fix available in build)
Category:Subcategory utility:fdisk
Keywords
Responsible Engineer Barry Harding
Reported Against
Duplicate Of
Introduced In solaris_10
Commit to Fix snv_89
Fixed In snv_89
Release Fixed solaris_nevada(snv_89)
Related Bugs 4961447 , 4410647
Submit Date 18-April-2008
Last Update Date 8-May-2008
Description
I have created following partition configuration:

[1] Solaris (0xbf)
[2] Linux swap (0x82)

Then I installed Indiana rc1 2008.05 into [1], which is to be supported configuration
for now, since we want to be able to coexist with Linux swap primary partition defined
at the same disk.

After reboot I ended up in GRUB. I booted Indiana LiveCD and it turned out that Solaris
VTOC was cleared, so zpool with installed Solaris instance was corrupted.

As far as fdisk(1M) is concerned, Indiana installer does following steps:

[1] "fdisk(1M) -F" is called to create Solaris2 partition
    with "active" flag not set
[2] Solaris is installed
[3] "fdisk(1M) -F" is called to set "active" flag for
    Solaris2 partition

VTOC shouldn't be cleared in [3], since partition geometry is not changed, only "active"
lag is turned on.

Looking at the fdisk code, the algorithm for determining if VTOC should be cleared is
confused, if there are more than one SUNIXOS (0x82) or SUNIXOS2 (0xbf) partitions
present on one disk:

dev_mboot_write()
{
   int    clr_efi = -1, old_solaris = -1, new_solaris = -1;

[Block A]

   /* see if the old table had EFI or Solaris partitions */
   for (old_pt = 0; old_pt < FD_NUMPART; old_pt++) {
       if (Old_Table[old_pt].systid == SUNIXOS ||
           Old_Table[old_pt].systid == SUNIXOS2) {
           old_solaris = old_pt;
   }
[Block B]

   /* look to see if Solaris partition changed in relsect/numsect */
   for (new_pt = 0; new_pt < FD_NUMPART; new_pt++) {
       /*
        * if this is not a Solaris partition, ignore it
        */
       if (Table[new_pt].systid != SUNIXOS &&
           Table[new_pt].systid != SUNIXOS2)
           continue;

       /*
        * if there was no previous Solaris partition
        * or if the old partition was in a different place
        * or if the old partition was a different size
        * then this must be a new Solaris partition
        */
       if (old_solaris == -1 ||
           Old_Table[old_solaris].relsect != Table[new_pt].relsect ||
           Old_Table[old_solaris].numsect != Table[new_pt].numsect) {
           new_solaris = new_pt;
           break;
       }
   }

[Block C]

   if (new_solaris >= 0) {
       clear_vtoc(NEW, new_solaris);
   }
}


In our particular configuration, it behaves in following way:

[Block A] loop searches for last Solaris partition defined (0x82 or 0xbf) - thus
"old_solaris" picks up the Linux swap.

In [Block B] it is incorrectly decided that partition changed, since Linux swap is being
compared to the Solaris partition (if there is at least one which is different it is
picked up in this loop).

VTOC is cleared in [Block C] for partition which differs - Solaris one in our case.
Work Around
N/A
Comments
N/A