Wednesday, July 20, 2022

Docker BadBlocks

I was wanting to run badblocks on a couple of external hard drives before shucking, and of course I had to over-complicate it.

I bought a Lenovo ThinkCentre last year for the express purpose of serving as a Docker server, so other than the tutorial, this is the first thing I’m doing with it.

Writing the Dockerfile was easy enough:

FROM alpine:latest
RUN apk add --no-cache e2fsprogs

Build with sudo docker build -t badblocks . (note the period at the end.)

A docker-compose.yml would probably be the correct thing to do, but for now I’m just going with the following command:

sudo docker run -v "/home/matt/bbout:/home/bb" -v "/dev/sda:/dev/sda" --name bbsda -dit badblocks

This runs in detached mode, but lets me dip in and out as I please. I think the proper way would be to just run the badblocks command in the initial command, but that will be in the next iteration.

Per the documentation: 

To stop a container, use CTRL-c. . . If the container was run with -i and -t, you can detach from a container and leave it running using the CTRL-p CTRL-q key sequence.

Start badblocks with sudo badblocks -c 2048 -sw -o /home/bb/sdaout.txt /dev/sda

I’m getting a response “ash: badblocks: not found” when I run as su. I’m sure it’s something dumb.

I appreciate the lightweightness of Alpine, but sometimes it gets to me when I can't even run man badblocks to see if everything is installed like I expect.

A tiny bit more experimentation also gives me the "badblocks: not found" when I install and run in Alpine via WSL rather than Docker. So I guess it's more likely than not that it's an Alpine problem (or more accurately, a PEBAAC (Problem Exists Between Alpine And Chair)) rather than a Docker problem. In some ways this is frustrating, but at least I have a better idea of where to focus my searches.

I'll just keep flailing in the meantime.

Update 2022-07-21

I got it! Alpine has more than just one e2fsprogs package. And as it turns out, badblocks is only found in e2fsprogs-extra.

So now my Dockerfile is as follows:

FROM alpine:latest
RUN apk add --no-cache e2fsprogs-extra

 Build and run using the same commands, and:

badblocks: Operation not permitted while trying to determine device size
Do some more digging, and aha! I need to set the hard drive up as a device, not a volume. I kind of wondered about this at the beginning, and wasn't sure that /dev/sda would be interpreted correctly. So now my command is:

sudo docker run -v "/home/matt/bbout:/home/bb" --device=/dev/sda --name bbsda -dit badblocks

 And yet another issue!

badblocks: Value too large for data type invalid end block (13672382464): must be 32-bit value

 Update 2022-07-23

Seems like the 32-bit limit is not only a known issue, but also intentional design, at least as of 2021.

Anyways, the workaround I found is to just change the command to actually run badblocks to

sudo docker exec bbsda badblocks -b 4096 -c 2048 -sw -o /home/bb/sdaout.txt /dev/sda

Upping the block size to 4096 lets it run! So now I have it running on both hard drives.

If I feel particularly inspired, I may write a simple bash script that lets me just type badblocks.sh [drive name here] and slot in sda/sdb/whatever to the Docker commands. The way I did it this time leaves a lot of room for error on forgetting to change sda to sdb in all the different places.

But hopefully these drives will all run without errors and I can shuck'n'drive them into my NAS and not worry about it for a few years.