Skip to content

Instantly share code, notes, and snippets.

@azat
Last active February 3, 2024 01:06
Show Gist options
  • Save azat/e370bae012c05c983c798131cee0c846 to your computer and use it in GitHub Desktop.
Save azat/e370bae012c05c983c798131cee0c846 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import sys
import re
"""
Decode kernel message from mpt*sas, like:
mpt3sas_cm0: log_info(0x31120303): originator(PL), code(0x12), sub_code(0x0303)
mpt2sas_cm0: log_info(0x31120303): originator(PL), code(0x12), sub_code(0x0303)
This script does a bitwise AND between the error code and the #defines in the LSI driver header file
It returns the text code and the bitmask for the code
Usage: ./lsi-decode-loginfo.py 0x31120303
"""
# This code originated from https://gist.github.com/azat/e370bae012c05c983c798131cee0c846
# Revised 8/2019 RichardFoo
#
# Tip: The specific error code shown here is commonly associated with a cable fault and is
# accompanied by very slow performance and occasional application-level I/O errors
def get_consts():
res = []
# Can be executed cross-platform by fetching the
# following file and pointing open() to it:
# https://elixir.bootlin.com/linux/v5.3-rc2/source/drivers/message/fusion/lsi/mpi_log_sas.h
# It's from the latest Linux kernel, but the file
# doesn't appear to have changed in 10 years.
with open("/usr/src/linux/drivers/message/fusion/lsi/mpi_log_sas.h") as f:
for line in f:
# Parse the #define lines into the tag and value
m = re.match(r'^#define[\s]+(?P<name>[0-9a-zA-Z_]+)[\s]+(?:\(|)(?P<value>[0-9a-fA-Fx]+)(?:\)|)$', line)
if not m:
continue
name = m.group('name')
if name == 'IOC_LOGINFO_CODE_SHIFT':
continue
if 'COMPAT_' in name:
continue
res.append({
'name': m.group('name'),
'value': int(m.group('value'), 16),
'valueHex': m.group('value'),
})
return res
def main():
if len(sys.argv) != 2:
print('\nSee comments in code for usage syntax.\n')
quit()
# Read the error code from the command-line
val = int(sys.argv[1], 16)
print()
print(sys.argv[1], '= Error code being matched\n')
for c in get_consts():
compare = (val & c['value'])
# Output if the code is a full bitwise match
if compare and compare == c['value']:
print(c['valueHex'], c['name'])
print()
if __name__ == '__main__':
main()
@hagfelsh
Copy link

This looks like it'd be very useful, but I can't quite figure out how to give it what it wants. Can you provide a usage example?

@RichardFoo
Copy link

@azat - thanks for this script! It came in handy for a troubleshooting session. I've made some edits to the code, but apparently gist doesn't support pull requests, so... https://gist.github.com/RichardFoo/8784f760f4abb8a4c6ac10ce63f5710d

@azat
Copy link
Author

azat commented Aug 13, 2019

@RichardFoo applied, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment