Compré una caja externa con dos discos de 4 TB. La idea era simple: un espejo, para que si un disco muere el otro siga teniendo todo. Lo armé desde Utilidad de Discos, le copié unos archivos de prueba, y me quedé mirando la pantalla con una duda incómoda.

¿Está bien hecho? ¿Y cómo me voy a enterar el día que falle algo?

Esta es la bitácora de responder esas dos preguntas. Terminó con el RAID destruido y vuelto a crear, y con tres hallazgos que no aparecen en los tutoriales de “cómo hacer RAID en Mac en 5 pasos”.


El laboratorio

ComponenteDetalle
EquipoMac mini (Mac16,10), chip Apple M4
SistemamacOS 26.6.2 (build 25G83)
Caja externaPuente USB JMicron JMS56x (0x152D:0xA580), modo UAS
DiscosSeagate ST4000DM004 y ST4000DM000, 4 TB cada uno
ConexiónUSB
smartmontools7.5 (Darwin 25.6.0 arm64), instalado con Homebrew

El dato del chipset importa más de lo que parece, y aparece más adelante. Se obtiene así:

ioreg -c IOUSBHostDevice -r -l | grep -iE "USB Product Name|USB Vendor Name|idProduct|idVendor"

Curiosamente, system_profiler SPUSBDataType no devolvía nada en mi equipo. ioreg sí.


Antes de empezar: qué es un RAID 1 y qué no es

Un RAID es una forma de combinar varios discos para que el sistema los vea como uno solo. Hay varios tipos; el que me interesa es el RAID 1, también llamado espejo o mirror.

En un espejo, cada byte se escribe simultáneamente en los dos discos. Son copias idénticas en todo momento. Si un disco muere, el otro sigue funcionando y ni te enteras hasta que lo revisas.

Dos consecuencias que conviene tener claras desde el principio:

Pierdes la mitad del espacio. Dos discos de 4 TB no dan 8 TB, dan 4 TB. Si tu sistema reporta la suma de ambos, no tienes un espejo — tienes otra cosa (un RAID 0, que es lo contrario: más espacio, cero protección). Este fue mi primer chequeo. (Con discos de distinto tamaño, el espejo se limita al menor y sobra el resto.)

Un RAID 1 no es un backup. Esto es lo que más gente confunde. El espejo te protege contra el fallo físico de un disco. No te protege contra:

  • Borrar una carpeta por error — se borra en los dos discos, instantáneamente
  • Ransomware — cifra los dos discos
  • Corrupción de archivos — se replica fielmente
  • Que se te caiga la caja por las escaleras

Un backup es una copia separada en el tiempo y en el espacio. El espejo es redundancia, que es otra cosa. Ambas sirven; ninguna reemplaza a la otra.


Punto de partida

Utilidad de Discos me mostraba esto:

  • Volumen Caja_Raid, formato APFS, 4 TB
  • “Estado del grupo mirror (RAID 1): Conectado”
  • Los dos discos listados como “Conectado”

Los 4 TB confirmaban que era espejo y no stripe. Aparentemente todo bien. Pero la interfaz gráfica dice poco, así que me fui a la terminal.


Paso 1: verificar de verdad

macOS trae diskutil, la versión de línea de comandos de Utilidad de Discos. Con muchas más opciones y mucha más información.

diskutil appleRAID list

Salida:

AppleRAID sets (1 found)
===============================================================================
Name:                 Caja_Raid
Unique ID:            9B4E10E4-00AE-4B02-B7CC-0ED0EBA41580
Type:                 Mirror
Status:               Online
Size:                 4.0 TB (4000443039744 Bytes)
Rebuild:              automatic
Device Node:          disk8
-------------------------------------------------------------------------------
#  DevNode   UUID                                  Status     Size
-------------------------------------------------------------------------------
0  disk4s2   848718FB-9213-4868-BE55-370F0188DDF8  Online     4000443039744
1  disk5s2   49798402-AEC3-466D-A338-5E8FABAE6733  Online     4000443039744
===============================================================================

Cómo se lee esto:

  • Type: Mirror — es un espejo. Confirmado.
  • Status: Online — el conjunto está sano. Los otros valores posibles son Degraded (falta un disco) y Failed.
  • Rebuild: automatic — si reinserto un disco caído, se reconstruye solo. Guarda este dato, que reaparece al final del artículo de forma incómoda.
  • Los dos miembros en Online — ambos discos respondiendo.

La cadena de cuatro capas

diskutil list revela algo que al principio marea: entre los discos físicos y el volumen que ves en el Finder hay cuatro niveles de abstracción.

┌─────────────────┐
│  disk6 (físico) │  Seagate ST4000DM004 · 4 TB
└────────┬────────┘
         │
         ├──────────────┐
         │              │
┌────────┴────────┐     │
│  disk7 (físico) │     │  Seagate ST4000DM000 · 4 TB
└─────────────────┘     │
                        ▼
              ┌───────────────────┐
              │  Set AppleRAID    │  disk4 — disco VIRTUAL
              │  (Mirror, 4 TB)   │  no existe físicamente
              └─────────┬─────────┘
                        ▼
              ┌───────────────────┐
              │ Contenedor APFS   │  disk5
              └─────────┬─────────┘
                        ▼
              ┌───────────────────┐
              │ Volumen Caja_Raid │  disk5s1 → /Volumes/Caja_Raid
              └───────────────────┘

De abajo hacia arriba:

  1. Discos físicos — el hardware real, los dos de 4 TB.
  2. Set AppleRAID — un disco virtual que macOS inventa. No existe físicamente; es la abstracción que hace que los dos discos se vean como uno.
  3. Contenedor APFS — APFS (el sistema de archivos moderno de Apple) no formatea discos directamente. Crea un “contenedor” que puede alojar varios volúmenes compartiendo espacio.
  4. Volumen — lo que finalmente ves en el Finder.

Esto importa por una razón práctica: los números de disco cambian entre reconexiones. En mis pruebas el set fue disk8, luego disk5, luego disk4. Los discos físicos pasaron de disk4/disk5 a disk6/disk7. No son estables. Cualquier script que escribas no debe depender de ellos.


Paso 2: lo que la interfaz gráfica no te dice

Aquí empezaron las sorpresas. Tres cosas que Utilidad de Discos no menciona.

AppleRAID no te avisa de nada

Si un disco falla, macOS no muestra ninguna notificación. No hay correo, no hay alerta, no hay icono rojo. El volumen sigue montado y funcionando con normalidad, en modo degradado, y tú sigues trabajando feliz sobre un espejo que ya no es espejo.

Si en ese estado falla el segundo disco, pierdes todo. Y nunca supiste que estabas en riesgo.

Esto es un problema serio y es la razón de la mitad de esta bitácora.

El SMART no está disponible (y la causa no es la que parece)

SMART (Self-Monitoring, Analysis and Reporting Technology) es un sistema que traen los discos duros para reportar su propia salud: horas de uso, sectores defectuosos, temperatura, errores de lectura. Sirve para detectar un disco que se está muriendo antes de que muera.

Utilidad de Discos decía: Estado S.M.A.R.T.: Incompatible.

La explicación que dan casi todos los foros es que el puente USB no soporta SAT (SCSI/ATA Translation, el mecanismo que permite pasar comandos SMART a través de USB). Fui a comprobarlo con smartmontools, la herramienta estándar:

brew install smartmontools
sudo smartctl -a -d sat /dev/disk6
/dev/disk6: Type 'sat+...': Not a device of type 'scsi'

Aquí es donde vale la pena no conformarse con la primera hipótesis. Probé cuatro caminos distintos:

sudo smartctl --scan                          # solo lista el NVMe interno
sudo smartctl -a /dev/rdisk6                  # Operation not supported by device
sudo smartctl -a -d sat,auto /dev/rdisk6      # Not a device of type 'scsi'
sudo smartctl -a -d auto /dev/rdisk6          # Operation not supported by device

Y luego, ya sabiendo por ioreg que el puente era un JMicron JMS56x, probé el driver específico que smartmontools trae para ese chip:

sudo smartctl -a -d jms56x,1 /dev/disk6
/dev/disk6: Type 'jms56x,1+...': Not a device of type 'scsi'

Falla igual. Y eso cambia la conclusión.

