summaryrefslogtreecommitdiffstats
path: root/plugins/solidigm/solidigm-telemetry/data-area.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/solidigm/solidigm-telemetry/data-area.c')
-rw-r--r--plugins/solidigm/solidigm-telemetry/data-area.c208
1 files changed, 128 insertions, 80 deletions
diff --git a/plugins/solidigm/solidigm-telemetry/data-area.c b/plugins/solidigm/solidigm-telemetry/data-area.c
index 2f18ea2..0cfa56c 100644
--- a/plugins/solidigm/solidigm-telemetry/data-area.c
+++ b/plugins/solidigm/solidigm-telemetry/data-area.c
@@ -6,25 +6,29 @@
*/
#include "common.h"
+#include "header.h"
+#include "cod.h"
#include "data-area.h"
#include "config.h"
+#include "nlog.h"
#include <ctype.h>
#define SIGNED_INT_PREFIX "int"
#define BITS_IN_BYTE 8
#define MAX_WARNING_SIZE 1024
+#define MAX_ARRAY_RANK 16
static bool telemetry_log_get_value(const struct telemetry_log *tl,
- uint32_t offset_bit, uint32_t size_bit,
+ uint64_t offset_bit, uint32_t size_bit,
bool is_signed, struct json_object **val_obj)
{
uint32_t offset_bit_from_byte;
uint32_t additional_size_byte;
uint32_t offset_byte;
- uint32_t val;
+ uint64_t val;
- if (size_bit == 0) {
+ if (!size_bit) {
char err_msg[MAX_WARNING_SIZE];
snprintf(err_msg, MAX_WARNING_SIZE,
@@ -34,7 +38,7 @@ static bool telemetry_log_get_value(const struct telemetry_log *tl,
return false;
}
additional_size_byte = (size_bit - 1) ? (size_bit - 1) / BITS_IN_BYTE : 0;
- offset_byte = offset_bit / BITS_IN_BYTE;
+ offset_byte = (uint32_t)offset_bit / BITS_IN_BYTE;
if (offset_byte > (tl->log_size - additional_size_byte)) {
char err_msg[MAX_WARNING_SIZE];
@@ -47,15 +51,14 @@ static bool telemetry_log_get_value(const struct telemetry_log *tl,
return false;
}
- offset_bit_from_byte = offset_bit - (offset_byte * BITS_IN_BYTE);
+ offset_bit_from_byte = (uint32_t) (offset_bit - ((uint64_t)offset_byte * BITS_IN_BYTE));
if ((size_bit + offset_bit_from_byte) > (sizeof(uint64_t) * BITS_IN_BYTE)) {
char err_msg[MAX_WARNING_SIZE];
snprintf(err_msg, MAX_WARNING_SIZE,
- "Value crossing 64 bit, byte aligned bounday, "
- "not supported. size_bit=%u, offset_bit_from_byte=%u.",
- size_bit, offset_bit_from_byte);
+ "Value crossing 64 bit, byte aligned bounday, not supported. size_bit=%u, offset_bit_from_byte=%u.",
+ size_bit, offset_bit_from_byte);
*val_obj = json_object_new_string(err_msg);
return false;
@@ -67,7 +70,7 @@ static bool telemetry_log_get_value(const struct telemetry_log *tl,
val &= (1ULL << size_bit) - 1;
if (is_signed) {
if (val >> (size_bit - 1))
- val |= -1ULL << size_bit;
+ val |= (0ULL - 1) << size_bit;
*val_obj = json_object_new_int64(val);
} else {
*val_obj = json_object_new_uint64(val);
@@ -78,23 +81,24 @@ static bool telemetry_log_get_value(const struct telemetry_log *tl,
static int telemetry_log_structure_parse(const struct telemetry_log *tl,
struct json_object *struct_def,
- size_t parent_offset_bit,
+ uint64_t parent_offset_bit,
struct json_object *output,
struct json_object *metadata)
{
struct json_object *obj_arraySizeArray = NULL;
struct json_object *obj = NULL;
struct json_object *obj_memberList;
- struct json_object *major_dimension;
+ struct json_object *major_dimension = NULL;
struct json_object *sub_output;
bool is_enumeration = false;
bool has_member_list;
const char *type = "";
const char *name;
size_t array_rank;
- size_t offset_bit;
- size_t size_bit;
- uint32_t linear_array_pos_bit;
+ uint64_t offset_bit;
+ uint32_t size_bit;
+ uint64_t linear_array_pos_bit;
+ uint32_t array_size_dimension[MAX_ARRAY_RANK];
if (!json_object_object_get_ex(struct_def, "name", &obj)) {
SOLIDIGM_LOG_WARNING("Warning: Structure definition missing property 'name': %s",
@@ -113,22 +117,22 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
type = json_object_get_string(obj);
if (!json_object_object_get_ex(struct_def, "offsetBit", &obj)) {
- SOLIDIGM_LOG_WARNING("Warning: Structure definition missing "
- "property 'offsetBit': %s",
- json_object_to_json_string(struct_def));
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Structure definition missing property 'offsetBit': %s",
+ json_object_to_json_string(struct_def));
return -1;
}
offset_bit = json_object_get_uint64(obj);
if (!json_object_object_get_ex(struct_def, "sizeBit", &obj)) {
- SOLIDIGM_LOG_WARNING("Warning: Structure definition missing "
- "property 'sizeBit': %s",
- json_object_to_json_string(struct_def));
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Structure definition missing property 'sizeBit': %s",
+ json_object_to_json_string(struct_def));
return -1;
}
- size_bit = json_object_get_uint64(obj);
+ size_bit = (uint32_t)json_object_get_uint64(obj);
if (json_object_object_get_ex(struct_def, "enum", &obj))
is_enumeration = json_object_get_boolean(obj);
@@ -139,25 +143,30 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
if (!json_object_object_get_ex(struct_def, "arraySize",
&obj_arraySizeArray)) {
- SOLIDIGM_LOG_WARNING("Warning: Structure definition missing "
- "property 'arraySize': %s",
- json_object_to_json_string(struct_def));
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Structure definition missing property 'arraySize': %s",
+ json_object_to_json_string(struct_def));
return -1;
}
array_rank = json_object_array_length(obj_arraySizeArray);
- if (array_rank == 0) {
- SOLIDIGM_LOG_WARNING("Warning: Structure property 'arraySize' "
- "don't support flexible array: %s",
- json_object_to_json_string(struct_def));
+ if (!array_rank) {
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Structure property 'arraySize' don't support flexible array: %s",
+ json_object_to_json_string(struct_def));
+ return -1;
+ }
+ if (array_rank > MAX_ARRAY_RANK) {
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Structure property 'arraySize' don't support more than %d dimensions: %s",
+ MAX_ARRAY_RANK, json_object_to_json_string(struct_def));
return -1;
}
- uint32_t array_size_dimension[array_rank];
for (size_t i = 0; i < array_rank; i++) {
struct json_object *dimension = json_object_array_get_idx(obj_arraySizeArray, i);
- array_size_dimension[i] = json_object_get_uint64(dimension);
+ array_size_dimension[i] = json_object_get_int(dimension);
major_dimension = dimension;
}
if (array_rank > 1) {
@@ -165,7 +174,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
uint32_t prev_index_offset_bit = 0;
struct json_object *dimension_output;
- for (int i = 1; i < (array_rank - 1); i++)
+ for (unsigned int i = 1; i < (array_rank - 1); i++)
linear_pos_per_index *= array_size_dimension[i];
dimension_output = json_create_array();
@@ -181,9 +190,9 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
json_object_get(major_dimension);
json_object_array_del_idx(obj_arraySizeArray, array_rank - 1, 1);
- for (int i = 0 ; i < array_size_dimension[0]; i++) {
+ for (unsigned int i = 0 ; i < array_size_dimension[0]; i++) {
struct json_object *sub_array = json_create_array();
- size_t offset;
+ uint64_t offset;
offset = parent_offset_bit + prev_index_offset_bit;
@@ -214,7 +223,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
if (is_enumeration || !has_member_list) {
bool is_signed = !strncmp(type, SIGNED_INT_PREFIX, sizeof(SIGNED_INT_PREFIX)-1);
struct json_object *val_obj;
- size_t offset;
+ uint64_t offset;
offset = parent_offset_bit + offset_bit + linear_array_pos_bit;
if (telemetry_log_get_value(tl, offset, size_bit, is_signed, &val_obj)) {
@@ -223,10 +232,10 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
else
json_object_object_add(sub_output, name, val_obj);
} else {
- SOLIDIGM_LOG_WARNING("Warning: %s From property '%s', "
- "array index %u, structure definition: %s",
- json_object_get_string(val_obj),
- name, j, json_object_to_json_string(struct_def));
+ SOLIDIGM_LOG_WARNING(
+ "Warning: %s From property '%s', array index %u, structure definition: %s",
+ json_object_get_string(val_obj), name, j,
+ json_object_to_json_string(struct_def));
json_free_object(val_obj);
}
} else {
@@ -241,7 +250,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
num_members = json_object_array_length(obj_memberList);
for (int k = 0; k < num_members; k++) {
struct json_object *member = json_object_array_get_idx(obj_memberList, k);
- size_t offset;
+ uint64_t offset;
offset = parent_offset_bit + offset_bit + linear_array_pos_bit;
telemetry_log_structure_parse(tl, member, offset,
@@ -293,6 +302,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;
@@ -319,7 +349,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,
@@ -331,30 +360,35 @@ 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;
-
- if ((char *)&toc->items[i] > (((char *)toc) + da_size - sizeof(const struct toc_item))) {
- SOLIDIGM_LOG_WARNING("Warning: Data Area %d, "
- "Table of Contents item %d "
- "crossed Data Area size.", da, i);
+ 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, Table of Contents item %d crossed Data Area size.",
+ da, i);
return;
}
obj_offset = toc->items[i].OffsetBytes;
if ((obj_offset + sizeof(const struct telemetry_object_header)) > da_size) {
- SOLIDIGM_LOG_WARNING("Warning: Data Area %d, item %d "
- "data, crossed Data Area size.", da, i);
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Data Area %d, item %d data, crossed Data Area size.", da, i);
continue;
}
@@ -372,53 +406,67 @@ 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,
- header->Token,
- header->versionMajor,
- header->versionMinor,
- &structure_definition);
-
- if (has_struct) {
- struct json_object *tele_obj_item = json_create_object();
+ 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();
- 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_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);
- uint32_t file_offset;
+ json_object_add_value_object(tele_obj_item, "objectData", parsed_struct);
+ struct json_object *obj_hasTelemObjHdr = NULL;
+ uint64_t object_file_offset;
- if (json_object_object_get_ex(structure_definition,
- "hasTelemObjHdr",
- &obj_hasTelemObjHdr)) {
- bool hasHeader = json_object_get_boolean(obj_hasTelemObjHdr);
+ if (json_object_object_get_ex(structure_definition,
+ "hasTelemObjHdr",
+ &obj_hasTelemObjHdr)) {
+ bool hasHeader = json_object_get_boolean(obj_hasTelemObjHdr);
- if (hasHeader)
- header_offset = 0;
- }
-
- file_offset = 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);
}
}
}
-int solidigm_telemetry_log_data_areas_parse(const struct telemetry_log *tl,
+int solidigm_telemetry_log_data_areas_parse(struct telemetry_log *tl,
enum nvme_telemetry_da last_da)
{
struct json_object *tele_obj_array = json_create_array();
struct json_object *toc_array = json_create_array();
- json_object_add_value_array(tl->root, "tableOfContents", toc_array);
- json_object_add_value_array(tl->root, "telemetryObjects", tele_obj_array);
-
- for (enum nvme_telemetry_da da = NVME_TELEMETRY_DA_1; da <= last_da; da++)
- telemetry_log_data_area_toc_parse(tl, da, toc_array, tele_obj_array);
+ solidigm_telemetry_log_header_parse(tl);
+ solidigm_telemetry_log_cod_parse(tl);
+ if (tl->configuration) {
+ json_object_add_value_array(tl->root, "tableOfContents", toc_array);
+ json_object_add_value_array(tl->root, "telemetryObjects", tele_obj_array);
+ for (enum nvme_telemetry_da da = NVME_TELEMETRY_DA_1; da <= last_da; da++)
+ telemetry_log_data_area_toc_parse(tl, da, toc_array, tele_obj_array);
+ }
return 0;
}