NetApp storage administrators tend to be a little lazy. Perhaps understandably so---NetApps are really good at "fire and forget" storage; you simply set up a volume and let WAFL handle the rest, versus sitting down and developing a working strategy up front that maximizes the filer's potential.

Unfortunately, as a result, a goodly number of otherwise good SAN admins only start to pay attention when performance begins to go south....And when it goes south, it goes south in a hurry.

This script looks to prevent the going-south part, by examining everything from the environmentals on the filer to volume and aggregate space utilization. It relies on some general rules of thumb when it comes to its suggestions, such as preserving at least 15-20% in the volume to prevent heavy increases in fragmentation under the hood.

The only added part you need to get FilerProbe working for you is the MIB file for your particular filer, since it pulls information via SNMP. This is available via NetApp and other sources on the web. Place it in the same directory as this script, and you're ready to fly.


When not sailing in his 15 foot beechwood schooner, FilerProbe enjoys long walk on the beach, fine wines, and listening to his extensive collection of Foreigner bootlegs. "Even though i'm a Perl script, I like to think i'm a trend-bucker", says FilerProbe. "I'm a Gemini -- I blaze my own path, and any foxy lady I might meet will enjoy that part of me, I think."

To meet FilerProbe, press 3 at the tone.




#!/usr/bin/perl ## FilerProbe written (061909:0914) by Bowie J. Poag ## FilerProbe keeps tabs on a NetApp, warns of error states and attemp +ts to predict problems with storage utilization. ## ## Usage: ## ## filerprobe.pl <hostname> ## ## Internal: ## ## snmpget -v1 -c public -m ./NETWORK-APPLIANCE-MIB.txt tmcnetapp3 NET +WORK-APPLIANCE-MIB::productModel.0 ## ## chomp($date=`date`); $fetchCommand="snmpget"; $tableFetchCommand="snmptable"; $SNMPVersion=1; $communityString="public"; $MIBFilename="./NETWORK-APPLIANCE-MIB.txt"; $MIB="NETWORK-APPLIANCE-MIB"; $filerName=$ARGV[0]; spinUp(); analyzeFilerHealth(); collectVolumeMetrics(); reportDump(); spinDown(); sub spinUp { print "\n"; print "FilerProbe: Spinning up..\n"; ## Ho hum.. } sub analyzeFilerHealth { print "FilerProbe: Collecting filer status data..\n"; @fetchList= ( productModel, # productVersion, # cpuUpTime, # miscGlobalStatusMessage, # diskTotalCount, # diskActiveCount, # diskReconstructingCount, # diskReconstructingParityCount, # diskFailedCount, # envFailedFanCount, # envFailedPowerSupplyCount, # nvramBatteryStatus # ); foreach $item (@fetchList) { chomp($item=`$fetchCommand -v$SNMPVersion -O qv -c $co +mmunityString -m $MIBFilename $filerName $MIB\:\:$item.0\n`); $item=~s/\"//g; $item=~s/\n//g; } @version=split(":",$fetchList[1]); @uptime=split(":",$fetchList[2]); print "FilerProbe: Filer $filerName ($version[0]) has been up +for $uptime[0] days, $uptime[1] hours, $uptime[2] minutes, $uptime[3] + seconds.\n"; if ($fetchList[8]>0) { push(@statusReport,"There are currently $fetchList[8] +spindles marked as dead on this filer. They need to be replaced.\n"); } if ($fetchList[6]>0) { push(@statusReport,"FilerProbe: One or more spindles a +re running degraded.. $fetchList[6] volume reconstructions and $fetch +List[7] parity reconstructions are currently active.\n"); } if ($fetchList[9]>0) { push(@statusReport,"One or more cooling fans have fail +ed. This is potentially bad.\n"); } if ($fetchList[10]>0) { push(@statusReport,"One or more power supplies have fa +iled. This is very bad.\n"); } if ($fetchList[11]!~/ok/) { push(@statusReport,"Something's wrong with NVRAM batte +ry. (Status is $fetchList[11])\n"); } print "FilerProbe: Current global status message is: $fetchLis +t[3]\n"; } sub collectVolumeMetrics { print "FilerProbe: Collecting volume status data..\n"; print "FilerProbe: \n"; @volumes=`$tableFetchCommand -v1 -c $communityString -C Hf \: +-m $MIBFilename $filerName $MIB\:\:dfTable\n`; foreach $item (@volumes) { @temp=split(":",$item); $temp[1]=~s/\"//g; graphIt(); $temp[1]=~s/\/$//g; if ($temp[5] >=85) { $badAreas{$temp[1]}=$temp[5]; } } print sort @graphs; } sub graphIt { $volName=$temp[1]; $percentUsed=$temp[5]; $barLength=($percentUsed*50)/100; $starString=""; $barGraph="["; $x=0; while ($x<25) { if ($x<$barLength/2) { $barGraph.="#"; } else { $barGraph.=" "; } $x++; } $barGraph.="] $percentUsed%"; push (@graphs,sprintf "FilerProbe: %-28.28s %s\n",$volName,$ba +rGraph); } sub reportDump { print "FilerProbe:\n"; print "FilerProbe: Report date: $date\n"; print "FilerProbe:\n"; print "FilerProbe: Filer Status: \n"; print "FilerProbe:\n"; if ($#statusReport==-1) { print "FilerProbe: This filer appears to be in good sh +ape health-wise. No hardware warnings found.\n"; } else { print "FilerProbe: There appears to be one or more thi +ngs wrong with the filer.\n"; print @statusReport; } print "FilerProbe:\n"; print "FilerProbe: Suggested actions:\n"; print "FilerProbe:\n"; while (($volName,$percentUsed)=each %badAreas) { if ($percentUsed>100) { $increment=($percentUsed-100)+20; push(@actions,"FilerProbe: Snapshot region $vo +lName is eating into it's parent volume. Not good.\n"); } else { $increment=20-(100-$percentUsed); } if ($volName=~/vol/ && $volName!~/snap/) { push(@actions,"FilerProbe: Volume $volName sho +uld be expanded by at least $increment%, and defragged.\n"); } if ($volName=~/aggr/i) { push(@actions,"FilerProbe: Aggregate $volName +needs more spindles added to it to allow for volume growth.\n"); } if ($volName=~/snap/ || ($volName=~/snap/i && $volName +=~/aggr/i)) { push(@actions,"FilerProbe: Snapshot region $vo +lName should be increased by at least $increment%.\n"); } } print sort(@actions); } sub spinDown { print "FilerProbe: \n"; print "FilerProbe: Exiting..\n\n"; }

(Unfortunately, my employer's security policy prevents me from pasting a detailed copy of FilerProbe's rather nicely-formatted output.)

In reply to FilerProbe: Tidy Up Your NetApp by bpoag

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.