Lo que la evidencia realmente muestra:

  • --scan no ve ningún disco USB. Solo el NVMe interno del Mac.
  • Sin -d, el error es al abrir el dispositivo, antes de enviar comando alguno.
  • Con cualquier -d, macOS no expone el disco como objeto SCSI, que es el requisito previo para intentar SAT.
  • El chipset sí tiene driver en smartmontools y sí opera en modo UAS (USB Attached SCSI).

Es decir: el bloqueo está en la capa de dispositivo de macOS, no en el puente USB. smartctl ni siquiera llega a hablar con la caja. La capacidad SAT del JMS56x queda sin probar, no descartada — con este mismo hardware conectado a un Linux, es probable que funcionara.

No afirmo que esto sea así en toda combinación de macOS y hardware; afirmo que en este equipo, con esta versión y con cinco variantes de driver, smartctl no logró abrir el dispositivo ni una sola vez.

Opciones reales, ninguna gratis:

  1. Aceptarlo. Vives sin monitoreo de salud y confías en el chequeo del RAID.
  2. DriveDx (comercial). Trae su propio driver y esquiva esta limitación en varias cajas USB.
  3. Conectar los discos por SATA a otra máquina de vez en cuando para revisarlos.

Elegí la 1 por ahora. Pero conviene entender qué significa: sin SMART, la primera señal de que un disco se está muriendo es que ya se murió. El espejo te salva esa vez. No te avisa antes.

Los propietarios venían desactivados

diskutil info mostraba Owners: Disabled.

Traducción: macOS estaba ignorando los permisos de archivo en ese volumen. Cualquier usuario puede leer y escribir todo, sin importar a quién pertenezca cada archivo.

Es el comportamiento por defecto en discos externos, y para una memoria USB que pasa de mano en mano tiene sentido. Para un disco donde voy a guardar proyectos de trabajo, no.

sudo diskutil enableOwnership /Volumes/Caja_Raid
diskutil info /Volumes/Caja_Raid | grep -i owners

Debe responder Enabled. Ojo: este ajuste puede revertirse al remontar el volumen. Toca revisarlo de vez en cuando.


Paso 3: el script de monitoreo

Como macOS no avisa, hay que construir el aviso. La idea: un script que revise el estado del RAID y mande una notificación si algo está mal.

Primera versión, en ~/bin/check-raid.sh:

#!/bin/bash
VOL="/Volumes/Caja_Raid"

[ -d "$VOL" ] || exit 0
sleep 10

if diskutil appleRAID list | grep -qiE "degraded|failed|rebuild|missing|offline"; then
  osascript -e 'display notification "Caja_Raid en estado anormal" with title "RAID degradado"'
  logger -t raidcheck "RAID anormal: $(diskutil appleRAID list)"
else
  logger -t raidcheck "RAID OK"
fi

La lógica es directa: si el estado contiene alguna palabra de fallo, alerta. El sleep 10 le da tiempo al set a ensamblarse antes de leer su estado — si consultas de inmediato tras conectar la caja, puedes leer un estado transitorio y alarmarte por nada.

osascript ejecuta AppleScript desde bash, y es la forma de lanzar una notificación nativa de macOS.

Lo ejecuté. Y me alertó.

Con el RAID perfectamente sano.

El bug: Rebuild: automatic

Miré la salida que el script había guardado:

Status:               Online
Rebuild:              automatic

Ahí está. Mi patrón buscaba la palabra rebuild, y Rebuild: automatic es una línea de configuración que aparece siempre, en todo momento, esté sano o no el RAID. No es un estado de fallo. Es la etiqueta que dice cómo se comportará el sistema si llegara a haber uno.

Mi script iba a gritar “¡fallo!” cada vez que conectara la caja. Para siempre.

Esto es peor que no tener monitoreo. Un sistema de alertas que da falsos positivos constantes entrena a su dueño a ignorarlo, y el día que la alerta es real, la descartas por reflejo.

La corrección: filtrar primero las líneas que sí describen estado, y cambiar rebuild por rebuilding (que es el estado activo durante una reconstrucción real).

#!/bin/bash
VOL="/Volumes/Caja_Raid"
LOG="$HOME/raidcheck.log"

[ -d "$VOL" ] || exit 0
sleep 10

