You plugged in two drives and need redundancy
You bought two identical hard drives to protect your photo library, or you are building a home server and need RAID 1 for the root filesystem. You plug them in, run lsblk, and see /dev/sdb and /dev/sdc. You know you need mdadm, but the man page is a wall of text and you are worried about wiping the wrong disk. You want the array to survive a reboot, you want SELinux to play nice, and you want to know exactly what the kernel is doing under the hood.
What the kernel is actually doing
Software RAID is the kernel performing the work of a hardware controller. The md driver (multi-device) sits between the block layer and the filesystem. It presents a single virtual device, like /dev/md0, to the rest of the system. When you write a file, the kernel splits the data across the underlying disks according to the RAID level.
RAID 1 writes the exact same data to both disks. RAID 5 stripes data and calculates parity so one disk can fail without data loss. The kernel handles reconstruction when a disk dies and a replacement is inserted. mdadm is just the tool that talks to the kernel to create, manage, and monitor these arrays. It does not store the RAID metadata itself. The metadata lives on the disks in a specific format called the superblock.
Think of the RAID array as a single logical drive managed by the kernel. The kernel acts as a traffic controller. When the filesystem asks to write a block, the controller directs that data to the physical disks based on the RAID level. For RAID 1, the controller sends the exact same packet to two different disks. If one disk stops responding, the controller notices the timeout and marks that disk as failed. The data remains available from the surviving disk. The controller can also rebuild the failed disk by copying data from the good one when you insert a replacement.
mdadm writes the superblock to the disks during creation. This superblock tells the kernel how to assemble the array on boot. The metadata version matters. Version 1.2 is the standard for modern systems. It stores the superblock at the end of the device, which works correctly with GPT partition tables and UEFI bootloaders. Older versions store metadata at the beginning and can conflict with partition tables. Always use 1.2 unless you have a specific legacy reason not to.
Create the array and mount it
Install the tool and verify the disks are empty. mdadm is pre-installed on Fedora Server but may need installation on Workstation. Run dnf upgrade --refresh weekly to keep your system current, but install mdadm explicitly if the command is missing.
sudo dnf install mdadm -y # WHY: Install the mdadm package which provides user-space tools for managing kernel RAID.
sudo lsblk -o NAME,SIZE,TYPE,MOUNTPOINT # WHY: List block devices to verify target disks are unmounted and contain no partitions.
Create the array with the correct level and devices. The --create flag initializes the superblocks. The kernel will warn you that the devices contain data. This is expected. Confirm the prompt to proceed.
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 --metadata=1.2 /dev/sdb /dev/sdc # WHY: Create a RAID 1 mirror with metadata version 1.2 suitable for GPT disks.
# WHY: The kernel prompts for confirmation. Type 'y' to initialize the array and wipe existing signatures.
Format the virtual device and mount it. The array appears as /dev/md0. Treat it like any other block device. XFS is Fedora's default filesystem and handles large files and parallel writes efficiently.
sudo mkfs.xfs /dev/md0 # WHY: Format the virtual RAID device with XFS, Fedora's default filesystem.
sudo mkdir -p /mnt/raid-data # WHY: Create the directory where the array will be mounted.
sudo mount /dev/md0 /mnt/raid-data # WHY: Mount the filesystem to make it accessible.
Save the array configuration so it assembles on boot. The system reads /etc/mdadm.conf during startup to find arrays. Edit /etc/mdadm.conf for user changes. Never edit files in /usr/lib/mdadm/ as those ship with the package and will be overwritten.
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm.conf # WHY: Append the array definition to the config file so the system assembles it on boot.
sudo systemctl enable --now mdmonitor # WHY: Enable and start the monitoring service to track array health and send alerts.
Add the mount to fstab using the UUID. Device names like /dev/sdb can change between boots if you add or remove hardware. The UUID is stable.
sudo blkid /dev/md0 # WHY: Print the UUID of the filesystem to use in fstab for stable mounting.
# WHY: Add a line to /etc/fstab using the UUID, for example: UUID=xxxx-xxxx /mnt/raid-data xfs defaults 0 0.
Fix SELinux contexts so applications can read the data. Fedora runs SELinux in enforcing mode by default. A fresh mount point may have the wrong context, causing silent denials.
sudo restorecon -Rv /mnt/raid-data # WHY: Recursively restore default SELinux security contexts on the new mount point.
Reboot the system immediately. The array must assemble correctly from /etc/mdadm.conf or the data is inaccessible on the next boot.
Verify the array state
Check the array status and sync progress. The kernel exposes RAID state in /proc/mdstat. This file updates in real time. Use cat /proc/mdstat to see the current state.
cat /proc/mdstat # WHY: Display the kernel's real-time view of RAID status, sync progress, and device states.
sudo mdadm --detail /dev/md0 # WHY: Show detailed array metadata including event count, device roles, and bitmap status.
The output shows the array name, level, and device roles. The [UU] status means both devices are active and synchronized. A [U_] status indicates one device is missing or failed. The sync line shows the percentage complete and estimated time.
Personalities : [raid1]
md0 : active raid1 sdc[1] sdb[0]
244198559 blocks super 1.2 [2/2] [UU]
[======>............] resync = 35.2% (86000000/244198559) finish=120.5min speed=21800K/sec
The mdadm --detail command shows the event count. This number increments on every change to the array. If the event counts differ between disks, the array is inconsistent. Check journalctl -xe if the array fails to assemble. The journal often contains the exact reason, such as a missing device or metadata mismatch.
Read the actual error before guessing. Run journalctl -xeu mdmonitor to see monitoring alerts and assembly logs.
Common pitfalls and error messages
Wiping the wrong disk is the most dangerous mistake. mdadm --create will warn you, but the warning is easy to miss if you are typing fast. Verify the device names with lsblk twice. Check the size and model. If you accidentally create an array on your root disk, the system will become unbootable.
You may see this error if a disk has an existing filesystem:
mdadm: /dev/sdb appears to contain an ext2fs file system.
mdadm: /dev/sdb appears to be in use.
The kernel refuses to create the array over existing data without explicit confirmation. This is a safety feature. If you are sure the data is gone, type y at the prompt. If the error persists, the disk might be mounted or used by LVM. Unmount the disk and deactivate any LVM volumes before retrying.
Device name drift breaks fstab entries that use /dev/sdX. Always use UUIDs. If you see mount: /dev/md0: wrong fs type, bad option, bad superblock on /dev/md0, the array likely did not assemble. Check /proc/mdstat to see if md0 exists. If it does not, the kernel failed to assemble the array. Check /etc/mdadm.conf for typos.
SELinux denials can block access even if the mount works. Applications may fail silently. Check journalctl -t setroubleshoot for one-line summaries of denials. Run restorecon again if you changed the mount point or filesystem type.
The initial sync can take hours for large disks. Do not interrupt the sync. The system remains usable, but performance may be reduced. The sync speed is throttled by default to avoid impacting other I/O. You can adjust the speed in /proc/sys/dev/raid/speed_limit_min and speed_limit_max if needed, but the default is usually safe.
Trust the package manager. Manual file edits drift, snapshots stay. Use dnf to install mdadm and related tools. Do not download binaries from random sites.
When to use RAID levels and alternatives
Use RAID 1 when you need simple redundancy and fast reads with two disks. Use RAID 5 when you have three or more disks and want capacity efficiency with single-disk fault tolerance. Use RAID 6 when you have four or more disks and need to survive two simultaneous disk failures. Use LVM over RAID when you need to resize volumes dynamically or snapshot the filesystem. Use Btrfs RAID when you want filesystem-level redundancy and compression without a separate block layer. Use ZFS when you need end-to-end checksums and advanced pooling features.