[SOLVED] Nuked partition table on expansion card drive

TL;DR: While using gparted accidentally created a bogus partition table on my 250GB expansion card, now shows as entirely unallocated, advice for safest possible rescue attempt from any gurus out there?

Full details:

This is not Framework-specific per se, but I wonder if some knowledge that would be more likely found in this community might be part of the solution.

I was preparing a regular USB thumbdrive (ironically enough to make a Clonezilla disk to do backups) using gparted, and rather foolishly did not notice I was editing my 250 GB expansion card when I clicked Device → Create Partition Table, and continued not to notice I was editing the wrong drive when I chose “gpt” and said yes.

As a result, what was previously a single recognized partition with several un-backed-up and unfortunately somewhat important files (not smart, I know) is now showing as unallocated space.

The Framework-specific knowledge I think might be helpful, since I do not believe I modified the structure of the drive when I received it, is what the default partition information is - gpt vs msdos partition table, format, offsets, etc - hoping that knowing that may help recovery. If anyone has one of the 250GB drives handy, which hasn’t been reformatted or otherwise customized, and would be willing to look that up and share it here I would be grateful.

Less Framework-specific, if any gurus out there have tips on attempting recovery I would also be grateful for that. At the moment my plan is to (very carefully) use dd to make a copy of the drive, and then run testdisk on that copy. Of course this is a high-wire act that I’ve never done before so any experience would be helpful.

Thanks for reading so far!

Requisite data for posting:

  • Which OS (Operating System)? Linux, although issue was PEBKAC and not OS-specific
  • Which release of your OS (Operating System / Windows 10, 11, Distribution of Linux)? Mint Xfce
  • Which Framework laptop (11th, 12th or 13th generation Framework laptop) are you asking for support with? 11th
  • If this is a Linux issue, please use the Linux tag or at least put Linux in the title. Check
  • If there is no information pertaining to your issue or question, please let us know here: Framework | Support Framework | Support Not entirely Framework-specific

I’m far from a guru and this advice might be self-evident. Do not write to the drive until you are certain you understand how it was partitioned. Your copy-using-dd idea is sound. Do all experiments on the copy.

I have successfully grafted a working partition table to an overwritten disk in almost precisely the manner you propose. I’ll be silently cheering from the sidelines.

Dino

1 Like

Your plan is good. Making a copy with dd will ensure extra safety. If no new partition was created on the device, then all filesystem data is still there and testdisk will find it. For the OS the only thing that matters is the start and end of the partition. If recreate a partition in the same place you will get you data back. It might even be that if you create single partition it would end up starting in the same place and be of the same size. Although relying on luck is less of the plan :slight_smile: If you’re not comfortable with inspecting sectors of a block device to find where the partition starts using a dedicated tool will be better. Having backup allows for safe experiments.
Or if somebody could share the standard partition layout of the 250GB expansion card - you could just apply that. Assuming you haven’t change it.

1 Like

I would concur with the thoughts above, dd is going to be a solid suggestion going forward. Get the dd done, and hopefully this is recoverable.

Regarding an OS on the expansion card. Doable, but, I will always suggest that it’s an (treat as storage) device. USB and running an OS on it can be, finicky.

2 Likes

Thank you all for the comments! I’ve decided to be even more conservative and ordered a new 250GB expansion card (on sale! :slight_smile:) on which I’ll put some dummy files and try to do a dry run of everything (dd backup first, then testdisk or others if needed) in hopes of being more confident applying the procedure to the drive with the actual files. That should also let me note down “good” partition parameters in case that ends up being needed.

This drive was being used just for storage, I’ve generally been wary of having multiboot setups even off a single drive and this would seem even a step beyond that…

Two additional suggestions; carefully evaluate suitability to your situation.

If partitions on the overwritten drive are mounted via /etc/fstab, take a safety copy so you can extract their UUIDs.

You can use the -d option of sfdisk(8) to dump the partition table of the new expansion card when it arrives and capture it in a file. If you have partition UUIDs from the fstab, you can modify the captured partition table to use the original UUIDs. The captured table can then be written to your dd clone using sfdisk.

