@@ -187,8 +187,19 @@ struct erri_get_cq_entry {
187
187
__u32 rsvd7 :25 ;
188
188
};
189
189
190
+ struct erri_config {
191
+ char * file ;
192
+ __u8 number ;
193
+ __u16 type ;
194
+ __u16 nrtdp ;
195
+ };
196
+
190
197
static const char * sel = "[0-3]: current/default/saved/supported" ;
191
198
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" ;
192
203
193
204
static int ocp_print_C3_log_normal (struct nvme_dev * dev ,
194
205
struct ssd_latency_monitor_log * log_data )
@@ -4039,3 +4050,98 @@ static int get_error_injection(int argc, char **argv, struct command *cmd, struc
4039
4050
4040
4051
return error_injection_get (dev , cfg .sel , !argconfig_parse_seen (opts , "no-uuid" ));
4041
4052
}
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
+ }
0 commit comments