@@ -10144,6 +10144,130 @@ static int get_rotational_media_info_log(int argc, char **argv, struct command *
1014410144 return err ;
1014510145}
1014610146
10147+ static int get_log_offset (struct nvme_dev * dev , struct nvme_get_log_args * args , __u64 * offset ,
10148+ __u32 len , void * * log )
10149+ {
10150+ args -> lpo = * offset ,
10151+ args -> log = * log + * offset ,
10152+ args -> len = len ;
10153+ * offset += args -> len ;
10154+ * log = nvme_realloc (* log , * offset );
10155+ if (!* log )
10156+ return - ENOMEM ;
10157+ return nvme_cli_get_log_page (dev , NVME_LOG_PAGE_PDU_SIZE , args );
10158+ }
10159+
10160+ static int get_reachability_group_desc (struct nvme_dev * dev , struct nvme_get_log_args * args ,
10161+ __u64 offset , struct nvme_reachability_groups_log * * logp )
10162+ {
10163+ int err ;
10164+ struct nvme_reachability_groups_log * log = * logp ;
10165+ __u16 i ;
10166+ __u32 len ;
10167+
10168+ for (i = 0 ; i < le16_to_cpu (log -> nrgd ); i ++ ) {
10169+ len = sizeof (* log -> rgd );
10170+ err = get_log_offset (dev , args , & offset , len , (void * * )& log );
10171+ if (err )
10172+ goto err_free ;
10173+ len = le32_to_cpu (log -> rgd [i ].nnid ) * sizeof (* log -> rgd [i ].nsid );
10174+ err = get_log_offset (dev , args , & offset , len , (void * * )& log );
10175+ if (err )
10176+ goto err_free ;
10177+ }
10178+
10179+ * logp = log ;
10180+ return 0 ;
10181+
10182+ err_free :
10183+ free (log );
10184+ * logp = NULL ;
10185+ return err ;
10186+ }
10187+
10188+ static int get_reachability_groups (struct nvme_dev * dev , bool rgo , bool rae ,
10189+ struct nvme_reachability_groups_log * * logp )
10190+ {
10191+ int err ;
10192+ struct nvme_reachability_groups_log * log ;
10193+ __u64 log_len = sizeof (* log );
10194+ struct nvme_get_log_args args = {
10195+ .args_size = sizeof (args ),
10196+ .fd = dev_fd (dev ),
10197+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
10198+ .lid = NVME_LOG_LID_REACHABILITY_GROUPS ,
10199+ .nsid = NVME_NSID_ALL ,
10200+ .lsp = rgo ,
10201+ .rae = rae ,
10202+ };
10203+
10204+ log = nvme_alloc (log_len );
10205+ if (!log )
10206+ return - ENOMEM ;
10207+
10208+ err = nvme_cli_get_log_reachability_groups (dev , rgo , rae , log_len , log );
10209+ if (err )
10210+ goto err_free ;
10211+
10212+ err = get_reachability_group_desc (dev , & args , log_len , & log );
10213+ if (err )
10214+ goto err_free ;
10215+
10216+ * logp = log ;
10217+ return 0 ;
10218+
10219+ err_free :
10220+ free (log );
10221+ return err ;
10222+ }
10223+
10224+ static int get_reachability_groups_log (int argc , char * * argv , struct command * cmd ,
10225+ struct plugin * plugin )
10226+ {
10227+ const char * desc = "Retrieve Reachability Groups Log, show it" ;
10228+ const char * rgo = "Return Groups Only" ;
10229+ nvme_print_flags_t flags ;
10230+ int err ;
10231+
10232+ _cleanup_free_ struct nvme_reachability_groups_log * log = NULL ;
10233+
10234+ _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
10235+
10236+ struct config {
10237+ bool rgo ;
10238+ bool rae ;
10239+ };
10240+
10241+ struct config cfg = {
10242+ .rgo = false,
10243+ .rae = false,
10244+ };
10245+
10246+ NVME_ARGS (opts ,
10247+ OPT_FLAG ("groups-only" , 'g' , & cfg .rgo , rgo ),
10248+ OPT_FLAG ("rae" , 'r' , & cfg .rae , rae ));
10249+
10250+ err = parse_and_open (& dev , argc , argv , desc , opts );
10251+ if (err )
10252+ return err ;
10253+
10254+ err = validate_output_format (nvme_cfg .output_format , & flags );
10255+ if (err < 0 ) {
10256+ nvme_show_error ("Invalid output format" );
10257+ return err ;
10258+ }
10259+
10260+ err = get_reachability_groups (dev , cfg .rgo , cfg .rae , & log );
10261+ if (!err )
10262+ nvme_show_reachability_groups_log (log , flags );
10263+ else if (err > 0 )
10264+ nvme_show_status (err );
10265+ else
10266+ nvme_show_perror ("rotational media info log" );
10267+
10268+ return err ;
10269+ }
10270+
1014710271void register_extension (struct plugin * plugin )
1014810272{
1014910273 plugin -> parent = & nvme ;
0 commit comments