Dino

3 Likes

@truffaldino Thank you for the suggestion to look at fstab! It seems it only has information for the partitions on my internal nvme ssd unfortunately. Have done some unsuccessful searching, but in case this is just me not searching well I don’t suppose you know of where there might be a log of previously-mounted partition UUIDs on a Linux Mint distribution? I’ve searched through syslog which references mounting the old disk but doesn’t seem to give more information than

<time and computer name> kernel: [    1.886479] usb 2-4: New USB device found, idVendor=13fe, idProduct=6500, bcdDevice= 1.10
<time and computer name> kernel: [    1.886487] usb 2-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
<time and computer name> kernel: [    1.886490] usb 2-4: Product: USB DISK 3.2
<time and computer name> kernel: [    1.886492] usb 2-4: Manufacturer:         
<time and computer name> kernel: [    1.886494] usb 2-4: SerialNumber: 0700179C35878810
<time and computer name> kernel: [    1.892823] usbcore: registered new interface driver usb-storage
<time and computer name> kernel: [    1.896863] scsi host0: uas
<time and computer name> kernel: [    1.897024] usbcore: registered new interface driver uas
<time and computer name> kernel: [    1.898213] scsi 0:0:0:0: Direct-Access              USB DISK 3.2     PMAP PQ: 0 ANSI: 6
<time and computer name> kernel: [    1.900480] sd 0:0:0:0: Attached scsi generic sg0 type 0
<time and computer name> kernel: [    1.902265] sd 0:0:0:0: [sda] 488397168 512-byte logical blocks: (250 GB/233 GiB)
<time and computer name> kernel: [    1.902691] sd 0:0:0:0: [sda] Write Protect is off
<time and computer name> kernel: [    1.902692] sd 0:0:0:0: [sda] Mode Sense: 23 00 00 00
<time and computer name> kernel: [    1.903382] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
<time and computer name> kernel: [    1.903759] sd 0:0:0:0: [sda] Optimal transfer size 33553920 bytes
<time and computer name> kernel: [    1.907793]  sda: sda1
<time and computer name> kernel: [    1.910422] sd 0:0:0:0: [sda] Attached SCSI disk

<time and computer name> udisksd[791]: Mounted /dev/sdb1 at /media/<name>/USB DISK on behalf of uid 1000

There is an entry in the boot process

<time and computer name> systemd[1]: Starting Disk Manager...

That makes me think there might be something there but I’m also coming up empty looking for systemd log entries

Thanks again!

Apologies @A_L, I unintentionally sent you on a wild goose chase.

What you want to avoid: two drives with the same partition UUIDs, As you may know, ‘UU’ stands for universally unique and a whole bunch of stuff is built around the assumption that partition IDs have that property.

My suggestion–that you capture the original (overwritten) drive’s partition UUIDs from fstab–seemed an easy way to guarantee the desired outcome. That they’re not in your fstab is no biggie. There are other ways to generate them. I’d use uuidgen(1). Not sure if that’s best practice though.

For the sake of clear exposition, lets call the overwritten drive ‘olddrive’ and the one you’ve just purchased ‘newdrive’. Assuming you’re planning to use sfdisk(8) to capture the newdisk partition table in a file, you want to change all the UUIDs in that file before you write it to olddisk. If you do not, newdisk and olddisk will share UUIDs which wil certainly cause you problems down the track.

Dino

2 Likes

^^^^ Everything Dino just suggested - especially with UUIDs.

1 Like

Hello again, folks to whom I am grateful for all the advice! I bring good news, that the drive has been recovered successfully, and the data promptly backed up (twice!).

