Zero a GPT Label Using dd

When re-using a disk with a GPT label (GUID Partition Table) it’s important to wipe the label stored on both the first and last blocks of the device.

With an MBR Partition Table it was easy enough to just nuke the beginning of the drive (adapt sdz for your drive), ala:

dd if=/dev/zero of=/dev/sdz bs=1M count=1

and be on your way.  Wouldn’t it be lovely if dd understood negative indexing and you could just say:

dd if=/dev/zero of=/dev/sdz bs=1M count=-1

and be done?   Alas, it’s not meant to be.

One way to do this is to simply use ‘dd’ to write zeroes to the entire device:

dd if=/dev/zero of=/dev/sdz bs=8M

This is entirely effective, but with today’s 2-3TB drives, this can take quite a while.  You can start it and go home for the night, but if you’re not paying attention, a dd that doesn’t finish can cause you frustration and embarrassment.  Since we only need to write 34 512-byte blocks, really what we need to do is to calculate the size of the drive and find the correct blocks to overwrite.

In the recent past, people will have told you to run fdisk, look for the cylinder/heads/sectors/clusters information, apply a mathematical transform, and plug that into ‘dd’.  Besides being a pain, fdisk doesn’t even claim to support disks over 3TB.  Before the floods, those were becoming quite common.

Fortunately, Linux’s sysfs will report a block device’s size, conveniently in 512-byte block units (though that’s not necessarily obvious in context).  For instance:

# cat /sys/block/sdz/size

shows me a 2TB disk’s actual size. I’ve looked at a 3TB disk, and fortunately (for now at least), even though the drive really uses 4k blocks, linux is still reporting in terms of 512-byte blocks.  This helps since GPT size is defined in terms of 512-byte blocks, but I wouldn’t count on sysfs to maintain this convention forever.  At some point nobody will have any 512-byte block drives and somebody will decide it’s silly to keep reporting fake block counts in sysfs.  Sanity check before blowing away drives, eh?

So, now that we know that we have the right value with the right units, it’s simply a matter of taking out the first GPT label:

/bin/dd if=/dev/zero of=/dev/sdz bs=512 count=34

and then the second (3907029168-34=3907029134):

/bin/dd if=/dev/zero of=/dev/sdz bs=512 count=34 skip=3907029134

To make sure linux understands what you’ve done here, run:

partprobe /dev/sdz

and make sure partprobe doesn’t insist upon a reboot to get the kernel straight about this (so far I haven’t found a way around this).

Verify with other partition information tools that might be relevant, e.g.:

zdb -l /dev/sdz

for ZFS.

TL;DR : for convenience, here’s a perl script that automates the above process.  Call it as:

perl /dev/sdz

or, simply:

perl sdz

As of this writing, the script simply prints commands for you to run – it’s not brave enough to run them itself.  So, check them before you run them.