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