systemadmin.es » SAN » Como buscar las LUNs nuevas de una HBA QLogic

Como buscar las LUNs nuevas de una HBA QLogic

En entornos SAN (Storage Area Network) resulta fácil añadir y eliminar discos de un host en concreto: Desde la Command View EVA (para la SAN de HP Enterprise Virtual Array) o mediante el Navisphere (para las cabinas CLARiiON de EMC) se puede presentar un disco a un hosts con la misma facilidad que se le puede quitar. Para el caso de los adaptadores qlogic (muy comunes) veremos como indicar al sistema que busque los nuevos discos añadidos al host sin necesidad de reiniciar la máquina para que se detecten.

Primero de todo debemos buscar todas las HBA (Host Bus Adapter) del sistema. Como siempre, lo podemos hacer mediante una búsqueda en el sistema de ficheros /proc:

find /proc/scsi | grep /[0-9/].* | grep qla | sort -u

A continuación para cada HBA mandamos la señal “scsi-qlascan” (rescan) mediante un echo. Por ejemplo:

echo "scsi-qlascan" > /proc/scsi/qla2xxx/3

Para mandar la señal a todos los dispositivos (en el caso de tener múltiples HBAs conectadas al equipo) lo haríamos mediante un for:

for disp in $(find /proc/scsi | grep /[0-9/].* | grep qla | sort -u);
do
        echo "scsi-qlascan" > $disp
done

El número de dispositivo lo necesitaremos más adelante, por lo que mediante basename podemos guardarlo. Por ejemplo:

for disp in $(find /proc/scsi | grep /[0-9/].* | grep qla | sort -u);
do
        echo $(basename $disp);
done

Esperamos unos segunos para dar tiempo a completar el scan a la HBA y podemos continuar buscando primero los targets mediante un cat al fichero que representa el dispositivo usando un grep para encontrar los targets:

# cat /proc/scsi/qla2xxx/3 | grep target
scsi-qla0-target-0=5009011030dead09;
scsi-qla0-target-1=5009011830dead09;

Nos quedamos con el número de target, para más adelante, mediante el siguiente comando:

cat /proc/scsi/qla2xxx/3 | grep target | grep -v adapter | cut -d '-' -f 4 | sed 's/=.*//ig'

A continuación para cada target que exista buscamos las LUNs. Para ello si hacemos un cat al fichero que representa el dispositivo, al final de todo, veremos la información referente a las LUNs, similar a:

SCSI LUN Information:
(Id:Lun)  * - indicates lun is not registered witqh the OS.
( 0: 0): Total reqs 126738651, Pending reqs 0, flags 0x0, Dflags 0x0, 0:0:81 00
( 0: 1): Total reqs 285826, Pending reqs 0, flags 0x0, Dflags 0x0, 0:0:81 00
( 1: 0): Total reqs 242711, Pending reqs 0, flags 0x0, Dflags 0x0, 0:0:82 00
( 1: 1): Total reqs 1262471, Pending reqs 0, flags 0x0, Dflags 0x0, 0:0:82 00

Para obtener el listado de LUNs, en este caso es el tercer elemento, según el driver puede cambiar por lo que hace falta ver el caso. Para simplificar esto, también es possible hacerlo en todas las LUNs possibles mediante un seq de 0 a 32:

for lunid in $(seq 0 32);
do
        echo $lunid
done

Mediante este for mandamos el comando add-single-device al fichero /proc/scsi/scsi indicando el identificador de dispositivo, target y LUN:

echo "scsi add-single-device <DISPOSITIVO> 0 <TARGET> <LUNID>" > /proc/scsi/scsi

Todos estos valores los hemos sacado anteriormente, por lo que podemos hacer un script que haga lo siguiente:

for disp in $(find /proc/scsi | grep /[0-9/].* | grep qla | sort -u);
do
        dispid=$(basename $disp)
        for target in $(cat $disp | grep target | grep -v adapter | cut -d '-' -f 4 | sed 's/=.*//ig');
        do
                for lunid in $(seq 0 32);
                do
                        echo "scsi add-single-device $dispid 0 $target $lunid" > /proc/scsi/scsi
                done
        done

done

Estos comandos deberiamos evitar ejecutarlos en la LUN que contiene la partición raiz del sistema. Mediante el siguiente comando podemos obtener el disco que contiene la partición:

# mount | grep "on / " | awk '{print $1}' | sed 's/\/dev\///g' | sed 's/[0-9/]//g'

A continuación hacemos un ls -l al sistema de ficheros /sys para obtener el identificador. Por ejemplo, en este caso:

$ ls -l /sys/block/sdb/
total 0
-r--r--r--  1 root root 4096 Dec 16 09:07 dev
lrwxrwxrwx  1 root root    0 Dec 16 09:07 device -> ../../devices/pci0000:00/0000:00:03.0/0000:01:00.0/0000:02:0e.0/host2/target2:2:0/2:2:0:0
drwxr-xr-x  3 root root    0 Nov 19 09:19 queue
-r--r--r--  1 root root 4096 Dec 16 09:07 range
-r--r--r--  1 root root 4096 Dec 16 09:07 removable
drwxr-xr-x  2 root root    0 Dec 10 15:46 sdb1
drwxr-xr-x  2 root root    0 Dec 10 15:46 sdb2
drwxr-xr-x  2 root root    0 Dec 10 15:46 sdb3
drwxr-xr-x  2 root root    0 Dec 10 15:46 sdb4
drwxr-xr-x  2 root root    0 Dec 10 15:46 sdb5
drwxr-xr-x  2 root root    0 Dec 10 15:46 sdb6
drwxr-xr-x  2 root root    0 Dec 10 15:46 sdb7
-r--r--r--  1 root root 4096 Dec 16 09:07 size
-r--r--r--  1 root root 4096 Dec 16 09:07 stat

En el enlace de device nos indica el dispositivo, bus ,target y LUN, por lo que para obtenerlo hacemos:

# basename $(ls -l /sys/block/sdb/ | grep device | awk '{ print $NF }') | sed 's/:/ /g'
2 2 0 0

Estos cuatro identificadores los comparamos siempre antes de hacer un comando scsi sobre una LUN. Si coinciden, se trata del dispositivo raiz, por lo que se debería evitar mandar el comando.

En este caso, los identificadores 2 2 0 0 corresponden a un dispositivo local, ya que el segundo valor (identifica el bus) debería ser un 0 si se tratase de un disco de una SAN usando una HBA QLogic.

Relacionados

Imprimir Imprimir

Deja un comentario:

XHTML - Tags permitidos:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>