For future reference if anybody else ever overwrites or deletes or otherwise mangles their partition table, here is the protocol that worked, hopefully in enough detail that it is manageable with only basic command line comfort:

  1. For safety, use dd to copy the broken drive (“damageddrive”) to a backup (“damageddrivecopy”)
    a. start without any external drives (including damageddrive) plugged in
    b. use lsblk to see currently mounted drives/partitions
    c. plug in damageddrive
    d. use lsblk to see where damageddrive is mounted (the new entry relative to before plugging damageddrive in), in my case it was /dev/sda, without any visible partitions underneath it
    e. plug in damageddrivecopy
    f. use lsblk to see where damageddrivecopy is mounted, in my case it was /dev/sdb
    g. use dd to copy damageddrive to damagedrivecopy, the template of the command is sudo dd if=/dev/MOUNTPOINTOFDAMAGEDDRIVE of=/dev/MOUNTPOINTOFDAMAGEDDRIVECOPY, and the exact command in my case was sudo dd if=/dev/sda of=/dev/sdb

A comment on 1.g, the dd command has a variety of flags that can be set, at least for the Framework storage module whatever the default behavior is seems to have worked well. It is a somewhat slow process, in my setup (damageddrive plugged in to one of the Framework’s slots, damageddrivebackup plugged in through USB-A 3.0 interface) it took about 2.5 hours. There are apparently ways of having it display progress in the terminal but I didn’t try any of those to minimize complexity. After this is done, running sudo fdisk -u -l will show that damageddrive and damageddrivecopy will have the same Disklabel types (in my case gpt, since my original sin was overwriting the original partition table with an empty gpt one) and Disk identifiers (which for gpt seems to be five fields of hex characters of varying lengths separated by hyphens). As per the comments of @truffaldino and @Matt_Hartley this is not a desirable situation in general, but for the moment for this procedure it is OK (and in fact seems unavoidable when making dd copies at least initially).

  1. Extract the partition table from a known good drive (“gooddrive”) using sfdisk and save it somewhere. If this is not possible (not having a known good drive of the same type available) I have attached a copy of the file created by this step and used later, which may work for you, at least for the 250GB storage module. Modules (or maybe any drive) of different sizes may likely require an adjustment to the size= number in the file
    a. I shut down everything, unplugged all the external drives, and booted up again fresh to minimize the possibility for confusion
    b. you might want to check the version of sfdisk as for GPT partition tables there was a change of behavior in the semi-recent past (see comments here: command line - How to copy the partition layout of a whole disk using standard tools - Unix & Linux Stack Exchange); in my case I think it was moot since the drive’s original/desired partition table was mbr (aka dos?) and anyway a current distribution as of 2023 is likely to have sufficiently updated tools)
    c. plug in gooddrive and use lsblk to verify where it mounts (for me it was /dev/sda)
    d. use sfdisk --dump \dev\sda > ~/gooddisk_partition_backup.dump to write a file to your home directory with the partition table information from gooddisk
    e. Note that there is a line in the .dump file starting with “label-id”. You should delete this line (and save it as a different file, gooddisk_partition_backup_nolabelid.dump), because by doing so, the later step to write the partition table to the damaged drive’s copy will automatically generate a new Disk identifier (this apparently is behavior of sfdisk, see same link as above), which is desirable.

Will comment here that I was somewhat suprised to see that the .dump file has a "device: " line that seems to list the mount location of the drive. I would have thought that this is not part of the partition table information since it is endowed by the OS on mount. In my case this was dev/sda, so I just made sure that there was not anything already mounted as /dev/sda in the next step when I wrote the partition information from this file to the damageddrivecopy.

At this point I again shut down the machine, unplugged all the external drives, and rebooted.

  1. Write the label-free partition table information from the .dump file to damageddrivecopy using sfdisk
    a. plug in damageddrivecopy and use lsblk to verify the mount location (in my case /dev/sda)
    b. run sudo sfdisk /dev/sda < ~/gooddisk_partition_backup_nolabelid.dump

This is the moment of truth, if this simple strategy worked, it should relatively quickly mount damageddrivecopy and you should see all of the formerly missing files. That was an enormous relief. At this stage I plugged in a backup drive and drag-and-dropped all of the files to copy them over, and because this experience has made me paranoid did it again with a second backup drive. This was probably overkill.

For reference, there were some initially slightly scary messages printed to the terminal, which I’ll put here to reassure anyone if they see it:

