Friday, November 7, 2014

Can we change disk label from msdos or linux to GPT without losing data?

Can we change disk label ( using fdisk or parted utility) of a diks from msdos/linux to GPT without losing data?

Say we have a 10 GB disk, having disk label msdos(Linux or hex code 83)  and that has ext3 filesystem on 1 GB primary partition.

  • Short answer is NO
  • Long answer is also NO. On my test system, changing label using fdisk preserve data byt filesystem is not longer mountable. Changing label using parted is complete damage - no data and no mounting !!


Here is test output  and explanations


Create a 1 GB partition using fdisk label hex code 83 (Linux)- parted detects it as msdos label

# fdisk -l /dev/sdb

Disk /dev/sdb: 10.7 GB, 10737418240 bytes
64 heads, 32 sectors/track, 10240 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000a652f

   Device Boot      Start         End      Blocks   Id  System

# fdisk -l /dev/sdb

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-10240, default 1): 
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-10240, default 10240): +1G

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
# fdisk /dev/sdb[3@-l /dev/sdb

Disk /dev/sdb: 10.7 GB, 10737418240 bytes
64 heads, 32 sectors/track, 10240 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000a652f

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1        1025     1049584   83  Linux



Create ext3 filesystem on 1G partition created by fdisk, mount it, copy some dummy data and take note of number of files / total size

# mkfs.ext3 /dev/sdb1
mke2fs 1.41.12 (17-May-2010)
warning: 252 blocks unused.

Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
65664 inodes, 262144 blocks
13119 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=268435456
8 block groups
32768 blocks per group, 32768 fragments per group
8208 inodes per group
Superblock backups stored on blocks: 
32768, 98304, 163840, 229376

Writing inode tables: 0/81/82/83/84/85/86/87/8done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 20 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

# mkdir /dummyfs
# mount /dev/sdb1 /dummyfs
# cp -a /etc/* /dummyfs/
# ls -lR /dummyfs|wc -l
2465
# du -sh /dummyfs
27M /dummyfs




Unmount it and cahnge disklabel to hex code ee (GPT )

# umount /dummyfs

fdisk -l /dev/sdb

