Replacing our PVR's hard drive: what I learnt

The hard drive in our Panasonic PVR had been failing for a while. Recently, the symptoms had become too bad to ignore. I replaced the hard drive but managed to keep all the programmes. This is what I learnt.

Symptoms of a failing hard drive in a PVR

The symptoms changed every time I used the machine: the machine wouldn't boot; or it booted, but couldn't bring up the programme list; or it brought up the programme list, but couldn't play the chosen programme; or it could play a programme, but playback paused, glitched, halted or looped, especially when I jumped over the adverts.

Familiar hardware

The machine was long out of warranty, so I took a screwdriver to it. When I opened it up, I found a standard Seagate 1TB 3.5” Sata disk. That gave me hope. If the disk had had some weird proprietary interface to resist repair, I'd probably have given up. I whipped out the disk and connected it to a Linux PC via a USB disk cradle, because that was easier than opening up the PC and plumbing the disk in. I could have installed the disk in the machine: that would have worked, and disk I/O would have been a faster.

Verifying the problem

I first needed to verify that the disk was really failing, and that the problem wasn't caused by a software bug in the PVR. I used dd to read and discard all the data off the disk. It failed with a read error after about 200GB. That told me the disk was really in trouble.

The exact dd command I used was

sudo dd if=/dev/sdc of=/dev/null status=progress bs=16M

The phrase if=/dev/sdc told dd where to read from /dev/sdc is the device name that Linux had assigned to the disk when I plugged it in. of=/dev/null told dd to discard the data after reading it; status=progress told dd to report its progress as it went; bs=16M told dd to read and write in big chunks, which generally makes things faster; and sudo ran the command as root, which was necessary because I was reading directly from a disk device.

Reading the data off the old drive

The disk had neither a partition table nor any filesystem that Linux recognised. That prevented me from mounting it and having a look around, which would have been interesting. I assume that Panasonic engineers didn't bother with a conventional filesystem, and just wrote to the disk directly. That would let them use disk space as efficiently as possible, let them control fragmentation, and avoid problems when the disk got really full. (Conventional filesystems slow down when they get too full, and they don't speed up again when you delete files.) That means it wouldn't have been practical to copy raw video files from the disk, even if I'd wanted to (which I didn't).

Instead, I used ddrescue to copy as much data as possible off the disk into a 1TB file on my PC. It took almost three days, but ddrescue managed to retrieve over 99.99% of the data.

The exact ddrescue command I used was

sudo ddrescue -S -d /dev/sdc hd map

The -S switch avoided wasting disk space on any data that ddrescue couldn't salvage. (I didn't know, at that stage, how successful it would be.) -d requested direct reads from the disk, which prevented Linux from amalgamating several consecutive read requests; that might have made ddrescue's clever algorithms less effective. /dev/sdc was the disk device to read from, hd was the name of the 1TB file to write to, and map was the name of the map file, which would have enabled me to restart where I'd left off if I'd had to (let's say) reboot the PC.

The ddrescue manual says:

As ddrescue uses standard library functions to read data from the device being rescued, only mountable device formats can be rescued with ddrescue.

That does not mean that Linux needs to be able to mount the filesystem. It doesn't. That was just as well for me.

More about disk failure

While I waited for ddrescue to run, I had time to notice the way the disk had failed.

Bad blocks weren't distributed evenly across the disk: there were good regions and bad regions. Large parts of the disk were so degraded that they couldn't read more than a few megabytes per second, but they were still readable. Many regions could return only a few KB or tens of KB per second — too slow for video playback — but ddrescue still managed to retrieve the data by persevering.

That had two consequences:

Ddrescue's progress is not linear. It assumes that the disk drive is degrading all the time, and so it tries to salvage as much data as possible from the fast regions of the disk and then go back progressively to slower and slower regions, getting less and less return on greater and greater investments of time. You can abort ddrescue at any time and just use what it's managed to retrieve so far, but you get the best results from letting it run to completion.

Picking a replacement disk

Not all 1TB disks have the same capacity (and that's not only because disk manufacturers use a stingy definition of a terabyte). I ran sudo fdisk -l /dev/sdc to find the precise number of sectors on the old disk, and then bought a replacement disk with exactly the same number of sectors. It seems likely that a slightly larger disk would have worked, but who knows what goes on in Panasonic's closed-source software? I don't. So I played it as safe as I could. That meant reading spec sheets and getting out a calculator. The new disk cost £21 in early 2024, which was cheaper than I'd dared to hope.

I unplugged the old disk from the USB cradle and plugged in the new one. Once again, Linux named it /dev/sdc. One review claimed that the customer had been sent a used, failing disk rather than a new one, and so I ran sudo smartctl -x /dev/sdc to make sure that the new disk really was new and wasn't riddled with errors. In particular, Power_On_Hours and Reallocated_Sector_Ct were both zero, which was a strong indication that the disk was new.

Copying the data to the new disk

I used dd to write the 1TB file to the new disk:

sudo dd if=hd of=/dev/sdc status=progress bs=16M

The phrase if=hd tells dd to read from the disk file called “hd”; of=/dev/sdc tells it to write to the disk presented at /dev/sdc; status=progress requests regular progress updates; and bs=16M just reads and writes large amounts of data at a time, which makes the process a bit faster. Even so, on my cheap USB cradle, it took about seven hours.

You want to think three times and check everything carefully before pressing Enter on a command like that, because it writes directly to a disk: choose the wrong disk and it'll immediately wipe out the partition table and the first filesystem on the disk. Do not just copy and paste commands from the Internet; make sure you know what they mean, and adjust them as necessary.

I then read the data back from the new disk to make sure it was readable. It was. (I used sudo strings -n 5 /dev/sdc > strings, just out of curiosity, but I could have used diff instead. Strings showed me the names of programs that were on the disk, but also the names of programs we'd watched and deleted — in some cases, years ago. Panasonic, are you leaking metadata?)

Tidying up

I disconnected the new disk from the PC and installed it into the PVR. Everything worked: I got all my programs back, now on a disk that's healthy enough to play them.

I won't just put the old disk in the Weee pile, just in case some crook sells it on as new. I'll either smash it up with a sledgehammer first, so that it can't be read or resold, or give it to a friend who works in QA and might find it useful.