RAID and macOS

RAIDs are a strange edge case that are rarely useful outside of servers, but when they are useful, they are very important. RAID is an acronym for ‘Redundant Array of Independent/Inexpensive Disks.’ It is a technology where you combine multiple, physical disks into a single virtual drive for redundancy, speed, or both.

Often the RAID system is handled by a dedicated controller in an external enclosure, but sometimes, you want or need to work with drives directly. macOS has some basic RAID functionality built-in and there are good third party options if you want to go further.

RAID Levels

If you are unfamiliar with RAIDs, we need to get some terminology sorted out first. There are different kinds of RAIDs which are called ‘levels.’

In this post, I am going to focus on level 1 or ‘RAID 1.’ With RAID 1, the data is ‘mirrored’ between two or more drives, so that each drive carries a complete copy of the data. This protects from data loss because of drive failure. Note that RAID 1 does not protect from other common reasons for data loss, such as file system or individual file corruption, accidental or malicious file deletion. A RAID is never a replacement for a good backup strategy. Since the data is mirrored on all the devices, a RAID 0 will only have the capacity of the smallest drive in the set. It is generally recommended that drives in any RAID set should be of the same capacity and type, for best performance and efficiency.

A level 0 RAID (or ‘RAID 0’) is not actually redundant. In a RAID 0 the data is ‘striped’ across two or more drives so that writes and reads happen in parallel, which increases the data bandwidth available. Since the data is spread evenly (striped) across all drives in the RAID 0 set, failure of a single drive will result in complete data loss. The capacity of the stripe raid is the capacity of the smallest drive in the set multiplied by the number of drives in the set. Having drives of the same type and capacity is even more relevant for RAID 0 performance.

There are more RAID levels, such as 0+1, 10 and 5 and dedicated disk controllers will have more options (such as combining multiple drives of different sizes more efficiently), but we will focus RAID 1 (mirror).

Here, there be dragons

Warning: many of the commands shown here to setup and experiment with disk drives and RAIDs may or will lead to loss of the data on the drives involved, so be careful. I strongly recommend disconnecting any drives other than those you are experimenting with from the Mac you are working on.

I would also recommend to experiment with a set of drives that contain no relevant data at all. Two USB sticks will do just fine to explore and test the functionality. Drives do not have to be of the same capacity and type for testing, but I do recommend that for actual use.

Apple RAID

macOS has built-in support for software-based mirror and stripe RAID called “AppleRAID.” This also provides a third option to concatenate drives, but concatenation provides neither redundancy, nor performance, so I do not recommend using it.

You can use the Disk Utility app to setup a RAID. It has a nice assistant that you an access from the File menu called RAID Assistant. It will ask you what kind of RAID you want to setup and allow you to select the drives and create a new RAID volume. This will delete the data on the disk drives and there are few features that are not exposed in the Disk Utility UI, so I will focus on how to do it in the command line.

You can keep Disk Utility open to get a visual representation of what is going on, though the Disk Utility app often has problems keeping up with changes done from the command line. You may have to quit and restart the app to force it to update its status. You want to enable “Show all Devices” from the View menu to see the physical drives as well as the file systems and virtual drives.

First, we need to identify the disks that we want to work with. When you run diskutil list it will list all the disk on the system. Usually disk0 will be the built-in drive, and disk3 will be the (synthesized) APFS container inside (with the System and Data volume). But depending on what Mac you are using, what your configuration is, and what devices you had attached to the Mac before you started this, the numbers may be different.

Again, to be safe, unmount and disconnect any drives or file servers with data that you care about at this point, and the connect the two drives you want to use for experimentation. Their data will be erased!

Run diskutil list again and identify the device identifiers for the drives you will be working with. They should look like this:

/dev/disk4 (external, physical):

For me, the two drives where disk4 and disk5, so I will be using those numbers in my examples, but be sure to replace those with the device numbers on your system, other wise you might be working with the wrong disk or volume.

Promoting a drive to mirror RAID

One of the features you can use from the command line is to ‘promote’ an existing drive to a mirror RAID without data loss. Apple RAID promotion works (as far as I can tell) only with HFS+ formatted Volumes, so let us reformat the first disk (disk4) as such:

> diskutil eraseDisk JHFS+ DiskName disk4 
Started erase on disk4
Unmounting disk
Creating the partition map
Waiting for partitions to activate
Formatting disk4s2 as Mac OS Extended (Journaled) with name DiskName
Initialized /dev/rdisk4s2 as a 59 GB case-insensitive HFS Plus volume with a 8192k journal
Mounting disk
Finished erase on disk4

Using the command line, we will be able to promote this HFS+ drive without have to erase it (again), so copy some (un-important) files to it now.

diskutil has a sub-group of commands dedicated to the RAID functions called appleRAID or ar for short. I am going to use the short form. You can run diskutil ar to get a list of the sub-commands for working with Apple Raid. You can read the diskutil man page for details.

