Skip to content

Commit bce4a5e

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 bce4a5e

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

plugins/ocp/ocp-nvme.c

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

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)