SALIDA=$(diskutil appleRAID list)

# Solo la línea "Status:" y las filas de los miembros
PROBLEMA=$(echo "$SALIDA" | grep -E "^Status:|^[0-9]+ +disk" | grep -icE "degraded|failed|missing|offline|rebuilding")

if [ "$PROBLEMA" -gt 0 ]; then
  osascript -e 'display notification "Caja_Raid en estado anormal" with title "RAID degradado" sound name "Basso"'
  echo "$(date '+%F %T') RAID ANORMAL" >> "$LOG"
  echo "$SALIDA" >> "$LOG"
else
  echo "$(date '+%F %T') RAID OK" >> "$LOG"
fi

También cambié logger por escribir a un archivo propio. logger manda al unified log de macOS, que es potente pero incómodo de consultar — necesitas predicados y banderas específicas, y por defecto oculta los mensajes de nivel informativo. Un archivo de texto plano se lee con tail y ya.


Paso 4: ¿cuándo ejecutar el chequeo?

Mi primer instinto fue programarlo a diario. Pero la caja no está encendida todos los días — la conecto cuando la necesito.

Un chequeo diario habría intentado revisar un RAID ausente y generado ruido. Lo correcto es disparar el chequeo cuando se conecta el disco.

macOS tiene exactamente eso. Se llama StartOnMount.

Qué es un LaunchAgent

macOS usa launchd para gestionar procesos automáticos: servicios, tareas programadas, cosas que se ejecutan al iniciar sesión. Es el equivalente moderno de cron en Linux, y mucho más flexible.

Le indicas qué ejecutar y cuándo con un archivo .plist (un XML de configuración). Si va en ~/Library/LaunchAgents/, se llama LaunchAgent y corre con tu usuario.

Mi archivo ~/Library/LaunchAgents/com.mauro.raidcheck.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.mauro.raidcheck</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/TU_USUARIO/bin/check-raid.sh</string>
    </array>
    <key>StartOnMount</key>
    <true/>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/tmp/raidcheck.err</string>
</dict>
</plist>

Las claves:

  • Label — identificador único del servicio.
  • ProgramArguments — qué ejecutar. Debe ser ruta absoluta: launchd no expande ~.
  • StartOnMount — ejecuta cada vez que se monta cualquier volumen. Por eso el script sale de inmediato si /Volumes/Caja_Raid no existe.
  • RunAtLoad — también al iniciar sesión, por si la caja ya estaba conectada.
  • StandardErrorPath — dónde van los errores, para depurar.

Validar y cargar:

plutil -lint ~/Library/LaunchAgents/com.mauro.raidcheck.plist
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.mauro.raidcheck.plist
launchctl list | grep raidcheck

plutil -lint verifica que el XML esté bien formado. bootstrap registra el agente. La salida de launchctl list muestra PID y último código de salida — un 0 significa que el script corrió sin errores.

Nota para Apple Silicon: intenté poner el script en /usr/local/bin y ese directorio no existe. En Macs con chip Apple, Homebrew usa /opt/homebrew y /usr/local queda vacío. Terminé usando ~/bin, que además evita necesitar sudo.


Paso 5: romper el RAID a propósito

Aquí está la parte que casi nadie hace.

Yo tenía un script que decía “RAID OK”. Pero nunca lo había visto detectar un fallo real. Y acababa de descubrir, por casualidad, que el mismo script tenía un bug que lo hacía mentir en la dirección contraria. Confiar en él sin probarlo habría sido ingenuo.

La única prueba válida es provocar el fallo. Con datos de prueba, el costo es cero.

El procedimiento:

  1. Desmontar y apagar la caja:
    diskutil unmountDisk /dev/disk9
    
  2. Sacar físicamente uno de los dos discos.
  3. Encender la caja con un solo disco.
  4. Ver qué pasa.

Y pasó lo que debía:

Status:               Degraded
-------------------------------------------------------------------------------
#  DevNode   UUID                                  Status     Size
-------------------------------------------------------------------------------
-  -none-    848718FB-9213-4868-BE55-370F0188DDF8  Missing/Damaged
1  disk4s2   49798402-AEC3-466D-A338-5E8FABAE6733  Online     4000443039744