Next we have to enable AppleRAID on the drive. Enabling RAID on single drive seems a bit pointless, but this prepares everything on that drive, so that we can add more drives later.

> diskutil ar enable mirror DiskName
Started RAID operation on disk4s2 (DiskName)
Resizing disk
Unmounting disk
Adding a booter for the disk
Creating a RAID set
Bringing the RAID partition online
Waiting for the new RAID to spin up "8D05B6EB-DCFB-426D-885B-ED8C76DC2484"
Finished RAID operation on disk4s2 (DiskName)

The volume and the files you had copied earlier are still there. But the volume is now listed under “RAID Sets” in Disk Utility. You can see the single drive in the RAID Set in the UI there. You can also get this info in command line with

> diskutil ar list   
AppleRAID sets (1 found)
===============================================================================
Name:                 DiskName
Unique ID:            8D05B6EB-DCFB-426D-885B-ED8C76DC2484
Type:                 Mirror
Status:               Online
Size:                 63.8 GB (63816400896 Bytes)
Rebuild:              manual
Device Node:          disk6
-------------------------------------------------------------------------------
#  DevNode   UUID                                  Status     Size
-------------------------------------------------------------------------------
0  disk4s2   467826B1-BBA2-4671-99CE-5CBB04E06882  Online     63816400896
===============================================================================

To make this a real mirror RAID, we need to add the second drive:

> diskutil ar add member disk5 DiskName                
Started RAID operation on disk6 (DiskName)
Unmounting disk
Repartitioning disk5 so it can be in a RAID set
Unmounting disk
Creating the partition map
Adding disk5s2 to the RAID Set
Finished RAID operation on disk6 (DiskName)

This will add the drive to the RAID. This will delete any data that might be on disk5!

When you look at the RAID in Disk Utility (you might have to restart the app for it to pick up the new status) you will now see both drives, but one of them has the status “Rebuilding” with a percentage. The status of the entire RAID set is now “Degraded.” The RAID system is still in the process of mirroring data to the new member. You can use the volume to read and write data at this time, but it is not redundant yet. If the first drive fails during rebuilding, the data will be gone.

Once the rebuilding is done, the status of the RAID will change to “Online,” which is the “good” status. At this point the data on the RAID will be resilient to the failure or removal of either of the drives.

