]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
plugins/ocp: Add ocp TCG Configuration Log Page
authorVigneshwaran Saravanan <s.vignesh@samsungds.net>
Wed, 5 Jun 2024 06:08:15 +0000 (11:38 +0530)
committerDaniel Wagner <wagi@monom.org>
Tue, 18 Jun 2024 07:15:09 +0000 (09:15 +0200)
Add TCG Configuration Log Page support to the ocp plugin.

Reviewed-by: Karthik Balan <karthik.b82@samsung.com>
Reviewed-by: Arunpandian J <arun.j@samsung.com>
Signed-off-by: Vigneshwaran Saravanan <s.vignesh@samsungds.net>
[dwagner: - updated commmit message
          - dropped html doc generation]
Signed-off-by: Daniel Wagner <dwagner@suse.de>
Documentation/nvme-ocp-tcg-configuration-log.txt [new file with mode: 0644]
completions/_nvme
completions/bash-nvme-completion.sh
plugins/ocp/ocp-nvme.c
plugins/ocp/ocp-nvme.h

diff --git a/Documentation/nvme-ocp-tcg-configuration-log.txt b/Documentation/nvme-ocp-tcg-configuration-log.txt
new file mode 100644 (file)
index 0000000..41312ea
--- /dev/null
@@ -0,0 +1,44 @@
+nvme-ocp-tcg-configuration-log(1)
+=========================
+
+NAME
+----
+nvme-ocp-tcg-configuration-log - Retrieves tcg configuration of given OCP
+compliant device
+
+SYNOPSIS
+--------
+[verse]
+'nvme ocp tcg-configuration-log' <device> [--output-format=<fmt> | -o <fmt>]
+
+DESCRIPTION
+-----------
+For the NVMe device given, send a tcg-configuration-log command and
+provide the tcg configuration log.
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).
+
+This will only work on OCP compliant devices supporting this feature.
+Results for any other device are undefined.
+
+On success it returns 0, error code otherwise.
+
+OPTIONS
+-------
+-o <fmt>::
+--output-format=<fmt>::
+       Set the reporting format to 'normal' or 'json'. Only one output format
+       can be used at a time. The default is normal.
+
+EXAMPLES
+--------
+* Has the program issue a tcg-configuration-log command to retrieve the 0xC7 log page.
++
+------------
+# nvme ocp tcg-configuration-log /dev/nvme0
+------------
+
+NVME
+----
+Part of the nvme-user suite.
index ba7725d7458d716dceff9f78cfae370337f32779..77800f6139f6327e72700ce2ed7323644d0b4290 100644 (file)
@@ -303,6 +303,16 @@ _nvme () {
                                _arguments '*:: :->subcmds'
                                _describe -t commands "nvme ocp get-dssd-async-event-config options" _get_dssd_async_event_config
                                ;;
+                       (tcg-configuration-log)
+                               local _ocp_tcg_configuration_log
+                               _ocp_tcg_configuration_log=(
+                               /dev/nvme':supply a device to use (required)'
+                               --output-format=':Output format: normal|json'
+                               -o':alias for --output-format'
+                               )
+                               _arguments '*:: :->subcmds'
+                               _describe -t commands "nvme ocp tcg-configuration-log options" _ocp_tcg_configuration_log
+                               ;;
                        (*)
                                _files
                                ;;
@@ -2375,6 +2385,7 @@ _nvme () {
                        get-dssd-power-state-feature':Get DSSD Power State'
                        telemetry-string-log':Retrieve Telemetry string Log Page'
                        set-telemetry-profile':Set Telemetry Profile'
+                       tcg-configuration-log':tcg configuration log'
                        )
                        _arguments '*:: :->subcmds'
                        _describe -t commands "nvme ocp options" _ocp
index ad0a4c44e92b25c6446f4f8c7c4e5088d1596a5c..8b5fe36104121f41c6429ff937bf9d36c4b10b3c 100644 (file)
@@ -1470,6 +1470,9 @@ plugin_ocp_opts () {
                "get-dssd-async-event-config")
                opts+=" --sel= -S"
                        ;;
+               "tcg-configuration-log")
+               opts+=" --output-file= -o"
+                       ;;
                "help")
                opts+=$NO_OPTS
                        ;;
index 602c43ced5bf9f3dc208c0b87edeb08baaee4c3e..134b1751ccf1791b7605bdc8b69b5c4f40387670 100644 (file)
@@ -3258,6 +3258,290 @@ static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *c
        return ret;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/// TCG Configuration Log Page (LID : C7h)