Status: Degraded. Un miembro como Missing/Damaged. El script escribió RAID ANORMAL en el log con el volcado completo del estado. La notificación apareció.

Y lo más importante: el volumen siguió montado y accesible con un solo disco. Los archivos ahí, funcionando. Eso es exactamente lo que un espejo debe hacer.

La reintegración

Apagué, reinserté el disco, encendí:

0  disk4s2   848718FB-...  0% (Rebuilding)  4000443039744
1  disk5s2   49798402-...  Online           4000443039744

Reconstrucción automática, sin comandos manuales. Eso era el Rebuild: automatic de la primera salida haciendo su trabajo.

Pero la reconstrucción es lenta. Muy lenta. AppleRAID copia a nivel de bloque: replica los 4 TB completos, sin importar que yo estuviera usando 885 GB. Por USB, son varias horas.

Y durante todo ese tiempo no tienes redundancia. Si el disco sano falla mientras reconstruye, perdiste el volumen.


Paso 6: el error que salió gratis

Como eran datos de prueba, pensé: no voy a esperar horas. Apago la caja y ya.

Interrumpí la reconstrucción. Y cuando volví a conectar:

/dev/disk6 (external, physical):
   2:         Apple_RAID_Offline                         4.0 TB     disk6s2
/dev/disk7 (external, physical):
   2:         Apple_RAID_Offline                         4.0 TB     disk7s2

Apple_RAID_Offline. El set virtual había desaparecido. diskutil appleRAID list respondía “No AppleRAID sets found”. El volumen ya no existía y los datos no eran accesibles.

Los discos quedaron con las particiones RAID huérfanas, sin conjunto al cual pertenecer.

Seré preciso con lo que puedo afirmar: en mi caso, interrumpir la reconstrucción dejó el conjunto en un estado del que no lo recuperé. No agoté las opciones de recuperación — iba a recrear el RAID de todos modos, así que no insistí. Puede que existiera una forma de reensamblarlo. Lo que sí sé es que el set desapareció de diskutil y el volumen se volvió inaccesible sin intervención manual.

Aun con ese matiz, la lección práctica se sostiene: la reconstrucción es el momento más frágil de la vida de un RAID. No es un trámite en segundo plano. Es el escenario donde alguien descubre que el espejo no lo salvó — falla un disco, empieza la reconstrucción, el proceso se corta (un apagón, un cable suelto, alguien impaciente que apaga la caja) y el margen de error desaparece.

En mi caso perdí archivos desechables. Lección barata.


Paso 7: reconstruir desde cero

Como iba a recrear el RAID de todos modos, aproveché.

Un detalle contraintuitivo: borrar archivos no acelera la reconstrucción. Como copia bloques, no archivos, vaciar el volumen no ahorra ni un minuto. En cambio, destruir y recrear el set sí es instantáneo — un espejo nuevo nace vacío y sincronizado, sin nada que copiar.

# Confirmar identificadores — los números cambian
diskutil list

# Verificar que son los correctos ANTES de borrar
diskutil info /dev/disk6 | grep -E "Device / Media Name|Disk Size"
diskutil info /dev/disk7 | grep -E "Device / Media Name|Disk Size"

# Limpiar
diskutil eraseDisk APFS Temp1 GPT /dev/disk6
diskutil eraseDisk APFS Temp2 GPT /dev/disk7

# Recrear
diskutil appleRAID create mirror Caja_Raid APFS /dev/disk6 /dev/disk7

Sobre la verificación de identificadores: yo tenía otro disco externo conectado con 1.1 TB de datos reales. eraseDisk no pide confirmación. Equivocarse de número borra el disco equivocado, sin red. El tamaño es la señal más confiable: 4 TB contra 2 TB.

La trampa que casi se me pasa: Rebuild: manual

El set nuevo quedó Online con ambos discos sanos. Todo perfecto. Pero al comparar la salida completa con la del RAID original, apareció una sola línea distinta:

Rebuild:              manual

El RAID creado desde Utilidad de Discos tenía automatic. Al crearlo por línea de comandos, diskutil usa manual por defecto.

