Adding upstream version 1.16.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
90b6101daf
commit
50aec1e4c5
345 changed files with 7594 additions and 7512 deletions
512
nvme.c
512
nvme.c
|
@ -365,18 +365,25 @@ ret:
|
|||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
__u16 get_feat_buf_len(unsigned short feature) {
|
||||
return nvme_feat_buf_len[feature];
|
||||
}
|
||||
|
||||
static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Retrieve telemetry log and write to binary file";
|
||||
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 char *dgen = "Pick which telemetry data area to report. Default is 3 to fetch areas 1-3. Valid options are 1, 2, 3, 4.";
|
||||
const size_t bs = 512;
|
||||
struct nvme_telemetry_log_page_hdr *hdr;
|
||||
struct nvme_id_ctrl ctrl;
|
||||
size_t full_size, offset = bs;
|
||||
int err = -1, fd, output;
|
||||
void *page_log;
|
||||
__u32 result;
|
||||
void *buf = NULL;
|
||||
|
||||
struct config {
|
||||
char *file_name;
|
||||
|
@ -454,6 +461,46 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct
|
|||
case 3:
|
||||
full_size = (le16_to_cpu(hdr->dalb3) * bs) + offset;
|
||||
break;
|
||||
case 4:
|
||||
err = nvme_identify_ctrl(fd, &ctrl);
|
||||
if (err) {
|
||||
perror("identify-ctrl");
|
||||
goto close_output;
|
||||
}
|
||||
|
||||
if (posix_memalign(&buf, getpagesize(), nvme_feat_buf_len[NVME_FEAT_HOST_BEHAVIOR])) {
|
||||
fprintf(stderr, "can not allocate feature payload\n");
|
||||
errno = ENOMEM;
|
||||
err = -1;
|
||||
goto close_output;
|
||||
}
|
||||
memset(buf, 0, nvme_feat_buf_len[NVME_FEAT_HOST_BEHAVIOR]);
|
||||
|
||||
err = nvme_get_feature(fd, NVME_NSID_ALL, NVME_FEAT_HOST_BEHAVIOR, 0, 0,
|
||||
0, nvme_feat_buf_len[NVME_FEAT_HOST_BEHAVIOR], buf, &result);
|
||||
if (err > 0) {
|
||||
nvme_show_status(err);
|
||||
} else if (err < 0) {
|
||||
perror("get-feature");
|
||||
} else {
|
||||
if ((ctrl.lpa & 0x40)) {
|
||||
if (((unsigned char *)buf)[1] == 1)
|
||||
full_size = (le32_to_cpu(hdr->dalb4) * bs) + offset;
|
||||
else {
|
||||
fprintf(stderr, "Data area 4 unsupported, Host Behavior Support ETDAS not set to 1\n");
|
||||
errno = EINVAL;
|
||||
err = -1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Data area 4 unsupported, bit 6 of Log Page Attributes not set\n");
|
||||
errno = EINVAL;
|
||||
err = -1;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
if (err)
|
||||
goto close_output;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Invalid data area requested\n");
|
||||
errno = EINVAL;
|
||||
|
@ -593,6 +640,56 @@ ret:
|
|||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
static int get_supported_log_pages(int argc, char **argv, struct command *cmd,
|
||||
struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Retrieve supported logs and print the table.";
|
||||
const char *verbose = "Increase output verbosity";
|
||||
struct nvme_support_log_pages supports;
|
||||
|
||||
int err = -1, fd;
|
||||
enum nvme_print_flags flags;
|
||||
|
||||
struct config {
|
||||
int verbose;
|
||||
char *output_format;
|
||||
};
|
||||
|
||||
struct config cfg = {
|
||||
.output_format = "normal",
|
||||
};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
|
||||
OPT_FLAG("verbose", 'v', &cfg.verbose, verbose),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
err = fd = parse_and_open(argc, argv, desc, opts);
|
||||
if (fd < 0)
|
||||
goto ret;
|
||||
|
||||
err = flags = validate_output_format(cfg.output_format);
|
||||
if (flags < 0)
|
||||
goto close_fd;
|
||||
|
||||
if (cfg.verbose)
|
||||
flags |= VERBOSE;
|
||||
|
||||
err = nvme_supported_log(fd, &supports);
|
||||
if (!err)
|
||||
nvme_show_supported_log(&supports, devicename, flags);
|
||||
else if (err > 0)
|
||||
nvme_show_status(err);
|
||||
else
|
||||
perror("supported log pages");
|
||||
|
||||
close_fd:
|
||||
close(fd);
|
||||
ret:
|
||||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
static int get_error_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Retrieve specified number of "\
|
||||
|
@ -929,7 +1026,7 @@ static int get_persistent_event_log(int argc, char **argv,
|
|||
const char *log_len = "number of bytes to retrieve";
|
||||
const char *raw = "use binary output";
|
||||
void *pevent_log_info;
|
||||
struct nvme_persistent_event_log_head *pevent_log_head = NULL;
|
||||
struct nvme_persistent_event_log_head *pevent_log_head, *collected_head;
|
||||
enum nvme_print_flags flags;
|
||||
int err = -1, fd;
|
||||
bool huge;
|
||||
|
@ -985,22 +1082,22 @@ static int get_persistent_event_log(int argc, char **argv,
|
|||
sizeof(*pevent_log_head), pevent_log_head);
|
||||
if (err < 0) {
|
||||
perror("persistent event log");
|
||||
goto close_fd;
|
||||
goto free_head;
|
||||
} else if (err) {
|
||||
nvme_show_status(err);
|
||||
goto close_fd;
|
||||
goto free_head;
|
||||
}
|
||||
|
||||
if (cfg.action == NVME_PEVENT_LOG_RELEASE_CTX) {
|
||||
printf("Releasing Persistent Event Log Context\n");
|
||||
goto close_fd;
|
||||
goto free_head;
|
||||
}
|
||||
|
||||
if (!cfg.log_len && cfg.action != NVME_PEVENT_LOG_EST_CTX_AND_READ) {
|
||||
cfg.log_len = le64_to_cpu(pevent_log_head->tll);
|
||||
} else if (!cfg.log_len && cfg.action == NVME_PEVENT_LOG_EST_CTX_AND_READ) {
|
||||
printf("Establishing Persistent Event Log Context\n");
|
||||
goto close_fd;
|
||||
goto free_head;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1018,22 +1115,39 @@ static int get_persistent_event_log(int argc, char **argv,
|
|||
perror("could not alloc buffer for persistent event log page\n");
|
||||
errno = ENOMEM;
|
||||
err = -1;
|
||||
goto close_fd;
|
||||
goto free_head;
|
||||
}
|
||||
err = nvme_persistent_event_log(fd, cfg.action,
|
||||
cfg.log_len, pevent_log_info);
|
||||
if (!err)
|
||||
if (!err) {
|
||||
err = nvme_persistent_event_log(fd, cfg.action,
|
||||
sizeof(*pevent_log_head), pevent_log_head);
|
||||
if (err < 0) {
|
||||
perror("persistent event log");
|
||||
goto free;
|
||||
} else if (err) {
|
||||
nvme_show_status(err);
|
||||
goto free;
|
||||
}
|
||||
collected_head = pevent_log_info;
|
||||
if(collected_head->gen_number != pevent_log_head->gen_number) {
|
||||
printf("Collected Persistent Event Log may be invalid, "\
|
||||
"Re-read the log is reiquired\n");
|
||||
goto free;
|
||||
}
|
||||
nvme_show_persistent_event_log(pevent_log_info, cfg.action,
|
||||
cfg.log_len, devicename, flags);
|
||||
}
|
||||
else if (err > 0)
|
||||
nvme_show_status(err);
|
||||
else
|
||||
perror("persistent event log");
|
||||
|
||||
free:
|
||||
nvme_free(pevent_log_info, huge);
|
||||
|
||||
close_fd:
|
||||
free_head:
|
||||
free(pevent_log_head);
|
||||
close_fd:
|
||||
close(fd);
|
||||
ret:
|
||||
return nvme_status_to_errno(err, false);
|
||||
|
@ -1249,6 +1363,113 @@ ret:
|
|||
|
||||
}
|
||||
|
||||
static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Retrieve Boot Partition " \
|
||||
"log page and prints it, for the given " \
|
||||
"device in either decoded format(default), " \
|
||||
"json or binary.";
|
||||
const char *lsp = "log specific field";
|
||||
const char *fname = "boot partition data output file name";
|
||||
struct nvme_boot_part_hdr boot;
|
||||
__u8 *bp_log;
|
||||
enum nvme_print_flags flags;
|
||||
int err = -1, fd = 0, output = 0;
|
||||
__u32 bpsz = 0;
|
||||
|
||||
struct config {
|
||||
__u8 lsp;
|
||||
char *output_format;
|
||||
char *file_name;
|
||||
};
|
||||
|
||||
struct config cfg = {
|
||||
.lsp = 0,
|
||||
.file_name = NULL,
|
||||
.output_format = "normal",
|
||||
};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_BYTE("lsp", 's', &cfg.lsp, lsp),
|
||||
OPT_FILE("output-file", 'f', &cfg.file_name, fname),
|
||||
OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
err = fd = parse_and_open(argc, argv, desc, opts);
|
||||
if (fd < 0)
|
||||
goto ret;
|
||||
|
||||
err = flags = validate_output_format(cfg.output_format);
|
||||
if (flags < 0)
|
||||
goto close_fd;
|
||||
|
||||
if (!cfg.file_name) {
|
||||
fprintf(stderr, "Please provide an output file!\n");
|
||||
errno = EINVAL;
|
||||
err = -1;
|
||||
goto close_fd;
|
||||
}
|
||||
|
||||
if (cfg.lsp > 128) {
|
||||
fprintf(stderr, "invalid lsp param: %u\n", cfg.lsp);
|
||||
errno = EINVAL;
|
||||
err = -1;
|
||||
goto close_fd;
|
||||
}
|
||||
|
||||
output = open(cfg.file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (output < 0) {
|
||||
fprintf(stderr, "Failed to open output file %s: %s!\n",
|
||||
cfg.file_name, strerror(errno));
|
||||
err = output;
|
||||
goto close_fd;
|
||||
}
|
||||
|
||||
err = nvme_boot_part_log(fd, cfg.lsp, &boot, sizeof(boot));
|
||||
if (err < 0) {
|
||||
perror("boot partition log");
|
||||
goto close_output;
|
||||
} else if (err) {
|
||||
nvme_show_status(err);
|
||||
goto close_output;
|
||||
}
|
||||
|
||||
bpsz = (boot.bpinfo & 0x7fff) * 128 * 1024;
|
||||
bp_log = calloc(sizeof(boot) + bpsz, 1);
|
||||
if (!bp_log) {
|
||||
perror("could not alloc buffer for boot partition log");
|
||||
errno = ENOMEM;
|
||||
err = -1;
|
||||
goto close_output;
|
||||
}
|
||||
|
||||
err = nvme_boot_part_log(fd, cfg.lsp, &bp_log, sizeof(boot) + bpsz);
|
||||
if (!err)
|
||||
nvme_show_boot_part_log(&bp_log, devicename, flags, sizeof(boot) + bpsz);
|
||||
else if (err > 0)
|
||||
nvme_show_status(err);
|
||||
else
|
||||
perror("boot partition log");
|
||||
|
||||
err = write(output, (void *) bp_log + sizeof(boot), bpsz);
|
||||
if (err != bpsz) {
|
||||
fprintf(stderr, "Failed to flush all data to file!\n");
|
||||
} else {
|
||||
printf("Data flushed into file %s\n", cfg.file_name);
|
||||
}
|
||||
err = 0;
|
||||
|
||||
free(bp_log);
|
||||
|
||||
close_output:
|
||||
close(output);
|
||||
close_fd:
|
||||
close(fd);
|
||||
ret:
|
||||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
static int get_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Retrieve desired number of bytes "\
|
||||
|
@ -1428,6 +1649,53 @@ ret:
|
|||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
static int get_fid_support_effects_log(int argc, char **argv, struct command *cmd,
|
||||
struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Retrieve FID Support and Effects log and show it.";
|
||||
const char *human_readable = "show log in readable format";
|
||||
struct nvme_fid_support_effects fid_support_log;
|
||||
enum nvme_print_flags flags;
|
||||
int fd, err = -1;
|
||||
|
||||
struct config {
|
||||
int human_readable;
|
||||
char *output_format;
|
||||
};
|
||||
|
||||
struct config cfg = {
|
||||
.output_format = "normal",
|
||||
};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
|
||||
OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
err = fd = parse_and_open(argc, argv, desc, opts);
|
||||
if (fd < 0)
|
||||
goto ret;
|
||||
|
||||
err = flags = validate_output_format(cfg.output_format);
|
||||
if (flags < 0)
|
||||
goto close_fd;
|
||||
if (cfg.human_readable)
|
||||
flags |= VERBOSE;
|
||||
|
||||
err = nvme_fid_support_effects_log(fd, &fid_support_log);
|
||||
if (!err)
|
||||
nvme_show_fid_support_effects_log(&fid_support_log, devicename, flags);
|
||||
else if (err > 0)
|
||||
nvme_show_status(err);
|
||||
else
|
||||
perror("fid support effects log");
|
||||
close_fd:
|
||||
close(fd);
|
||||
ret:
|
||||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Show controller list information for the subsystem the "\
|
||||
|
@ -1554,6 +1822,67 @@ ret:
|
|||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
|
||||
struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Show endurance group list information for the given endurance "\
|
||||
"group id";
|
||||
const char *endurance_grp_id = "Endurance Group ID";
|
||||
int err = -1, fd;
|
||||
struct nvme_endurance_group_list *endgrp_list;
|
||||
enum nvme_print_flags flags;
|
||||
|
||||
struct config {
|
||||
__u16 endgrp_id;
|
||||
char *output_format;
|
||||
};
|
||||
|
||||
struct config cfg = {
|
||||
.endgrp_id = 0,
|
||||
.output_format = "normal",
|
||||
};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_SHRT("endgrp-id", 'i', &cfg.endgrp_id, endurance_grp_id),
|
||||
OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
err = fd = parse_and_open(argc, argv, desc, opts);
|
||||
if (fd < 0)
|
||||
goto ret;
|
||||
|
||||
err = flags = validate_output_format(cfg.output_format);
|
||||
if (flags < 0)
|
||||
goto close_fd;
|
||||
if (flags != JSON && flags != NORMAL) {
|
||||
err = -EINVAL;
|
||||
fprintf(stderr, "invalid output format\n");
|
||||
goto close_fd;
|
||||
}
|
||||
|
||||
if (posix_memalign((void *)&endgrp_list, getpagesize(), 0x1000)) {
|
||||
fprintf(stderr, "can not allocate memory for endurance gropu list\n");
|
||||
errno = ENOMEM;
|
||||
err = -1;
|
||||
goto close_fd;
|
||||
}
|
||||
|
||||
err = nvme_identify_endurance_group_list(fd, cfg.endgrp_id, endgrp_list);
|
||||
if (!err)
|
||||
nvme_show_endurance_group_list(endgrp_list, flags);
|
||||
else if (err > 0)
|
||||
nvme_show_status(err);
|
||||
else
|
||||
perror("id endurance group list");
|
||||
|
||||
free(endgrp_list);
|
||||
close_fd:
|
||||
close(fd);
|
||||
ret:
|
||||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Delete the given namespace by "\
|
||||
|
@ -2224,6 +2553,73 @@ ret:
|
|||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
static int cmd_set_independent_id_ns(int argc, char **argv,
|
||||
struct command *cmd, struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Send an I/O Command Set Independent Identify "\
|
||||
"Namespace command to the given device, returns properties of the "\
|
||||
"specified namespace in human-readable or binary or json format.";
|
||||
const char *raw = "show identify in binary format";
|
||||
const char *human_readable = "show identify in readable format";
|
||||
const char *namespace_id = "identifier of desired namespace";
|
||||
|
||||
enum nvme_print_flags flags;
|
||||
struct nvme_cmd_set_independent_id_ns ns;
|
||||
int err = -1, fd;
|
||||
|
||||
struct config {
|
||||
__u32 namespace_id;
|
||||
int raw_binary;
|
||||
int human_readable;
|
||||
char *output_format;
|
||||
};
|
||||
|
||||
struct config cfg = {
|
||||
.namespace_id = 0,
|
||||
.output_format = "normal",
|
||||
};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
|
||||
OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
|
||||
OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
|
||||
OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
err = fd = parse_and_open(argc, argv, desc, opts);
|
||||
if (fd < 0)
|
||||
goto ret;
|
||||
|
||||
err = flags = validate_output_format(cfg.output_format);
|
||||
if (flags < 0)
|
||||
goto close_fd;
|
||||
if (cfg.raw_binary)
|
||||
flags = BINARY;
|
||||
if (cfg.human_readable)
|
||||
flags |= VERBOSE;
|
||||
|
||||
if (!cfg.namespace_id) {
|
||||
err = cfg.namespace_id = nvme_get_nsid(fd);
|
||||
if (err < 0) {
|
||||
perror("get-namespace-id");
|
||||
goto close_fd;
|
||||
}
|
||||
}
|
||||
|
||||
err = nvme_cmd_set_independent_identify_ns(fd, cfg.namespace_id, &ns);
|
||||
if (!err)
|
||||
nvme_show_cmd_set_independent_id_ns(&ns, cfg.namespace_id, flags);
|
||||
else if (err > 0)
|
||||
nvme_show_status(err);
|
||||
else
|
||||
perror("I/O command set independent identify namespace");
|
||||
close_fd:
|
||||
close(fd);
|
||||
ret:
|
||||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Send an Identify Namespace Granularity List command to the "\
|
||||
|
@ -5244,7 +5640,7 @@ static int submit_io(int opcode, char *command, const char *desc,
|
|||
gettimeofday(&start_time, NULL);
|
||||
err = nvme_io(fd, opcode, cfg.namespace_id, cfg.start_block, cfg.block_count,
|
||||
control, dsmgmt, cfg.ref_tag, cfg.app_tag, cfg.app_tag_mask,
|
||||
cfg.storage_tag, buffer, mbuffer);
|
||||
cfg.storage_tag, buffer, buffer_size, mbuffer, mbuffer_size);
|
||||
gettimeofday(&end_time, NULL);
|
||||
if (cfg.latency)
|
||||
printf(" latency: %s: %llu us\n",
|
||||
|
@ -5788,6 +6184,100 @@ static int rpmb_cmd(int argc, char **argv, struct command *cmd, struct plugin *p
|
|||
return rpmb_cmd_option(argc, argv, cmd, plugin);
|
||||
}
|
||||
|
||||
static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "The Lockdown command is used to control the "\
|
||||
"Command and Feature Lockdown capability which configures the "\
|
||||
"prohibition or allowance of execution of the specified command "\
|
||||
"or Set Features command targeting a specific Feature Identifier.";
|
||||
const char *ofi_desc = "Opcode or Feature Identifier(OFI) "\
|
||||
"specifies the command opcode or Set Features Feature Identifier "\
|
||||
"identified by the Scope field.";
|
||||
const char *ifc_desc = "[0-3] Interface (INF) field identifies the "\
|
||||
"interfaces affected by this command.";
|
||||
const char *prhbt_desc = "[0-1]Prohibit(PRHBT) bit specifies whether "\
|
||||
"to prohibit or allow the command opcode or Set Features Feature "\
|
||||
"Identifier specified by this command.";
|
||||
const char *scp_desc = "[0-15]Scope(SCP) field specifies the contents "\
|
||||
"of the Opcode or Feature Identifier field.";
|
||||
const char *uuid_desc = "UUID Index - If this field is set to a non-zero "\
|
||||
"value, then the value of this field is the index of a UUID in the UUID "\
|
||||
"List that is used by the command.If this field is cleared to 0h,"\
|
||||
"then no UUID index is specified";
|
||||
|
||||
int fd, err = -1;
|
||||
|
||||
struct config {
|
||||
__u8 ofi;
|
||||
__u8 ifc;
|
||||
__u8 prhbt;
|
||||
__u8 scp;
|
||||
__u8 uuid;
|
||||
};
|
||||
|
||||
struct config cfg = {
|
||||
.ofi = 0,
|
||||
.ifc = 0,
|
||||
.prhbt = 0,
|
||||
.scp = 0,
|
||||
.uuid = 0,
|
||||
};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_BYTE("ofi", 'o', &cfg.ofi, ofi_desc),
|
||||
OPT_BYTE("ifc", 'f', &cfg.ifc, ifc_desc),
|
||||
OPT_BYTE("prhbt", 'p', &cfg.prhbt, prhbt_desc),
|
||||
OPT_BYTE("scp", 's', &cfg.scp, scp_desc),
|
||||
OPT_BYTE("uuid", 'U', &cfg.uuid, uuid_desc),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
err = fd = parse_and_open(argc, argv, desc, opts);
|
||||
if (fd < 0)
|
||||
goto ret;
|
||||
|
||||
/* check for input arguement limit */
|
||||
if (cfg.ifc > 3) {
|
||||
fprintf(stderr, "invalid interface settings:%d\n", cfg.ifc);
|
||||
errno = EINVAL;
|
||||
err = -1;
|
||||
goto close_fd;
|
||||
}
|
||||
if (cfg.prhbt > 1) {
|
||||
fprintf(stderr, "invalid prohibit settings:%d\n", cfg.prhbt);
|
||||
errno = EINVAL;
|
||||
err = -1;
|
||||
goto close_fd;
|
||||
}
|
||||
if (cfg.scp > 15) {
|
||||
fprintf(stderr, "invalid scope settings:%d\n", cfg.scp);
|
||||
errno = EINVAL;
|
||||
err = -1;
|
||||
goto close_fd;
|
||||
}
|
||||
if (cfg.uuid > 127) {
|
||||
fprintf(stderr, "invalid UUID index settings:%d\n", cfg.uuid);
|
||||
errno = EINVAL;
|
||||
err = -1;
|
||||
goto close_fd;
|
||||
}
|
||||
|
||||
err = nvme_lockdown(fd, cfg.scp,cfg.prhbt,cfg.ifc,cfg.ofi,
|
||||
cfg.uuid);
|
||||
|
||||
if (err < 0)
|
||||
perror("lockdown");
|
||||
else if (err > 0)
|
||||
nvme_show_status(err);
|
||||
else
|
||||
printf("Lockdown Command is Successful\n");
|
||||
|
||||
close_fd:
|
||||
close(fd);
|
||||
ret:
|
||||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
static int passthru(int argc, char **argv, int ioctl_cmd, uint8_t cmd_type,
|
||||
const char *desc, struct command *cmd)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue