mar 18 2011

Obtenir une vision synthétique du stockage sous Linux avec une baie XP (HP).

Tag: ScriptsUggla @ 15 h 11 min

Un script perl qui combine les sorties de différents outils (xpinfo, multipath, mount) pour produire une vue complète du stockage disque.

Ce script fonctionne sur une machine Linux (RHEL5.5) avec une baie XP (HP).

Note : Ce script fonctionne mais peut probablement être grandement amélioré


#!/usr/bin/perl
# --------------------------------------------------------------------------------
# Script :   map.pl
# Revision : 1.1
# Author :   Rene Ribaud
# Description :
# --------------------------------------------------------------------------------
use strict;
use warnings;
#use diagnostics;   # Only use it for debugging purpose.

# --------------------------------------------------------------------------------
# Global variables
# --------------------------------------------------------------------------------
# Time
my ($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst);
my $timestamp;

# Data
# Define a full structure
#my %mpaths =(
#        name =>{
#               size => undef,
#               uuid => undef,
#               dm => undef,
#               fs => undef,
#               disk =>         {
#                               diskname =>     {
#                                               port => undef,
#                                               lunid => undef,
#                                               sfnum => undef,
#                                               ldev => undef,
#                                               type => undef,
#                                               xp => undef,
#                                               },
#                               },
#               },
#        );

my %mpaths;

# --------------------------------------------------------------------------------
# Functions
# --------------------------------------------------------------------------------

# --------------------------------------------------------------------------------
# Main
# --------------------------------------------------------------------------------

# Get variable from command line

# Get timestamp
($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst)=localtime();
$timestamp=sprintf("%4d%02d%02d-%02d:%02d:%02d",($year+1900),($month+1),$day,$hour,$min,$sec);

# Slurp tools data into arrays in memory
my @xpinfo=`xpinfo -i`;
my @multipath=`multipath -ll`;
my @mounts=`mount`;

