Monday, December 29, 2014

Persistantly Bind Tape Devices in Solaris via Perl

The following script will look for fiber channel tape devices and then configure thedevlinks.tab file with the appropriate information so the tape drives will persistently bind to the same device across reboots on a Solaris server.   This script was tested on Solaris 10.

#!/usr/bin/perl
use strict;
my($junk,$path,$devices,$dev,$file);
my(@devices,@file);
my $date = `date +%m%d%Y`;
$file = `/usr/bin/cp /etc/devlink.tab /etc/devlink.tab.$date`;
@file = `cat /etc/devlink.tab`;
@file = grep !/type=ddi_byte:tape/, @file;
open (FILE,">/etc/devlink.tab.new");
print FILE @file;
close (FILE);
 
@devices = `ls -l /dev/rmt/*cbn|awk {'print \$9 \$11'}`;
open (FILE,">>/etc/devlink.tab.new");
foreach $devices (@devices) {
        chomp($devices);
        ($dev,$path) = split(/\.\.\/\.\./,$devices);
        $dev =~ s/cbn//g;
        $dev =~ s/\/dev\/rmt\///g;
        $path =~ s/:cbn//g;
        ($junk,$path) = split(/st\@/,$path);
        print FILE "type=ddi_byte:tape;addr=$path;\trmt/$dev\\M0\n";
}
close (FILE);
$file = `/usr/bin/mv /etc/devlink.tab.new /etc/devlink.tab`;
exit;

Ceph Repair One Liner

The following one liner will look for inconsistent page groups in a Ceph page group dump and repair them.    Nice quick way to fix-up inconsistencies!

ceph pg dump | grep -i incons | cut -f 1 | while read i; do ceph pg repair ${i} ; done

Solaris LUN Online Report

If you are using fiber channel storage with Solaris in a multipath configuration, sometimes before fabric maintenance or array maintenance you might want to check and confirm the status of all the paths on the Solaris client.   The following script utilizing luxadm will report on the status of each path for a fiber channel device.

#!/bin/perl
@luns = `/usr/sbin/luxadm probe | grep Logical | sed -e 's/.*\://g'|grep rdsk`;
foreach $lun (@luns) {
        chomp($lun);
        $lun2 = $lun;
        $lun2 =~ s/\/dev\/rdsk\///g;
        print "Disk:$lun2\t";
        @luxadm = `/usr/sbin/luxadm display $lun`;
        $pathcount = 0;
        foreach $luxadm (@luxadm) {
                chomp($luxadm);
                if ($luxadm =~ /State/) {
                        $luxadm =~ s/State//g;
                        $luxadm =~ s/^\s+//;
                        print "Path$pathcount:$luxadm\t";
                        $pathcount++;
                }
        }
        print "\n";
}

The output from the script will look something like the output below:

#perl pathfinder.pl
Disk:c6t60060E80054337000000433700000526d0s2    Path0:ONLINE    Path1:ONLINE    Path2:ONLINE    Path3:ONLINE
Disk:c6t60060E80054337000000433700000527d0s2    Path0:ONLINE    Path1:ONLINE    Path2:ONLINE    Path3:ONLINE
Disk:c6t60060E80054337000000433700000301d0s2    Path0:ONLINE    Path1:ONLINE    Path2:ONLINE    Path3:ONLINE
Disk:c6t60060E80054337000000433700000300d0s2    Path0:ONLINE    Path1:ONLINE    Path2:ONLINE    Path3:ONLINE
Disk:c6t60060E80054337000000433700000278d0s2    Path0:ONLINE    Path1:ONLINE    Path2:ONLINE    Path3:ONLINE
Disk:c6t60060E80054337000000433700000277d0s2    Path0:ONLINE    Path1:ONLINE    Path2:ONLINE    Path3:ONLINE
Disk:c6t60060E80054337000000433700000275d0s2    Path0:ONLINE    Path1:ONLINE    Path2:ONLINE    Path3:ONLINE
#

Cleanup Shared Memory Segments Solaris

If you have ever used an application in Solaris that uses shared memory and that application has a tendency to not cleanup those memory segments properly on shutdown (SAP comes to mind)  then this little Perl script is what you have been waiting for.

All this script does is take certain field output from the ipcs command and then iterate through it to determine if the memory is still actively in use by a process or if it it can safely be purged.   I recommended testing this out with the $memclean line commented out to gain a good understanding before you remove the comment and allow the cleanup (#$memclean = `ipcrm -m $shmem`;).  This script was tested on Solaris 10.


#!/usr/bin/perl
@sms = `ipcs -pm|grep "^m"|awk {'print \$2":"\$7":"\$8'}`;
foreach $sms (@sms) {
        chomp($sms);
       ($shmem,$cpid,$lpid) = split(/:/,$sms);
        $cpids=` ps -ef|grep $cpid|grep -v grep >/dev/null 2>&1;echo \$?`;
        $lpids=` ps -ef|grep $lpid|grep -v grep >/dev/null 2>&1;echo \$?`;
        chomp($cpids,$lpids);
        if (($cpids eq "1") && ($lpids eq "1")) {
                $message = "Memory can be reclaimed";
                #$memclean = `ipcrm -m $shmem`;
        } else {
                $message = "Memory active";
        }
        print "$shmem - $cpid - $lpid - $cpids - $lpids - $message\n";
}

The output from the script will look similar to the following:

# perl mem_clean.pl
587203562 - 10885 - 17891 - 0 - 0 - Memory active
922746991 - 9728 - 10885 - 0 - 0 - Memory active
150995435 - 9728 - 10885 - 0 - 0 - Memory active
150995432 - 9728 - 17891 - 0 - 0 - Memory active
150995398 - 17421 - 17891 - 1 - 0 - Memory active
150995396 - 13421 - 13891 - 1 - 1 - Memory can be reclaimed
150995387 - 9728 - 10885 - 0 - 0 - Memory active
150995382 - 9728 - 10885 - 0 - 0 - Memory active
150995380 - 9728 - 10885 - 0 - 0 - Memory active
150995379 - 9728 - 10885 - 0 - 0 - Memory active
150995377 - 9728 - 17891 - 0 - 0 - Memory active
150995374 - 9728 - 17891 - 0 - 0 - Memory active
150995371 - 9727 - 10886 - 1 - 0 - Memory active
117440821 - 9728 - 10885 - 0 - 0 - Memory active
117440819 - 9728 - 10885 - 0 - 0 - Memory active
#