dannyman.toldme.com


Linux, Technical

Forcing Together a Broken RAID5 with mdadm

Link: https://dannyman.toldme.com/2026/07/17/mdadm-force/

Scenario:

Ideally you pull from backups into a new or rebuilt system. But what if you wanted to get at the data on the broken RAID? I recently ran through this exercise.

To check out the health of the RAID you would say, for example mdadm --detail /dev/md0 which gives you plenty of detail, including, for example:

[...]
           State : active, FAILED, Not Started
[...]
    Number   Major   Minor   RaidDevice State
       -       0       49        1      sync   /dev/sda1
       -       0       33        2      sync   /dev/sdb1

Let’s say /dev/sdd1 had failed and /dev/sdc1 had been pulled in error. You can inspect each disk with, for example: mdadmn --examine /dev/sda1 and note useful stuff near the bottom. The sample output here is heavily trimmed for clarity.

/dev/sda1:
   Update Time : Fri Jul 17 14:42:15 2026
        Events : 1100008
   Device Role : Active device 0
   Array State : AA.. ('A' == active, '.' == missing, 'R' == replacing)

/dev/sdb1:
   Update Time : Fri Jul 17 14:42:15 2026
        Events : 1100008
   Device Role : Active device 1
   Array State : AA.. ('A' == active, '.' == missing, 'R' == replacing)

/dev/sdc1:
   Update Time : Fri Jul 17 14:42:00 2026
        Events : 1100000
   Device Role : Active device 2
   Array State : AAA. ('A' == active, '.' == missing, 'R' == replacing)

/dev/sdd1:
   Update Time : Thu Jul 16 14:42:00 2026
        Events : 1000000
   Device Role : Active device 3
   Array State : AAAA ('A' == active, '.' == missing, 'R' == replacing)

This says:

So, sdd1 is the dead disk and sdc1 was errantly pulled. But they can’t just form an array because their metadata do not line up.

# mdadm --run /dev/md0
mdadm: failed to start array: Input/output error

We can try manual assembly. First, I run --stop to “forget” the two-element array, then try mdadm --assemble:

# mdadm --stop /dev/md0
mdadm: stopped /dev/md0
# mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1 /dev/sdc1
mdadm: /dev/md0 assembled from 2 drives - not enough to start the array.

“But I asked it to use three drives! Oh yeah, the event count differs on sdc.”

Next, you spend some quality time reading the man page, and you perform your own risk analysis.

If approriate, you might be able to “fix” your RAID thus:

# mdadm --stop /dev/md0
mdadm: stopped /dev/md0
# mdadm --assemble --force /dev/md0 /dev/sda1 /dev/sdb1 /dev/sdc1
mdadm: forcing event count in /dev/sdc1(2) from 1100000 to 1100008
mdadm: /dev/md0 assembled from 3 drives (out of 4).

At this point, you may find yourself with a working RAID and a filesystem you can mount. Copy off whatever data you value to an array that hasn’t been “forced” together!

Feedback Welcome


Linux, Technical

How To Blacklist a Disk on Linux

Link: https://dannyman.toldme.com/2026/07/29/block-a-bad-disk-at-boot/

Full disclosure: I got this from Claude after a bunch of more traditional research didn’t get me there.

Use case:

  1. you have a server with a bad disk
  2. and low urgency to replace the disk
  3. automation which detects and uses available disks
  4. also, the drive numbering is non-deterministic at boot
  5. so you want that disk to not be used until you get around to replacing it

The basic workaround to disable a disk, for example:

echo offline > /sys/block/sdd/device/state

That is fine until you reboot. You need something more robust.

Above, I suggested you had “automation which detects and uses available disks” so you could implement a blacklist mechanism in your automation. I thought I would mention that.

Okay, so, here’s the solution that Claude gave me. It works for me so now share with you.

First, get the serial number that udev sees. For example:

> udevadm info --query=property --name=/dev/sdd | grep ID_SERIAL_SHORT=
ID_SERIAL_SHORT=abc123

And tell udev to … I think this means “when you add it, delete it”

> cat /etc/udev/rules.d/99-blacklist-baddisk.rules
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd?", ENV{ID_SERIAL_SHORT}=="abc123", ATTR{device/delete}="1"

Okay, so, why am I posting some AI slop? Well, because I like the idea that if you search for an answer on the Internet it ought to be out there somewhere. And whatever advice you find on online, in a blog, in a forum, or from an LLM, you need to test that out yourself. I found a solution that works for me, so I am posting it online for others to find, and test, and use.

I don’t reckon anyone is going to get on my case, but I figured I would offer that description and the caveat up top just so we’re all on the same page.

Feedback Welcome


Arrr! . . . Avast!
Site Archive