Disk /dev/sdb: 10.7 GB, 10737418240 bytes
64 heads, 32 sectors/track, 10240 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000a652f

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1        1025     1049584   83  Linux
# fdisk -l /dev/sdb

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): L

 0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris        
 1  FAT12           39  Plan 9          82  Linux swap / So c1  DRDOS/sec (FAT-
 2  XENIX root      3c  PartitionMagic  83  Linux           c4  DRDOS/sec (FAT-
 3  XENIX usr       40  Venix 80286     84  OS/2 hidden C:  c6  DRDOS/sec (FAT-
 4  FAT16 <32m 85="" boot="" c7="" extended="" font="" inux="" nbsp="" prep="" yrinx="">
 5  Extended        42  SFS             86  NTFS volume set da  Non-FS data    
 6  FAT16           4d  QNX4.x          87  NTFS volume set db  CP/M / CTOS / .
 7  HPFS/NTFS       4e  QNX4.x 2nd part 88  Linux plaintext de  Dell Utility   
 8  AIX             4f  QNX4.x 3rd part 8e  Linux LVM       df  BootIt         
 9  AIX bootable    50  OnTrack DM      93  Amoeba          e1  DOS access     
 a  OS/2 Boot Manag 51  OnTrack DM6 Aux 94  Amoeba BBT      e3  DOS R/O        
 b  W95 FAT32       52  CP/M            9f  BSD/OS          e4  SpeedStor      
 c  W95 FAT32 (LBA) 53  OnTrack DM6 Aux a0  IBM Thinkpad hi eb  BeOS fs        
 e  W95 FAT16 (LBA) 54  OnTrackDM6      a5  FreeBSD         ee  GPT            
 f  W95 Ext'd (LBA) 55  EZ-Drive        a6  OpenBSD         ef  EFI (FAT-12/16/
10  OPUS            56  Golden Bow      a7  NeXTSTEP        f0  Linux/PA-RISC b
11  Hidden FAT12    5c  Priam Edisk     a8  Darwin UFS      f1  SpeedStor      
12  Compaq diagnost 61  SpeedStor       a9  NetBSD          f4  SpeedStor      
14  Hidden FAT16 <3 63="" ab="" arwin="" boot="" f2="" font="" hurd="" nbsp="" or="" secondary="" sys="">
16  Hidden FAT16    64  Novell Netware  af  HFS / HFS+      fb  VMware VMFS    
17  Hidden HPFS/NTF 65  Novell Netware  b7  BSDI fs         fc  VMware VMKCORE 
18  AST SmartSleep  70  DiskSecure Mult b8  BSDI swap       fd  Linux raid auto
1b  Hidden W95 FAT3 75  PC/IX           bb  Boot Wizard hid fe  LANstep        
1c  Hidden W95 FAT3 80  Old Minix       be  Solaris boot    ff  BBT            
1e  Hidden W95 FAT1
Hex code (type L to list codes): ee
Changed system type of partition 1 to ee (GPT)

Command (m for help): p

Disk /dev/sdb: 10.7 GB, 10737418240 bytes
64 heads, 32 sectors/track, 10240 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000a652f

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1        1025     1049584   ee  GPT

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
# fdisk -l /dev/sdb

Disk /dev/sdb: 10.7 GB, 10737418240 bytes
64 heads, 32 sectors/track, 10240 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000a652f

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1        1025     1049584   ee  GPT



After changing label from hexcode type 83 ( Linux ) to GPT, mount did not recognoze filesystem type and not able to mount. Did you loose your data?!! Hold one a second !!

# mount /dev/sdb1 /dummyfs/
mount: you must specify the filesystem type
# mount -t ext3 /dev/sdb1 /dummyfs/ 
mount: special device /dev/sdb1 does not exist




Now change disk label back to hexcode 83 (Linux) from GPT ( hex code ee), mount filesystem and your data is there ! Conclusion: Changing disk label using fdisk from msdos/Linux to GPT will preserve data but you will be not able to mount - hence effectively unusable ( I do not know if there is any way to mount it ! )

# fdisk -l /dev/sdb

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 83
Changed system type of partition 1 to 83 (Linux)

Command (m for help): p

Disk /dev/sdb: 10.7 GB, 10737418240 bytes
64 heads, 32 sectors/track, 10240 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000a652f

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1        1025     1049584   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
# fdisk /dev/sdb
#mount -t ext3 /dev/sdb1 /dummyfs
# ls -lR /dummyfs|wc -l
2465

du -sh /dummyfs
27M /dummyfs



Now change disk label from Linux (83) to Linux LVM (8e). You will be able to mount it. Conclusion : Changing label from 83 to 8e preserve data and allow to mount filesystem.

# umount /dummyfs
# fdisk /dev/sdb

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 8e

Command (m for help): p

Disk /dev/sdb: 10.7 GB, 10737418240 bytes
64 heads, 32 sectors/track, 10240 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000a652f

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1        1025     1049584   8e  Linux LVM

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

mount /dev/sdb1 /dummyfs# ls -lR /dummyfs|wc -l
2465

du -sh /dummyfs
27M /dummyfs



Changing label using parted - result loss of partition information in parted print output !! 

# umount /dummyfs/
# parted 
GNU Parted 2.1
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) select /dev/sdb
Using /dev/sdb

(parted) p
Model: VMware Virtual disk (scsi)
Disk /dev/sdb: 10.7GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End     Size    Type     File system  Flags
 1      16.4kB  1075MB  1075MB  primary  ext3         lvm

(parted) mklabel

New disk label type? gpt

Warning: The existing disk label on /dev/sdb will be destroyed and all data on this disk will be lost. Do you want to continue?

Yes/No? Yes

(parted) p
Model: VMware Virtual disk (scsi)
Disk /dev/sdb: 10.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start  End  Size  File system  Name  Flags
      ( nothing printed here )

(parted) rescue

Start? 16.4kB

End? 1075MB

searching for file systems... 3% (time left 00:27)
                     searching for file systems... 97% (time left 00:00)

(parted) p
Model: VMware Virtual disk (scsi)
Disk /dev/sdb: 10.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start  End  Size  File system  Name  Flags
      ( nothing printed here )

(parted) quit

Information: You may need to update /etc/fstab.



fdisk still recognize partition as GPT, but you will not be able to mount it.

# fdisk -l /dev/sdb

WARNING: GPT (GUID Partition Table) detected on '/dev/sdb'! The util fdisk doesn't support GPT. Use GNU Parted.


Disk /dev/sdb: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1        1306    10485759+  ee  GPT
# mount      /dev/sdb1 /dummyfs
mount: you must specify the filesystem type
# mount /dev/sdb1 /dummyfs-t ext3 
mount: special device /dev/sdb1 does not exist



So, once disk label has been changed to GPT using parted, parted do not list partition at all but fdisk still recognize it at GPT.

# parted
GNU Parted 2.1
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.

(parted) / select /dev/sdb
Using /dev/sdb

(parted) p
Model: VMware Virtual disk (scsi)
Disk /dev/sdb: 10.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start  End  Size  File system  Name  Flags

(parted) quit



I am sure there will be some way to deal with using parted or cfdisk or some other utility. Do let me know if you know it.