71e2cb
From 3a38f8e66a2aa5c477cea152e1acc9a781834b83 Mon Sep 17 00:00:00 2001
71e2cb
From: Aristeu Rozanski <aris@redhat.com>
71e2cb
Date: Mon, 1 Jun 2015 17:04:00 -0300
71e2cb
Subject: [PATCH 11/13] rasdaemon: add support to match the machine by system's
71e2cb
 product name
71e2cb
71e2cb
In some cases the motherboard names will change but the mapping won't
71e2cb
across a line of products. This patch adds support for "Product:" to be
71e2cb
specified in the label files instead of Model:.
71e2cb
71e2cb
An example:
71e2cb
	Vendor: Dell Inc.
71e2cb
	  Product: PowerEdge R610
71e2cb
	    DIMM_A1: 0.0.0;     DIMM_A2:  0.0.1;        DIMM_A3:  0.0.2;
71e2cb
	    DIMM_A4: 0.1.0;     DIMM_A5:  0.1.1;        DIMM_A6:  0.1.2;
71e2cb
71e2cb
	    DIMM_B1: 1.0.0;     DIMM_B2:  1.0.1;        DIMM_B3:  1.0.2;
71e2cb
	    DIMM_B4: 1.1.0;     DIMM_B5:  1.1.1;        DIMM_B6:  1.1.2;
71e2cb
71e2cb
Would match all 'PowerEdge R610' machines.
71e2cb
71e2cb
Signed-off-by: Aristeu Rozanski <arozansk@redhat.com>
71e2cb
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
71e2cb
---
71e2cb
 util/ras-mc-ctl.in | 127 +++++++++++++++++++++++++++++++++++++++++------------
71e2cb
 1 file changed, 98 insertions(+), 29 deletions(-)
71e2cb
71e2cb
diff --git a/util/ras-mc-ctl.in b/util/ras-mc-ctl.in
71e2cb
index 7b6d798..6350f62 100755
71e2cb
--- a/util/ras-mc-ctl.in
71e2cb
+++ b/util/ras-mc-ctl.in
71e2cb
@@ -288,8 +288,27 @@ sub parse_dimm_nodes
71e2cb
     }
71e2cb
 }
71e2cb
 
