Raid 1 por software en linux

raid 1 en linux con ubuntu

Introducción

En linux existe un programa para hacer raid por software. Este se llama mdadm. En esta guia explicaré como hacer un raid 1 con dos particiones del mismo tamaño.

Detectar un raid ya construido

Puede ser que hayamos creado un raid anteriormente en otro SO y queramos montarlo en el nuestro. Para ello podemos decirle al programa que los gestiona, que escanée las particiones para descubrir los raid que hay en ella.

Para ello tendremos que ejecutar los siguientes comandos:

>> sudo apt-get install mdadm
>> sudo mdadm --assemble --scan

Hacer un raid

Lo primero será tener instalado mdadm, que es el programa que hará el raid por software. Instalamos el programa mdadm con la siguiente orden:

>> sudo apt-get install mdadm

Por ejemplo, tenemos una partición con datos (/dev/sda5) y queremos hacer un raid 1 con otra partición que tenemos sin datos (/dev/sdb1). Lo primero será desmontar las dos particiones:

>> sudo umount /dev/sda5
>> sudo umount /dev/sdb1

Comprobamos que las dos particiones tienen el mismo tamaño:

>>sudo fdisk -l
...
/dev/sda5            5227       35741   245111706   83  Linux
...
/dev/sdb1               1       30515   245111706   83  Linux
...

Ahora vamos a crear el raid con la partición que no tiene los datos originales (acordaros que si creáis varios raid, tendréis que poner un nombre a cada uno: /dev/md0, /dev/md1, ...):

>> sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 missing
  mdadm: /dev/sda5 appears to contain an ext2fs file system
      size=245111704K  mtime=Sun Jun 21 13:01:34 2009
  Continue creating array? y
  mdadm: array /dev/md0 started.

Ahora formateamos la partición del raid. Por ejemplo, para crear un sistema de ficheros de linux lo haremos con la siguiente orden (podemos formatearlo con lo que queramos: ntfs, fat32, ext4, ...):

>> sudo mkfs -t ext4 /dev/md0

Ya tenemos el raid creado con la partición sin datos. Ahora vamos a pasar los datos, de la partición que los contiene, al raid. Para hacerlo, primero tendremos que montar las particiones:

>> sudo mount /dev/sda5 /media/datos
>> sudo mount /dev/md0 /media/raid

Ahora copiaremos todos los datos de /media/datos a /media/raid (no hay que copiar las carpetas del sistema de archivos como lost+found).

Una vez hemos llegado aquí, ya tendremos el raid creado con los datos dentro, pero solo con 1 disco. Ahora añadiremos  al raid la partición que tenía los datos (/dev/sda5) para que se reconstruya con los datos del raid:

>> sudo mdadm --manage /dev/md0 --add /dev/sda5
   mdadm: added /dev/sdb1

Se empecará a copiar la información de la partición primaria en la que hemos añadido ahora. Para ver como va el proceso podremos ejecutar el siguiente comando para ver el % que lleva: 

>> cat /proc/mdstat
  Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
  md0 : active raid1 sdb1[2] sda5[0]
        245111616 blocks [2/1] [U_]
        [>....................]  recovery =  0.3% (857600/245111616) finish=66.4min speed=61257K/sec

O tambien podemos ver el proceso de reconstrucción con este otro comando:

>> sudo mdadm --detail /dev/md0
/dev/md0:
...
    Update Time : Sun Jun 21 15:38:24 2009
          State : clean, degraded, recovering
 Active Devices : 1
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 1
 
 Rebuild Status : 13% complete
...
    Number   Major   Minor   RaidDevice State
       0       8        5        0      active sync   /dev/sda5
       2       8       17        1      spare rebuilding   /dev/sdb1

Esperaremos hasta que desaparezca esta línea. Una vez acabado este proceso, iremos al fichero /etc/mdadm/mdadm.conf y añadiremos la línea en la que indicamos las particiones queu forman el raid, quedando el fichero de la siguiente forma:

