Vic/Solaris 10/scripts/set scsi retry.pl

From Summerseas

Jump to: navigation, search

Script to tune ssd/sd retry_count on a Running Kernel

  • Note - This script may very well be dangerous. I wouldn't advise running this on a production system.
  • This script will accept a '-c' command line option and set the retry count to whatever you provide. It expects decimal and converts to hex. The script automatically detects SPARC and x86 architecture and tunes the appropriate driver module. This script does NOT require kadb and I haven't tested it with kadb loaded. The script makes 2 calls to the modular debugger, mdb; 1 to get a list of addresses for the retry count for each lun and a second call to modify each of those addresses with the desired value.
  • I have tested on Solaris 10 U4 x86 and sparc. There is no need for this script with Solaris releases prior to Sol10 because the scsi retry count was tunable via the system file.


#!/usr/bin/perl -w

use strict;
use Getopt::Std;


my($SD,$MDB,%COMMAND_LINE_OPTIONS,$RETRY_COUNT,$DRIVER,$CMD,$ADDR,@ADDR,@TARGETS,$child);


&_get_arch;
$MDB='/bin/mdb';

$RETRY_COUNT = "5";

# Check for and process the command line options.
%COMMAND_LINE_OPTIONS=();
getopts("c:",\%COMMAND_LINE_OPTIONS);


$RETRY_COUNT = "$COMMAND_LINE_OPTIONS{c}" if ( defined $COMMAND_LINE_OPTIONS{c});
# Convert to hex
$RETRY_COUNT = sprintf("%x", $RETRY_COUNT);

die "\n\n$MDB does not exis on this host. Exiting...\n\n" 
		if ( ! -e "$MDB");


print "DRIVER $DRIVER\nRETRY_COUNT $RETRY_COUNT\n\n";


$CMD = "/usr/bin/echo \"$SD |  ::print -at struct sd_lun un_retry_count\" | $MDB -k";

print "Getting sd_lun retry_count addresses...\n";
open(MODR,"$CMD|") or die "\nFailed opening $CMD ($!)\n";

while ($ADDR = <MODR>) {
	chomp($ADDR);
	@ADDR = split(/\s+/,$ADDR);
	push(@TARGETS,"$ADDR[0]");
}

print "Spawning a process modify the retry count for all luns. Starting 10 second timer...\n";
unless ( $child = fork ) {
			die "Cannot spawn process ($!)" unless defined $child;
	open(MODW,"|$MDB -kw")  or die "\nFailed opening $MDB ($!)\n";
	foreach $ADDR (@TARGETS) {
		print MODW "$ADDR/W $RETRY_COUNT\n";
	}
	exit; # Exit child proc
}

sleep(10);
print "\n\nComplete...\n\n";


exit 0;


sub _get_arch {
	 my($arch);
	 $arch = `/usr/bin/uname -p`;
	 if ($arch =~ /sparc/) {
		$SD = '*ssd_state::walk softstate';
		$DRIVER = 'ssd';
	 } else {
		$SD = '*sd_state::walk softstate';
		$DRIVER = 'sd';
	 }
	 return(0);
}



Personal tools