Archivo del blog

miércoles, 1 de marzo de 2017

Raid 1 por software en linux


Raid 1 por software en linux

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

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:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
#
#       raidmon.py - mdadm RAID-Monitor
#      
#       Copyright 2008 Thimo Kraemer <<a href="mailto:thimo.kraemer@joonis.de">thimo.kraemer@joonis.de</a>>
#      
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#      
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#      
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.
 
 
from datetime import datetime
import sys
import os
import subprocess
import pygtk
pygtk.require('2.0')
import gtk
import gobject
import re
 
 
class RaidMonitor:
   
    def __init__(self):
        self.period = 300
        self.path = os.path.dirname(sys.argv[0])
        self.pattern = re.compile('\[[U_]*_[U_]*\]')
        self.title = 'RAID Monitor'
        self.message = 'Initializing...'
        self.status = 'RAID status not available'
       
        self.dialog = None
        self.icon = gtk.StatusIcon()
 
        menu = gtk.Menu()
        item = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
        item.connect('activate', self.show_dialog)
        menu.append(item)
        item = gtk.ImageMenuItem(gtk.STOCK_REFRESH)
        item.connect('activate', self.check_raid)
        menu.append(item)
        item = gtk.SeparatorMenuItem()
        menu.append(item)
        item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
        item.connect('activate', self.quit)
        menu.append(item)
       
        self.icon.connect('activate', self.show_dialog)
        self.icon.connect('popup-menu', self.popup_menu, menu)
        self.check_raid()
        self.icon.set_visible(True)
 
    def popup_menu(self, widget, button, time, menu=None):
        if button == 3:
            if menu:
                menu.show_all()
                menu.popup(None, None, None, 3, time)
 
    def show_dialog(self, widget=None):
        if self.dialog:
            self.dialog.destroy()
       
        if self.icon.get_blinking():
            dlg_type = gtk.MESSAGE_WARNING
        else:
            dlg_type = gtk.MESSAGE_INFO
       
        self.dialog = gtk.MessageDialog(
            parent=None,
            type=dlg_type,
            buttons=gtk.BUTTONS_CLOSE,
            message_format=self.message
            )
        self.dialog.set_icon(self.icon.get_pixbuf())
        self.dialog.set_title(self.title)
        self.dialog.format_secondary_text(self.status)
        self.dialog.run()
        if self.dialog:
            self.dialog.destroy()
            self.dialog = None
   
    def quit(self, widget):
        if self.dialog:
            self.dialog.destroy()
        self.icon.set_visible(False)
        gtk.main_quit()
   
    def check_raid(self, widget=None):
        proc = subprocess.Popen(['cat', '/proc/mdstat'], stdout=subprocess.PIPE)
        self.status = proc.communicate()[0]
        if self.status.find('raid') == -1 or self.pattern.search(self.status):
            if not self.status:
                self.status = "Could not execute 'cat /proc/mdstat'"
            self.title = 'RAID Monitor - Error'
            self.icon.set_from_file(self.path+'/err.png')
            self.icon.set_blinking(True)
            gtk.gdk.beep()
        else:
            self.title = 'RAID Monitor - Running'
            self.icon.set_from_file(self.path+'/ok.png')
            self.icon.set_blinking(False)
            gobject.timeout_add(self.period*1000, self.check_raid)
       
        self.icon.set_tooltip(self.title)
        self.message = 'Last updated: ' + datetime.now().ctime()
       
        if self.dialog:
            self.show_dialog()
 
 
if __name__ == "__main__":
    rm = RaidMonitor()
    gtk.main()

No hay comentarios:

Publicar un comentario