Skip to content

Commit 79abafe

Browse files
lgdacunhigaw
authored andcommitted
plugins/solidigm: Compressing vs-internal-log log files into zip file.
Creates zip file containing files useful to debug. Signed-off-by: Leonardo da Cunha <leonardo.da.cunha@solidigm.com>
1 parent 3196089 commit 79abafe

File tree

2 files changed

+85
-33
lines changed

2 files changed

+85
-33
lines changed

plugins/solidigm/solidigm-internal-logs.c

+84-32
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <unistd.h>
1414
#include <inttypes.h>
1515
#include <linux/limits.h>
16+
#include <time.h>
1617

1718
#include "common.h"
1819
#include "nvme.h"
@@ -122,7 +123,7 @@ struct nlog_dump_header4_1 {
122123

123124
struct config {
124125
__u32 namespace_id;
125-
char *file_prefix;
126+
char *dir_prefix;
126127
char *type;
127128
bool verbose;
128129
};
@@ -222,6 +223,7 @@ static int dump_assert_logs(struct nvme_dev *dev, struct config cfg)
222223
__u8 buf[INTERNAL_LOG_MAX_BYTE_TRANSFER];
223224
__u8 head_buf[INTERNAL_LOG_MAX_BYTE_TRANSFER];
224225
char file_path[PATH_MAX];
226+
char file_name[] = "AssertLog.bin";
225227
struct assert_dump_header *ad = (struct assert_dump_header *) head_buf;
226228
struct nvme_passthru_cmd cmd = {
227229
.opcode = 0xd2,
@@ -236,7 +238,8 @@ static int dump_assert_logs(struct nvme_dev *dev, struct config cfg)
236238
if (err)
237239
return err;
238240

239-
sprintf(file_path, "%s_AssertLog.bin", cfg.file_prefix);
241+
snprintf(file_path, sizeof(file_path), "%.*s/%s",
242+
(int) (sizeof(file_path) - sizeof(file_name) - 1), cfg.dir_prefix, file_name);
240243
output = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
241244
if (output < 0)
242245
return -errno;
@@ -291,7 +294,7 @@ static int dump_event_logs(struct nvme_dev *dev, struct config cfg)
291294
err = read_header(&cmd, dev_fd(dev));
292295
if (err)
293296
return err;
294-
sprintf(file_path, "%s_EventLog.bin", cfg.file_prefix);
297+
snprintf(file_path, sizeof(file_path), "%s/EventLog.bin", cfg.dir_prefix);
295298
output = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
296299
if (output < 0)
297300
return -errno;
@@ -387,7 +390,8 @@ static int dump_nlogs(struct nvme_dev *dev, struct config cfg, int core)
387390
count = nlog_header->totalnlogs;
388391
core_num = core < 0 ? nlog_header->corecount : 0;
389392
if (!header_size) {
390-
sprintf(file_path, "%s_NLog.bin", cfg.file_prefix);
393+
snprintf(file_path, sizeof(file_path), "%s/NLog.bin",
394+
cfg.dir_prefix);
391395
output = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
392396
if (output < 0)
393397
return -errno;
@@ -423,25 +427,32 @@ enum telemetry_type {
423427

424428
static int dump_telemetry(struct nvme_dev *dev, struct config cfg, enum telemetry_type ttype)
425429
{
426-
struct nvme_telemetry_log *log = NULL;
430+
_cleanup_free_ struct nvme_telemetry_log *log = NULL;
427431
size_t log_size = 0;
428-
int err = 0, output;
432+
int err = 0;
429433
__u8 *buffer = NULL;
430434
size_t bytes_remaining = 0;
431435
enum nvme_telemetry_da da;
432436
size_t max_data_tx;
433437
char file_path[PATH_MAX];
434-
char *log_name;
438+
char *file_name;
439+
char *log_descr;
440+
struct stat sb;
441+
442+
_cleanup_file_ int output = -1;
435443

436444
switch (ttype) {
437445
case HOSTGENNEW:
438-
log_name = "TelemetryHostGenNew";
446+
file_name = "lid_0x07_lsp_0x01_lsi_0x0000.bin";
447+
log_descr = "Generated Host Initiated";
439448
break;
440449
case HOSTGENOLD:
441-
log_name = "TelemetryHostGenOld";
450+
file_name = "lid_0x07_lsp_0x00_lsi_0x0000.bin";
451+
log_descr = "Existing Host Initiated";
442452
break;
443453
case CONTROLLER:
444-
log_name = "TelemetryController";
454+
file_name = "lid_0x08_lsp_0x00_lsi_0x0000.bin";
455+
log_descr = "Controller Initiated";
445456
break;
446457
default:
447458
return -EINVAL;
@@ -453,11 +464,6 @@ static int dump_telemetry(struct nvme_dev *dev, struct config cfg, enum telemetr
453464
if (max_data_tx > DRIVER_MAX_TX_256K)
454465
max_data_tx = DRIVER_MAX_TX_256K;
455466

456-
sprintf(file_path, "%s_%s.bin", cfg.file_prefix, log_name);
457-
output = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
458-
if (output < 0)
459-
return -errno;
460-
461467
switch (ttype) {
462468
case HOSTGENNEW:
463469
err = nvme_get_telemetry_log(dev_fd(dev), true, false, false, max_data_tx, da,
@@ -474,7 +480,20 @@ static int dump_telemetry(struct nvme_dev *dev, struct config cfg, enum telemetr
474480
}
475481

476482
if (err)
477-
goto tele_close_output;
483+
return err;
484+
485+
snprintf(file_path, sizeof(file_path), "%s/log_pages", cfg.dir_prefix);
486+
if (!(stat(file_path, &sb) == 0 && S_ISDIR(sb.st_mode))) {
487+
if (mkdir(file_path, 777) != 0) {
488+
perror(file_path);
489+
return -errno;
490+
}
491+
}
492+
493+
snprintf(file_path, sizeof(file_path), "%s/log_pages/%s", cfg.dir_prefix, file_name);
494+
output = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
495+
if (output < 0)
496+
return -errno;
478497

479498
bytes_remaining = log_size;
480499
buffer = (__u8 *)log;
@@ -486,45 +505,49 @@ static int dump_telemetry(struct nvme_dev *dev, struct config cfg, enum telemetr
486505
err = -errno;
487506
goto tele_close_output;
488507
}
508+
489509
bytes_remaining -= bytes_written;
490510
buffer += bytes_written;
491511
}
492-
printf("Successfully wrote log to %s\n", file_path);
512+
printf("Successfully wrote %s Telemetry log to %s\n", log_descr, file_path);
493513

494514
tele_close_output:
495-
free(log);
496515
close(output);
497-
498516
return err;
499517
}
500518

501519
int solidigm_get_internal_log(int argc, char **argv, struct command *command,
502520
struct plugin *plugin)
503521
{
522+
char folder[PATH_MAX];
523+
char zip_name[PATH_MAX];
524+
char *output_path;
504525
char sn_prefix[sizeof(((struct nvme_id_ctrl *)0)->sn)+1];
505526
int log_count = 0;
506527
int err;
507-
struct nvme_dev *dev;
528+
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
508529
bool all = false;
530+
time_t t;
531+
struct tm tm;
509532

510533
const char *desc = "Get Debug Firmware Logs and save them.";
511534
const char *type =
512535
"Log type: ALL, CONTROLLERINITTELEMETRY, HOSTINITTELEMETRY, HOSTINITTELEMETRYNOGEN, NLOG, ASSERT, EVENT. Defaults to ALL.";
513-
const char *prefix = "Output file prefix; defaults to device serial number.";
536+
const char *prefix = "Output dir prefix; defaults to device serial number.";
514537
const char *verbose = "To print out verbose info.";
515538
const char *namespace_id = "Namespace to get logs from.";
516539

517540

518541
struct config cfg = {
519542
.namespace_id = NVME_NSID_ALL,
520-
.file_prefix = NULL,
543+
.dir_prefix = NULL,
521544
.type = NULL,
522545
};
523546

524547
OPT_ARGS(opts) = {
525548
OPT_STR("type", 't', &cfg.type, type),
526549
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
527-
OPT_FILE("file-prefix", 'p', &cfg.file_prefix, prefix),
550+
OPT_FILE("dir-prefix", 'p', &cfg.dir_prefix, prefix),
528551
OPT_FLAG("verbose", 'v', &cfg.verbose, verbose),
529552
OPT_END()
530553
};
@@ -533,12 +556,22 @@ int solidigm_get_internal_log(int argc, char **argv, struct command *command,
533556
if (err)
534557
return err;
535558

536-
if (!cfg.file_prefix) {
559+
if (!cfg.dir_prefix) {
537560
err = get_serial_number(sn_prefix, dev_fd(dev));
538561
if (err)
539-
goto out_dev;
540-
cfg.file_prefix = sn_prefix;
562+
return err;
563+
cfg.dir_prefix = sn_prefix;
564+
}
565+
t = time(NULL);
566+
tm = *localtime(&t);
567+
snprintf(folder, sizeof(folder), "%s-%d%02d%02d%02d%02d%02d", cfg.dir_prefix,
568+
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
569+
if (mkdir(folder, 0777) != 0) {
570+
perror("mkdir");
571+
return -errno;
541572
}
573+
cfg.dir_prefix = folder;
574+
output_path = folder;
542575

543576
if (!cfg.type)
544577
cfg.type = "ALL";
@@ -547,8 +580,9 @@ int solidigm_get_internal_log(int argc, char **argv, struct command *command,
547580
*p = toupper(*p);
548581
}
549582

550-
if (!strcmp(cfg.type, "ALL"))
583+
if (!strcmp(cfg.type, "ALL")) {
551584
all = true;
585+
}
552586
if (all || !strcmp(cfg.type, "ASSERT")) {
553587
err = dump_assert_logs(dev, cfg);
554588
if (err == 0)
@@ -592,14 +626,32 @@ int solidigm_get_internal_log(int argc, char **argv, struct command *command,
592626
perror("Error retrieving Telemetry Host Initiated");
593627
}
594628

629+
if (log_count > 0) {
630+
int ret_cmd;
631+
char cmd[ARG_MAX];
632+
char *where_err = cfg.verbose ? "" : ">/dev/null 2>&1";
633+
634+
snprintf(zip_name, sizeof(zip_name), "%s.zip", cfg.dir_prefix);
635+
snprintf(cmd, sizeof(cmd), "cd \"%s\" && zip -r \"../%s\" ./* %s", cfg.dir_prefix,
636+
zip_name, where_err);
637+
printf("Compressing logs to %s\n", zip_name);
638+
ret_cmd = system(cmd);
639+
if (ret_cmd == -1)
640+
perror(cmd);
641+
else {
642+
output_path = zip_name;
643+
snprintf(cmd, sizeof(cmd), "rm -rf %s", cfg.dir_prefix);
644+
printf("Removing %s\n", cfg.dir_prefix);
645+
if (system(cmd) != 0)
646+
perror("Failed removing logs folder");
647+
}
648+
}
649+
595650
if (log_count == 0) {
596651
if (err > 0)
597652
nvme_show_status(err);
598653
} else if ((log_count > 1) || cfg.verbose)
599-
printf("Total: %d log files with prefix: %s\n", log_count, cfg.file_prefix);
600-
out_dev:
601-
/* Redundant close() to make static code analysis happy */
602-
close(dev->direct.fd);
603-
dev_close(dev);
654+
printf("Total: %d log files in %s\n", log_count, output_path);
655+
604656
return err;
605657
}

plugins/solidigm/solidigm-nvme.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
#include "cmd.h"
1515

16-
#define SOLIDIGM_PLUGIN_VERSION "1.0"
16+
#define SOLIDIGM_PLUGIN_VERSION "1.1"
1717

1818
PLUGIN(NAME("solidigm", "Solidigm vendor specific extensions", SOLIDIGM_PLUGIN_VERSION),
1919
COMMAND_LIST(

0 commit comments

Comments
 (0)