]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
plugins/solidigm: Fixes and clean-up of Telemetry parse code.
authorda Cunha, Leonardo <leonardo.da.cunha@solidigm.com>
Thu, 16 Mar 2023 23:53:37 +0000 (16:53 -0700)
committerDaniel Wagner <wagi@monom.org>
Wed, 12 Apr 2023 14:17:43 +0000 (16:17 +0200)
Fixed parsing of 64 bit values.
Fixed COD field name.
Fixed compilation warnings when compiling for 32 bit.
Added missing free().
Consolidated single entry function to telemetry parser.
Consolidated use of integer types.

plugins/solidigm/solidigm-nvme.h
plugins/solidigm/solidigm-telemetry.c
plugins/solidigm/solidigm-telemetry/cod.c
plugins/solidigm/solidigm-telemetry/data-area.c
plugins/solidigm/solidigm-telemetry/data-area.h
plugins/solidigm/solidigm-telemetry/header.c

index 43e178a418d97c5375aa89f016bd19ec6bb5af29..654ab4efb03cc93b277445a676894177fe984c48 100644 (file)
@@ -13,7 +13,7 @@
 
 #include "cmd.h"
 
-#define SOLIDIGM_PLUGIN_VERSION "0.8"
+#define SOLIDIGM_PLUGIN_VERSION "0.10"
 
 PLUGIN(NAME("solidigm", "Solidigm vendor specific extensions", SOLIDIGM_PLUGIN_VERSION),
        COMMAND_LIST(
index 9946991d748740e686751c41aafedaac6f18261e..061e60daf593c6df83b7690e2f3c745e98bf8e6e 100644 (file)
@@ -112,7 +112,7 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
        }
 
        if (cfg.cfg_file) {
-               char *conf_str = 0;
+               char *conf_str = NULL;
                size_t length = 0;
 
                err = read_file2buffer(cfg.cfg_file, &conf_str, &length);
@@ -124,6 +124,7 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
                struct json_tokener * jstok = json_tokener_new();
 
                tl.configuration = json_tokener_parse_ex(jstok, conf_str, length);
+               free(conf_str);
                if (jstok->err != json_tokener_success) {
                        SOLIDIGM_LOG_WARNING("Parsing error on JSON configuration file %s: %s (at offset %d)",
                                             cfg.cfg_file,
@@ -160,11 +161,7 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
                        goto close_fd;
                }
        }
-       solidigm_telemetry_log_header_parse(&tl);
-       if (cfg.cfg_file)
-               solidigm_telemetry_log_data_areas_parse(&tl, cfg.data_area);
-       else
-               solidigm_telemetry_log_cod_parse(&tl);
+       solidigm_telemetry_log_data_areas_parse(&tl, cfg.data_area);
 
        json_print_object(tl.root, NULL);
        json_free_object(tl.root);
index 7accc5384c6418d304b34b73580b396a250966fc..12cf42bbb4f90ba90e3fbb99017c6cafc591a6df 100644 (file)
@@ -51,10 +51,10 @@ const char *oemDataMapDesc[] = {
        "All Time Current Max Wear Level", // 0x28
        "Media Wear Remaining", // 0x29
        "Total Non-Defrag Writes",  // 0x2A
-       "Number of sectors relocated in reaction to an error" //Uid 0x2B = 43
+       "Media Health Relocations" //Uid 0x2B = 43
 };
 
-static const char * getOemDataMapDescription(__u32 id)
+static const char *getOemDataMapDescription(uint32_t id)
 {
        if (id < (sizeof(oemDataMapDesc) / sizeof(oemDataMapDesc[0]))) {
                return oemDataMapDesc[id];
@@ -121,7 +121,7 @@ void solidigm_telemetry_log_cod_parse(struct telemetry_log *tl)
        if  (!json_object_object_get_ex(reason_id, "OemDataMapOffset", &COD_offset))
                return;
 
-       __u64 offset = json_object_get_int(COD_offset);
+       uint64_t offset = json_object_get_int(COD_offset);
 
        if  (offset ==  0) {
                return;
@@ -132,7 +132,7 @@ void solidigm_telemetry_log_cod_parse(struct telemetry_log *tl)
                return;
        }
 
-       const struct cod_map *data = (struct cod_map *) (((__u8 *)tl->log ) + offset);
+       const struct cod_map *data = (struct cod_map *) (((uint8_t *)tl->log) + offset);
 
        uint32_t signature = be32_to_cpu(data->header.Signature);
        if ( signature != OEMSIGNATURE){
@@ -147,10 +147,11 @@ void solidigm_telemetry_log_cod_parse(struct telemetry_log *tl)
        struct json_object *cod = json_create_object();
        json_object_object_add(tl->root, "cod", cod);
 
-       for (int i =0 ; i < data->header.EntryCount; i++) {
+       for (uint64_t i = 0; i < data->header.EntryCount; i++) {
                if ((offset + sizeof(struct cod_header) + (i + 1) * sizeof(struct cod_item)) >
                tl->log_size){
-                       SOLIDIGM_LOG_WARNING("Warning: COD data out of bounds at item %d!", i);
+                       SOLIDIGM_LOG_WARNING("Warning: COD data out of bounds at item %"PRIu64"!",
+                                            i);
                        return;
                }
                struct cod_item item = data->items[i];
index 2f18ea262db2882fc34cf0b5a1cdcbcc0f028543..31f7836cd4b4759d45f9527951e54320c282f676 100644 (file)
@@ -6,6 +6,8 @@
  */
 
 #include "common.h"
+#include "header.h"
+#include "cod.h"
 #include "data-area.h"
 #include "config.h"
 #include <ctype.h>
 #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) {
                char err_msg[MAX_WARNING_SIZE];
@@ -34,7 +37,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,7 +50,7 @@ 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];
@@ -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",
@@ -128,7 +132,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
                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);
@@ -152,12 +156,17 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
                                     json_object_to_json_string(struct_def));
                return -1;
        }
-       uint32_t array_size_dimension[array_rank];
+       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;
+       }
 
        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)) {
@@ -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,
@@ -389,7 +398,7 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
                        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;
+                       uint64_t file_offset;
 
                        if (json_object_object_get_ex(structure_definition,
                                                      "hasTelemObjHdr",
@@ -400,7 +409,7 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
                                        header_offset = 0;
                        }
 
-                       file_offset = da_offset + obj_offset + header_offset;
+                       file_offset = ((uint64_t)da_offset) + obj_offset + header_offset;
                        telemetry_log_structure_parse(tl, structure_definition,
                                                      BITS_IN_BYTE * file_offset,
                                                      parsed_struct, toc_item);
@@ -408,17 +417,20 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
        }
 }
 
-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;
 }
index 095eb64ce141954156bfce88b6ce97320d09d73e..6b690d880e7e62811f172c5be7bdaacd968a455a 100644 (file)
@@ -4,8 +4,7 @@
  *
  * Author: leonardo.da.cunha@solidigm.com
  */
-#include "common.h"
 #include "telemetry-log.h"
 
-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);
index d085c2462f17c4a3dae0bbbedd03d52f53d9cdfe..2f2684af7cbc03abff68087de4badd6f2ea4631b 100644 (file)
@@ -137,8 +137,8 @@ static void solidigm_telemetry_log_reason_id_parse(const struct telemetry_log *t
 {
        const struct reason_indentifier_1_0 *ri1_0 =
                (struct reason_indentifier_1_0 *) tl->log->rsnident;
-       __u16 version_major = le16_to_cpu(ri1_0->versionMajor);
-       __u16 version_minor = le16_to_cpu(ri1_0->versionMinor);
+       uint16_t version_major = le16_to_cpu(ri1_0->versionMajor);
+       uint16_t version_minor = le16_to_cpu(ri1_0->versionMinor);
 
        json_object_add_value_uint(reason_id, "versionMajor", version_major);
        json_object_add_value_uint(reason_id, "versionMinor", version_minor);