]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
plugins/solidigm: Added NLog support to Telemetry parsing.
authorleonardo.da.cunha <leo.da.cunha@solidigm.com>
Sat, 22 Apr 2023 00:19:50 +0000 (17:19 -0700)
committerDaniel Wagner <wagi@monom.org>
Thu, 1 Jun 2023 17:19:16 +0000 (19:19 +0200)
Telemetry Reason Identifier fields changed to start with lower case.

Signed-off-by: leonardo.da.cunha <leonardo.da.cunha@solidigm.com>
plugins/solidigm/solidigm-nvme.h
plugins/solidigm/solidigm-telemetry/cod.c
plugins/solidigm/solidigm-telemetry/config.c
plugins/solidigm/solidigm-telemetry/config.h
plugins/solidigm/solidigm-telemetry/data-area.c
plugins/solidigm/solidigm-telemetry/header.c
plugins/solidigm/solidigm-telemetry/meson.build
plugins/solidigm/solidigm-telemetry/nlog.c [new file with mode: 0644]
plugins/solidigm/solidigm-telemetry/nlog.h [new file with mode: 0644]

index 9d653069350cb3c094f5033d2dc9509d8aa5a521..bb56aeb1cfc1e5657e6552f5daf9f18ffac0eb52 100644 (file)
@@ -13,7 +13,7 @@
 
 #include "cmd.h"
 
