krishnanadh / rpms / rasdaemon

Forked from rpms/rasdaemon a year ago
Clone
8051f9
commit 60a91e4da4f2daf2b10143fc148a8043312b61e5
8051f9
Author: Aristeu Rozanski <aris@redhat.com>
8051f9
Date:   Wed Aug 1 16:29:58 2018 -0400
8051f9
8051f9
    rasdaemon: ras-mc-ctl: add option to show error counts
8051f9
    
8051f9
    In some scenarios it might not be desirable to have a daemon running
8051f9
    to parse and store the errors provided by EDAC and only having the
8051f9
    number of CEs and UEs is enough. This patch implements this feature
8051f9
    as an ras-mc-ctl option.
8051f9
    
8051f9
    Signed-off-by: Aristeu Rozanski <arozansk@redhat.com>
8051f9
    Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
8051f9
8051f9
diff --git a/util/ras-mc-ctl.in b/util/ras-mc-ctl.in
8051f9
index 38b7824..aee431a 100755
8051f9
--- a/util/ras-mc-ctl.in
8051f9
+++ b/util/ras-mc-ctl.in
8051f9
@@ -50,6 +50,8 @@ my %dimm_location = ();
8051f9
 my %csrow_size  = ();
8051f9
 my %rank_size   = ();
8051f9
 my %csrow_ranks = ();
8051f9
+my %dimm_ce_count = ();
8051f9
+my %dimm_ue_count = ();
8051f9
 
8051f9
 my @layers;
8051f9
 my @max_pos;
8051f9
@@ -76,6 +78,7 @@ Usage: $prog [OPTIONS...]
8051f9
  --layout           Display the memory layout.
8051f9
  --summary          Presents a summary of the logged errors.
8051f9
  --errors           Shows the errors stored at the error database.
8051f9
+ --error-count      Shows the corrected and uncorrected error counts using sysfs.
8051f9
  --help             This help message.
8051f9
 EOF
8051f9
 
8051f9
@@ -83,7 +86,7 @@ parse_cmdline();
8051f9
 
8051f9
 if (  $conf{opt}{mainboard} || $conf{opt}{print_labels}
8051f9
    || $conf{opt}{register_labels} || $conf{opt}{display_memory_layout}
8051f9
-   || $conf{opt}{guess_dimm_label}) {
8051f9
+   || $conf{opt}{guess_dimm_label} || $conf{opt}{error_count}) {
8051f9
 
8051f9
     get_mainboard_info();
8051f9
 
8051f9
@@ -105,6 +108,9 @@ if (  $conf{opt}{mainboard} || $conf{opt}{print_labels}
8051f9
     if ($conf{opt}{guess_dimm_label}) {
8051f9
         guess_dimm_label ();
8051f9
     }
8051f9
+    if ($conf{opt}{error_count}) {
8051f9
+        display_error_count ();
8051f9
+    }
8051f9
 }
8051f9
 
8051f9
 if ($conf{opt}{status}) {
8051f9
@@ -134,6 +140,7 @@ sub parse_cmdline
8051f9
     $conf{opt}{guess_dimm_label} = 0;
8051f9
     $conf{opt}{summary} = 0;
8051f9
     $conf{opt}{errors} = 0;
8051f9
+    $conf{opt}{error_count} = 0;
8051f9
 
8051f9
     my $rref = \$conf{opt}{report};
8051f9
     my $mref = \$conf{opt}{mainboard};
8051f9
@@ -150,7 +157,8 @@ sub parse_cmdline
8051f9
                          "status" =>          \$conf{opt}{status},
8051f9
                          "layout" =>          \$conf{opt}{display_memory_layout},
8051f9
                          "summary" =>         \$conf{opt}{summary},
8051f9
-                         "errors" =>          \$conf{opt}{errors}
8051f9
+                         "errors" =>          \$conf{opt}{errors},
8051f9
+                         "error-count" =>     \$conf{opt}{error_count}
8051f9
             );
8051f9
 
8051f9
     usage(1) if !$rc;
8051f9
@@ -284,6 +292,30 @@ sub parse_dimm_nodes
8051f9
         $dimm_label_file{$str_loc} = $file;
8051f9
         $dimm_location{$str_loc} = $location;
8051f9
 
8051f9
+        my $count;
8051f9
+
8051f9
+        $file =~s/dimm_label/dimm_ce_count/;
8051f9
+        if (-e $file) {
8051f9
+                open IN, $file;
8051f9
+                chomp($count = <IN>);
8051f9
+                close IN;
8051f9
+        } else {
8051f9
+                log_error ("dimm_ce_count not found in sysfs. Old kernel?\n");
8051f9
+                exit -1;
8051f9
+        }
8051f9
+        $dimm_ce_count{$str_loc} = $count;
8051f9
+
8051f9
+        $file =~s/dimm_ce_count/dimm_ue_count/;
8051f9
+        if (-e $file) {
8051f9
+                open IN, $file;
8051f9
+                chomp($count = <IN>);
8051f9
+                close IN;
8051f9
+        } else {
8051f9
+                log_error ("dimm_ue_count not found in sysfs. Old kernel?\n");
8051f9
+                exit -1;
8051f9
+        }
8051f9
+        $dimm_ue_count{$str_loc} = $count;
8051f9
+
8051f9
         return;
8051f9
     }
8051f9
 }
8051f9
@@ -906,6 +938,45 @@ sub display_memory_layout
8051f9
     dimm_display_mem();
8051f9
 }
8051f9
 
8051f9
+sub display_error_count
8051f9
+{
8051f9
+    my $sysfs_dir = "/sys/devices/system/edac/mc";
8051f9
+    my $key;
8051f9
+    my $max_width = 0;
8051f9
+    my %dimm_labels = ();
8051f9
+
8051f9
+    find ({wanted => \&parse_dimm_nodes, no_chdir => 1}, $sysfs_dir);
8051f9
+
8051f9
+    if (!scalar(keys %dimm_node)) {
8051f9
+        log_error ("No DIMMs found in /sys or new sysfs EDAC interface not found.\n");
8051f9
+        exit -1;
8051f9
+    }
8051f9
+
8051f9
+    foreach $key (keys %dimm_node) {
8051f9
+        my $label_width;
8051f9
+
8051f9
+        open IN, $dimm_label_file{$key};
8051f9
+        chomp(my $label = <IN>);
8051f9
+        close IN;
8051f9
+        $label_width = length $label;
8051f9
+
8051f9
+        if ($label_width > $max_width) {
8051f9
+            $max_width = $label_width;
8051f9
+        }
8051f9
+        $dimm_labels{$key} = $label;
8051f9
+    }
8051f9
+    my $string = "Label";
8051f9
+    $string .= " " x ($max_width - length $string);
8051f9
+    print($string . "\tCE\tUE\n");
8051f9
+
8051f9
+    foreach $key (keys %dimm_node) {
8051f9
+        my $ce_count = $dimm_ce_count{$key};
8051f9
+        my $ue_count = $dimm_ue_count{$key};
8051f9
+
8051f9
+        print("$dimm_labels{$key}\t$ce_count\t$ue_count\n");
8051f9
+    }
8051f9
+}
8051f9
+
8051f9
 sub find_prog
8051f9
 {
8051f9
     my ($file) = @_;