]> www.infradead.org Git - users/mchehab/rasdaemon.git/commitdiff
rasdaemon: Fix for vendor errors are not recorded in the SQLite database if some...
authorShiju Jose <shiju.jose@huawei.com>
Wed, 20 Mar 2024 12:16:05 +0000 (12:16 +0000)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Tue, 11 Jun 2024 09:54:37 +0000 (11:54 +0200)
Fix for vendor errors are not recorded in the SQLite database if some cpus
are offline at the system start.

Issue:

This issue is reproducible by offline some cpus, run
./rasdaemon -f --record & and
inject vendor specific error supported in the rasdaemon.

Reason:

When the system starts with some of the cpus offline and then run
the rasdaemon, read_ras_event_all_cpus() exit with error and switch to
the multi thread way. However read() in read_ras_event() return error in
threads for each of the offline CPUs and does clean up including calling
ras_ns_finalize_vendor_tables(), which invokes sqlite3_finalize() on vendor
tables created. Thus the vendor error data does not stored in the SQLite
database when such error is reported next time.

Solution:

In ras_ns_add_vendor_tables() and ras_ns_finalize_vendor_tables() use
reference count and close vendor tables which created in ras_ns_add_vendor_tables()
based on the reference count.

Reported-by: Junhao He <hejunhao3@huawei.com>
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
ras-non-standard-handler.c
ras-non-standard-handler.h

index 940fd87ffa5ab19b8f439dcadd094eaaacd6d4bf..e21455aac686159c9b574f3882580b4f42fef913 100644 (file)
@@ -66,6 +66,7 @@ int register_ns_ev_decoder(struct ras_ns_ev_decoder *ns_ev_decoder)
 #endif
        if (!ras_ns_ev_dec_list) {
                ras_ns_ev_dec_list = ns_ev_decoder;
+               ras_ns_ev_dec_list->ref_count = 0;
        } else {
                list = ras_ns_ev_dec_list;
                while (list->next)
@@ -86,6 +87,8 @@ int ras_ns_add_vendor_tables(struct ras_events *ras)
                return -1;
 
        ns_ev_decoder = ras_ns_ev_dec_list;
+       if (ras_ns_ev_dec_list)
+               ras_ns_ev_dec_list->ref_count++;
        while (ns_ev_decoder) {
                if (ns_ev_decoder->add_table && !ns_ev_decoder->stmt_dec_record) {
                        error = ns_ev_decoder->add_table(ras, ns_ev_decoder);
@@ -128,6 +131,16 @@ void ras_ns_finalize_vendor_tables(void)
 #ifdef HAVE_SQLITE3
        struct ras_ns_ev_decoder *ns_ev_decoder = ras_ns_ev_dec_list;
 
+       if (!ras_ns_ev_dec_list)
+               return;
+
+       if (ras_ns_ev_dec_list->ref_count > 0)
+               ras_ns_ev_dec_list->ref_count--;
+       else
+               return;
+       if (ras_ns_ev_dec_list->ref_count > 0)
+               return;
+
        while (ns_ev_decoder) {
                if (ns_ev_decoder->stmt_dec_record) {
                        ras_mc_finalize_vendor_table(ns_ev_decoder->stmt_dec_record);
@@ -141,6 +154,9 @@ void ras_ns_finalize_vendor_tables(void)
 static void unregister_ns_ev_decoder(void)
 {
 #ifdef HAVE_SQLITE3
+       if (!ras_ns_ev_dec_list)
+               return;
+       ras_ns_ev_dec_list->ref_count = 1;
        ras_ns_finalize_vendor_tables();
 #endif
        ras_ns_ev_dec_list = NULL;
index d19a5649cd80de5fc94d4aa291a525769d8e1d32..913ce00480b7b4115b2e2ea3a74480289e27ff04 100644 (file)
@@ -19,6 +19,7 @@
 
 struct ras_ns_ev_decoder {
        struct ras_ns_ev_decoder *next;
+       uint16_t ref_count;
        const char *sec_type;
        int (*add_table)(struct ras_events *ras, struct ras_ns_ev_decoder *ev_decoder);
        int (*decode)(struct ras_events *ras, struct ras_ns_ev_decoder *ev_decoder,