-#define SOLIDIGM_PLUGIN_VERSION "0.11"
+#define SOLIDIGM_PLUGIN_VERSION "0.12"
 
 PLUGIN(NAME("solidigm", "Solidigm vendor specific extensions", SOLIDIGM_PLUGIN_VERSION),
        COMMAND_LIST(
index 12cf42bbb4f90ba90e3fbb99017c6cafc591a6df..58a6e709ea4f5f2110f478ebe827634fc8e483fe 100644 (file)
@@ -118,7 +118,7 @@ void solidigm_telemetry_log_cod_parse(struct telemetry_log *tl)
                return;
        if (!json_object_object_get_ex(telemetry_header, "reasonIdentifier", &reason_id))
                return;
-       if  (!json_object_object_get_ex(reason_id, "OemDataMapOffset", &COD_offset))
+       if  (!json_object_object_get_ex(reason_id, "oemDataMapOffset", &COD_offset))
                return;
 
        uint64_t offset = json_object_get_int(COD_offset);
index 5111703123f6861d30c6a8a51ffd21004168e3ef..cc2a8bb0ed5360a2312e72e881a381ebd1dd2f8d 100644 (file)
@@ -4,13 +4,17 @@
  *
  * Author: leonardo.da.cunha@solidigm.com
  */
-#include <stdbool.h>
-#include "util/json.h"
+
 #include <stdio.h>
+#include <string.h>
+#include "config.h"
 
 // max 16 bit unsigned integer nummber 65535
 #define MAX_16BIT_NUM_AS_STRING_SIZE  6
 
+#define OBJ_NAME_PREFIX "UID_"
+#define NLOG_OBJ_PREFIX OBJ_NAME_PREFIX "NLOG_"
+
 static bool config_get_by_version(const struct json_object *obj, int version_major,
                                  int version_minor, struct json_object **value)
 {
@@ -28,17 +32,45 @@ static bool config_get_by_version(const struct json_object *obj, int version_maj
        return value != NULL;
 }
 
-bool solidigm_config_get_by_token_version(const struct json_object *obj, int token_id,
+bool solidigm_config_get_struct_by_token_version(const struct json_object *config, int token_id,
                                          int version_major, int version_minor,
                                          struct json_object **value)
 {
-       struct json_object *token_obj = NULL;
+       struct json_object *token = NULL;
        char str_key[MAX_16BIT_NUM_AS_STRING_SIZE];
 
        snprintf(str_key, sizeof(str_key), "%d", token_id);
-       if (!json_object_object_get_ex(obj, str_key, &token_obj))
+       if (!json_object_object_get_ex(config, str_key, &token))
                return false;
-       if  (!config_get_by_version(token_obj, version_major, version_minor, value))
+       if  (!config_get_by_version(token, version_major, version_minor, value))
                return false;
        return value != NULL;
 }
+
+const char *solidigm_config_get_nlog_obj_name(const struct json_object *config, uint32_t token)
+{
+       struct json_object *nlog_names = NULL;
+       struct json_object *obj_name;
+       char hex_header[STR_HEX32_SIZE];
+       const char *name;
+
+       if (!json_object_object_get_ex(config, "TELEMETRY_OBJECT_UIDS", &nlog_names))
+               return NULL;
+       snprintf(hex_header, STR_HEX32_SIZE, "0x%08X", token);
+
+       if (!json_object_object_get_ex(nlog_names, hex_header, &obj_name))
+               return NULL;
+       name = json_object_get_string(obj_name);
+       if (strncmp(NLOG_OBJ_PREFIX, name, strlen(NLOG_OBJ_PREFIX)))
+               return NULL;
+
+       return &name[strlen(OBJ_NAME_PREFIX)];
+}
+
+struct json_object *solidigm_config_get_nlog_formats(const struct json_object *config)
+{
+       struct json_object *nlog_formats = NULL;
+
+       json_object_object_get_ex(config, "NLOG_FORMATS", &nlog_formats);
+       return nlog_formats;
+}
index 30e61ffb9cc8c6fb91d6c6766b3f1f1744f63722..4e56ba3b5c69aa549d23486339965b548cbef4dc 100644 (file)
@@ -7,7 +7,13 @@
 #include <stdbool.h>
 #include "util/json.h"
 
-bool solidigm_config_get_by_token_version(const struct json_object *obj,
+#define STR_HEX32_SIZE sizeof("0x00000000")
+
+bool solidigm_config_get_struct_by_token_version(const struct json_object *obj,
                                          int key, int subkey,
                                          int subsubkey,
                                          struct json_object **value);
+
+const char *solidigm_config_get_nlog_obj_name(const struct json_object *config, uint32_t token);
+struct json_object *solidigm_config_get_nlog_formats(const struct json_object *config);
+
index 31f7836cd4b4759d45f9527951e54320c282f676..93ea0fff21482312449a2990700eb778ee2fcdb6 100644 (file)
@@ -10,6 +10,7 @@
 #include "cod.h"
 #include "data-area.h"
 #include "config.h"
+#include "nlog.h"
 #include <ctype.h>
 
 #define SIGNED_INT_PREFIX "int"
@@ -302,6 +303,27 @@ static int telemetry_log_data_area_get_offset(const struct telemetry_log *tl,
        return 0;
 }
 
+static int telemetry_log_nlog_parse(const struct telemetry_log *tl, struct json_object *formats,
+                                   uint64_t nlog_file_offset,  uint64_t nlog_size,
+                                   struct json_object *output, struct json_object *metadata)
+{
+       /* boundary check */
+       if (tl->log_size < (nlog_file_offset + nlog_size)) {
+               const char *name = "";
+               int media_bank = -1;
+               struct json_object *jobj;
+
+               if (json_object_object_get_ex(metadata, "objName", &jobj))
+                       name = json_object_get_string(jobj);
+               if (json_object_object_get_ex(metadata, "mediaBankId", &jobj))
+                       media_bank = json_object_get_int(jobj);
+               SOLIDIGM_LOG_WARNING("%s:%d do not fit this log dump.", name, media_bank);
+               return -1;
+       }
+       return solidigm_nlog_parse(((char *) tl->log) + nlog_file_offset,
+                                  nlog_size, formats, metadata, output);
+}
+
 struct toc_item {
        uint32_t OffsetBytes;
        uint32_t ContentSizeBytes;
@@ -328,7 +350,6 @@ struct telemetry_object_header {
        uint8_t Reserved[3];
 };
 
-
 static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
                                              enum nvme_telemetry_da da,
                                              struct json_object *toc_array,
@@ -340,18 +361,22 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
        char *payload;
        uint32_t da_offset;
        uint32_t da_size;
+       struct json_object *nlog_formats;
 
        if (telemetry_log_data_area_get_offset(tl, da, &da_offset, &da_size))
                return;
 
        toc = (struct table_of_contents *)(((char *)tl->log) + da_offset);
        payload = (char *) tl->log;
+       nlog_formats = solidigm_config_get_nlog_formats(tl->configuration);
 
        for (int i = 0; i < toc->header.TableOfContentsCount; i++) {
                struct json_object *structure_definition = NULL;
                struct json_object *toc_item;
                uint32_t obj_offset;
                bool has_struct;
+               const char *nlog_name = NULL;
+               uint32_t header_offset = sizeof(const struct telemetry_object_header);
 
                if ((char *)&toc->items[i] > (((char *)toc) + da_size - sizeof(const struct toc_item))) {
                        SOLIDIGM_LOG_WARNING("Warning: Data Area %d, "
@@ -381,38 +406,49 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
                json_object_add_value_uint(toc_item, "objectId", header->Token);
                json_object_add_value_uint(toc_item, "mediaBankId", header->CoreId);
 
-               has_struct = solidigm_config_get_by_token_version(tl->configuration,
+               has_struct = solidigm_config_get_struct_by_token_version(tl->configuration,
                                                                  header->Token,
                                                                  header->versionMajor,
                                                                  header->versionMinor,
                                                                  &structure_definition);
+               if (!has_struct) {
+                       if (!nlog_formats)
+                               continue;
+                       nlog_name = solidigm_config_get_nlog_obj_name(tl->configuration,
+                                                                       header->Token);
+                       if (!nlog_name)
+                               continue;
+               }
+               struct json_object *tele_obj_item = json_create_object();
 
-               if (has_struct) {
-                       struct json_object *tele_obj_item = json_create_object();
-
-                       json_object_array_add(tele_obj_array, tele_obj_item);
-                       json_object_get(toc_item);
-                       json_object_add_value_object(tele_obj_item, "metadata", toc_item);
-                       struct json_object *parsed_struct = json_create_object();
-
-                       json_object_add_value_object(tele_obj_item, "objectData", parsed_struct);
-                       struct json_object *obj_hasTelemObjHdr = NULL;
-                       uint32_t header_offset = sizeof(const struct telemetry_object_header);
-                       uint64_t file_offset;
+               json_object_array_add(tele_obj_array, tele_obj_item);
+               json_object_get(toc_item);
+               json_object_add_value_object(tele_obj_item, "metadata", toc_item);
+               struct json_object *parsed_struct = json_create_object();
 
-                       if (json_object_object_get_ex(structure_definition,
-                                                     "hasTelemObjHdr",
-                                                      &obj_hasTelemObjHdr)) {
-                               bool hasHeader = json_object_get_boolean(obj_hasTelemObjHdr);
+               json_object_add_value_object(tele_obj_item, "objectData", parsed_struct);
+               struct json_object *obj_hasTelemObjHdr = NULL;
+               uint64_t object_file_offset;
 
-                               if (hasHeader)
-                                       header_offset = 0;
-                       }
+               if (json_object_object_get_ex(structure_definition,
+                                               "hasTelemObjHdr",
+                                               &obj_hasTelemObjHdr)) {
+                       bool hasHeader = json_object_get_boolean(obj_hasTelemObjHdr);
 
-                       file_offset = ((uint64_t)da_offset) + obj_offset + header_offset;
+                       if (hasHeader)
+                               header_offset = 0;
+               }
+               object_file_offset = ((uint64_t)da_offset) + obj_offset + header_offset;
+               if (has_struct) {
                        telemetry_log_structure_parse(tl, structure_definition,
-                                                     BITS_IN_BYTE * file_offset,
-                                                     parsed_struct, toc_item);
+                                               BITS_IN_BYTE * object_file_offset,
+                                               parsed_struct, toc_item);
+               } else if (nlog_formats) {
+                       json_object_object_add(toc_item, "objName",
+                                              json_object_new_string(nlog_name));
+                       telemetry_log_nlog_parse(tl, nlog_formats, object_file_offset,
+                                                toc->items[i].ContentSizeBytes - header_offset,
+                                                parsed_struct, toc_item);
                }
        }
 }
index 2f2684af7cbc03abff68087de4badd6f2ea4631b..bd488ae54cb100eb35e53ad752c8423ad4153cb2 100644 (file)
@@ -69,12 +69,18 @@ static void telemetry_log_reason_id_parse1_0_ext(const struct telemetry_log *tl,
        struct json_object *reserved;
 
        ri = (struct reason_indentifier_1_0 *) tl->log->rsnident;
-       json_object_object_add(reason_id, "FirmwareVersion", json_object_new_string_len(ri->FirmwareVersion, sizeof(ri->FirmwareVersion)));
-       json_object_object_add(reason_id, "BootloaderVersion", json_object_new_string_len(ri->BootloaderVersion, sizeof(ri->BootloaderVersion)));
-       json_object_object_add(reason_id, "SerialNumber", json_object_new_string_len(ri->SerialNumber, sizeof(ri->SerialNumber)));
+       json_object_object_add(reason_id, "firmwareVersion",
+                              json_object_new_string_len(ri->FirmwareVersion,
+                                                         sizeof(ri->FirmwareVersion)));
+       json_object_object_add(reason_id, "bootloaderVersion",
+                              json_object_new_string_len(ri->BootloaderVersion,
+                                                         sizeof(ri->BootloaderVersion)));
+       json_object_object_add(reason_id, "serialNumber",
+                              json_object_new_string_len(ri->SerialNumber,
+                                                         sizeof(ri->SerialNumber)));
 
        reserved = json_create_array();
-       json_object_add_value_array(reason_id, "Reserved", reserved);
+       json_object_add_value_array(reason_id, "reserved", reserved);
        for ( int i=0; i < sizeof(ri->Reserved); i++) {
                struct json_object *val = json_object_new_int(ri->Reserved[i]);
                json_object_array_add(reserved, val);
@@ -88,15 +94,24 @@ static void telemetry_log_reason_id_parse1_1_ext(const struct telemetry_log *tl,
        struct json_object *reserved;
 
        ri = (struct reason_indentifier_1_1 *) tl->log->rsnident;
-       json_object_object_add(reason_id, "FirmwareVersion", json_object_new_string_len(ri->FirmwareVersion, sizeof(ri->FirmwareVersion)));
-       json_object_object_add(reason_id, "BootloaderVersion", json_object_new_string_len(ri->BootloaderVersion, sizeof(ri->BootloaderVersion)));
-       json_object_object_add(reason_id, "SerialNumber", json_object_new_string_len(ri->SerialNumber, sizeof(ri->SerialNumber)));
-       json_object_add_value_uint64(reason_id, "OemDataMapOffset", le64_to_cpu(ri->OemDataMapOffset));
-       json_object_add_value_uint(reason_id, "TelemetryMajorVersion", le16_to_cpu(ri->TelemetryMajorVersion));
-       json_object_add_value_uint(reason_id, "TelemetryMinorVersion", le16_to_cpu(ri->TelemetryMinorVersion));
+       json_object_object_add(reason_id, "firmwareVersion",
+                              json_object_new_string_len(ri->FirmwareVersion,
+                                                         sizeof(ri->FirmwareVersion)));
+       json_object_object_add(reason_id, "bootloaderVersion",
+                              json_object_new_string_len(ri->BootloaderVersion,
+                                                         sizeof(ri->BootloaderVersion)));
+       json_object_object_add(reason_id, "serialNumber",
+                              json_object_new_string_len(ri->SerialNumber,
+                                                         sizeof(ri->SerialNumber)));
+       json_object_add_value_uint64(reason_id, "oemDataMapOffset",
+                                  le64_to_cpu(ri->OemDataMapOffset));
+       json_object_add_value_uint(reason_id, "telemetryMajorVersion",
+                                  le16_to_cpu(ri->TelemetryMajorVersion));
+       json_object_add_value_uint(reason_id, "telemetryMinorVersion",
+                                  le16_to_cpu(ri->TelemetryMinorVersion));
 
        reserved = json_create_array();
-       json_object_add_value_array(reason_id, "Reserved", reserved);
+       json_object_add_value_array(reason_id, "reserved", reserved);
        for (int i = 0; i < sizeof(ri->Reserved); i++) {
                struct json_object *val = json_object_new_int(ri->Reserved[i]);
                json_object_array_add(reserved, val);
@@ -112,21 +127,26 @@ static void telemetry_log_reason_id_parse1_2_ext(const struct telemetry_log *tl,
 
        ri = (struct reason_indentifier_1_2 *) tl->log->rsnident;
 
-       json_object_object_add(reason_id, "SerialNumber", json_object_new_string_len(ri->SerialNumber, sizeof(ri->SerialNumber)));
-       json_object_add_value_uint64(reason_id, "OemDataMapOffset", le64_to_cpu(ri->OemDataMapOffset));
-       json_object_add_value_uint(reason_id, "TelemetryMajorVersion", le16_to_cpu(ri->TelemetryMajorVersion));
-       json_object_add_value_uint(reason_id, "TelemetryMinorVersion", le16_to_cpu(ri->TelemetryMinorVersion));
-       json_object_add_value_uint(reason_id, "ProductFamilyId", ri->ProductFamilyId);
+       json_object_object_add(reason_id, "serialNumber",
+                              json_object_new_string_len(ri->SerialNumber,
+                                                         sizeof(ri->SerialNumber)));
+       json_object_add_value_uint64(reason_id, "oemDataMapOffset",
+                                    le64_to_cpu(ri->OemDataMapOffset));
+       json_object_add_value_uint(reason_id, "telemetryMajorVersion",
+                                  le16_to_cpu(ri->TelemetryMajorVersion));
+       json_object_add_value_uint(reason_id, "telemetryMinorVersion",
+                                  le16_to_cpu(ri->TelemetryMinorVersion));
+       json_object_add_value_uint(reason_id, "productFamilyId", ri->ProductFamilyId);
 
        reserved = json_create_array();
-       json_object_add_value_array(reason_id, "Reserved2", reserved);
+       json_object_add_value_array(reason_id, "reserved2", reserved);
        for (int i = 0; i < sizeof(ri->Reserved2); i++) {
                struct json_object *val = json_object_new_int(ri->Reserved2[i]);
                json_object_array_add(reserved, val);
        }
 
        dp_reserved = json_create_array();
-       json_object_add_value_array(reason_id, "DualPortReserved", dp_reserved);
+       json_object_add_value_array(reason_id, "dualPortReserved", dp_reserved);
        for (int i = 0; i < sizeof(ri->DualPortReserved); i++) {
                struct json_object *val =  json_object_new_int(ri->DualPortReserved[i]);
                json_object_array_add(dp_reserved, val);
@@ -143,7 +163,9 @@ static void solidigm_telemetry_log_reason_id_parse(const struct telemetry_log *t
        json_object_add_value_uint(reason_id, "versionMajor", version_major);
        json_object_add_value_uint(reason_id, "versionMinor", version_minor);
        json_object_add_value_uint(reason_id, "reasonCode", le32_to_cpu(ri1_0->reasonCode));
-       json_object_add_value_object(reason_id, "DriveStatus", json_object_new_string_len(ri1_0->DriveStatus, sizeof(ri1_0->DriveStatus)));
+       json_object_add_value_object(reason_id, "driveStatus",
+                                    json_object_new_string_len(ri1_0->DriveStatus,
+                                                               sizeof(ri1_0->DriveStatus)));
        if (version_major == 1) {
                switch (version_minor) {
                        case 0:
index 53ab452c21ec97e3b0aa8cbfbfb946d055f95b84..96273b706da5c85046fc910e7fc620717a80dc1f 100644 (file)
@@ -3,4 +3,5 @@ sources += [
   'plugins/solidigm/solidigm-telemetry/header.c',
   'plugins/solidigm/solidigm-telemetry/config.c',
   'plugins/solidigm/solidigm-telemetry/data-area.c',
+  'plugins/solidigm/solidigm-telemetry/nlog.c',
 ]
diff --git a/plugins/solidigm/solidigm-telemetry/nlog.c b/plugins/solidigm/solidigm-telemetry/nlog.c
new file mode 100644 (file)
index 0000000..43b8918
--- /dev/null
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+#include "nlog.h"
+#include "config.h"
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+
+#define LOG_ENTRY_HEADER_SIZE 1
+#define LOG_ENTRY_TIMESTAMP_SIZE 2
+#define LOG_ENTRY_NUM_ARGS_MAX 8
+#define LOG_ENTRY_MAX_SIZE (LOG_ENTRY_HEADER_SIZE + LOG_ENTRY_TIMESTAMP_SIZE + \
+                           LOG_ENTRY_NUM_ARGS_MAX)
+#define NUM_ARGS_MASK ((1 << ((int)log2(LOG_ENTRY_NUM_ARGS_MAX)+1)) - 1)
+#define MAX_HEADER_MISMATCH_TRACK 10
+
+static int formats_find(struct json_object *formats, uint32_t val, struct json_object **format)
+{
+       char hex_header[STR_HEX32_SIZE];
+
+       snprintf(hex_header, STR_HEX32_SIZE, "0x%08X", val);
+       return json_object_object_get_ex(formats, hex_header, format);
+}
+
+static uint32_t nlog_get_pos(const uint32_t *nlog, const uint32_t nlog_size, int pos)
+{
+       return nlog[pos % nlog_size];
+}
+
+static uint32_t nlog_get_events(const uint32_t *nlog, const uint32_t nlog_size, int start_offset,
+              struct json_object *formats, struct json_object *events, uint32_t *tail_mismatches)
+{
+       uint32_t event_count = 0;
+       int last_bad_header_pos = nlog_size + 1; // invalid nlog offset
+       uint32_t tail_count = 0;
+
+       for (int i = nlog_size - start_offset - 1; i >= -start_offset; i--) {
+               struct json_object *format;
+               uint32_t header = nlog_get_pos(nlog, nlog_size, i);
+               uint32_t num_data;
+
+               if (header == 0 || !formats_find(formats, header, &format)) {
+                       if (event_count > 0) {
+                               //check if fould circular buffer tail
+                               if (i != (last_bad_header_pos - 1)) {
+                                       if (tail_mismatches &&
+                                           (tail_count < MAX_HEADER_MISMATCH_TRACK))
+                                               tail_mismatches[tail_count] = header;
+                                       tail_count++;
+                               }
+                               last_bad_header_pos = i;
+                       }
+                       continue;
+               }
+               num_data = header & NUM_ARGS_MASK;
+               if (events) {
+                       struct json_object *event = json_object_new_array();
+                       struct json_object *param = json_object_new_array();
+                       uint32_t val = nlog_get_pos(nlog, nlog_size, i - 1);
+
+                       json_object_array_add(events, event);
+                       json_object_array_add(event, json_object_new_int64(val));
+                       val = nlog_get_pos(nlog, nlog_size, i - 2);
+                       json_object_array_add(event, json_object_new_int64(val));
+                       json_object_array_add(event, json_object_new_int64(header));
+                       json_object_array_add(event, param);
+                       for (uint32_t j = 0; j < num_data; j++) {
+                               val = nlog_get_pos(nlog, nlog_size, i - 3 - j);
+                               json_object_array_add(param, json_object_new_int64(val));
+                       }
+                       json_object_get(format);
+                       json_object_array_add(event, format);
+               }
+               i -= 2 + num_data;
+               event_count++;
+       }
+       return tail_count;
+}
+
+int solidigm_nlog_parse(const char *buffer, uint64_t buff_size,        struct json_object *formats,
+                       struct json_object *metadata, struct json_object *output)
+{
+       uint32_t smaller_tail_count = UINT32_MAX;
+       int best_offset = 0;
+       uint32_t offset_tail_mismatches[LOG_ENTRY_MAX_SIZE][MAX_HEADER_MISMATCH_TRACK];
+       struct json_object *events = json_object_new_array();
+       const uint32_t *nlog = (uint32_t *)buffer;
+       const uint32_t nlog_size = buff_size / sizeof(uint32_t);
+
+       for (int i = 0; i < LOG_ENTRY_MAX_SIZE; i++) {
+               uint32_t tail_count = nlog_get_events(nlog, nlog_size, i, formats, NULL,
+                                                     offset_tail_mismatches[i]);
+               if (tail_count < smaller_tail_count) {
+                       best_offset = i;
+                       smaller_tail_count = tail_count;
+               }
+               if (tail_count == 0)
+                       break;
+       }
+       if (smaller_tail_count > 1) {
+               const char *name = "";
+               int media_bank = -1;
+               char str_mismatches[(STR_HEX32_SIZE + 1) * MAX_HEADER_MISMATCH_TRACK];
+               int pos = 0;
+               int show_mismatch_num = smaller_tail_count < MAX_HEADER_MISMATCH_TRACK ?
+                                       smaller_tail_count : MAX_HEADER_MISMATCH_TRACK;
+               struct json_object *jobj;
+
+               if (json_object_object_get_ex(metadata, "objName", &jobj))
+                       name = json_object_get_string(jobj);
+               if (json_object_object_get_ex(metadata, "mediaBankId", &jobj))
+                       media_bank = json_object_get_int(jobj);
+
+               for (int i = 0; i < show_mismatch_num; i++)
+                       pos += snprintf(&str_mismatches[pos], STR_HEX32_SIZE + 1, "0x%08X ",
+                                      offset_tail_mismatches[best_offset][i]);
+
+               SOLIDIGM_LOG_WARNING("%s:%d with %d header mismatches ( %s). Configuration file may be missing format headers.",
+                                     name, media_bank, smaller_tail_count, str_mismatches);
+       }
+       nlog_get_events(nlog, nlog_size, best_offset, formats, events, NULL);
+
+       json_object_object_add(output, "events", events);
+       return 0;
+}
diff --git a/plugins/solidigm/solidigm-telemetry/nlog.h b/plugins/solidigm/solidigm-telemetry/nlog.h
new file mode 100644 (file)
index 0000000..f33aa45
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+#include "telemetry-log.h"
+
+int solidigm_nlog_parse(const char *buffer, uint64_t bufer_size,
+                       struct json_object *formats, struct json_object *metadata,
+                       struct json_object *output);