Skip to content

Commit f0ebf0d

Browse files
committed
ocp: add set-error-injection command
The command injects error conditions. Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
1 parent 0979f22 commit f0ebf0d

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

plugins/ocp/ocp-nvme.c

+106
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,19 @@ struct erri_get_cq_entry {
187187
__u32 rsvd7:25;
188188
};
189189

190+
struct erri_config {
191+
char *file;
192+
__u8 number;
193+
__u16 type;
194+
__u16 nrtdp;
195+
};
196+
190197
static const char *sel = "[0-3]: current/default/saved/supported";
191198
static const char *no_uuid = "Skip UUID index search (UUID index not required for OCP 1.0)";
199+
const char *data = "Error injection data structure entries";
200+
const char *number = "number of valid error injection data entries";
201+
static const char *type = "Error injection type";
202+
static const char *nrtdp = "Number of reads to trigger device panic";
192203

193204
static int ocp_print_C3_log_normal(struct nvme_dev *dev,
194205
struct ssd_latency_monitor_log *log_data)
@@ -4039,3 +4050,98 @@ static int get_error_injection(int argc, char **argv, struct command *cmd, struc
40394050

40404051
return error_injection_get(dev, cfg.sel, !argconfig_parse_seen(opts, "no-uuid"));
40414052
}
4053+
4054+
static int error_injection_set(struct nvme_dev *dev, struct erri_config *cfg, bool uuid)
4055+
{
4056+
int err;
4057+
__u32 result;
4058+
struct nvme_set_features_args args = {
4059+
.args_size = sizeof(args),
4060+
.fd = dev_fd(dev),
4061+
.fid = 0xc0,
4062+
.cdw11 = cfg->number,
4063+
.data_len = cfg->number * sizeof(struct erri_entry),
4064+
.timeout = nvme_cfg.timeout,
4065+
.result = &result,
4066+
};
4067+
4068+
_cleanup_fd_ int ffd = -1;
4069+
4070+
_cleanup_free_ struct erri_entry *entry = NULL;
4071+
4072+
if (uuid) {
4073+
/* OCP 2.0 requires UUID index support */
4074+
err = ocp_get_uuid_index(dev, &args.uuidx);
4075+
if (err || !args.uuidx) {
4076+
nvme_show_error("ERROR: No OCP UUID index found");
4077+
return err;
4078+
}
4079+
}
4080+
4081+
entry = nvme_alloc(args.data_len);
4082+
if (!entry) {
4083+
nvme_show_error("malloc: %s", strerror(errno));
4084+
return -errno;
4085+
}
4086+
4087+
if (cfg->file && strlen(cfg->file)) {
4088+
ffd = open(cfg->file, O_RDONLY);
4089+
if (ffd < 0) {
4090+
nvme_show_error("Failed to open file %s: %s", cfg->file, strerror(errno));
4091+
return -EINVAL;
4092+
}
4093+
err = read(ffd, entry, args.data_len);
4094+
if (err < 0) {
4095+
nvme_show_error("failed to read data buffer from input file: %s",
4096+
strerror(errno));
4097+
return -errno;
4098+
}
4099+
} else {
4100+
entry->enable = 1;
4101+
entry->single = 1;
4102+
entry->type = cfg->type;
4103+
entry->nrtdp = cfg->nrtdp;
4104+
}
4105+
4106+
args.data = entry;
4107+
4108+
err = nvme_set_features(&args);
4109+
if (err) {
4110+
if (err < 0)
4111+
nvme_show_error("set-error-injection: %s", nvme_strerror(errno));
4112+
else if (err > 0)
4113+
nvme_show_status(err);
4114+
return err;
4115+
}
4116+
4117+
printf("set-error-injection, data: %s, number: %d, uuid: %d, type: %d, nrtdp: %d\n",
4118+
cfg->file, cfg->number, args.uuidx, cfg->type, cfg->nrtdp);
4119+
if (args.data)
4120+
d(args.data, args.data_len, 16, 1);
4121+
4122+
return 0;
4123+
}
4124+
4125+
static int set_error_injection(int argc, char **argv, struct command *cmd, struct plugin *plugin)
4126+
{
4127+
const char *desc = "Inject error conditions";
4128+
int err;
4129+
struct erri_config cfg = {
4130+
.number = 1,
4131+
};
4132+
4133+
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
4134+
4135+
NVME_ARGS(opts,
4136+
OPT_FILE("data", 'd', &cfg.file, data),
4137+
OPT_BYTE("number", 'n', &cfg.number, number),
4138+
OPT_FLAG("no-uuid", 'N', NULL, no_uuid),
4139+
OPT_SHRT("type", 't', &cfg.type, type),
4140+
OPT_SHRT("nrtdp", 'r', &cfg.nrtdp, nrtdp));
4141+
4142+
err = parse_and_open(&dev, argc, argv, desc, opts);
4143+
if (err)
4144+
return err;
4145+
4146+
return error_injection_set(dev, &cfg, !argconfig_parse_seen(opts, "no-uuid"));
4147+
}

plugins/ocp/ocp-nvme.h

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),
3737
ENTRY("get-dssd-async-event-config", "Get DSSD Async Event Config", get_dssd_async_event_config)
3838
ENTRY("tcg-configuration-log", "Retrieve TCG Configuration Log Page", ocp_tcg_configuration_log)
3939
ENTRY("get-error-injection", "Return set of error injection", get_error_injection)
40+
ENTRY("set-error-injection", "Inject error conditions", set_error_injection)
4041
)
4142
);
4243

0 commit comments

Comments
 (0)