...
# by default, scan all partitions (/proc/partitions) for MD superblocks.
# alternatively, specify devices to scan, using wildcards if desired.
DEVICE partitions
# auto-create devices with Debian standard permissions
CREATE owner=root group=disk mode=0660 auto=yes
# automatically tag new arrays as belonging to the local system
HOMEHOST <system>
# instruct the monitoring daemon where to send mail alerts
MAILADDR root
# definitions of existing MD arrays
# This file was auto-generated on Thu, 21 May 2009 21:47:53 +0200
# by mkconf $Id$
ARRAY        /dev/md0 devices=/dev/sda5,/dev/sdb1

Una vez que ya tenemos creado dispositivo raid, vamos a ponerla en el /etc/fstab para que el ordenador la monte cada vez qeu se encienda. Lo primero que tenemos que saber es el UUID de nuestra particion raid. Para ello tendremos que ejecutar la siguiente orden (por ejemplo pasa saber el UUID del dispositivo md0):

>> sudo vol_id -u /dev/md0
XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

(* En versiones ams nuevas de ubuntu podemos usar >> sudo blkid)

Una vez tenemos el UUID vamos a editar el fichero /etc/fstab, comentaremos las líneas en las que aparezcan los dispositivos que forman parte del raid (en nuestro caso /dev/sdb1 y /dev/sda5) si es que estan en el fichero (igual aparecen por su UUID, podeis saber cual es con la orden sudo vol_id -u /dev/XXX) y añadiremos la línea del nuevo dispositivo:

# /dev/sda5
#UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX       /media/SIN_RAID1        ext3    relatime        0       2
# /dev/sdb1
#UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX       /media/SIN_RAID2        ext3    relatime        0       2
# /dev/md0
UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX    /media/CON_RAID    ext3    relatime    0    2

Quitar un raid

Lo primero que tendremos que saber es que particiones forman el raid. Por ejemplo, si queremos desacer el raid /dev/md1, tendremos que ejecutar el siguiente comando para saber las particiones que lo forman:

>> sudo mdadm --detail /dev/md1
/dev/md1:
...   
Number Major Minor RaidDevice State
0 8 6 0 active sync /dev/sda6
1 8 34 1 active sync /dev/sdc2

Como podemos ver, el raid esta formado por las particiones /dev/sda6 y /dev/sdc2. Una vez sabemos esto pararemos el raid y lo desmontamos con las siguientes ordenes:

>> mdadm --stop /dev/md1
>> sudo umount /dev/md1

Ahora limpiaremos las dos particiones de la configuración del raid con las siguientes ordenes:

>> mdadm --zero-superblock /dev/sda6
>> mdadm --zero-superblock /dev/sdc2

Y por último tendremos que ir al fichero /etc/mdadm/mdadm.conf y tendremos que quitar la línea correspondiente a el raid, en nuestro caso la siguiente:

ARRAY /dev/md1 devices=/dev/sda6,/dev/sdc2

Con esto ya habremos quitado el raid /dev/md1.

Comprobar el estado de un raid

Si lo que queremos es comprobar el estado de un raid, tendremos que ejecutar el siguiente comando. Por ejemplo para comprobar el estado del rad /dev/md0:

>> sudo mdadm --detail /dev/md0
/dev/md1:
        Version : 00.90
  Creation Time : Thu Jul  2 22:46:31 2009
     Raid Level : raid1
     Array Size : 271610816 (259.03 GiB 278.13 GB)
  Used Dev Size : 271610816 (259.03 GiB 278.13 GB)
  Raid Devices : 2
  Total Devices : 2
  Preferred Minor : 1
  Persistence : Superblock is persistent
 
    Update Time : Fri Jul  3 00:07:06 2009
          State : clean
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
 
           UUID : 8fe624fd:cef7961e:ce24d2e1:c686696d (local to host pcpedro)
         Events : 0.14
  
   Number   Major   Minor   RaidDevice State
       0       8        6        0      active sync   /dev/sda6
       1       8       34        1      active sync   /dev/sdc2

Problemas

Unexpected inconsistency