En modo manual, si falla un disco y lo reinsertas, no se reconstruye solo. Hay que lanzar la reparación a mano. Es decir: el comportamiento que yo acababa de probar y verificar habría dejado de funcionar, en silencio, sin ninguna señal.

De no haber comparado línea por línea con la salida anterior, lo habría descubierto el día que un disco fallara de verdad.

diskutil appleRAID update AutoRebuild 1 <UUID-del-set>

Y también hubo que reaplicar los propietarios, que se pierden al recrear:

sudo diskutil enableOwnership /Volumes/Caja_Raid

Si te llevas una sola cosa de este artículo, que sea esta: recrear algo por CLI no reproduce automáticamente la configuración que hizo la interfaz gráfica. Un RAID que se ve idéntico puede comportarse distinto en el único momento que importa.


Estado final

ElementoEstado
RAID 1 espejoOnline, ambos discos sanos
Reconstrucción automáticaHabilitada (tras corregirla)
Propietarios POSIXEnabled
Alerta al conectarProbada contra un fallo real
SMARTNo disponible
Backup externoPendiente

Comandos de referencia

ComandoPara qué
diskutil appleRAID listEstado del conjunto y de cada miembro
diskutil listTopología completa de discos y volúmenes
diskutil info /Volumes/<vol>Detalle del volumen: propietarios, cifrado, protocolo
diskutil enableOwnership <vol>Activar permisos POSIX en disco externo
diskutil appleRAID create mirror <nombre> APFS <d1> <d2>Crear el espejo
diskutil appleRAID update AutoRebuild 1 <UUID>Activar reconstrucción automática
diskutil appleRAID delete <UUID>Destruir el conjunto
diskutil appleRAID repairMirror <set> <disco>Reparación manual de un miembro
launchctl bootstrap gui/$(id -u) <plist>Registrar un LaunchAgent
plutil -lint <plist>Validar el XML antes de cargarlo
ioreg -c IOUSBHostDevice -r -lIdentificar el chipset del puente USB

Mi opinión sobre AppleRAID

Después de esta tarde, mi conclusión es que AppleRAID sirve perfectamente para almacenamiento doméstico o de laboratorio, pero exige más supervisión de la que esperaba.

Lo que hace bien lo hace bien: detectó el fallo, mantuvo el volumen accesible con un solo disco, reintegró el disco reinsertado sin intervención. La mecánica del espejo funciona.

Lo que no hace es todo lo demás. No hay alertas. No hay panel de estado. No hay correo cuando algo falla. No hay historial. Comparado con lo que ofrece cualquier NAS moderno o un mdadm en Linux con smartd, AppleRAID es la capa de redundancia y nada más — la observabilidad la tienes que construir tú.

Y en macOS, con discos por USB, la construyes a ciegas: sin SMART no puedes anticipar nada, solo reaccionar.

¿Lo usaría para datos críticos de producción? No. ¿Para el disco de trabajo de un equipo personal, con backup aparte y un script de veinte líneas vigilando? Sí, sin problema. Es lo que estoy haciendo.


Lo que me llevo

Verificar no es mirar la interfaz gráfica. Utilidad de Discos decía “Conectado” mientras los propietarios estaban desactivados, el SMART era inaccesible y no existía ninguna alerta configurada.

Un monitoreo sin probar no es monitoreo. Mi script tenía un falso positivo garantizado y yo no lo sabía. Si no hubiera provocado un fallo real, hoy tendría un sistema de alertas decorativo.

Probar cuesta poco cuando los datos son desechables. Después de mover proyectos reales, sacar un disco a ver qué pasa deja de ser una prueba y se vuelve un riesgo. El momento es al principio, siempre.

No te fíes de la primera hipótesis. Estuve a punto de publicar que mi caja USB no soportaba SAT. Cinco comandos más tarde resultó que el problema estaba en otra capa, y que el chipset ni siquiera había llegado a ser puesto a prueba.

Y el espejo sigue sin ser un backup. Me protege de que un disco muera. No de que yo borre una carpeta, ni de ransomware, ni de que la caja se caiga. Eso sigue pendiente, y es lo próximo.


Los identificadores de disco de los ejemplos son los de mi equipo y cambian entre reconexiones — verifica siempre los tuyos antes de ejecutar nada destructivo.