Blog O' Matty


Resetting Emulex HBAs

This article was posted by Matty on 2005-09-08 10:50:00 -0400 -0400

On rare ocassions it may be necessary to reset an Emulex HBA to re-establish connectivity to fabric services, and to find new targets and LUNs that have been added to the fabric. This can be accomplished with a system reboot ( which takes a good deal of time, and is not an option when availability is the primary service driver), or with the Emeulex hbacmd(1m) or lputil(1m) utilities. To reset an adaptor with hbacmd(1m), the WWPN is passed as an option:

$ /usr/sbin/hbanyware/hbacmd Reset 10:00:00:00:c9:49:2c:b4

Reset HBA 10:00:00:00:c9:49:2c:b4

To reset an HBA through the lputil(1m) text-base menu, you can select option 4 from the main menu, and pick the adaptor to reset:

$ /usr/sbin/lputil/lputil

LightPulse Common Utility for Solaris/SPARC. Version 2.0a5 (4/7/2005).
Copyright (c) 2005, Emulex Corporation

Emulex Fibre Channel Host Adapters Detected: 3
Host Adapter 0 (lpfc3) is an LP9802 (Ready Mode)
Host Adapter 1 (lpfc4) is an LP9802 (Ready Mode)
Host Adapter 2 (lpfc5) is an LP9802 (Ready Mode)

MAIN MENU

1. List Adapters
2. Adapter Information
3. Firmware Maintenance
4. Reset Adapter
5. Persistent Bindings

0. Exit

Enter choice => **4**
0. lpfc3
1. lpfc4
2. lpfc5

Select an adapter => **0**

MAIN MENU

1. List Adapters
2. Adapter Information
3. Firmware Maintenance
4. Reset Adapter
5. Persistent Bindings

0. Exit

Enter choice => **0**

Once the adaptor is reset, you should see a message similar to the following in the system logfile:

Sep 7 15:23:49 tiger lpfc: [ID 728700 kern.warning] WARNING: lpfc3:1303:LKe:Link Up Event x1 received Data: x1 x0 x8 x14

Emulex makes a killer HBA, and provides several awesome software utilities to manage host side SAN connectivity.

Debugging Perl code

This article was posted by Matty on 2005-09-07 23:00:00 -0400 -0400

While reading through the Perl documentation, I came across a good overview of the Perl debugger. This is a nifty utility would have been helpful while I was writing ldap-stats.pl. If you want to debug a specific Perl script, you can add the “-d” option to the perl interpreter:

$ head -1 ldap-stats.pl

#!/usr/bin/perl -w -d

Once this option is added, program execution will transfer to the debugger, allowing you to set breakpoints, and watch the execution of your program:

$ ldap-stats.pl

Loading DB routines from perl5db.pl version 1.19
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(./ldap-stats.pl-2.2.pl:195):
DB<1>

If you type “h” in the debugger’s help screen, you will get the following help screen:

DB<1> h
List/search source lines: Control script execution:
l [ln|sub] List source code T Stack trace
- or . List previous/current line s [expr] Single step [in expr]
v [line] View around line n [expr] Next, steps over subs
f filename View source in file Repeat last n or s
/pattern/ ?patt? Search forw/backw r Return from subroutine
M Show module versions c [ln|sub] Continue until position
Debugger controls: L List break/watch/actions
o [...] Set debugger options t [expr] Toggle trace [trace expr]
< [<]|{[{]|>[>] [cmd] Do pre/post-prompt b [ln|event|sub] [cnd] Set breakpoint
! [N|pat] Redo a previous command B ln|* Delete a/all breakpoints
H [-num] Display last num commands a [ln] cmd Do cmd before line
= [a val] Define/list an alias A ln|* Delete a/all actions
h [db_cmd] Get help on command w expr Add a watch expression
h h Complete help page W expr|* Delete a/all watch exprs
|[|]db_cmd Send output to pager ![!] syscmd Run cmd in a subprocess
q or ^D Quit R Attempt a restart
Data Examination: expr Execute perl code, also see: s,n,t expr
x|m expr Evals expr in list context, dumps the result or lists methods.
p expr Print expression (uses script's current package).
S [[!]pat] List subroutine names [not] matching pattern
V [Pk [Vars]] List Variables in Package. Vars can be ~pattern or !pattern.
X [Vars] Same as "V current_package [Vars]".
y [n [Vars]] List lexicals in higher scope . Vars same as V.
For more help, type h cmd_letter, or run man perldebug for all docs.
DB<1>

For navigating through code, the “T” (stack trace), “s” (single step), “n” (next step), “r” (return from subroutine), “c” (continue until next position) and “b” (set breakpoint) options will prove super useful. I think the “M” (print modules and versions) is my favorite option:

DB<1> M
'AutoLoader.pm' => '5.59 from /usr/local/lib/perl5/5.8.0/AutoLoader.pm'
'Carp.pm' => '1.01 from /usr/local/lib/perl5/5.8.0/Carp.pm'
'Carp/Heavy.pm' => '/usr/local/lib/perl5/5.8.0/Carp/Heavy.pm'
'Config.pm' => '/usr/local/lib/perl5/5.8.0/sun4-solaris/Config.pm'
'DynaLoader.pm' => '1.04 from /usr/local/lib/perl5/5.8.0/sun4-solaris/DynaLoader.pm'
'Exporter.pm' => '5.566 from /usr/local/lib/perl5/5.8.0/Exporter.pm'
'Getopt/Std.pm' => '1.03 from /usr/local/lib/perl5/5.8.0/Getopt/Std.pm'
'SelfLoader.pm' => '1.0903 from /usr/local/lib/perl5/5.8.0/SelfLoader.pm'
'Term/Cap.pm' => '1.07 from /usr/local/lib/perl5/5.8.0/Term/Cap.pm'
'Term/ReadKey.pm' => '2.21 from /usr/local/lib/perl5/site_perl/5.8.0/sun4-solaris/Term/ReadKey.pm'
'Term/ReadLine.pm' => '1.00 from /usr/local/lib/perl5/5.8.0/Term/ReadLine.pm'
'Term/ReadLine/Perl.pm' => '0.99 from /usr/local/lib/perl5/site_perl/5.8.0/Term/ReadLine/Perl.pm'
'Term/ReadLine/readline.pm' => '1.0203 from /usr/local/lib/perl5/site_perl/5.8.0/Term/ReadLine/readline.pm'
'perl5db.pl' => '1.19 from /usr/local/lib/perl5/5.8.0/perl5db.pl'
'strict.pm' => '1.02 from /usr/local/lib/perl5/5.8.0/strict.pm'
'vars.pm' => '1.01 from /usr/local/lib/perl5/5.8.0/vars.pm'
'warnings.pm' => '1.00 from /usr/local/lib/perl5/5.8.0/warnings.pm'
'warnings/register.pm' => '1.00 from /usr/local/lib/perl5/5.8.0/warnings/register.pm'

This option will print the modules required to run the application, and the current version of each module. I will cover program flow under the Perl debugger in a subsequent BLOG entry.

Printing individual perl module versions

This article was posted by Matty on 2005-09-07 23:00:00 -0400 -0400

Last week I discussed how to use the Perl debugger to print the module versions that a program references. While reading through the perlmod documentation, I saw Perl’s “-M” option. This allows a module to be specified on the command line (versus referencing it with a “use’ statement). Each Perl module should export the $VERSION variable, so finding the version number of a specific module is a snap:

$ perl -MNet::LDAP -e 'print "Net::LDAP::VERSION "'
0.32

This will print the module version for the Net::LDAP module, as listed in the Net::LDAP perl module (pm) file:

$ pwd
/usr/local/lib/perl5/site_perl/5.8.0/Net

$ grep \^\VERSION LDAP.pm
$ VERSION = "0.32";

It is amazing how many nifty things are available in Perl!

Running commands across zones

This article was posted by Matty on 2005-09-06 18:11:00 -0400 -0400

While reading through Brendan Gregg’s Solaris zones tutorial, I ran across his zonerun script. This nifty little script allows you to run a command across several Solaris zones (the script uses zlogin to accomplish the task):

$ zonerun "uname -a; echo"

SunOS irc 5.10 Generic_118822-11 sun4u sparc SUNW,Ultra-5_10

SunOS sunonews 5.10 Generic_118822-11 sun4u sparc SUNW,Ultra-5_10

$ zonerun "uptime ; echo"

12:08pm up 1 day(s), 10:55, 1 user, load average: 0.59, 0.41, 0.18

12:08pm up 2 min(s), 0 users, load average: 0.59, 0.41, 0.18

This nifty script kinda reminds me of Sun cluster’s ctelnet utility :)

Reading Solaris Memory

This article was posted by Matty on 2005-09-04 20:29:00 -0400 -0400

In the Solaris Operating System the /dev/mem pseudo-device provides access to the physical memory on a server. This pseudo-device can be immensly valuable for determing the contents of memory after an intrusion, locating the contents of a file when you accidentally delete it (this assumes the file was placed into memory and is still resident), or to test memory for errors (I believe the mem test utilities use /dev/mem). To view the contents of /dev/mem, you can use the less utility:

$ less -f /dev/mem /dev/memory_bandwidth

[ ... ]
^@ (try again later)^@^@^@^@^@^@SUNW_OST_OSLIB^@^@socket:
All ports in use
^@^@^@SUNW_OST_OSLIB^@^@connect to address %s:
^@SUNW_OST_OSLIB^@^@Trying %s...
^@^@^@SUNW_OST_OSLIB^@^@write: setting up
stderr^@^@^@^@SUNW_OST_OSLIB^@^@socket: protocol failure in
circuit setup.
^@SUNW_OST_OSLIB^@^@socket: protocol failure in circuit setup.
^@SUNW_OST_OSLIB^@^@socket: protocol failure in circuit setup.
^@SUNW_OST_OSLIB^@^@Protocol error, %s closed connection
^@^@^@SUNW_OST_OSLIB^@^@Protocol error, %s sent %d bytes
^@^@^@SUNW_OST_OSLIB^@^@%d: Address family not supported
^@^@^@SUNW_OST_OSLIB^@^@%s: unknown host

This page of memory looks to be part of a network library that was loaded recently. Viva la less!