1*902c8537SMatt Spinler#!/usr/bin/env perl 2*902c8537SMatt Spinler 3*902c8537SMatt Spinler#This script generates YAML that defines the presence detects used 4*902c8537SMatt Spinler#for FRUs. Its output is used by code that determines which FRUs 5*902c8537SMatt Spinler#are present in a system. 6*902c8537SMatt Spinler 7*902c8537SMatt Spinleruse strict; 8*902c8537SMatt Spinleruse warnings; 9*902c8537SMatt Spinler 10*902c8537SMatt Spinleruse Getopt::Long; 11*902c8537SMatt Spinleruse mrw::Inventory; 12*902c8537SMatt Spinleruse mrw::Targets; 13*902c8537SMatt Spinleruse mrw::Util; 14*902c8537SMatt Spinler 15*902c8537SMatt Spinlermy $serverwizFile; 16*902c8537SMatt Spinlermy $outputFile; 17*902c8537SMatt SpinlerGetOptions("i=s" => \$serverwizFile, 18*902c8537SMatt Spinler "o=s" => \$outputFile) or printUsage(); 19*902c8537SMatt Spinler 20*902c8537SMatt Spinlerif ((not defined $serverwizFile) || 21*902c8537SMatt Spinler (not defined $outputFile)) 22*902c8537SMatt Spinler{ 23*902c8537SMatt Spinler printUsage(); 24*902c8537SMatt Spinler} 25*902c8537SMatt Spinler 26*902c8537SMatt Spinlermy $targets = Targets->new; 27*902c8537SMatt Spinler$targets->loadXML($serverwizFile); 28*902c8537SMatt Spinler 29*902c8537SMatt Spinlermy @inventory = Inventory::getInventory($targets); 30*902c8537SMatt Spinlermy %presence; 31*902c8537SMatt Spinler 32*902c8537SMatt SpinlerfindTachBasedPresenceDetects(\%presence); 33*902c8537SMatt Spinler 34*902c8537SMatt Spinler#Future: Find other sorts of presence detects 35*902c8537SMatt Spinler 36*902c8537SMatt SpinlerprintYAML(\%presence, $outputFile); 37*902c8537SMatt Spinler 38*902c8537SMatt Spinlerexit 0; 39*902c8537SMatt Spinler 40*902c8537SMatt Spinler 41*902c8537SMatt Spinler#Finds FRUs and their Presence detects where a tach reading 42*902c8537SMatt Spinler#is used as the presence detect, such as when a nonzero fan RPM 43*902c8537SMatt Spinler#tach reading can be used to tell that a particular fan is present. 44*902c8537SMatt Spinlersub findTachBasedPresenceDetects 45*902c8537SMatt Spinler{ 46*902c8537SMatt Spinler my ($presence) = @_; 47*902c8537SMatt Spinler my %tachs; 48*902c8537SMatt Spinler 49*902c8537SMatt Spinler for my $target (keys %{$targets->getAllTargets()}) 50*902c8537SMatt Spinler { 51*902c8537SMatt Spinler my $connections = $targets->findConnections($target, "TACH"); 52*902c8537SMatt Spinler next if ($connections eq ""); 53*902c8537SMatt Spinler 54*902c8537SMatt Spinler for my $tach (sort @{$connections->{CONN}}) 55*902c8537SMatt Spinler { 56*902c8537SMatt Spinler #Because findConnections is recursive, we can hit this same 57*902c8537SMatt Spinler #connection multiple times so only use it once. 58*902c8537SMatt Spinler next if (exists $tachs{$tach->{SOURCE}}{$tach->{DEST}}); 59*902c8537SMatt Spinler $tachs{$tach->{SOURCE}}{$tach->{DEST}} = 1; 60*902c8537SMatt Spinler 61*902c8537SMatt Spinler my $fru = Util::getEnclosingFru($targets, $tach->{SOURCE}); 62*902c8537SMatt Spinler my $name = Util::getObmcName(\@inventory, $fru); 63*902c8537SMatt Spinler if (not defined $name) 64*902c8537SMatt Spinler { 65*902c8537SMatt Spinler die "$target was not found in the inventory\n"; 66*902c8537SMatt Spinler } 67*902c8537SMatt Spinler 68*902c8537SMatt Spinler my $sensor = getSensor($tach->{DEST}); 69*902c8537SMatt Spinler 70*902c8537SMatt Spinler #For now, assuming only fans use tachs 71*902c8537SMatt Spinler $$presence{Tach}{$name}{type} = 'Fan'; 72*902c8537SMatt Spinler 73*902c8537SMatt Spinler #Multi-rotor fans will have > 1 sensors per FRU 74*902c8537SMatt Spinler push @{$$presence{Tach}{$name}{sensors}}, $sensor; 75*902c8537SMatt Spinler } 76*902c8537SMatt Spinler } 77*902c8537SMatt Spinler} 78*902c8537SMatt Spinler 79*902c8537SMatt Spinler 80*902c8537SMatt Spinler#Creates the YAML representation of the data 81*902c8537SMatt Spinlersub printYAML 82*902c8537SMatt Spinler{ 83*902c8537SMatt Spinler my ($presence, $outputFile) = @_; 84*902c8537SMatt Spinler open (F, ">$outputFile") or die "Could not open $outputFile\n"; 85*902c8537SMatt Spinler 86*902c8537SMatt Spinler while (my ($method, $FRUs) = each(%{$presence})) 87*902c8537SMatt Spinler { 88*902c8537SMatt Spinler print F "- $method:\n"; 89*902c8537SMatt Spinler while (my ($name, $data) = each(%{$FRUs})) 90*902c8537SMatt Spinler { 91*902c8537SMatt Spinler my ($prettyName) = $name =~ /\b(\w+)$/; 92*902c8537SMatt Spinler 93*902c8537SMatt Spinler print F " - PrettyName: $prettyName\n"; 94*902c8537SMatt Spinler print F " Inventory: $name\n"; 95*902c8537SMatt Spinler print F " Description:\n"; #purposely leaving blank. 96*902c8537SMatt Spinler print F " Sensors:\n"; 97*902c8537SMatt Spinler for my $s (@{$data->{sensors}}) 98*902c8537SMatt Spinler { 99*902c8537SMatt Spinler print F " - $s\n"; 100*902c8537SMatt Spinler } 101*902c8537SMatt Spinler } 102*902c8537SMatt Spinler } 103*902c8537SMatt Spinler 104*902c8537SMatt Spinler close F; 105*902c8537SMatt Spinler} 106*902c8537SMatt Spinler 107*902c8537SMatt Spinler 108*902c8537SMatt Spinler#Find what hwmon will call this unit's reading by looking in 109*902c8537SMatt Spinler#the child unit-hwmon-feature unit. 110*902c8537SMatt Spinlersub getSensor 111*902c8537SMatt Spinler{ 112*902c8537SMatt Spinler my ($unit) = @_; 113*902c8537SMatt Spinler 114*902c8537SMatt Spinler my @hwmons = Util::getChildUnitsWithTargetType($targets, 115*902c8537SMatt Spinler "unit-hwmon-feature", 116*902c8537SMatt Spinler $unit); 117*902c8537SMatt Spinler die "No HWMON children found for $unit\n" unless (scalar @hwmons != 0); 118*902c8537SMatt Spinler 119*902c8537SMatt Spinler my $name = $targets->getAttributeField($hwmons[0], 120*902c8537SMatt Spinler "HWMON_FEATURE", 121*902c8537SMatt Spinler "DESCRIPTIVE_NAME"); 122*902c8537SMatt Spinler die "No HWMON name for hwmon unit $hwmons[0]\n" if ($name eq ""); 123*902c8537SMatt Spinler 124*902c8537SMatt Spinler return $name; 125*902c8537SMatt Spinler} 126*902c8537SMatt Spinler 127*902c8537SMatt Spinler 128*902c8537SMatt Spinlersub printUsage 129*902c8537SMatt Spinler{ 130*902c8537SMatt Spinler print "$0 -i [XML filename] -o [output YAML filename]\n"; 131*902c8537SMatt Spinler exit(1); 132*902c8537SMatt Spinler} 133