Skip to content

Commit e8b8c7f

Browse files
jeff-lien-sndkigaw
authored andcommitted
ocp: Add support for retrieving telemetry data area 4
The current ocp internal-log command will only retrieve up to data area 3. This change will enable retrieving of all 4 telemetry log data areas. It will also refactor the code used to save off the 2 files collected: telemetry log and string log along with the 1 generated file: the parsed da 1 and 2 data. Swap -o and -f on output-format and output-file parameters. Signed-off-by: jeff-lien-sndk <[email protected]> Reviewed-by: brandon-paupore-sndk <[email protected]>
1 parent ffb1b3e commit e8b8c7f

File tree

4 files changed

+98
-28
lines changed

4 files changed

+98
-28
lines changed

plugins/ocp/ocp-nvme.c

Lines changed: 88 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,12 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
12211221
size = le16_to_cpu(logheader->DataArea3LastBlock) -
12221222
le16_to_cpu(logheader->DataArea2LastBlock);
12231223
break;
1224+
case 4:
1225+
offset = TELEMETRY_HEADER_SIZE +
1226+
(le16_to_cpu(logheader->DataArea3LastBlock) * TELEMETRY_BYTE_PER_BLOCK);
1227+
size = le16_to_cpu(logheader->DataArea4LastBlock) -
1228+
le16_to_cpu(logheader->DataArea3LastBlock);
1229+
break;
12241230
default:
12251231
break;
12261232
}
@@ -1237,13 +1243,15 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
12371243
return err;
12381244
}
12391245

1240-
static int get_telemetry_log_page_data(struct nvme_dev *dev, int tele_type)
1246+
static int get_telemetry_log_page_data(struct nvme_dev *dev,
1247+
int tele_type,
1248+
int tele_area,
1249+
const char *output_file)
12411250
{
1242-
char file_path[PATH_MAX];
12431251
void *telemetry_log;
12441252
const size_t bs = 512;
12451253
struct nvme_telemetry_log *hdr;
1246-
size_t full_size, offset = bs;
1254+
size_t full_size = 0, offset = bs;
12471255
int err, fd;
12481256

12491257
if ((tele_type == TELEMETRY_TYPE_HOST_0) || (tele_type == TELEMETRY_TYPE_HOST_1))
@@ -1262,11 +1270,10 @@ static int get_telemetry_log_page_data(struct nvme_dev *dev, int tele_type)
12621270
}
12631271
memset(hdr, 0, bs);
12641272

1265-
sprintf(file_path, DEFAULT_TELEMETRY_BIN);
1266-
fd = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
1273+
fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
12671274
if (fd < 0) {
12681275
fprintf(stderr, "Failed to open output file %s: %s!\n",
1269-
file_path, strerror(errno));
1276+
output_file, strerror(errno));
12701277
err = fd;
12711278
goto exit_status;
12721279
}
@@ -1304,9 +1311,25 @@ static int get_telemetry_log_page_data(struct nvme_dev *dev, int tele_type)
13041311
goto close_fd;
13051312
}
13061313

1307-
full_size = (le16_to_cpu(hdr->dalb3) * bs) + offset;
1314+
switch (tele_area) {
1315+
case 1:
1316+
full_size = (le16_to_cpu(hdr->dalb1) * bs) + offset;
1317+
break;
1318+
case 2:
1319+
full_size = (le16_to_cpu(hdr->dalb2) * bs) + offset;
1320+
break;
1321+
case 3:
1322+
full_size = (le16_to_cpu(hdr->dalb3) * bs) + offset;
1323+
break;
1324+
case 4:
1325+
full_size = (le32_to_cpu(hdr->dalb4) * bs) + offset;
1326+
break;
1327+
default:
1328+
full_size = offset;
1329+
break;
1330+
}
13081331