71e2cb
+sub guess_product {
71e2cb
+    my $pvendor = undef;
71e2cb
+    my $pname = undef;
71e2cb
+
71e2cb
+    if (open (VENDOR, "/sys/class/dmi/id/product_vendor")) {
71e2cb
+        $pvendor = <VENDOR>;
71e2cb
+        close VENDOR;
71e2cb
+        chomp($pvendor);
71e2cb
+    }
71e2cb
+    if (open (NAME, "/sys/class/dmi/id/product_name")) {
71e2cb
+        $pname = <NAME>;
71e2cb
+        close NAME;
71e2cb
+        chomp($pname);
71e2cb
+    }
71e2cb
+
71e2cb
+    return ($pvendor, $pname);
71e2cb
+}
71e2cb
+
71e2cb
 sub get_mainboard_info {
71e2cb
     my ($vendor, $model);
71e2cb
+    my ($pvendor, $pname);
71e2cb
 
71e2cb
     if ($conf{opt}{mainboard} && $conf{opt}{mainboard} ne "report") {
71e2cb
         ($vendor, $model) = split (/[: ]/, $conf{opt}{mainboard}, 2);
71e2cb
@@ -301,6 +320,15 @@ sub get_mainboard_info {
71e2cb
 
71e2cb
     $conf{mainboard}{vendor} = $vendor;
71e2cb
     $conf{mainboard}{model}  = $model;
71e2cb
+
71e2cb
+    ($pvendor, $pname) = guess_product ();
71e2cb
+    # since product vendor is rare, use mainboard's vendor
71e2cb
+    if ($pvendor) {
71e2cb
+        $conf{mainboard}{product_vendor} = $pvendor;
71e2cb
+    } else {
71e2cb
+        $conf{mainboard}{product_vendor} = $vendor;
71e2cb
+    }
71e2cb
+    $conf{mainboard}{product_name} = $pname if $pname;
71e2cb
 }
71e2cb
 
71e2cb
 sub guess_vendor_model_dmidecode {
71e2cb
@@ -449,10 +477,11 @@ sub guess_dimm_label {
71e2cb
 
71e2cb
 sub parse_dimm_labels_file
71e2cb
 {
71e2cb
-    my ($lh, $num_layers, $file) = (@_);
71e2cb
+    my ($lh, $num_layers, $lh_prod, $num_layers_prod, $file) = (@_);
71e2cb
     my $line = -1;
71e2cb
     my $vendor = "";
71e2cb
     my @models = ();
71e2cb
+    my @products = ();
71e2cb
     my $num;
71e2cb
 
71e2cb
     open (LABELS, "$file")
71e2cb
@@ -469,12 +498,21 @@ sub parse_dimm_labels_file
71e2cb
         if (/vendor\s*:\s*(.*\S)\s*/i) {
71e2cb
             $vendor = lc $1;
71e2cb
             @models = ();
71e2cb
+            @products = ();
71e2cb
             $num = 0;
71e2cb
             next;
71e2cb
         }
71e2cb
         if (/(model|board)\s*:\s*(.*)$/i) {
71e2cb
             !$vendor && die "$file: line $line: MB model without vendor\n";
71e2cb
             @models = grep { s/\s*(.*)\s*$/$1/ } split(/[,;]+/, $2);
71e2cb
+            @products = ();
71e2cb
+            $num = 0;
71e2cb
+            next;
71e2cb
+        }
71e2cb
+        if (/(product)\s*:\s*(.*)$/i) {
71e2cb
+            !$vendor && die "$file: line $line: product without vendor\n";
71e2cb
+            @models = ();
71e2cb
+            @products = grep { s/\s*(.*)\s*$/$1/ } split(/[,;]+/, $2);
71e2cb
             $num = 0;
71e2cb
             next;
71e2cb
         }
71e2cb
@@ -513,10 +551,13 @@ sub parse_dimm_labels_file
71e2cb
                     }
71e2cb
                     map { $lh->{$vendor}{lc $_}{$mc}{$top}{$mid}{$low} = $label }
71e2cb
                             @models;
71e2cb
+                    map { $lh_prod->{$vendor}{lc $_}{$mc}{$top}{$mid}{$low} = $label }
71e2cb
+                            @products;
71e2cb
                 }
71e2cb
                 if (!$num) {
71e2cb
                         $num = $n;
71e2cb
                         map { $num_layers->{$vendor}{lc $_} = $num } @models;
71e2cb
+                        map { $num_layers_prod->{$vendor}{lc $_} = $num } @products;
71e2cb
                 } elsif ($num != $n) {
71e2cb
                         die ("Error: Inconsistent number of layers at label db \"$file\"\n");
71e2cb
                 }
71e2cb
@@ -531,6 +572,8 @@ sub parse_dimm_labels
71e2cb
 {
71e2cb
     my %labels = ();
71e2cb
     my %num_layers = ();
71e2cb
+    my %labels_prod = ();
71e2cb
+    my %num_layers_prod = ();
71e2cb
 
71e2cb
     #
71e2cb
     #  Accrue all DIMM labels from the labels.db file, as
71e2cb
@@ -538,10 +581,10 @@ sub parse_dimm_labels
71e2cb
     #
71e2cb
     for my $file ($conf{labeldb}, <$conf{labeldir}/*>) {
71e2cb
         next unless -r $file;
71e2cb
-        parse_dimm_labels_file (\%labels, \%num_layers, $file);
71e2cb
+        parse_dimm_labels_file (\%labels, \%num_layers, \%labels_prod, \%num_layers_prod, $file);
71e2cb
     }
71e2cb
 
71e2cb
-    return (\%labels, \%num_layers);
71e2cb
+    return (\%labels, \%num_layers, \%labels_prod, \%num_layers_prod);
71e2cb
 }
71e2cb
 
71e2cb
 sub read_dimm_label
71e2cb
@@ -598,25 +641,9 @@ sub get_dimm_label_node
71e2cb
 }
71e2cb
 
71e2cb
 
71e2cb
-sub print_dimm_labels
71e2cb
+sub _print_dimm_labels
71e2cb
 {
71e2cb
-    my $fh = shift || *STDOUT;
71e2cb
-    my ($lref, $num_layers) = parse_dimm_labels ();
71e2cb
-    my $vendor = lc $conf{mainboard}{vendor};
71e2cb
-    my $model  = lc $conf{mainboard}{model};
71e2cb
-    my $format = "%-35s %-20s %-20s\n";
71e2cb
-
71e2cb
-    if (!exists $$lref{$vendor}{$model}) {
71e2cb
-        log_error ("No dimm labels for $conf{mainboard}{vendor} " .
71e2cb
-                   "model $conf{mainboard}{model}\n");
71e2cb
-        return;
71e2cb
-    }
71e2cb
-
71e2cb
-    my $sysfs_dir = "/sys/devices/system/edac/mc";
71e2cb
-
71e2cb
-    find({wanted => \&parse_dimm_nodes, no_chdir => 1}, $sysfs_dir);
71e2cb
-
71e2cb
-    printf $fh $format, "LOCATION", "CONFIGURED LABEL", "SYSFS CONTENTS";
71e2cb
+    my ($lref, $num_layers, $vendor, $model, $fh, $format) = @_;
71e2cb
 
71e2cb
     for my $mc (sort keys %{$$lref{$vendor}{$model}}) {
71e2cb
         for my $top (sort keys %{$$lref{$vendor}{$model}{$mc}}) {
71e2cb
@@ -631,26 +658,40 @@ sub print_dimm_labels
71e2cb
         }
71e2cb
     }
71e2cb
     print $fh "\n";
71e2cb
-
71e2cb
 }
71e2cb
 
71e2cb
-sub register_dimm_labels
71e2cb
+sub print_dimm_labels
71e2cb
 {
71e2cb
-    my ($lref, $num_layers) = parse_dimm_labels ();
71e2cb
+    my $fh = shift || *STDOUT;
71e2cb
+    my ($lref, $num_layers, $lref_prod, $num_layers_prod) = parse_dimm_labels ();
71e2cb
     my $vendor = lc $conf{mainboard}{vendor};
71e2cb
     my $model  = lc $conf{mainboard}{model};
71e2cb
-    my $sysfs  = "/sys/devices/system/edac/mc";
71e2cb
+    my $pvendor = lc $conf{mainboard}{product_vendor};
71e2cb
+    my $pname = lc $conf{mainboard}{product_name};
71e2cb
+    my $format = "%-35s %-20s %-20s\n";
71e2cb
 
71e2cb
-    if (!exists $$lref{$vendor}{$model}) {
71e2cb
+    if (!exists $$lref{$vendor}{$model} && !exists $$lref_prod{$pvendor}{$pname}) {
71e2cb
         log_error ("No dimm labels for $conf{mainboard}{vendor} " .
71e2cb
-                                      "model $conf{mainboard}{model}\n");
71e2cb
-        return 0;
71e2cb
+                   "model $conf{mainboard}{model}\n");
71e2cb
+        return;
71e2cb
     }
71e2cb
+
71e2cb
     my $sysfs_dir = "/sys/devices/system/edac/mc";
71e2cb
 
71e2cb
     find({wanted => \&parse_dimm_nodes, no_chdir => 1}, $sysfs_dir);
71e2cb
 
71e2cb
-    select (undef, undef, undef, $conf{opt}{delay});
71e2cb
+    printf $fh $format, "LOCATION", "CONFIGURED LABEL", "SYSFS CONTENTS";
71e2cb
+
71e2cb
+    if (exists $$lref{$vendor}{$model}) {
71e2cb
+        _print_dimm_labels($lref, $num_layers, $vendor, $model, $fh, $format);
71e2cb
+    } elsif (exists $$lref_prod{$pvendor}{$pname}) {
71e2cb
+        _print_dimm_labels($lref_prod, $num_layers_prod, $pvendor, $pname, $fh, $format);
71e2cb
+    }
71e2cb
+}
71e2cb
+
71e2cb
+sub write_dimm_labels
71e2cb
+{
71e2cb
+    my ($lref, $num_layers, $vendor, $model) = @_;
71e2cb
 
71e2cb
     for my $mc (sort keys %{$$lref{$vendor}{$model}}) {
71e2cb
         for my $top (sort keys %{$$lref{$vendor}{$model}{$mc}}) {
71e2cb
@@ -675,6 +716,34 @@ sub register_dimm_labels
71e2cb
             }
71e2cb
         }
71e2cb
     }
71e2cb
+}
71e2cb
+
71e2cb
+sub register_dimm_labels
71e2cb
+{
71e2cb
+    my ($lref, $num_layers, $lref_prod, $num_layers_prod) = parse_dimm_labels ();
71e2cb
+    my $vendor = lc $conf{mainboard}{vendor};
71e2cb
+    my $model  = lc $conf{mainboard}{model};
71e2cb
+    my $pvendor = lc $conf{mainboard}{product_vendor};
71e2cb
+    my $pname = lc $conf{mainboard}{product_name};
71e2cb
+    my $sysfs  = "/sys/devices/system/edac/mc";
71e2cb
+
71e2cb
+    if (!exists $$lref{$vendor}{$model} && !exists $$lref_prod{$pvendor}{$pname}) {
71e2cb
+        log_error ("No dimm labels for $conf{mainboard}{vendor} " .
71e2cb
+                                      "model $conf{mainboard}{model}\n");
71e2cb
+        return 0;
71e2cb
+    }
71e2cb
+    my $sysfs_dir = "/sys/devices/system/edac/mc";
71e2cb
+
71e2cb
+    find({wanted => \&parse_dimm_nodes, no_chdir => 1}, $sysfs_dir);
71e2cb
+
71e2cb
+    select (undef, undef, undef, $conf{opt}{delay});
71e2cb
+
71e2cb
+    if (exists $$lref{$vendor}{$model}) {
71e2cb
+        write_dimm_labels($lref, $num_layers, $vendor, $model);
71e2cb
+    } else {
71e2cb
+        write_dimm_labels($lref_prod, $num_layers_prod, $pvendor, $pname);
71e2cb
+    }
71e2cb
+
71e2cb
     return 1;
71e2cb
 }
71e2cb
 
71e2cb
-- 
71e2cb
1.8.3.1
71e2cb