+
+/* C7 TCG Configuration Log Page */
+#define C7_GUID_LENGTH                     16
+#define C7_TCG_CONFIGURATION_LEN           512
+#define C7_TCG_CONFIGURATION_OPCODE        0xC7
+#define C7_TCG_CONFIGURATION_LOG_VERSION   0x1
+
+static __u8 tcg_configuration_guid[C7_GUID_LENGTH] = {
+       0x06, 0x40, 0x24, 0xBD,
+       0x7E, 0xE0, 0xE6, 0x83,
+       0xC0, 0x47, 0x54, 0xFA,
+       0x9D, 0x2A, 0xE0, 0x54
+};
+
+/*
+ * struct tcg_configuration_log - TCG Configuration Log Page Structure
+ * @state:                            state
+ * @rsvd1:                            Reserved1
+ * @locking_sp_act_count:             Locking SP Activation Count
+ * @type_rev_count:                   Tper Revert Count
+ * @locking_sp_rev_count:             Locking SP Revert Count.
+ * @no_of_locking_obj:                Number of Locking Objects
+ * @no_of_single_um_locking_obj:      Number of Single User Mode Locking Objects
+ * @no_of_range_prov_locking_obj:     Number of Range Provisioned Locking Objects
+ * @no_of_ns_prov_locking_obj:        Number of Namespace Provisioned Locking Objects
+ * @no_of_read_lock_locking_obj:      Number of Read Locked Locking Objects
+ * @no_of_write_lock_locking_obj:     Number of Write Locked Locking Objects
+ * @no_of_read_unlock_locking_obj:    Number of Read Unlocked Locking Objects
+ * @no_of_read_unlock_locking_obj:    Number of Write Unlocked Locking Objects
+ * @rsvd2:                            Reserved2
+ * @sid_auth_try_count:               SID Authentication Try Count
+ * @sid_auth_try_limit:               SID Authentication Try Limit
+ * @pro_tcg_rc:                       Programmatic TCG Reset Count
+ * @pro_rlc:                          Programmatic Reset Lock Count
+ * @tcg_ec:                           TCG Error Count
+ * @rsvd3:                            Reserved3
+ * @log_page_version:                 Log Page Version
+ */
+struct __packed tcg_configuration_log {
+       __u8    state;
+       __u8    rsvd1[3];
+       __u8    locking_sp_act_count;
+       __u8    type_rev_count;
+       __u8    locking_sp_rev_count;
+       __u8    no_of_locking_obj;
+       __u8    no_of_single_um_locking_obj;
+       __u8    no_of_range_prov_locking_obj;
+       __u8    no_of_ns_prov_locking_obj;
+       __u8    no_of_read_lock_locking_obj;
+       __u8    no_of_write_lock_locking_obj;
+       __u8    no_of_read_unlock_locking_obj;
+       __u8    no_of_write_unlock_locking_obj;
+       __u8    rsvd2;
+       __u32   sid_auth_try_count;
+       __u32   sid_auth_try_limit;
+       __u32   pro_tcg_rc;
+       __u32   pro_rlc;
+       __u32   tcg_ec;
+       __u8    rsvd3[458];
+       __le16  log_page_version;
+       __u8    log_page_guid[C7_GUID_LENGTH];
+
+};
+
+/* Function declaration for TCG Configuration log page (LID:C7h) */
+static int ocp_tcg_configuration_log(int argc, char **argv, struct command *cmd,
+                                           struct plugin *plugin);
+
+static int ocp_print_C7_log_normal(struct nvme_dev *dev,
+                                  struct tcg_configuration_log *log_data)
+{
+       int j;
+
+       printf("TCG Configuration C7 Log Page Data-\n");
+
+       printf("  State                                                  : 0x%x\n", log_data->state);
+       printf("  Reserved1                                              : 0x");
+       for (j = 0; j < 3; j++)
+               printf("%d", log_data->rsvd1[j]);
+       printf("\n");
+       printf("  Locking SP Activation Count                            : 0x%x\n", log_data->locking_sp_act_count);
+       printf("  Tper Revert Count                                      : 0x%x\n", log_data->type_rev_count);
+       printf("  Locking SP Revert Count                                : 0x%x\n", log_data->locking_sp_rev_count);
+       printf("  Number of Locking Objects                              : 0x%x\n", log_data->no_of_locking_obj);
+       printf("  Number of Single User Mode Locking Objects             : 0x%x\n", log_data->no_of_single_um_locking_obj);
+       printf("  Number of Range Provisioned Locking Objects            : 0x%x\n", log_data->no_of_range_prov_locking_obj);
+       printf("  Number of Namespace Provisioned Locking Objects        : 0x%x\n", log_data->no_of_ns_prov_locking_obj);
+       printf("  Number of Read Locked Locking Objects                  : 0x%x\n", log_data->no_of_read_lock_locking_obj);
+       printf("  Number of Write Locked Locking Objects                 : 0x%x\n", log_data->no_of_write_lock_locking_obj);
+       printf("  Number of Read Unlocked Locking Objects                : 0x%x\n", log_data->no_of_read_unlock_locking_obj);
+       printf("  Number of Write Unlocked Locking Objects               : 0x%x\n", log_data->no_of_write_unlock_locking_obj);
+       printf("  Reserved2                                              : 0x%x\n", log_data->rsvd2);
+
+       printf("  SID Authentication Try Count                           : 0x%x\n", le32_to_cpu(log_data->sid_auth_try_count));
+       printf("  SID Authentication Try Limit                           : 0x%x\n", le32_to_cpu(log_data->sid_auth_try_limit));
+       printf("  Programmatic TCG Reset Count                           : 0x%x\n", le32_to_cpu(log_data->pro_tcg_rc));
+       printf("  Programmatic Reset Lock Count                          : 0x%x\n", le32_to_cpu(log_data->pro_rlc));
+       printf("  TCG Error Count                                        : 0x%x\n", le32_to_cpu(log_data->tcg_ec));
+
+       printf("  Reserved3                                              : 0x");
+       for (j = 0; j < 458; j++)
+               printf("%d", log_data->rsvd3[j]);
+       printf("\n");
+
+       printf("  Log Page Version                                       : 0x%x\n", le16_to_cpu(log_data->log_page_version));
+       printf("  Log page GUID                                          : 0x");
+       for (j = C7_GUID_LENGTH - 1; j >= 0; j--)
+               printf("%x", log_data->log_page_guid[j]);
+       printf("\n");
+
+       return 0;
+}
+
+static void ocp_print_C7_log_json(struct tcg_configuration_log *log_data)
+{
+       int j;
+       struct json_object *root;
+       char guid_buf[C7_GUID_LENGTH];
+       char *guid = guid_buf;
+       char res_arr[458];
+       char *res = res_arr;
+
+       root = json_create_object();
+
+       json_object_add_value_int(root, "State", le16_to_cpu(log_data->state));
+       memset((__u8 *)res, 0, 3);
+       for (j = 0; j < 3; j++)
+               res += sprintf(res, "%d", log_data->rsvd1[j]);
+       json_object_add_value_string(root, "Reserved1", res_arr);
+       json_object_add_value_int(root, "Locking SP Activation Count", le16_to_cpu(log_data->locking_sp_act_count));
+       json_object_add_value_int(root, "Tper Revert Count", le16_to_cpu(log_data->locking_sp_rev_count));
+       json_object_add_value_int(root, "Number of Locking Objects", le16_to_cpu(log_data->no_of_locking_obj));
+       json_object_add_value_int(root, "Number of Single User Mode Locking Objects", le16_to_cpu(log_data->no_of_single_um_locking_obj));
+       json_object_add_value_int(root, "Number of Range Provisioned Locking Objects", le16_to_cpu(log_data->no_of_range_prov_locking_obj));
+       json_object_add_value_int(root, "Number of Namespace Provisioned Locking Objects", le16_to_cpu(log_data->no_of_ns_prov_locking_obj));
+       json_object_add_value_int(root, "Number of Read Locked Locking Objects", le16_to_cpu(log_data->no_of_read_lock_locking_obj));
+       json_object_add_value_int(root, "Number of Write Locked Locking Objects", le16_to_cpu(log_data->no_of_write_lock_locking_obj));
+       json_object_add_value_int(root, "Number of Read Unlocked Locking Objects", le16_to_cpu(log_data->no_of_read_unlock_locking_obj));
+       json_object_add_value_int(root, "Number of Write Unlocked Locking Objects", le16_to_cpu(log_data->no_of_write_unlock_locking_obj));
+       json_object_add_value_int(root, "Reserved2", le16_to_cpu(log_data->rsvd2));
+
+       json_object_add_value_int(root, "SID Authentication Try Count", le16_to_cpu(log_data->sid_auth_try_count));
+       json_object_add_value_int(root, "SID Authentication Try Limit", le16_to_cpu(log_data->sid_auth_try_limit));
+       json_object_add_value_int(root, "Programmatic TCG Reset Count", le16_to_cpu(log_data->pro_tcg_rc));
+       json_object_add_value_int(root, "Programmatic Reset Lock Count", le16_to_cpu(log_data->pro_rlc));
+       json_object_add_value_int(root, "TCG Error Count", le16_to_cpu(log_data->tcg_ec));
+
+       memset((__u8 *)res, 0, 458);
+       for (j = 0; j < 458; j++)
+               res += sprintf(res, "%d", log_data->rsvd3[j]);
+       json_object_add_value_string(root, "Reserved3", res_arr);
+
+       json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
+
+       memset((void *)guid, 0, C7_GUID_LENGTH);
+       for (j = C7_GUID_LENGTH - 1; j >= 0; j--)
+               guid += sprintf(guid, "%02x", log_data->log_page_guid[j]);
+       json_object_add_value_string(root, "Log page GUID", guid_buf);
+
+       json_print_object(root, NULL);
+       printf("\n");
+
+       json_free_object(root);
+}
+
+static void ocp_print_c7_log_binary(struct tcg_configuration_log *log_data)
+{
+       return d_raw((unsigned char *)log_data, sizeof(*log_data));
+}
+
+static int get_c7_log_page(struct nvme_dev *dev, char *format)
+{
+       enum nvme_print_flags fmt;
+       int ret;
+       __u8 *data;
+       int i;
+       struct tcg_configuration_log *log_data;
+       int j;
+
+       ret = validate_output_format(format, &fmt);
+       if (ret < 0) {
+               fprintf(stderr, "ERROR : OCP : invalid output format\n");
+               return ret;
+       }
+
+       data = (__u8 *)malloc(sizeof(__u8) * C7_TCG_CONFIGURATION_LEN);
+       if (!data) {
+               fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno));
+               return -1;
+       }
+       memset(data, 0, sizeof(__u8) * C7_TCG_CONFIGURATION_LEN);
+
+       ret = nvme_get_log_simple(dev_fd(dev), C7_TCG_CONFIGURATION_OPCODE,
+                                 C7_TCG_CONFIGURATION_LEN, data);
+       if (!ret) {
+               log_data = (struct tcg_configuration_log *)data;
+
+               /* check log page version */
+               if (log_data->log_page_version != C7_TCG_CONFIGURATION_LOG_VERSION) {
+                       fprintf(stderr, "ERROR : OCP : invalid TCG Configuration Log Page version\n");
+                       ret = -1;
+                       goto out;
+               }
+
+               /*
+                * check log page guid
+                * Verify GUID matches
+                */
+               for (i = 0; i < 16; i++) {
+                       if (tcg_configuration_guid[i] != log_data->log_page_guid[i]) {
+                               fprintf(stderr, "ERROR : OCP : Unknown GUID in C7 Log Page data\n");
+                               fprintf(stderr, "ERROR : OCP : Expected GUID: 0x");
+                               for (j = 0; j < 16; j++)
+                                       fprintf(stderr, "%x", tcg_configuration_guid[j]);
+                               fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
+                               for (j = 0; j < 16; j++)
+                                       fprintf(stderr, "%x", log_data->log_page_guid[j]);
+                               fprintf(stderr, "\n");
+
+                               ret = -1;
+                               goto out;
+                       }
+               }
+
+               switch (fmt) {
+               case NORMAL:
+                       ocp_print_C7_log_normal(dev, log_data);
+                       break;
+               case JSON:
+                       ocp_print_C7_log_json(log_data);
+                       break;
+               case BINARY:
+                       ocp_print_c7_log_binary(log_data);
+                       break;
+               default:
+                       break;
+               }
+       } else {
+               fprintf(stderr, "ERROR : OCP : Unable to read C7 data from buffer\n");
+       }
+
+out:
+       free(data);
+       return ret;
+}
+
+
+static int ocp_tcg_configuration_log(int argc, char **argv, struct command *cmd,
+                                           struct plugin *plugin)
+{
+       const char *desc = "Retrieve TCG Configuration Log Page Data";
+       struct nvme_dev *dev;
+       int ret = 0;
+
+       struct config {
+               char *output_format;
+       };
+
+       struct config cfg = {
+               .output_format = "normal",
+       };
+
+       OPT_ARGS(opts) = {
+               OPT_FMT("output-format", 'o', &cfg.output_format, "output Format: normal|json"),
+               OPT_END()
+       };
+
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret)
+               return ret;
+
+       ret = get_c7_log_page(dev, cfg.output_format);
+       if (ret)
+               fprintf(stderr, "ERROR : OCP : Failure reading the C7 Log Page, ret = %d\n", ret);
+
+       dev_close(dev);
+       return ret;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
index 334c77c248a5f809856586d7e99173e6e2cb1925..f468b22fda86a263c6b6fdc643dd1c5336c3561b 100644 (file)
@@ -35,6 +35,7 @@ PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),
                ENTRY("set-telemetry-profile", "Set Telemetry Profile Feature", ocp_set_telemetry_profile_feature)
                ENTRY("set-dssd-async-event-config", "Set DSSD Async Event Config", set_dssd_async_event_config)
                ENTRY("get-dssd-async-event-config", "Get DSSD Async Event Config", get_dssd_async_event_config)
+               ENTRY("tcg-configuration-log", "Retrieve TCG Configuration Log Page", ocp_tcg_configuration_log)
        )
 );