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.



1 comment:

  1. I know this is an older post but in case someone comes across and it and wants to know: yes it can be done!

    I had formatted a 4TB drive using a repurposed USB bridge from a Seagate Backup Plus external enclosure (the original drive had died so I took it apart).

    I had trouble aligning the partition and such but that is another story. When I installed the drive into the system using the native SATA, the system had trouble recognizing the partition. It never occurred to me that the USB Bridge was translating the drive CHS. It presented the drive as 4096 sized sectors when in reality it is 512 sized. The system partitioned the drive as msdos when on the USB Bridge. This caused problems when hooked up to SATA connection on the system because msdos partition labels do not support drives larger than 2TB. I was unable to mount the 4TB EXT4 filesystem on the drive. When I finally had the partition visible to the OS, it had chopped the partition in half due to the 2TB limit.

    After much searching I found a post that fixed the problem using a combination of gpart and testdisk. It fixed my issues of an insufficient msdos label which was successfully migrated to GPT; all data safe and sound, happy to say.

    https://serverfault.com/questions/764271/cant-mount-sata-drives-when-moved-from-usb-enclosure-to-internal

    Thanks!

    ReplyDelete