1309-
while (offset != full_size) {
1332+
while (offset < full_size) {
13101333
args.log = telemetry_log;
13111334
args.lpo = offset;
13121335
args.lsp = NVME_LOG_LSP_NONE;
@@ -1431,7 +1454,7 @@ int parse_ocp_telemetry_log(struct ocp_telemetry_parse_options *options)
14311454

14321455
if (options->telemetry_log) {
14331456
if (strstr((const char *)options->telemetry_log, "bin")) {
1434-
// Read the data from the telemetry binary file
1457+
/* Read the data from the telemetry binary file */
14351458
ptelemetry_buffer =
14361459
read_binary_file(NULL, (const char *)options->telemetry_log,
14371460
&telemetry_buffer_size, 1);
@@ -1452,7 +1475,7 @@ int parse_ocp_telemetry_log(struct ocp_telemetry_parse_options *options)
14521475
}
14531476

14541477
if (options->string_log) {
1455-
// Read the data from the string binary file
1478+
/* Read the data from the string binary file */
14561479
if (strstr((const char *)options->string_log, "bin")) {
14571480
pstring_buffer = read_binary_file(NULL, (const char *)options->string_log,
14581481
&string_buffer_size, 1);
@@ -1483,11 +1506,15 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct
14831506
const char *telemetry_log = "Telemetry log binary;\n 'host.bin' or 'controller.bin'";
14841507
const char *string_log = "String log binary; 'C9.bin'";
14851508
const char *output_file = "Output file name with path;\n"
1486-
"e.g. '-o ./path/name'\n'-o ./path1/path2/';\n"
1509+
"e.g. '-f ./path/name'\n'-f ./path1/path2/';\n"
14871510
"If requested path does not exist, the directory will be newly created.";
14881511
const char *output_format = "output format normal|json";
1489-
const char *data_area = "Telemetry Data Area; 1 or 2;\n"
1490-
"e.g. '-a 1 for Data Area 1.'\n'-a 2 for Data Areas 1 and 2.';\n";
1512+
const char *data_area = "Telemetry Data Area; 1, 2, 3, or 4;\n"
1513+
"e.g. '-a 1 for Data Area 1.'\n"
1514+
"e.g. '-a 2 for Data Areas 1 and 2.'\n"
1515+
"e.g. '-a 3 for Data Areas 1, 2, and 3.'\n"
1516+
"e.g. '-a 4 for Data Areas 1, 2, 3, and 4.';\n";
1517+
14911518
const char *telemetry_type = "Telemetry Type; 'host', 'host0', 'host1' or 'controller'";
14921519

14931520
struct nvme_dev *dev;
@@ -1500,12 +1527,16 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct
15001527
struct ocp_telemetry_parse_options opt;
15011528
int tele_type = 0;
15021529
int tele_area = 0;
1530+
char file_path_telemetry[PATH_MAX], file_path_string[PATH_MAX];
1531+
const char *string_suffix = "string.bin";
1532+
const char *tele_log_suffix = "telemetry.bin";
1533+
bool host_behavior_changed = false;
15031534

15041535
OPT_ARGS(opts) = {
15051536
OPT_STR("telemetry-log", 'l', &opt.telemetry_log, telemetry_log),
15061537
OPT_STR("string-log", 's', &opt.string_log, string_log),
1507-
OPT_FILE("output-file", 'o', &opt.output_file, output_file),
1508-
OPT_FMT("output-format", 'f', &opt.output_format, output_format),
1538+
OPT_FILE("output-file", 'f', &opt.output_file, output_file),
1539+
OPT_FMT("output-format", 'o', &opt.output_format, output_format),
15091540
OPT_INT("data-area", 'a', &opt.data_area, data_area),
15101541
OPT_STR("telemetry-type", 't', &opt.telemetry_type, telemetry_type),
15111542
OPT_END()
@@ -1536,11 +1567,15 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct
15361567

15371568
is_support_telemetry_controller = ((ctrl.lpa & 0x8) >> 3);
15381569

1570+
if (opt.output_file == NULL)
1571+
opt.output_file = DEFAULT_TELEMETRY_LOG;
1572+
15391573
if (!opt.data_area) {
15401574
nvme_show_result("Missing data-area. Using default data area 1.\n");
15411575
opt.data_area = DATA_AREA_1;//Default data area 1
1542-
} else if (opt.data_area != 1 && opt.data_area != 2) {
1543-
nvme_show_result("Invalid data-area specified. Please specify 1 or 2.\n");
1576+
} else if (opt.data_area != 1 && opt.data_area != 2 &&
1577+
opt.data_area != 3 && opt.data_area != 4) {
1578+
nvme_show_result("Invalid data-area specified. Please specify 1, 2, 3, or 4.\n");
15441579
goto out;
15451580
}
15461581

@@ -1568,25 +1603,55 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct
15681603

15691604
if (!opt.telemetry_log) {
15701605
nvme_show_result("\nMissing telemetry-log. Fetching from drive...\n");
1571-
err = get_telemetry_log_page_data(dev, tele_type);//Pull Telemetry log
1606+
1607+
if (tele_area == 4) {
1608+
if (!(ctrl.lpa & 0x40)) {
1609+
nvme_show_error("Telemetry data area 4 not supported by device.\n");
1610+
goto out;
1611+
}
1612+
1613+
err = nvme_set_etdas(dev_fd(dev), &host_behavior_changed);
1614+
if (err) {
1615+
fprintf(stderr, "%s: Failed to set ETDAS bit\n", __func__);
1616+
return err;
1617+
}
1618+
}
1619+
1620+
/* Pull the Telemetry log */
1621+
sprintf(file_path_telemetry, "%s-%s", opt.output_file, tele_log_suffix);
1622+
err = get_telemetry_log_page_data(dev,
1623+
tele_type,
1624+
tele_area,
1625+
(const char *)file_path_telemetry);
15721626
if (err) {
15731627
nvme_show_error("Failed to fetch telemetry-log from the drive.\n");
15741628
goto out;
15751629
}
15761630
nvme_show_result("telemetry.bin generated. Proceeding with next steps.\n");
1577-
opt.telemetry_log = DEFAULT_TELEMETRY_BIN;
1631+
opt.telemetry_log = file_path_telemetry;
1632+
1633+
if (host_behavior_changed) {
1634+
host_behavior_changed = false;
1635+
err = nvme_clear_etdas(dev_fd(dev), &host_behavior_changed);
1636+
if (err) {
1637+
/* Continue on if this fails, it's not a fatal condition */
1638+
nvme_show_error("Failed to clear ETDAS bit.\n");
1639+
}
1640+
}
15781641
}
15791642

15801643
if (!opt.string_log) {
15811644
nvme_show_result("Missing string-log. Fetching from drive...\n");
1645+
15821646
/* Pull String log */
1583-
err = get_c9_log_page_data(dev, 0, 1, (const char *)opt.output_file);
1647+
sprintf(file_path_string, "%s-%s", opt.output_file, string_suffix);
1648+
err = get_c9_log_page_data(dev, 0, 1, (const char *)file_path_string);
15841649
if (err) {
15851650
nvme_show_error("Failed to fetch string-log from the drive.\n");
15861651
goto out;
15871652
}
15881653
nvme_show_result("string.bin generated. Proceeding with next steps.\n");
1589-
opt.string_log = DEFAULT_STRING_BIN;
1654+
opt.string_log = file_path_string;
15901655
}
15911656

15921657
if (!opt.output_format) {
@@ -1597,6 +1662,7 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct
15971662
switch (tele_type) {
15981663
case TELEMETRY_TYPE_HOST:
15991664
printf("Extracting Telemetry Host Dump (Data Area %d)...\n", tele_area);
1665+
16001666
err = parse_ocp_telemetry_log(&opt);
16011667
if (err)
16021668
nvme_show_result("Status:(%x)\n", err);
@@ -2634,7 +2700,7 @@ static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *c
26342700
return ret;
26352701

26362702
if (cfg.output_file != NULL)
2637-
sprintf(file_path, "%s%s", cfg.output_file, string_suffix);
2703+
sprintf(file_path, "%s-%s", cfg.output_file, string_suffix);
26382704
else
26392705
sprintf(file_path, "%s", DEFAULT_STRING_BIN);
26402706

plugins/ocp/ocp-nvme.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#if !defined(OCP_NVME) || defined(CMD_HEADER_MULTI_READ)
1212
#define OCP_NVME
1313

14-
#define OCP_PLUGIN_VERSION "2.15.2"
14+
#define OCP_PLUGIN_VERSION "2.15.3"
1515
#include "cmd.h"
1616

1717
PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),

plugins/ocp/ocp-telemetry-decode.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,9 +1522,11 @@ int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets
15221522
int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
15231523
{
15241524
int status = 0;
1525+
char file_path[PATH_MAX];
15251526

15261527
if (options->output_file != NULL) {
1527-
FILE *fp = fopen(options->output_file, "w");
1528+
sprintf(file_path, "%s.%s", options->output_file, "txt");
1529+
FILE *fp = fopen(file_path, "w");
15281530

15291531
if (fp) {
15301532
fprintf(fp, STR_LINE);
@@ -1639,7 +1641,7 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
16391641
fprintf(fp, STR_LINE);
16401642
fclose(fp);
16411643
} else {
1642-
nvme_show_error("Failed to open %s file.\n", options->output_file);
1644+
nvme_show_error("Failed to open %s file.\n", file_path);
16431645
return -1;
16441646
}
16451647
} else {
@@ -1753,6 +1755,7 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
17531755
int print_ocp_telemetry_json(struct ocp_telemetry_parse_options *options)
17541756
{
17551757
int status = 0;
1758+
char file_path[PATH_MAX];
17561759

17571760
//create json objects
17581761
struct json_object *root, *pheader, *preason_identifier, *da1_header, *smart_obj,
@@ -1848,13 +1851,14 @@ int print_ocp_telemetry_json(struct ocp_telemetry_parse_options *options)
18481851

18491852
if (options->output_file != NULL) {
18501853
const char *json_string = json_object_to_json_string(root);
1851-
FILE *fp = fopen(options->output_file, "w");
1854+
sprintf(file_path, "%s.%s", options->output_file, "json");
1855+
FILE *fp = fopen(file_path, "w");
18521856

18531857
if (fp) {
18541858
fputs(json_string, fp);
18551859
fclose(fp);
18561860
} else {
1857-
nvme_show_error("Failed to open %s file.\n", options->output_file);
1861+
nvme_show_error("Failed to open %s file.\n", file_path);
18581862
return -1;
18591863
}
18601864
} else {

plugins/ocp/ocp-telemetry-decode.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ struct telemetry_data_area_1 {
604604
#define DEFAULT_ASCII_STRING_SIZE 16
605605
#define SIZE_OF_VU_EVENT_ID 2
606606

607-
#define DEFAULT_TELEMETRY_BIN "telemetry.bin"
607+
#define DEFAULT_TELEMETRY_LOG "telemetry-log"
608608
#define DEFAULT_STRING_BIN "string.bin"
609609
#define DEFAULT_OUTPUT_FORMAT_JSON "json"
610610

0 commit comments

Comments
 (0)