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 the devlinks.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