File s390-tools-sles11sp2-zfcpdbf-fix-decoding-deferred-errors.patch of Package s390-tools
Subject: [PATCH] [BZ 87255] zfcpdbf: fix decoding of deferred errors
From: Steffen Maier <maier@linux.vnet.ibm.com>
Description: zfcpdbf: fix decoding of deferred errors
Symptom: Deferred errors are printed unsorted and out of context.
Command line options -e or --def-error do not suppress
output of deferred errors.
SBALs with ((index & 0xf) > 9) are decoded as independent
faulty trace records.
Scount printed in hex despite output lacking '0x' prefix.
Signaling SBAL not output despite being in trace record.
Problem: Deferred errors are treated differently from other record
types.
The exclamation mark in GetOptions entries does not invert
the option meaning but only allows the user to also use
negative option variants such as '--no-def-error'.
SBAL number text was interpreted as decimal number.
Scount number text in hex was output without conversion.
Signaling SBAL was skipped when dumping output.
Solution: Introduce pseudo records in global list which is sorted by
timestamp. Add a function to print such pseudo record and
hook it into output loop without depending on included and
excluded trace areas.
Invert variable that tracks the -e or --def-error option.
Interpret SBAL number string as hex.
Interpret Scount number string as hex.
Dump signaling SBAL.
Reproduction: Use zfcpdbf with zfcp s390dbf input containing at least one
deferred error trace record from a failed qdio request
with a request size of at least 10 or more SBALs.
Enabled FCP hardware data router is a prerequisite to get
deferred errors on failing qdio requests.
Alternatively, one can use fake s390dbf records as input.
Upstream-ID: -
Problem-ID: 87255
Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
---
scripts/zfcpdbf | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
--- a/scripts/zfcpdbf
+++ b/scripts/zfcpdbf
@@ -37,6 +37,7 @@ use constant PROGNAME => (fileparse($0))
our @TRACE_RECORDS;
our %PAYLOAD_RECORDS;
+our %def_error;
our @print_hba_id = ();
our @print_rec_id = ();
our @print_san_id = ();
@@ -109,7 +110,6 @@ sub get_payload_records
my $adapter = shift();
my $tf;
local *HANDLE;
- my %def_error;
$tf = catfile($root, $dir, "zfcp_".$adapter."_pay", "hex_ascii");
@@ -133,12 +133,13 @@ sub get_payload_records
$PAYLOAD_RECORDS{$fsf_req_id}{$area}[$counter] = [@record];
if ($def_error && ($area =~ /def_err/)) {
$def_error{$fsf_req_id}[$counter] = [@record];
+ if ($counter == 0) {
+ # pseudo area record for first def_err part
+ push @TRACE_RECORDS, [$area, @record];
+ }
}
}
close(*HANDLE);
- foreach my $de (keys %def_error) {
- print_deferred_error($def_error{$de});
- }
return 0;
}
@@ -371,12 +372,21 @@ sub _print_hba_id3
print "Cur B2B t-cred : ", substr($rec, 104, 8), "\n";
}
+sub print_deferr_common
+{
+ my $rec = shift();
+ my $fsf_req_id = substr($rec->[2], 16, 16);
+
+ print_deferred_error($def_error{$fsf_req_id});
+ print "\n";
+}
+
sub print_deferred_error
{
my $rec = shift();
foreach my $t_rec (@$rec) {
- my $sbal = substr($t_rec->[2], 0, 2);
+ my $sbal = hex(substr($t_rec->[2], 0, 2));
if ($sbal == 0) {
print "Timestamp : ", $t_rec->[0], "\n";
print "Tag : def_err\n";
@@ -389,7 +399,9 @@ sub print_deferred_error
hex(substr($t_rec->[2], 0x20 + 0x16 * 2, 4)),
"\n";
print "Scount : ",
- substr($t_rec->[2], 0x20 + 4, 2), "\n";
+ hex(substr($t_rec->[2], 0x20 + 4, 2)), "\n";
+ printf "Signaling SBAL : %s",
+ payload_format(substr($t_rec->[2], 0x20));
next;
} else {
printf "Req. SBAL(%02d) : %s", $sbal - 1 ,
@@ -535,8 +547,10 @@ sub show_all_records_ordered
foreach my $entry (@all_rec_sorted) {
my $area = shift @$entry;
- next if (@excl_areas && map { $area =~ /^$_$/ } @excl_areas);
- next if (@incl_areas && !map { $area =~ /^$_$/ } @incl_areas);
+ if ($area !~ /def_err/) {
+ next if (@excl_areas && map { $area =~ /^$_$/ } @excl_areas);
+ next if (@incl_areas && !map { $area =~ /^$_$/ } @incl_areas);
+ }
SWITCH: {
$area =~ /REC/ && do {
@@ -547,6 +561,8 @@ sub show_all_records_ordered
print_hba_common($entry); last SWITCH; };
$area =~ /SCSI/ && do {
print_scsi_common($entry); last SWITCH; };
+ $area =~ /def_err/ && do {
+ print_deferr_common($entry); last SWITCH; };
print_foreign_rec($area, @$entry);
}
}
@@ -613,7 +629,7 @@ GetOptions(
"i|include=s" => \@incl_areas,
"z|zfcp-only" => sub {@incl_areas = qw/REC HBA SAN SCSI/;},
"t|timediff=i" => \$timediff,
- "e|def-error!" => \$def_error,
+ "e|def-error" => sub {$def_error = 0;},
"f|force" => \$force,
"p|path=s" => \$path,
"r|root=s" => \$root,