Al encender el ordenador, cuando esta cargando ubuntu se para el proceso y saca el siguiente mensaje:

Log of fsck -C3 -R -A -a
Sat Sep 19 13:01:06 2009
 
fsck 1.41.4 (27-Jan-2009)
D: The filesystem size (according to the superblock) is 61277926 blocks
The physical size of the device is 61277904 blocks
Either the superblock or the partition table is likely to be corrupt!
 
D: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
    (i.e., without -a or -p options)
 
fsck died with exit status 4
Sat Sep 19 13:01:07 2009
----------------

Se queda parado en la consola y tengo que poner exit para que siga la carga de ubuntu.

Solución

Este problema me apareció cuando metí al raid un sistema de ficheros ya creado para no tener qeu mover los datos que contenía. Y para solucionarlo, tuve que seguir estos pasos:

  • Quitar el raid (según indico en este artículo).
  • Volverlo ha hacer mediendo al raid una partición vacía.
  • Formatear el raid.
  • Copiar los datos en el raid.
  • Y por último meter la otra particion por el raid.

Has no superblock

A veces, cuando intentas activar un raid, puede aparecer el siguiente error:

>> sudo mdadm -A /dev/md1
mdadm: /dev/sdd2 has no superblock - assembly aborted

Miramos primero que raids tenemos activados:

>> cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md1 : inactive sda7[1](S)
      271610816 blocks
       
md_d1 : inactive sdd3[0](S)
      271610816 blocks

unused devices: <none>

Solución

Como podemos ver, hay un dispositivo que se ha creado con una de las particiones del raid md1, por eso no deja activarlo. Para solucionarlo tendremos que parar los dos raid (el que no nos funciona y el desconocido) y luego activaremos y montaremos el nuestro:

>> sudo mdadm --stop /dev/md_d1
mdadm: stopped /dev/md_d1
>> sudo mdadm --stop /dev/md1
mdadm: stopped /dev/md1
>> sudo mdadm -A /dev/md1
mdadm: /dev/md1 has been started with 2 drives.
>> sudo mount /dev/md1
temas: 

Comentarios