for (my $line=0; $line<scalar(@multipath); $line++){
if ($multipath[$line] =~ /^mpath/){   # Check & parse line : mpath23 (360060e8015276a000001276a0000d0fc) dm-8 HP,OPEN-V
        (my $mpath, my $uuid, my $dm, my $type) = split ('\s+',$multipath[$line]);
        $uuid=~s/\(//g;
        $uuid=~s/\)//g;
        $mpaths{$mpath}->{"dm"}=$dm;
        $mpaths{$mpath}->{"uuid"}=$uuid;
        $mpaths{$mpath}->{"type"}=$type;
        # Crosscheck into mount to get the fs name
        # /dev/mapper/mpath14 on /oradata/crs/voting1 type ocfs2 (rw,_netdev,datavolume,nointr,heartbeat=local)
        my $fs;
        my @mount = grep(/$mpath\s/,@mounts);
        if (scalar(@mount==0)){
                $fs="N/A";
                }
                else
                {
                (undef,undef,$fs) = split('\s+',$mount[0]);
                }
        $mpaths{$mpath}->{"fs"}=$fs;

        # Next line to parse : [size=36G][features=1 queue_if_no_path][hwhandler=0][rw]
        $line++;
        if ($multipath[$line] =~ /^\[size=/){
                (my $size) = $multipath[$line] =~ /\[size=([0-9]+\w)/;
                $mpaths{$mpath}->{"size"}=$size;

                # Next line to parse : \_ round-robin 0 [prio=0][active]
                $line++;
                if ($multipath[$line] =~ /^\\_/){
                        # Next line to parse :  \_ 0:0:4:13 sdad 65:208 [active][ready]
                        $line++;
                        if ($multipath[$line] =~ /^ \\_/){
                                my $no_more_device=0;
                                do{
                                        (undef,undef,undef,my $disk, my $sf, undef) = split ('\s+',$multipath[$line]);
                                        $mpaths{$mpath}->{"disk"}->{$disk}->{"sfnum"}=$sf;
                                        # Crosscheck into xpinfo
                                        my @device = grep(/$disk\s/,@xpinfo);

                                        # Handle the case where device was not unmapped correctly
                                        # Unmapped from XP and not remoove from multipath.
                                        if (scalar(@device) == 0){
                                                $mpaths{$mpath}->{"disk"}->{$disk}->{"port"} = "Not found";
                                                $mpaths{$mpath}->{"disk"}->{$disk}->{"lunid"}= "N/A";
                                                $mpaths{$mpath}->{"disk"}->{$disk}->{"ldev"}= "N/A";
                                                $mpaths{$mpath}->{"disk"}->{$disk}->{"type"}= "N/A";
                                                $mpaths{$mpath}->{"disk"}->{$disk}->{"xp"}= "N/A";
                                        }
                                        else{
                                                #/dev/sdu                     76  04  02  CL2H  d0:f1  OPEN-V           00075626
                                                (undef,undef,undef, my $lunid, my $port, my $ldev, my $type, my $xp) = split('\s+',$device[0]);
                                                $mpaths{$mpath}->{"disk"}->{$disk}->{"port"}=$port;
                                                $mpaths{$mpath}->{"disk"}->{$disk}->{"lunid"}=$lunid;
                                                $mpaths{$mpath}->{"disk"}->{$disk}->{"ldev"}=$ldev;
                                                $mpaths{$mpath}->{"disk"}->{$disk}->{"type"}=$type;
                                                $mpaths{$mpath}->{"disk"}->{$disk}->{"xp"}=$xp;
                                        }
                                        if ((defined($multipath[$line+1])) && ($multipath[$line+1] =~ /^ \\_/)){
                                                $line++;
                                                }
                                                else {
                                                $no_more_device=1;
                                                }
                                        } while ($no_more_device==0);
                                }
                        }
                }
        }
}

# Print mapping
printf("%-34s %-9s %-7s %-6s %-6s %-8s %-6s %-6s %s\n","UUID","xp","type","size","dm","mapth","lunid","ldev","fs");
foreach my $mpath (sort(keys(%mpaths))){
        my @first_disk=keys(%{$mpaths{$mpath}->{"disk"}});
        # Check to report disk not unmapped correctly
        printf("%-34s %-9s %-7s %-6s %-6s %-8s %-6s %-6s %s\n"  ,$mpaths{$mpath}->{"uuid"}
                                                                ,$mpaths{$mpath}->{"disk"}->{$first_disk[0]}->{"xp"}
                                                                ,$mpaths{$mpath}->{"disk"}->{$first_disk[0]}->{"type"}
                                                                ,$mpaths{$mpath}->{"size"}
                                                                ,$mpaths{$mpath}->{"dm"}
                                                                ,$mpath
                                                                ,$mpaths{$mpath}->{"disk"}->{$first_disk[0]}->{"lunid"}
                                                                ,$mpaths{$mpath}->{"disk"}->{$first_disk[0]}->{"ldev"}
                                                                ,$mpaths{$mpath}->{"fs"}
                                                                );
        my $notfoundcount=0;
        foreach my $disk (keys(%{$mpaths{$mpath}->{"disk"}})){
                printf("%-6s %-8s %-4s\n",$disk,$mpaths{$mpath}->{"disk"}->{$disk}->{"sfnum"},$mpaths{$mpath}->{"disk"}->{$disk}->{"port"});

                if ($mpaths{$mpath}->{"disk"}->{$disk}->{"port"} eq "Not found"){
                        $notfoundcount++;
                        }

                if ($notfoundcount == scalar(keys(%{$mpaths{$mpath}->{"disk"}}))){
                        printf("This device was found in multipath but not reported by xpinfo.\n");
                        printf("Multipath device was probably not flushed after unmapping the device.\n");
                        printf("Try to run multipath -f %s.\n",$mpath);
                        }

                }

print "\n";
}

Output result :

UUID                               xp        type    size   dm     mapth    lunid  ldev   fs
360060e8015276a000001276a0000d0f1  00075626  OPEN-V  201M   dm-13  mpath14  02     d0:f1  /oradata/crs/voting1
sdai   66:32    CL1F
sdc    8:32     CL2F
sday   67:32    CL1H
sds    65:32    CL2H

360060e8015276a000001276a0000d0f2  00075626  OPEN-V  201M   dm-14  mpath15  03     d0:f2  /oradata/crs/voting2
sdd    8:48     CL2F
sdaz   67:48    CL1H
sdaj   66:48    CL1F
sdt    65:48    CL2H

360060e8015276a000001276a0000d0f3  00075626  OPEN-V  201M   dm-15  mpath16  04     d0:f3  /oradata/crs/voting3
sde    8:64     CL2F
sdu    65:64    CL2H
sdba   67:64    CL1H
sdak   66:64    CL1F

360060e8015276a000001276a0000d0f4  00075626  OPEN-V  201M   dm-16  mpath17  05     d0:f4  /oradata/GFSTEUR1/pfile
sdal   66:80    CL1F
sdv    65:80    CL2H
sdbb   67:80    CL1H
sdf    8:80     CL2F

360060e8015276a000001276a0000d0f5  00075626  OPEN-V  36G    dm-17  mpath18  06     d0:f5  /oradata/GFSTEUR1/undo
sdg    8:96     CL2F
sdbc   67:96    CL1H
sdw    65:96    CL2H
sdam   66:96    CL1F

360060e8015276a000001276a0000d0f8  00075626  OPEN-V  99G    dm-18  mpath19  09     d0:f8  /oradata/RMAN/rman01
sdh    8:112    CL2F
sdan   66:112   CL1F
sdbd   67:112   CL1H
sdx    65:112   CL2H
...


fév 21 2011

Script mapping EVA

Tag: ScriptsUggla @ 15 h 07 min

Un petit script perl pour trouver les correspondances entre les luns UUIDs, special files, major numbers, minor numbers.

Dépendances :

evainfo –> outil client pour extraire les informations des EVA.

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my @evainfo=`evainfo -a`;
my @ioscan=`ioscan -m dsf`;
my %devmap;
my %devmap2;
my %lunmap;
my %sf;

my $dsf;
my $olddsf;
my $legacy;

# Create map : "legacy device" = "dsf device"
foreach(@ioscan){
        if ( /\/dev/ ){
                ($dsf, $legacy)=split(/\s+/,$_);
                if ( $dsf eq "" ){
                        $dsf=$olddsf;
                }
                $devmap{$legacy}=$dsf;
        $olddsf=$dsf;
        }
}

# Create map : "wwnn id" = "legacy device"
foreach(@evainfo){

        if ( /\/dev/){
                (my $legacy, undef, my $wwnn, my $size, my $ctrl)=split(/\s+/,$_);
                $lunmap{$wwnn}=$legacy;
        }
}

# Create map : "dsf device" = "major and minor"
%devmap2=%devmap; # values() modify the hash, so copy to a new one to avoid %devmap to be modified
foreach(values(%devmap2)){
        open (SHELLCMD,"ll $_ |");
                while (<SHELLCMD>){
                        (undef,undef,undef,undef,my $major, my $minor,undef,undef,undef,my $dev)=split(/\s+/,$_);
                        $sf{$dev}->{"major"}=$major;
                        $sf{$dev}->{"minor"}=$minor;
                }
        close (SHELLCMD)
}

# Debug purpose
#print Dumper(\%devmap);
#print Dumper(\%lunmap);
#print Dumper(\%sf);

# Print output
foreach(sort(keys(%lunmap))){
        my $legacy=$lunmap{$_};
        printf("%s %s %s %s\n",$_ ,$devmap{$legacy}, $sf{$devmap{$legacy}}->{"major"}, $sf{$devmap{$legacy}}->{"minor"});
}

Exemple d'usage :
root@hx000140: /root/home/root # perl eva_mapping.pl
6001-4380-05DE-C738-0000-6000-08B4-0000 /dev/oracle/asm_eva1 13 0x000019
6001-4380-05DE-C738-0000-6000-08B8-0000 /dev/oracle/asm_eva2 13 0x00001a
6001-4380-05DE-C738-0000-6000-08BC-0000 /dev/oracle/asm_eva3 13 0x00001b
6001-4380-05DE-C738-0000-6000-08C0-0000 /dev/oracle/asm_eva4 13 0x00001c
6001-4380-05DE-C738-0000-6000-08C4-0000 /dev/oracle.bak/asm_eva5 13 0x00001d
6001-4380-05DE-C738-0000-6000-08C8-0000 /dev/oracle.bak/asm_eva6 13 0x00001e
6001-4380-05DE-C738-0000-6000-08CC-0000 /dev/oracle.bak/asm_eva7 13 0x00001f
6001-4380-05DE-C738-0000-6000-08D0-0000 /dev/oracle.bak/asm_eva8 13 0x000020