Disclaimer
While I've made my best effort to document my actions and ensure their accuracy and correctness, this is merely sharing my personal experience. Attempting these steps can result in permanent data loss or negative consequences. Proceed at your own risk, and always have a backup!
Prologue
I was recently tasked with recovering the data from a Seagate GoFlex Home. It's a standard NAS system based on the SheevaPlug platform.
The Mistake
Unfortunately, I neglected to do any research before starting and naively attempted to factory reset the device. Since it's EoL and the servers required for first-time setup are now offline, it's effectively bricked. Another win for always-on-line!
First Steps
My first attempt at recovery was plugging it into my PC with a standard USB SATA bridge. The partition table was corrupt, which wasn't a good sign... Even worse was the same result when plugged in via SATA directly. Like a good citizen, I used ddrescue to make a backup before proceeding further.
Though there appeared to be a broken MBR, this is incorrect. After sufficient fiddling with testdisk, I discovered that even though the drive has 512-byte logical sectors, it was partitioned for 4 KiB sectors. When adjusted as above, the GPT is correct. The conclusion is that the USB enclosures these drives are designed for silently change the sector size.
But Why?
I think it has something to do with using disks larger than 2 TiB with MBR, but I'm not 100% sure. It seems pointless to me, considering that any OS that doesn't support GPT is also unlikely to support 4Kn. This drive is partitioned with GPT anyway... Maybe I'm missing something 🤷.
Accessing the Drive
Accessing the drive in Linux is easy! You can use losetup
to change the sector size:
# losetup -Pf -b 4096 --show /mnt/d/Seagate.img
/dev/loop0
# gdisk -l /dev/loop0
GPT fdisk (gdisk) version 1.0.10
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Disk /dev/loop0: 732566646 sectors, 2.7 TiB
Sector size (logical/physical): 4096/4096 bytes
Disk identifier (GUID): 4DDF80FA-EC2C-11EF-9BBF-00155DD12DD0
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 5
First usable sector is 6, last usable sector is 732566640
Partitions will be aligned on 8-sector boundaries
Total free space is 2635 sectors (10.3 MiB)
Number Start (sector) End (sector) Size Code Name
1 7 732564006 2.7 TiB 0700
# blkid /dev/loop0p1
/dev/loop0p1: LABEL="GoFlex Home" BLOCK_SIZE="4096" UUID="145F1F8D73E5415A" TYPE="ntfs" PARTUUID="4ddf80fb-ec2c-11ef-9bbf-00155dd12dd0"
I couldn't find a way to do anything similar in Windows, though I tried several third-party tools.
Correcting the Partition Table
Now comes the fun part! Let's backup the partition 4Kn table before we start:
# sfdisk -d /dev/loop0 | tee Seagate.gpt.4kn.sfdisk
label: gpt
label-id: 4DDF80FA-EC2C-11EF-9BBF-00155DD12DD0
device: /dev/loop0
unit: sectors
first-lba: 6
last-lba: 732566640
sector-size: 4096
/dev/loop0p1 : start= 7, size= 732564000, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, uuid=4DDF80FB-EC2C-11EF-9BBF-00155DD12DD0
Now, we can start rebuilding; we just have to multiply the sector offsets by eight (4096 / 512 = 8
). Since the partition was not (and will not be) aligned, we must also adjust the alignment value.
# gdisk /mnt/d/Seagate.img
GPT fdisk (gdisk) version 1.0.10
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: not present
Creating new GPT entries in memory.
Command (? for help): x
Expert command (? for help): z
About to wipe out GPT on /mnt/d/Seagate.img. Proceed? (Y/N): y
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
GPT data structures destroyed! You may now partition the disk using fdisk or
other utilities.
Blank out MBR? (Y/N): y
# gdisk /mnt/d/Seagate.img
GPT fdisk (gdisk) version 1.0.10
Partition table scan:
MBR: not present
BSD: not present
APM: not present
GPT: not present
Creating new GPT entries in memory.
Command (? for help): x
Expert command (? for help): l
Enter the sector alignment value (1-65536, default = 2048): 1
Expert command (? for help): m
Command (? for help): n
Partition number (1-128, default 1): 1
First sector (34-5860533134, default = 34) or {+-}size{KMGTP}: 56
Last sector (56-5860533134, default = 5860533134) or {+-}size{KMGTP}: 5860512055
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): 0700
Changed type of partition to 'Microsoft basic data'
Command (? for help): w
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /mnt/d/Seagate.img.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.
We can inspect the new partition table:
# sfdisk -d /mnt/d/Seagate.img
label: gpt
label-id: 9B9D7B44-4B19-4C3E-A9CE-8A6F8E2BD0F8
device: /mnt/d/Seagate.img
unit: sectors
first-lba: 34
last-lba: 5860533134
sector-size: 512
/dev/loop0p1 : start= 56, size= 5860512000, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, uuid=5B2922F8-A310-4C41-B3D6-174BC129E2CD, name="Microsoft basic data"
Looks good! We can even check that NTFS is a-ok:
# losetup -Pf --show /mnt/d/Seagate.img
/dev/loop0
# mount -o ro /dev/loop0p1 /mnt
# umount /mnt
It should mount just fine. But there's one last and essential step. If you try to read the drive in Windows at this point, you'll notice that it identifies the partition as RAW rather than NTFS. This is because NTFS keeps some information in its boot sector, notably a count of the bytes per sector. Luckily, a wonderful gentleman by the name of Sergey Kamenev has written a utility (star it on GitHub!) that will do the necessary bit-fiddling to correct this for us!
# wget https://raw.githubusercontent.com/sukamenev/ntfs_512_to_4k/refs/heads/main/ntfs_512_4k
# chmod 755 ntfs_512_4k
# ./ntfs_512_4k unfix /dev/loop0p1
Here, fix
does a 512 -> 4 KiB conversion, while unfix
is the reverse. Let's make sure it can mount again, then we can clean up.
# mount -o ro /dev/loop0p1 /mnt
# umount /mnt
# losetup -d /dev/loop0
Conclusion
At this point, we should be all set. You can access the drive/image in Windows, run a chkdsk (remember this can delete data!), shrink and clone to a VHD...