También está bien poder ver el estado del raid directamente desde el escritorio. Aquí te dejo un pequeño script en python que cumple esa labor a la perfección:

  1. #!/usr/bin/python
  2. # -*- coding: UTF-8 -*-
  3. #
  4. #       raidmon.py - mdadm RAID-Monitor
  5. #      
  6. #       Copyright 2008 Thimo Kraemer <<a href="mailto:thimo.kraemer@joonis.de">thimo.kraemer@joonis.de</a>>
  7. #      
  8. #       This program is free software; you can redistribute it and/or modify
  9. #       it under the terms of the GNU General Public License as published by
  10. #       the Free Software Foundation; either version 2 of the License, or
  11. #       (at your option) any later version.
  12. #      
  13. #       This program is distributed in the hope that it will be useful,
  14. #       but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. #       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. #       GNU General Public License for more details.
  17. #      
  18. #       You should have received a copy of the GNU General Public License
  19. #       along with this program; if not, write to the Free Software
  20. #       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  21. #       MA 02110-1301, USA.
  22.  
  23.  
  24. from datetime import datetime
  25. import sys
  26. import os
  27. import subprocess
  28. import pygtk
  29. pygtk.require('2.0')
  30. import gtk
  31. import gobject
  32. import re
  33.  
  34.  
  35. class RaidMonitor:
  36.    
  37.     def __init__(self):
  38.         self.period = 300
  39.         self.path = os.path.dirname(sys.argv[0])
  40.         self.pattern = re.compile('\[[U_]*_[U_]*\]')
  41.         self.title = 'RAID Monitor'
  42.         self.message = 'Initializing...'
  43.         self.status = 'RAID status not available'
  44.        
  45.         self.dialog = None
  46.         self.icon = gtk.StatusIcon()
  47.  
  48.         menu = gtk.Menu()
  49.         item = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
  50.         item.connect('activate', self.show_dialog)
  51.         menu.append(item)
  52.         item = gtk.ImageMenuItem(gtk.STOCK_REFRESH)
  53.         item.connect('activate', self.check_raid)
  54.         menu.append(item)
  55.         item = gtk.SeparatorMenuItem()
  56.         menu.append(item)
  57.         item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
  58.         item.connect('activate', self.quit)
  59.         menu.append(item)
  60.        
  61.         self.icon.connect('activate', self.show_dialog)
  62.         self.icon.connect('popup-menu', self.popup_menu, menu)
  63.         self.check_raid()
  64.         self.icon.set_visible(True)
  65.  
  66.     def popup_menu(self, widget, button, time, menu=None):
  67.         if button == 3:
  68.             if menu:
  69.                 menu.show_all()
  70.                 menu.popup(None, None, None, 3, time)
  71.  
  72.     def show_dialog(self, widget=None):
  73.         if self.dialog:
  74.             self.dialog.destroy()
  75.        
  76.         if self.icon.get_blinking():
  77.             dlg_type = gtk.MESSAGE_WARNING
  78.         else:
  79.             dlg_type = gtk.MESSAGE_INFO
  80.        
  81.         self.dialog = gtk.MessageDialog(
  82.             parent=None,
  83.             type=dlg_type,
  84.             buttons=gtk.BUTTONS_CLOSE,
  85.             message_format=self.message
  86.             )
  87.         self.dialog.set_icon(self.icon.get_pixbuf())
  88.         self.dialog.set_title(self.title)
  89.         self.dialog.format_secondary_text(self.status)
  90.         self.dialog.run()
  91.         if self.dialog:
  92.             self.dialog.destroy()
  93.             self.dialog = None
  94.    
  95.     def quit(self, widget):
  96.         if self.dialog:
  97.             self.dialog.destroy()
  98.         self.icon.set_visible(False)
  99.         gtk.main_quit()
  100.    
  101.     def check_raid(self, widget=None):
  102.         proc = subprocess.Popen(['cat', '/proc/mdstat'], stdout=subprocess.PIPE)
  103.         self.status = proc.communicate()[0]
  104.         if self.status.find('raid') == -1 or self.pattern.search(self.status):
  105.             if not self.status:
  106.                 self.status = "Could not execute 'cat /proc/mdstat'"
  107.             self.title = 'RAID Monitor - Error'
  108.             self.icon.set_from_file(self.path+'/err.png')
  109.             self.icon.set_blinking(True)
  110.             gtk.gdk.beep()
  111.         else:
  112.             self.title = 'RAID Monitor - Running'
  113.             self.icon.set_from_file(self.path+'/ok.png')
  114.             self.icon.set_blinking(False)
  115.             gobject.timeout_add(self.period*1000, self.check_raid)
  116.        
  117.         self.icon.set_tooltip(self.title)
  118.         self.message = 'Last updated: ' + datetime.now().ctime()
  119.        
  120.         if self.dialog:
  121.             self.show_dialog()
  122.  
  123.  
  124. if __name__ == "__main__":
  125.     rm = RaidMonitor()
  126.     gtk.main()

comorl? XD

El RAID por soft no es tan efectivo como el hecho por hard.   Tienden a fallar mas y no tenemos diversidad de opciones a elegir.

Por ejemplo, podemos optar por las dos mejores opciones en RAID que son RAID 5 o RAID 10.

No fallan tanto y tenemos una mayor performance a nuestro alcance.

Claro, hay que mencionar ademas que ninguna configuracion es 100% segura.  Cualquiera puede generarnos una perdida de acceso a los datos o lo peor: perdida total de la info.

Pero si se quiere recuperar la informacion inaccesible, existe un ultimo recurso.  La contratacion de los servicios de recuperacion de una empresa especializada. Las mas conocidas: ONRETRIEVAL, ONTRACK, RECOVERY LABS, entre otras.

Se supone que no son servicios dentro de lo economico pero si tienen un alto porcentaje de exito: 96% segun comenta alguna de esas empresas.

Pero si los datos lo valen, ok.

 

Saludos.

Añadir nuevo comentario