From: Maxim Date: Thu, 7 Jun 2018 18:06:04 +0000 (-0700) Subject: Add user parameter to specify data area region from telemetry log X-Git-Tag: v1.6~33 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=9800ff8a245f33c3b2f56c9e810d0a8b9980d532;p=users%2Fsagi%2Fnvme-cli.git Add user parameter to specify data area region from telemetry log And read in block size chunks instead of 4k. Link: https://github.com/linux-nvme/nvme-cli/pull/361 Signed-off-by: Maxim Veligan [changelog, formatting, set error on exit, removed unnecessary error check] Signed-off-by: Keith Busch --- diff --git a/nvme.c b/nvme.c index a065e5d8..d5492eda 100644 --- a/nvme.c +++ b/nvme.c @@ -234,26 +234,31 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct const char *fname = "File name to save raw binary, includes header"; const char *hgen = "Have the host tell the controller to generate the report"; const char *cgen = "Gather report generated by the controller."; + const char *dgen = "Pick which telemetry data area to report. Default is all. Valid options are 1, 2, 3."; + const size_t bs = 512; struct nvme_telemetry_log_page_hdr *hdr; + size_t full_size, offset = bs; + int err = 0, fd, output; void *page_log; - size_t full_size, offset, num_blocks; - int err = 0 , fd, output; struct config { char *file_name; __u32 host_gen; int ctrl_init; + int data_area; }; struct config cfg = { .file_name = NULL, .host_gen = 1, .ctrl_init = 0, + .data_area = 3, }; const struct argconfig_commandline_options command_line_options[] = { - {"output-file", 'o', "FILE", CFG_STRING, &cfg.file_name, required_argument, fname}, - {"host-generate", 'h', "NUM", CFG_POSITIVE, &cfg.host_gen, required_argument, hgen}, - {"controller-init", 'c', "", CFG_NONE, &cfg.ctrl_init, no_argument, cgen}, + {"output-file", 'o', "FILE", CFG_STRING, &cfg.file_name, required_argument, fname}, + {"host-generate", 'h', "NUM", CFG_POSITIVE, &cfg.host_gen, required_argument, hgen}, + {"controller-init", 'c', "", CFG_NONE, &cfg.ctrl_init, no_argument, cgen}, + {"data-area", 'd', "NUM", CFG_POSITIVE, &cfg.data_area, required_argument, dgen}, {NULL} }; @@ -275,44 +280,52 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct } cfg.host_gen = !!cfg.host_gen; + hdr = malloc(bs); + page_log = malloc(bs); + if (!hdr || !page_log) { + fprintf(stderr, "Failed to allocate %zu bytes for log\n", bs); + err = ENOMEM; + goto free_mem; + } - hdr = malloc(4096); - memset(hdr, 0, 4096); - - err = nvme_get_telemetry_log(fd, hdr, cfg.host_gen, cfg.ctrl_init, 4096, 0); + memset(hdr, 0, bs); + err = nvme_get_telemetry_log(fd, hdr, cfg.host_gen, cfg.ctrl_init, bs, 0); if (err) { fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(err), err); fprintf(stderr, "Failed to aquire telemetry header %d!\n", err); - free(hdr); - goto close_output; + close(output); + goto free_mem; } - err = write(output, (void *) hdr, 4096); - if (err != 4096) { + err = write(output, (void *) hdr, bs); + if (err != bs) { fprintf(stderr, "Failed to flush all data to file!"); - goto free_hdr; + goto free_mem; } - num_blocks = max(hdr->dalb1, max(hdr->dalb2, hdr->dalb3)); - - full_size = num_blocks * 512; - /* Round to page boundary */ - full_size += (4096 - (full_size % 4096)); - /* We've already pulled 1 page worth of data, lets remove that. */ - full_size -= 4096; - offset = 4096; - - page_log = malloc(4096); - if (!page_log) { - fprintf(stderr, "Failed to allocate %zu bytes for log\n", - full_size); - err = ENOMEM; - goto free_hdr; + switch (cfg.data_area) { + case 1: + full_size = (hdr->dalb1 * bs) + offset; + break; + case 2: + full_size = (hdr->dalb2 * bs) + offset; + break; + case 3: + full_size = (hdr->dalb3 * bs) + offset; + break; + default: + fprintf(stderr, "Invalid data area requested"); + err = EINVAL; + goto free_mem; } - while (full_size) { - err = nvme_get_telemetry_log(fd, page_log, 0, cfg.ctrl_init, 4096, offset); + /* + * Continuously pull data until the offset hits the end of the last + * block. + */ + while (offset != full_size) { + err = nvme_get_telemetry_log(fd, page_log, 0, cfg.ctrl_init, bs, offset); if (err) { fprintf(stderr, "Failed to aquire full telemetry log!\n"); fprintf(stderr, "NVMe Status:%s(%x)\n", @@ -320,20 +333,16 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct break; } - err = write(output, (void *) page_log, 4096); - if (err != 4096) { + err = write(output, (void *) page_log, bs); + if (err != bs) { fprintf(stderr, "Failed to flush all data to file!"); break; } - full_size -= 4096; - offset += 4096; + offset += bs; } - - free(page_log); - free_hdr: + free_mem: free(hdr); - close_output: - close(output); + free(page_log); close_fd: close(fd); return err;