@@ -206,6 +206,8 @@ static const char *doper = "directive operation";
206206static const char * dspec_w_dtype = "directive specification associated with directive type" ;
207207static const char * dtype = "directive type" ;
208208static const char * endgid = "Endurance Group Identifier (ENDGID)" ;
209+ static const char * force =
210+ "The \"I know what I'm doing\" flag, skip confirmation before sending command" ;
209211static const char * force_unit_access = "force device to commit data before command completes" ;
210212static const char * human_readable_directive = "show directive in readable format" ;
211213static const char * human_readable_identify = "show identify in readable format" ;
@@ -6348,7 +6350,6 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
63486350 const char * ms = "[0-1]: extended format off/on" ;
63496351 const char * reset = "Automatically reset the controller after successful format" ;
63506352 const char * bs = "target block size" ;
6351- const char * force = "The \"I know what I'm doing\" flag, skip confirmation before sending command" ;
63526353
63536354 _cleanup_free_ struct nvme_id_ctrl * ctrl = NULL ;
63546355 _cleanup_free_ struct nvme_id_ns * ns = NULL ;
@@ -10919,6 +10920,81 @@ static int get_pull_model_ddc_req_log(int argc, char **argv, struct command *cmd
1091910920 return err ;
1092010921}
1092110922
10923+ static int wait_input (unsigned int sec )
10924+ {
10925+ fd_set rfds ;
10926+ struct timeval tv ;
10927+
10928+ FD_ZERO (& rfds );
10929+ FD_SET (0 , & rfds );
10930+
10931+ tv .tv_sec = sec ;
10932+ tv .tv_usec = 0 ;
10933+
10934+ return select (1 , & rfds , NULL , NULL , & tv );
10935+ }
10936+
10937+ static int abort_cmd (int argc , char * * argv , struct command * cmd ,
10938+ struct plugin * plugin )
10939+ {
10940+ const char * desc = "send an abort command to the given device." ;
10941+ const char * sqid = "command SQID to be aborted is associated with" ;
10942+ const char * cid = "command identifier of the command to be aborted" ;
10943+ int err ;
10944+ nvme_print_flags_t flags ;
10945+ __u32 result ;
10946+ char input ;
10947+
10948+ _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
10949+
10950+ struct nvme_abort_args args = {
10951+ .args_size = sizeof (args ),
10952+ .timeout = nvme_cfg .timeout ,
10953+ .result = & result ,
10954+ };
10955+
10956+ NVME_ARGS (opts ,
10957+ OPT_SHRT ("sqid" , 's' , & args .sqid , sqid ),
10958+ OPT_SHRT ("cid" , 'c' , & args .cid , cid ),
10959+ OPT_FLAG ("force" , 0 , NULL , force ));
10960+
10961+ err = parse_and_open (& dev , argc , argv , desc , opts );
10962+ if (err )
10963+ return err ;
10964+
10965+ err = validate_output_format (nvme_cfg .output_format , & flags );
10966+ if (err < 0 ) {
10967+ nvme_show_error ("Invalid output format" );
10968+ return err ;
10969+ }
10970+
10971+ if (!argconfig_parse_seen (opts , "force" )) {
10972+ fprintf (stderr , "do you really want to do this? (y/n): " );
10973+ err = wait_input (10 );
10974+ if (err == 1 )
10975+ err = scanf ("%c" , & input );
10976+ if (err != 1 || input != 'y' ) {
10977+ fprintf (stderr , "canceled to abort.\n" );
10978+ return - ECANCELED ;
10979+ }
10980+ }
10981+
10982+ err = nvme_cli_abort (dev , & args );
10983+ if (!err ) {
10984+ if (NVME_GET (result , ABORT_CQEDW0_IANP ))
10985+ nvme_show_result ("Not performed aborting sqid:%d cid:%d" , args .sqid ,
10986+ args .cid );
10987+ else
10988+ nvme_show_result ("Success aborting sqid:%d cid:%d" , args .sqid , args .cid );
10989+ } else if (err > 0 ) {
10990+ nvme_show_status (err );
10991+ } else {
10992+ nvme_show_perror ("abort" );
10993+ }
10994+
10995+ return err ;
10996+ }
10997+
1092210998void register_extension (struct plugin * plugin )
1092310999{
1092411000 plugin -> parent = & nvme ;
0 commit comments