GPT PMBR size mismatch (488397167 != 976773167) will be corrected by write.
The backup GPT table is not on the end of the device. This problem will be corrected by write.
Checking that no-one is using this disk right now ... OK

Disk /dev/sda: 465.76 GiB, 500107862016 bytes, 976773168 sectors
Disk model: SSD 870 EVO 500G
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 0EEFDD29-B3BC-41E4-B562-AFEAD635F6AD

Old situation:

>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Created a new DOS disklabel with disk identifier 0x05033b06.
/dev/sda1: Created a new partition 1 of type 'HPFS/NTFS/exFAT' and of size 232.9 GiB.
Partition #1 contains a exfat signature.
/dev/sda2: Done.

New situation:
Disklabel type: dos
Disk identifier: 0x05033b06

Device     Boot Start       End   Sectors   Size Id Type
/dev/sda1        7552 488397167 488389616 232.9G  7 HPFS/NTFS/exFAT

The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Also note that at this point because you had removed the label-id line from the .dump file, the Disk identifier of damageddrivecopy (which you can see with sudo fdisk -u -l) should be different from the label-id in the first .dump file that came straight from gooddrive. This means that you can do the next step to copy the recovered data back to damageddrive using dd and not have to worry about Device identifier conflicts later on if you use gooddisk with damageddrive (now a misnomer fortunately!) contemporaneously later.

  1. Copy the recovered data from damageddrivecopy to damageddrive using dd
    a. again abundance of caution, shut down the computer, removed all external drives, booted freshly
    b. plug in damageddrivecopy, use lsblk to verify mount location, in my case /dev/sda
    c. use sudo fdisk -u -l and make note of the End entry of /dev/sda1, call it XXX, which in my case was 488397167
    c. plug in damageddrive, use lsblk to verify mount location, in my case /dev/sdb
    d. use dd to copy only the relevant portion (this matters if the backup drive is larger than the damaged drive, which in my case it was) from damageddrivebackup to damageddrive, template of the command is dd if=/dev/MOUNTPOINTOFDAMAGEDDRIVEBACKUP of=/dev/MOUNTPOINTOFDAMAGEDDRIVE count=XXX+1, so in my case this was dd if=/dev/sda of=/dev/sdb count=488397168

This should put the repaired data from damageddrivebackup back on damageddrive, which share the same Disk identifier, but presumably you will never have both plugged in at the same time for long (and might eventually want to reformat the damageddrivebackup back to full capacity for other uses), so I did not do anything to remedy that.

Some general thoughts and lessons:

  • not doing anything to potentially write to the damaged drive until establishing some success in fixing the backup copy was very important
  • I did try using the Data Rescue menu item in gparted (which needed me to sudo apt install gpart), which ran for a pretty long while, but ultimately failed as it reported not finding any partitions
  • for the brief time after I dd-ed the repaired backup to the damaged drive, the computer had two drives attached with the same Disk identifiers, and it seemed to do OK with that which I was relieved to see, but would not keep such a collision-guaranteed setup around long-term
  • I wonder if there is a simple adjustment to this for recovering drives with more complicated partitiont tables than a single partition occupying the entire drive

Thank you again everyone for the advice and support!

Edit:
Cannot seem to upload the gooddisk_partition_backup_nolabelid.dump file as an attachment to the message, so here are the contents (although tabs vs spaces might be an issue going through the forum software, please look up the requirements in the sfdisk documentation if you are planning to use this directly:

label: dos
device: /dev/sda
unit: sectors
sector-size: 512

/dev/sda1 : start=        7552, size=   488389616, type=7
1 Like

Interesting read and recap. Thank you for writing this up! In your case, the fact that you could get your hands on a nearly certainly correct version of the lost partition table helped greatly. Googling on recovering lost partitions, I find a lot of references to testdisk testdisk — testdisk 7.1 documentation (included in a lot of distros as well). It looks to me that this could be the next tool to try. By the looks of it, it scans the disk to try and identify markers for partitions on the disk (including LVM volumes). After making a copy of the damaged disk, one would likely be able to run testdisk on the image and hopefully reconstruct a partition table that way.

1 Like

Excellent write up!

1 Like