diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 898687c..b27d8a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: - name: prepare run: | sudo apt-get update - sudo apt-get install -y build-essential sqlite3 + sudo apt-get install -y build-essential libsqlite3-dev sqlite3 libtraceevent-dev libtraceevent1 - name: build run: | autoreconf -vfi diff --git a/.github/workflows/gen_release.pl b/.github/workflows/gen_release.pl new file mode 100755 index 0000000..75a698e --- /dev/null +++ b/.github/workflows/gen_release.pl @@ -0,0 +1,41 @@ +#!/usr/bin/perl + +my $body_path = shift or die "Need a file name to store the release body"; + +my $ver; + +open IN, "configure.ac" or die; +while () { + if (m/^[^\#]*AC_INIT\s*\(\s*\[\s*RASdaemon\s*\]\s*,\s*\[?(\d+[\.\d]+)/) { + $ver=$1; + last; + } +} +close IN or die "can't open configure.ac"; + +die "Can't get version from configure.ac" if (!$ver); + +sub gen_version() { + print "$ver\n"; + + open IN, "ChangeLog" or return "error opening ChangeLog"; + open OUT, ">$body_path" or return "error creating $body_path"; + while () { + last if (m/$ver/); + } + while () { + next if (m/^$/); + last if (m/^\S/); + + my $ln = $_; + $ln =~ s/^\s+\*/-/; + print OUT $ln; + } + close OUT or return "error closing $body_path"; + + return ""; +} + +my $ret = gen_version(); + +die($ret) if ($ret ne ""); diff --git a/.github/workflows/on_tag.yml b/.github/workflows/on_tag.yml new file mode 100644 index 0000000..71f2b09 --- /dev/null +++ b/.github/workflows/on_tag.yml @@ -0,0 +1,50 @@ +name: Create release on tag + +on: + workflow_dispatch: + push: + # Sequence of patterns matched against refs/tags + tags: + - 'v[0-9]+*' + +jobs: + release: + name: Create Release + runs-on: ubuntu-latest + outputs: + upload_url: ${{ steps.create_release.outputs.upload_url }} + steps: + - uses: actions/checkout@v2 + - name: Release changelog + run: | + .github/workflows/gen_release.pl body_file.tmp > version + echo "version=$(cat version)" >> $GITHUB_ENV + - name: Create Release + id: create_release + uses: actions/create-release@latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + body_path: body_file.tmp + draft: false + prerelease: true + - name: prepare + run: | + sudo apt-get update + sudo apt-get install -y build-essential sqlite3 libtraceevent-dev libtraceevent1 + - name: Create Source Package for version ${{ env.version }} + run: | + autoreconf -vfi + ./configure --enable-all + make dist-bzip2 + - name: upload + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: mchehab/upload-release-asset@v1.0.3 + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: rasdaemon-${{ env.version }}.tar.bz2 + asset_name: rasdaemon-${{ env.version }}.tar.bz2 + asset_content_type: application/bzip2 diff --git a/.gitignore b/.gitignore index b9c9e76..8cd7382 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,12 @@ .deps/ autom4te.cache/ +SRPMS/ misc/rasdaemon.spec misc/ras-mc-ctl.service misc/rasdaemon.service Makefile Makefile.in +compile config.h config.h.in config.h.in~ diff --git a/ChangeLog b/ChangeLog index 6fedafc..1c33d13 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,53 @@ +2023-02-18 Mauro Carvalho Chehab + - Version 0.8.0 + + * This version now uses libtraceevent. Since its beginning, + rasdaemon came with an early version of this library. Now, + instead of keeping it embedded, use it from the system's + package. + * Fix mock build target and rasdaemon.spec.in + * Update README with instructions about contributing and + convert to markdown + * Fix a regression with Kernel 6.1-rc6 + * make distcheck now works + * Add labels for ASRockRack model X399D8A-2T + +2023-01-21 Mauro Carvalho Chehab + - Version 0.7.0 + + * Add labels for ASUS TUF GAMING B450-PLUS II + * Add four modules supported by HiSilicon common section + * Updated HiSilicon platform name + * Relocate reading and display Kunpeng920 errors to under Kunpeng9xx + * Add support to display the HiSilicon vendor errors for a specified module + * Add printing usage if necessary parameters are not passed for the vendor-error options + * Reformat error info of the HiSilicon Kunpeng920 + * Modify error statistics for HiSilicon KunPeng9xx common errors + * Modify recording Hisilicon common error data + * Support cpu fault isolation for recoverable errors + * Support cpu fault isolation for corrected errors + * Use XSI version of strerror_r on non glibc systems + * Use the new block_rq_error tracepoint + * Fix bank limit types check + * Properly handle localtime() failure + * Fix for a memory out-of-bounds issue and optimized code to remove duplicate function. + * Fix possible but unlikely file descriptor leak + * Fix bashisms + +2022-04-12 Mauro Carvalho Chehab + - Version 0.6.8 + + * Fix some issues related to sysconfigdir + * Some fixes for hisi boards + * Update ras-mc-ctl manpage to match current options + * Fix ras-mc-ctl when parsing some dimm sizes + * New asrock x570 motherboard label + * New Supermicro labels + * Support MCE for AMD CPU family 19h + * Add new SMCA bank types with error decoding + * Add error handling for Ampere-specific errors. + * Add support for multi-arch builds + 2021-05-26 Mauro Carvalho Chehab - Version 0.6.7 diff --git a/INSTALL b/INSTALL index 8865734..e82fd21 100644 --- a/INSTALL +++ b/INSTALL @@ -1,8 +1,8 @@ Installation Instructions ************************* - Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software -Foundation, Inc. + Copyright (C) 1994-1996, 1999-2002, 2004-2017, 2020-2021 Free +Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright @@ -225,7 +225,7 @@ order to use an ANSI C compiler: and if that doesn't work, install pre-built binaries of GCC for HP-UX. - HP-UX 'make' updates targets which have the same time stamps as their + HP-UX 'make' updates targets which have the same timestamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. diff --git a/Makefile.am b/Makefile.am index fabca78..f72ef0d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,9 +1,16 @@ +AM_DISTCHECK_CONFIGURE_FLAGS = --enable-all ACLOCAL_AMFLAGS=-I m4 -SUBDIRS = libtrace util man +SUBDIRS = util man SYSTEMD_SERVICES_IN = misc/rasdaemon.service.in misc/ras-mc-ctl.service.in SYSTEMD_SERVICES = $(SYSTEMD_SERVICES_IN:.service.in=.service) EXTRA_DIST = $(SYSTEMD_SERVICES_IN) misc/rasdaemon.env +CLEANFILES= \ + misc/ras-mc-ctl.service \ + misc/rasdaemon.service + +DISTCLEANFILES = misc/rasdaemon.spec + # This rule is needed because \@sbindir\@ is expanded to \${exec_prefix\}/sbin # during ./configure phase, therefore it is not possible to add .service.in # files to AC_CONFIG_FILES in configure.ac @@ -61,15 +68,25 @@ if WITH_MEMORY_CE_PFA rasdaemon_SOURCES += rbtree.c ras-page-isolation.c endif if WITH_AMP_NS_DECODE - rasdaemon_SOURCES += non-standard-ampere.c + rasdaemon_SOURCES += non-standard-ampere.c dmi_processor_info.c +endif +if WITH_CPU_FAULT_ISOLATION + rasdaemon_SOURCES += ras-cpu-isolation.c queue.c endif -rasdaemon_LDADD = -lpthread $(SQLITE3_LIBS) libtrace/libtrace.a + +if WITH_CXL + rasdaemon_SOURCES += ras-cxl-handler.c +endif + +rasdaemon_LDADD = -lpthread $(SQLITE3_LIBS) $(LIBTRACEEVENT_LIBS) +rasdaemon_CFLAGS = $(SQLITE3_CFLAGS) $(LIBTRACEEVENT_CFLAGS) include_HEADERS = config.h ras-events.h ras-logger.h ras-mc-handler.h \ ras-aer-handler.h ras-mce-handler.h ras-record.h bitfield.h ras-report.h \ ras-extlog-handler.h ras-arm-handler.h ras-non-standard-handler.h \ ras-devlink-handler.h ras-diskerror-handler.h rbtree.h ras-page-isolation.h \ - non-standard-hisilicon.h non-standard-ampere.h ras-memory-failure-handler.h + non-standard-hisilicon.h non-standard-ampere.h ras-memory-failure-handler.h \ + ras-cxl-handler.h ras-cpu-isolation.h queue.h # This rule can't be called with more than one Makefile job (like make -j8) # I can't figure out a way to fix that @@ -85,7 +102,7 @@ srpm: dist-bzip2 rpmbuild -bs misc/@PACKAGE@.spec mock: srpm - mock `rpm --eval %{_topdir}`/SRPMS/@PACKAGE@-@PACKAGE_VERSION@*.src.rpm + mock --resultdir="./SRPMS" `rpm --eval %{_topdir}`/SRPMS/@PACKAGE@-@PACKAGE_VERSION@*.src.rpm rpmlint: rpmlint misc/@PACKAGE@.spec `rpm --eval %{_topdir}`/SRPMS/@PACKAGE@-@PACKAGE_VERSION@*.src.rpm `rpm --eval %{_topdir}`/RPMS/*/@PACKAGE@-@PACKAGE_VERSION@*.rpm diff --git a/README b/README.md similarity index 51% rename from README rename to README.md index 833b918..e41cb5d 100644 --- a/README +++ b/README.md @@ -6,24 +6,24 @@ and Serviceability (RAS) reports made via the Kernel tracing events. The main repository for the rasdaemon is at Fedora hosted: - http://git.infradead.org/users/mchehab/rasdaemon.git +- And two mirrors are available: - https://github.com/mchehab/rasdaemon - https://gitlab.com/mchehab_kernel/rasdaemon +- +- Tarballs for each release can be found at: - http://www.infradead.org/~mchehab/rasdaemon/ +- GOALS ===== Its initial goal is to replace the edac-tools that got bitroted after -the addition of the HERM (Hardware Events Report Method )patches[1] at +the addition of the HERM (Hardware Events Report Method )patches[^1] at the EDAC Kernel drivers. -[1] http://lkml.indiana.edu/hypermail/linux/kernel/1205.1/02075.html +[^1]: Its long term goal is to be the userspace tool that will collect all hardware error events reported by the Linux Kernel from several sources @@ -31,7 +31,7 @@ hardware error events reported by the Linux Kernel from several sources It is not meant to provide tools for doing error injection, as there are other tools already covering it, like: - git://git.kernel.org/pub/scm/linux/kernel/git/gong.chen/mce-test.git + Yet, a few set of testing scripts are provided under /contrib dir. @@ -47,13 +47,13 @@ the ionosphere. In other words, the rationale for not exposing such the information is that: - 1) can be easily accounted on userspace; - 2) they're not really meaningful. E. g. one system with, let's say -10 corrected errors can be fine, while another one with the same amount -of errors can have problems, as the error counters don't take into -account things like system uptime, memory error bursts (that could be -caused by a solar storm, for example), etc. +1. can be easily accounted on userspace; +2. they're not really meaningful. E. g. one system with, let's say + 10 corrected errors can be fine, while another one with the same amount + of errors can have problems, as the error counters don't take into + account things like system uptime, memory error bursts (that could be + caused by a solar storm, for example), etc. So, the idea since them was to make the kernel-userspace interface simpler and move the policy to the userspace daemon. It is up to the @@ -81,60 +81,84 @@ needed. COMPILING AND INSTALLING ======================== -sqlite3 and autoconf needs to be installed. On Fedora, this is done -by installing the following packages: - make - gcc - autoconf - automake - libtool - tar - sqlite-devel (if sqlite3 will be used) - perl-DBD-SQLite (if sqlite3 will be used) +sqlite3 and autoconf needs to be installed. On Fedora, this is done by +installing the following packages: + +``` + make + gcc + autoconf + automake + libtool + libtraceevent-devel + tar + sqlite-devel (if sqlite3 will be used) + perl-DBD-SQLite (if sqlite3 will be used) +``` To install then on Fedora, run: - yum install -y make gcc autoconf automake libtool tar perl-dbd-sqlite - +``` + $ dnf install -y make gcc autoconf automake libtool tar perl-dbd-sqlite \ + libtraceevent-devel +``` Or, if sqlite3 database will be used to store data: - yum install -y make gcc autoconf automake libtool tar sqlite-devel + +``` + $ dnf install -y make gcc autoconf automake libtool tar sqlite-devel \ + libtraceevent-devel +``` There are currently 3 features that are enabled optionally, via ./configure parameters: - --enable-sqlite3 enable storing data at SQL lite database (currently +``` + --enable-sqlite3 enable storing data at SQL lite database (currently experimental) - --enable-aer enable PCIe AER events (currently experimental) - --enable-mce enable MCE events (currently experimental) + --enable-aer enable PCIe AER events (currently experimental) + --enable-mce enable MCE events (currently experimental) +``` In order to compile it, run: - $ autoreconf -vfi - $ ./configure [parameters] - $ make +``` + $ autoreconf -vfi + $ ./configure [parameters] + $ make +``` So, for example, to enable everything but sqlite3: - $ autoreconf -vfi && ./configure --enable-aer --enable-mce && make +``` + $ autoreconf -vfi && ./configure --enable-aer --enable-mce && make +``` After compiling, run, as root: - # make install +``` + $ make install +``` -COMPILING AND INSTALLING -======================== +RPM-based compilation +===================== If the distribution is rpm-based, an alternative method would be to do: - $ autoreconf -vfi && ./configure +``` + $ autoreconf -vfi && ./configure +``` The above procedure will generate a file at misc/rasdaemon.spec. -You may edit it, in order to add/remove the --enable-[option] +You may edit it, in order to add/remove the --enable-\[option\] parameters. To generate the rpm files, do: - $ make dist-rpm +``` + # make mock +``` To install the rpm files, run, as root: - # rpm -i `rpm --eval %{_topdir}`/RPMS/x86_64/rasdaemon-0.*.fc18.x86_64.rpm +``` + # rpm -i $(ls SRPMS/rasdaemon-*.rpm|tail -1) +``` RUNNING ======= @@ -146,18 +170,29 @@ is mounted and use it while running. To run the rasdaemon in background, just call it without any parameters: - # rasdaemon +``` + # rasdaemon +``` The output will be available via syslog. Or, to run it in foreground and see the logs in console, run it as: - # rasdaemon -f + +``` + # rasdaemon -f +``` or, if you also want to record errors at the database (--enable-sqlite3 is required): - # rasdaemon -f -r + +``` + # rasdaemon -f -r +``` You may also start it via systemd: - # systemctl start rasdaemon + +``` + # systemctl start rasdaemon +``` The rasdaemon will then output the messages to journald. @@ -166,41 +201,47 @@ TESTING A script is provided under /contrib, in order to test the daemon EDAC handler. While the daemon is running, just run: - # contrib/edac-fake-inject + +``` +# contrib/edac-fake-inject +``` The script requires a Kernel compiled with CONFIG_EDAC_DEBUG and a running EDAC driver. MCE error handling can use the MCE inject: - https://git.kernel.org/pub/scm/utils/cpu/mce/mce-inject.git + + For it to work, Kernel mce-inject module should be compiled and loaded. APEI error injection can use this tool: - https://git.kernel.org/pub/scm/linux/kernel/git/gong.chen/mce-test.git/ + AER error injection can use this tool: - https://git.kernel.org/pub/scm/linux/kernel/git/gong.chen/aer-inject.git/ + -SUBMITTING PATCHES -================== +# SUBMITTING PATCHES If you want to help improving this tool, be my guest! We try to follow -the Kernel's CodingStyle and submission rules as a reference. +the Kernel's CodingStyle and submission rules as a reference. -Please send patches enclosed in an email, in plain text, to: +In order to contribute with rasdaemon, please send a Merge Request via +github repository at: - linux-edac@vger.kernel.org +- -With a copy to: +Or, alternatively, send a pull request against gitlab repository at: - Mauro Carvalho Chehab +- -Or, alternatively, send a pull request against github or gitlab repositories at: +It is also recommended to send patches to +with a copy to: - https://github.com/mchehab/rasdaemon - https://gitlab.com/mchehab_kernel/rasdaemon +- Mauro Carvalho Chehab \<\> -(github preferred) +Please notice that github is the preferred way. If you're not using +it, please be kind enough to add an issue there for us to track the +patch series. Don't foget to add a description of the patch in the body of the email, adding a Signed-off-by: at the end of the patch description (before the unified diff @@ -209,44 +250,47 @@ with the patch). We use Signed-off-by the same way as in kernel, so I'm transcribing bellow the same text as found under Kernel's Documentation/SubmittingPatches: - "To improve tracking of who did what, especially with patches that can - percolate to their final resting place in the kernel through several - layers of maintainers, we've introduced a "sign-off" procedure on - patches that are being emailed around. +``` + "To improve tracking of who did what, especially with patches that can + percolate to their final resting place in the kernel through several + layers of maintainers, we've introduced a "sign-off" procedure on + patches that are being emailed around. - The sign-off is a simple line at the end of the explanation for the - patch, which certifies that you wrote it or otherwise have the right to - pass it on as an open-source patch. The rules are pretty simple: if you - can certify the below: + The sign-off is a simple line at the end of the explanation for the + patch, which certifies that you wrote it or otherwise have the right to + pass it on as an open-source patch. The rules are pretty simple: if you + can certify the below: - Developer's Certificate of Origin 1.1 + Developer's Certificate of Origin 1.1 - By making a contribution to this project, I certify that: + By making a contribution to this project, I certify that: - (a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license indicated in the file; or - (b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. - (c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. - (d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. + then you just add a line saying - then you just add a line saying + Signed-off-by: Random J Developer - Signed-off-by: Random J Developer + using your real name (sorry, no pseudonyms or anonymous contributions.)" - using your real name (sorry, no pseudonyms or anonymous contributions.)" +``` diff --git a/configure.ac b/configure.ac index 33b81fe..a1c7372 100644 --- a/configure.ac +++ b/configure.ac @@ -1,18 +1,17 @@ -AC_INIT([RASdaemon], 0.6.7) +AC_INIT([RASdaemon],[0.8.0]) AM_SILENT_RULES([yes]) -AC_CANONICAL_SYSTEM +AC_CANONICAL_TARGET AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE AC_PROG_CC AC_PROG_INSTALL -AC_PROG_LIBTOOL +LT_INIT X_AC_META AC_CONFIG_FILES([ Makefile - libtrace/Makefile man/Makefile man/ras-mc-ctl.8 man/rasdaemon.1 @@ -27,140 +26,167 @@ AC_ARG_ENABLE([all], AC_ARG_ENABLE([sqlite3], AS_HELP_STRING([--enable-sqlite3], [enable storing data at SQL lite database (currently experimental)])) -AS_IF([test "x$enable_sqlite3" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_sqlite3" = "xyes" || test "x$enable_all" = "xyes"], [ AC_CHECK_LIB(sqlite3, sqlite3_open,[echo "found sqlite3"] , AC_MSG_ERROR([*** Unable to find sqlite3 library]), ) SQLITE3_LIBS="-lsqlite3" AC_DEFINE(HAVE_SQLITE3,1,"have sqlite3") AC_SUBST([WITH_SQLITE3]) ]) -AM_CONDITIONAL([WITH_SQLITE3], [test x$enable_sqlite3 = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_SQLITE3], [test x$enable_sqlite3 = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_SQLITE3], [USE_SQLITE3="yes"], [USE_SQLITE3="no"]) AC_SUBST([SQLITE3_LIBS]) +has_libtraceevent_ver=0 +dnl check for tracevent library +PKG_CHECK_MODULES([LIBTRACEEVENT], [libtraceevent], [has_libtraceevent_ver=1]) + +AS_IF([test "$has_libtraceevent_ver" -eq 0], [ + AC_MSG_ERROR([libtraceevent is required but were not found]) +]) AC_ARG_ENABLE([aer], AS_HELP_STRING([--enable-aer], [enable PCIe AER events (currently experimental)])) -AS_IF([test "x$enable_aer" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_aer" = "xyes" || test "x$enable_all" = "xyes"], [ AC_DEFINE(HAVE_AER,1,"have PCIe AER events collect") AC_SUBST([WITH_AER]) ]) -AM_CONDITIONAL([WITH_AER], [test x$enable_aer = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_AER], [test x$enable_aer = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_AER], [USE_AER="yes"], [USE_AER="no"]) AC_ARG_ENABLE([non_standard], AS_HELP_STRING([--enable-non-standard], [enable NON_STANDARD events (currently experimental)])) -AS_IF([test "x$enable_non_standard" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_non_standard" = "xyes" || test "x$enable_all" = "xyes"], [ AC_DEFINE(HAVE_NON_STANDARD,1,"have UNKNOWN_SEC events collect") AC_SUBST([WITH_NON_STANDARD]) ]) -AM_CONDITIONAL([WITH_NON_STANDARD], [test x$enable_non_standard = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_NON_STANDARD], [test x$enable_non_standard = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_NON_STANDARD], [USE_NON_STANDARD="yes"], [USE_NON_STANDARD="no"]) AC_ARG_ENABLE([arm], AS_HELP_STRING([--enable-arm], [enable ARM events (currently experimental)])) -AS_IF([test "x$enable_arm" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_arm" = "xyes" || test "x$enable_all" = "xyes"], [ AC_DEFINE(HAVE_ARM,1,"have ARM events collect") AC_SUBST([WITH_ARM]) ]) -AM_CONDITIONAL([WITH_ARM], [test x$enable_arm = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_ARM], [test x$enable_arm = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_ARM], [USE_ARM="yes"], [USE_ARM="no"]) AC_ARG_ENABLE([mce], AS_HELP_STRING([--enable-mce], [enable MCE events (currently experimental)])) -AS_IF([test "x$enable_mce" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_mce" = "xyes" || test "x$enable_all" = "xyes"], [ AC_DEFINE(HAVE_MCE,1,"have PCIe MCE events collect") AC_SUBST([WITH_MCE]) ]) -AM_CONDITIONAL([WITH_MCE], [test x$enable_mce = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_MCE], [test x$enable_mce = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_MCE], [USE_MCE="yes"], [USE_MCE="no"]) AC_ARG_ENABLE([extlog], AS_HELP_STRING([--enable-extlog], [enable EXTLOG events (currently experimental)])) -AS_IF([test "x$enable_extlog" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_extlog" = "xyes" || test "x$enable_all" = "xyes"], [ AC_DEFINE(HAVE_EXTLOG,1,"have EXTLOG events collect") AC_SUBST([WITH_EXTLOG]) ]) -AM_CONDITIONAL([WITH_EXTLOG], [test x$enable_extlog = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_EXTLOG], [test x$enable_extlog = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_EXTLOG], [USE_EXTLOG="yes"], [USE_EXTLOG="no"]) AC_ARG_ENABLE([devlink], AS_HELP_STRING([--enable-devlink], [enable devlink health events (currently experimental)])) -AS_IF([test "x$enable_devlink" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_devlink" = "xyes" || test "x$enable_all" = "xyes"], [ AC_DEFINE(HAVE_DEVLINK,1,"have devlink health events collect") AC_SUBST([WITH_DEVLINK]) ]) -AM_CONDITIONAL([WITH_DEVLINK], [test x$enable_devlink = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_DEVLINK], [test x$enable_devlink = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_DEVLINK], [USE_DEVLINK="yes"], [USE_DEVLINK="no"]) AC_ARG_ENABLE([diskerror], AS_HELP_STRING([--enable-diskerror], [enable disk I/O error events (currently experimental)])) -AS_IF([test "x$enable_diskerror" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_diskerror" = "xyes" || test "x$enable_all" = "xyes"], [ AC_DEFINE(HAVE_DISKERROR,1,"have disk I/O errors collect") AC_SUBST([WITH_DISKERROR]) ]) -AM_CONDITIONAL([WITH_DISKERROR], [test x$enable_diskerror = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_DISKERROR], [test x$enable_diskerror = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_DISKERROR], [USE_DISKERROR="yes"], [USE_DISKERROR="no"]) AC_ARG_ENABLE([memory_failure], AS_HELP_STRING([--enable-memory-failure], [enable memory failure events (currently experimental)])) -AS_IF([test "x$enable_memory_failure" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_memory_failure" = "xyes" || test "x$enable_all" = "xyes"], [ AC_DEFINE(HAVE_MEMORY_FAILURE,1,"have memory failure events collect") AC_SUBST([WITH_MEMORY_FAILURE]) ]) -AM_CONDITIONAL([WITH_MEMORY_FAILURE], [test x$enable_memory_failure = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_MEMORY_FAILURE], [test x$enable_memory_failure = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_MEMORY_FAILURE], [USE_MEMORY_FAILURE="yes"], [USE_MEMORY_FAILURE="no"]) +AC_ARG_ENABLE([cxl], + AS_HELP_STRING([--enable-cxl], [enable CXL events (currently experimental)])) + +AS_IF([test "x$enable_cxl" = "xyes" || test "x$enable_all" == "xyes"], [ + AC_DEFINE(HAVE_CXL,1,"have CXL events collect") + AC_SUBST([WITH_CXL]) +]) +AM_CONDITIONAL([WITH_CXL], [test x$enable_cxl = xyes || test x$enable_all == xyes]) +AM_COND_IF([WITH_CXL], [USE_CXL="yes"], [USE_CXL="no"]) + AC_ARG_ENABLE([abrt_report], AS_HELP_STRING([--enable-abrt-report], [enable report event to ABRT (currently experimental)])) -AS_IF([test "x$enable_abrt_report" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_abrt_report" = "xyes" || test "x$enable_all" = "xyes"], [ AC_DEFINE(HAVE_ABRT_REPORT,1,"have report event to ABRT") AC_SUBST([WITH_ABRT_REPORT]) ]) -AM_CONDITIONAL([WITH_ABRT_REPORT], [test x$enable_abrt_report = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_ABRT_REPORT], [test x$enable_abrt_report = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_ABRT_REPORT], [USE_ABRT_REPORT="yes"], [USE_ABRT_REPORT="no"]) AC_ARG_ENABLE([hisi_ns_decode], AS_HELP_STRING([--enable-hisi-ns-decode], [enable HISI_NS_DECODE events (currently experimental)])) -AS_IF([test "x$enable_hisi_ns_decode" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_hisi_ns_decode" = "xyes" || test "x$enable_all" = "xyes"], [ AC_DEFINE(HAVE_HISI_NS_DECODE,1,"have HISI UNKNOWN_SEC events decode") AC_SUBST([WITH_HISI_NS_DECODE]) ]) -AM_CONDITIONAL([WITH_HISI_NS_DECODE], [test x$enable_hisi_ns_decode = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_HISI_NS_DECODE], [test x$enable_hisi_ns_decode = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_HISI_NS_DECODE], [USE_HISI_NS_DECODE="yes"], [USE_HISI_NS_DECODE="no"]) AC_ARG_ENABLE([memory_ce_pfa], AS_HELP_STRING([--enable-memory-ce-pfa], [enable memory Corrected Error predictive failure analysis])) -AS_IF([test "x$enable_memory_ce_pfa" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_memory_ce_pfa" = "xyes" || test "x$enable_all" = "xyes"], [ AC_DEFINE(HAVE_MEMORY_CE_PFA,1,"have memory corrected error predictive failure analysis") AC_SUBST([WITH_MEMORY_CE_PFA]) ]) -AM_CONDITIONAL([WITH_MEMORY_CE_PFA], [test x$enable_memory_ce_pfa = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_MEMORY_CE_PFA], [test x$enable_memory_ce_pfa = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_MEMORY_CE_PFA], [USE_MEMORY_CE_PFA="yes"], [USE_MEMORY_CE_PFA="no"]) AC_ARG_ENABLE([amp_ns_decode], AS_HELP_STRING([--enable-amp-ns-decode], [enable AMP_NS_DECODE events (currently experimental)])) -AS_IF([test "x$enable_amp_ns_decode" = "xyes" || test "x$enable_all" == "xyes"], [ +AS_IF([test "x$enable_amp_ns_decode" = "xyes" || test "x$enable_all" = "xyes"], [ AC_DEFINE(HAVE_AMP_NS_DECODE,1,"have AMP UNKNOWN_SEC events decode") AC_SUBST([WITH_AMP_NS_DECODE]) ]) -AM_CONDITIONAL([WITH_AMP_NS_DECODE], [test x$enable_amp_ns_decode = xyes || test x$enable_all == xyes]) +AM_CONDITIONAL([WITH_AMP_NS_DECODE], [test x$enable_amp_ns_decode = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_AMP_NS_DECODE], [USE_AMP_NS_DECODE="yes"], [USE_AMP_NS_DECODE="no"]) +AC_ARG_ENABLE([cpu_fault_isolation], + AS_HELP_STRING([--enable-cpu-fault-isolation], [enable cpu online fault isolation])) + +AS_IF([test "x$enable_cpu_fault_isolation" = "xyes" || test "x$enable_all" = "xyes"], [ + AC_DEFINE(HAVE_CPU_FAULT_ISOLATION,1,"have cpu online fault isolation") + AC_SUBST([WITH_CPU_FAULT_ISOLATION]) +]) +AM_CONDITIONAL([WITH_CPU_FAULT_ISOLATION], [test x$enable_cpu_fault_isolation = xyes || test x$enable_all = xyes]) +AM_COND_IF([WITH_CPU_FAULT_ISOLATION], [USE_CPU_FAULT_ISOLATION="yes"], [USE_CPU_FAULT_ISOLATION="no"]) + test "$sysconfdir" = '${prefix}/etc' && sysconfdir=/etc CFLAGS="$CFLAGS -Wall -Wmissing-prototypes -Wstrict-prototypes" @@ -170,11 +196,16 @@ AC_DEFINE_DIR([RASSTATEDIR], [rasstatedir], [rasdaemon db store state dir]) AC_SUBST([RASSTATEDIR]) AC_ARG_WITH(sysconfdefdir, - AC_HELP_STRING([--with-sysconfdefdir=DIR], [rasdaemon environment file dir]), + AS_HELP_STRING([--with-sysconfdefdir=DIR],[rasdaemon environment file dir]), [SYSCONFDEFDIR=$withval], [SYSCONFDEFDIR=/etc/sysconfig]) AC_SUBST([SYSCONFDEFDIR]) +AC_ARG_VAR([IPMITOOL], [location of the ipmitool command used on Ampere Altra]) +AS_IF([test "x$IPMITOOL" != "x"], [ + AC_DEFINE_UNQUOTED([IPMITOOL_CMD], ["${IPMITOOL}"], "ipmitool cmd path") +]) + AC_DEFINE([RAS_DB_FNAME], ["ras-mc_event.db"], [ras events database]) AC_SUBST([RAS_DB_FNAME], ["ras-mc_event.db"]) @@ -199,6 +230,8 @@ compile time options summary DEVLINK : $USE_DEVLINK Disk I/O errors : $USE_DISKERROR Memory Failure : $USE_MEMORY_FAILURE + CXL events : $USE_CXL Memory CE PFA : $USE_MEMORY_CE_PFA AMP RAS errors : $USE_AMP_NS_DECODE + CPU fault isolation : $USE_CPU_FAULT_ISOLATION EOF diff --git a/dmi_processor_info.c b/dmi_processor_info.c new file mode 100644 index 0000000..3eb5c52 --- /dev/null +++ b/dmi_processor_info.c @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Code adapted from util-linux/sys-utils/lscpu-dmi.c lscpu.h lscpu-virt.c + * Copyright (C) 2020 FUJITSU LIMITED. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dmi_processor_info.h" + +#define _PATH_SYS_DMI "/sys/firmware/dmi/tables/DMI" + +struct lscpu_cputype { + char *bios_vendor; + char *bios_modelname; + char *bios_family; +}; + +struct lscpu_dmi_header +{ + uint8_t type; + uint8_t length; + uint16_t handle; + uint8_t *data; +}; + +#define MIN_DMI_HEADER_LEN 4 + +struct dmi_info { + char *vendor; + char *product; + char *manufacturer; + int sockets; + + /* Processor Information */ + uint16_t processor_family; + char *processor_manufacturer; + char *processor_version; + uint16_t current_speed; + char *part_num; +}; + +static void to_dmi_header(struct lscpu_dmi_header *h, uint8_t *data) +{ + h->type = data[0]; + h->length = data[1]; + memcpy(&h->handle, data + 2, sizeof(h->handle)); + h->data = data; +} + +static char *dmi_string(const struct lscpu_dmi_header *dm, uint8_t s) +{ + char *bp = (char *)dm->data; + + if (!s || !bp) + return NULL; + + bp += dm->length; + while (s > 1 && *bp) { + bp += strlen(bp); + bp++; + s--; + } + + return !*bp ? NULL : bp; +} + +static int parse_dmi_table(uint16_t len, uint16_t num, + uint8_t *data, + struct dmi_info *di) +{ + uint8_t *buf = data; + int rc = -1; + int i = 0; + + while (i < num && data + MIN_DMI_HEADER_LEN <= buf + len) { + uint8_t *next; + struct lscpu_dmi_header h; + + to_dmi_header(&h, data); + + /* + * If a short entry is found (less than 4 bytes), not only it + * is invalid, but we cannot reliably locate the next entry. + * Better stop at this point. + */ + if (h.length < MIN_DMI_HEADER_LEN) + goto done; + + /* + * Look for the next handle, skipping the possible strings section, + * ending with 2 null bytes (even when empty). + */ + next = data + h.length; + while (next - buf + 1 < len && (next[0] != 0 || next[1] != 0)) + next++; + next += 2; + + /* + * Types and data offsets are defined in the System Management BIOS + * (SMBIOS) Reference specification. + */ + switch (h.type) { + case 0: + di->vendor = dmi_string(&h, data[0x04]); + break; + case 1: + di->manufacturer = dmi_string(&h, data[0x04]); + di->product = dmi_string(&h, data[0x05]); + break; + case 4: + /* Get the first processor information */ + if (di->sockets == 0) { + di->processor_manufacturer = dmi_string(&h, data[0x7]); + di->processor_version = dmi_string(&h, data[0x10]); + di->current_speed = *((uint16_t *)(&data[0x16])); + di->part_num = dmi_string(&h, data[0x22]); + + if (data[0x6] == 0xfe) + di->processor_family = *((uint16_t *)(&data[0x28])); + else + di->processor_family = data[0x6]; + } + di->sockets++; + break; + default: + break; + } + + data = next; + i++; + } + rc = 0; +done: + return rc; +} + +static inline ssize_t read_all(int fd, char *buf, size_t count) +{ + ssize_t ret; + ssize_t c = 0; + int tries = 0; + + memset(buf, 0, count); + while (count > 0) { + ret = read(fd, buf, count); + if (ret < 0) { + if ((errno == EAGAIN || errno == EINTR) && (tries++ < 5)) { + usleep(250000); + continue; + } + return c ? c : -1; + } + if (ret == 0) + return c; + tries = 0; + count -= ret; + buf += ret; + c += ret; + } + return c; +} + +static void *get_mem_chunk(size_t base, size_t len, const char *devmem) +{ + void *p = NULL; + int fd; + + if ((fd = open(devmem, O_RDONLY)) < 0) + return NULL; + + if (!(p = malloc(len))) + goto nothing; + if (lseek(fd, base, SEEK_SET) == -1) + goto nothing; + if (read_all(fd, p, len) == -1) + goto nothing; + + close(fd); + return p; + +nothing: + free(p); + close(fd); + return NULL; +} + +static int dmi_decode_cputype(struct lscpu_cputype *ct) +{ + static char const sys_fw_dmi_tables[] = _PATH_SYS_DMI; + struct dmi_info di = { }; + struct stat st; + uint8_t *data; + int rc = -1; + char buf[100] = { }; + + if (stat(sys_fw_dmi_tables, &st)) + return rc; + + data = get_mem_chunk(0, st.st_size, sys_fw_dmi_tables); + if (!data) + return rc; + + rc = parse_dmi_table(st.st_size, st.st_size/4, data, &di); + if (rc < 0) { + free(data); + return rc; + } + + if (di.processor_manufacturer) + ct->bios_vendor = strdup(di.processor_manufacturer); + + snprintf(buf, sizeof(buf), "%s %s CPU @ %d.%dGHz", + (di.processor_version ?: ""), (di.part_num ?: ""), + di.current_speed/1000, (di.current_speed % 1000) / 100); + ct->bios_modelname = strdup(buf); + + /* Get CPU family */ + memset(buf, 0, sizeof(buf)); + snprintf(buf, sizeof(buf), "%d", di.processor_family); + ct->bios_family = strdup(buf); + + free(data); + return 0; +} + + +#define AMPERE_PREFIX "Ampere(R) Altra(R)" +int is_ampere_altra(void) +{ + int rc = 0; + struct lscpu_cputype c; + c.bios_vendor = NULL; + c.bios_modelname = NULL; + c.bios_family = NULL; + + if (dmi_decode_cputype(&c) != 0) + return 0; + + /* + * This depends on BIOS implementation to provide the CPU information. + * If the BIOS doesn't provide it or gives a different string, the + * ipmitool use will be disabled. + */ + if (strncmp(c.bios_modelname, AMPERE_PREFIX, strlen(AMPERE_PREFIX)) == 0) + rc = 1; + + if (c.bios_vendor) + free(c.bios_vendor); + if (c.bios_modelname) + free(c.bios_modelname); + if (c.bios_family) + free(c.bios_family); + return rc; +} diff --git a/dmi_processor_info.h b/dmi_processor_info.h new file mode 100644 index 0000000..3e3099a --- /dev/null +++ b/dmi_processor_info.h @@ -0,0 +1,2 @@ +#include "config.h" +int is_ampere_altra(void); diff --git a/labels/asrock b/labels/asrock new file mode 100644 index 0000000..cf0a765 --- /dev/null +++ b/labels/asrock @@ -0,0 +1,27 @@ +# RASDAEMON Motherboard DIMM labels Database file. +# +# Vendor-name and model-name are found from the program 'dmidecode' +# labels are found from the silk screen on the motherboard. +# +#Vendor: +# Product: +# Model: +#