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