You can also create the RAID with both drives from the start, but this will erase all the data on both drives (this is what RAID Assistant in Disk Utility does.

Before we can try the other way of creating a mirror RAID set, we need to “break” the mirror we have built so far.

> diskutil ar delete DiskName
Started RAID operation on disk6 (DiskName)
Unmounting volume for RAID set 8D05B6EB-DCFB-426D-885B-ED8C76DC2484
Destroying the RAID set 8D05B6EB-DCFB-426D-885B-ED8C76DC2484
Finished RAID operation on disk6 (DiskName)

If you waited for the rebuilding to be complete, both individual drives will each contain the data of the former mirror RAID. If the rebuilding was not complete yet, only the first drive will contain the data, the second drive will be empty.

Create a new RAID set

Now let’s build a new empty mirror RAID with both drives included from the start:

> diskutil ar create mirror DiskName APFS disk4 disk5
Started RAID operation
Unmounting proposed new member disk4
Unmounting proposed new member disk5
Repartitioning disk4 so it can be in a RAID set
Unmounting disk
Creating the partition map
Using disk4s2 as a data slice
Repartitioning disk5 so it can be in a RAID set
Unmounting disk
Creating the partition map
Using disk5s2 as a data slice
Creating a RAID set
Bringing the RAID partitions online
Waiting for the new RAID to spin up "FE3E7A3F-E4BF-4AEE-BC3C-094A9BFB3251"
Mounting disk
Finished RAID operation

Note that we can build an APFS volume on the RAID set with the command line tool. RAID Assistant in Disk Utility will build a HFS+ volume. In this new empty RAID set both drives will be online immediately.

When you replace the mirror with stripe in this command you will get a striped RAID 0 volume. (performance instead of redundancy)

Drive failure

We can simulate a drive failure by unplugging one of the members. Sadly, macOS does not seem to have a notification for this event. Once you have removed the drive you can run disktutil ar list and see the status is “Degraded” and the which member is “Missing/Damaged.” You can keep using the volume in degraded mode.

Once you plug the drive back in it will appear as ‘failed.’ You can start the process of repairing or rebuilding the mirror with

> diskutil ar repairMirror FE3E7A3F-E4BF-4AEE-BC3C-094A9BFB3251 disk5  
Started RAID operation
Unmounting disk
Repartitioning disk5 so it can be in a RAID set
Unmounting disk
Creating the partition map
Adding disk5s2 to the RAID Set
Finished RAID operation

Note: Syncing data between mirror partitions can take a very long time.
Note: The mirror should now be repairing itself.  You can check its status using 'diskutil appleRAID list'.

The UUID is the UniqueID of the RAID set you see with diskutil ar list. The warning you get at the end is fair. The rebuilding process will take a while. How it takes depends on how full the volume is and how fast the new member drive is.

Downsides of AppleRAID

There are quite a few downsides to the built-in AppleRAID functionality. There is no notification or warning when one of the drives in a mirror goes offline and the RAID is running in degraded state. The RAID will also not automatically rebuild when a missing drive re-appears. (There is an AutoRebuild option mention in man page, but whenever I tried to enable that, the entire disk management stack froze in a way that required a reboot.)

AppleRAID can be useful to quickly stripe some random disks for performance. But generally, if the data was of so much concern that I am considering RAID 1, I would not rely on AppleRAID.

SoftRAID

There is a wonderful third party tool for managing software based RAIDs on macOS called SoftRAID (14-day free trial, then a tiered license). And, much to my delight, it also comes with a command line tool. Creating a RAID is not something you do regularly, so I went ahead and did this in the GUI app. Once that was setup, I used the command line tool to get the RAID’s status:

> softraidtool volume DiskName info

Info for "DiskName":

Mountpoint: /Volumes/DiskName
BSD disk: disk4
Total Bytes: 59.6 GB (64,016,478,208)
Free Bytes: 59.6 GB (64,016,478,208)
Volume format: unknown
Volume is DiskName
RAID level: RAID 1
DiskName ID: 09DF05C72BFFAD20
Optimized for: Workstation
Created: Jul 17, 2023 at 3:33:39 PM
Last Validated: never
Volume state: normal, 
Volume Safeguard: enabled
Total I/Os: 5,610
Total I/O Errors: 0
Total number secondary disks (including offline ones): 1

Disks used for this volume:
bsd disk:    SoftRAID ID:         Location and Size:
disk7     09DF053ECE82F980     (USB3 bus 0, id 4 - 59.8 GB)  secondary disk, 
disk6     09DF053D23386500     (USB3 bus 0, id 5 - 59.8 GB)  primary disk, 

The SoftRAID software also comes with a menubar app that shows the status of the RAID.

When you unplug one of the drives, the ‘Volume state’ changes to ‘missing disk.’ When you plug the missing drive back in, SoftRAID will automatically detect it and rebuild the RAID, when necessary. Rebuilding went so quickly that I had a hard time capturing the state from the command line. The more changes you apply to the degraded RAID the longer the rebuild takes.

> softraidtool volume SoftRAID info
SoftRAIDTool status: waiting for disk5 to finish (00:00:01)

Info for "SoftRAID":

Mountpoint: /Volumes/SoftRAID
BSD disk: disk5
Total Bytes: 59.6 GB (64,016,478,208)
Free Bytes: 59.6 GB (64,016,478,208)
Volume format: unknown
Volume is SoftRAID
RAID level: RAID 1
SoftRAID ID: 09DF06D95024CBE0
Optimized for: Workstation
Created: Jul 17, 2023 at 3:53:16 PM
Last Validated: never
Volume state: rebuiding, out of sync, 
Volume Safeguard: enabled
Volume progress: 15%
Current offset: 7,343,685,632
Time remaining: 00:07:24
Total I/Os: 22,752
Total I/O Errors: 0
Total number secondary disks (including offline ones): 1

Disks used for this volume:
bsd disk:    SoftRAID ID:         Location and Size:
disk4     09DF053ECE82F980     (USB3 bus 0, id 4 - 59.8 GB)  primary disk, 
disk7     09DF053D23386500     (USB3 bus 0, id 5 - 59.8 GB)  secondary disk, rebuiding, out of sync, 

You can parse this output using awk to get just the volume state. This is useful for reporting the state to Jamf Pro with an extension attribute:

#!/bin/sh

# reports the SoftRAID status

softraidtool="/usr/local/bin/softraidtool"

if [ ! -x "$softraidtool" ]; then
    echo "<result>SoftRAID not installed</result>"
fi

volumestate=$(softraidtool volume SoftRAID info | awk -F ': ' '/Volume state/ {print $2}')

echo "<result>$volumestate</result>"

Keep in mind that Jamf Inventory Updates (aka as recon) may run very infrequently (recommended default is once per day, and it shouldn’t run much more often than that to avoid database bloat), so the data in your Jamf Pro may be hours or sometimes longer out of date. If you want to react to changes in the RAID status more quickly, you should rely on other tools than Jamf Pro.

Conclusion

The best solution for RAIDs will always be a dedicated hardware controller. But there also good reasons (cost) to just put together a “bunch of disks” into a RAID. The built-in AppleRAID functionality works, but has limitations, especially for mirror RAIDs. SoftRAID is a great tool to overcome these limitations. For Mac admins, both can be managed and monitored with command line tools, which allows automation and integration with your management system.