krishnanadh / rpms / rasdaemon

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