@@ -10256,6 +10256,130 @@ static int get_dispersed_ns_participating_nss_log(int argc, char **argv, struct
1025610256 return err ;
1025710257}
1025810258
10259+ static int get_log_offset (struct nvme_dev * dev , struct nvme_get_log_args * args , __u64 * offset ,
10260+ __u32 len , void * * log )
10261+ {
10262+ args -> lpo = * offset ,
10263+ args -> log = * log + * offset ,
10264+ args -> len = len ;
10265+ * offset += args -> len ;
10266+ * log = nvme_realloc (* log , * offset );
10267+ if (!* log )
10268+ return - ENOMEM ;
10269+ return nvme_cli_get_log_page (dev , NVME_LOG_PAGE_PDU_SIZE , args );
10270+ }
10271+
10272+ static int get_reachability_group_desc (struct nvme_dev * dev , struct nvme_get_log_args * args ,
10273+ __u64 offset , struct nvme_reachability_groups_log * * logp )
10274+ {
10275+ int err ;
10276+ struct nvme_reachability_groups_log * log = * logp ;
10277+ __u16 i ;
10278+ __u32 len ;
10279+
10280+ for (i = 0 ; i < le16_to_cpu (log -> nrgd ); i ++ ) {
10281+ len = sizeof (* log -> rgd );
10282+ err = get_log_offset (dev , args , & offset , len , (void * * )& log );
10283+ if (err )
10284+ goto err_free ;
10285+ len = le32_to_cpu (log -> rgd [i ].nnid ) * sizeof (* log -> rgd [i ].nsid );
10286+ err = get_log_offset (dev , args , & offset , len , (void * * )& log );
10287+ if (err )
10288+ goto err_free ;
10289+ }
10290+
10291+ * logp = log ;
10292+ return 0 ;
10293+
10294+ err_free :
10295+ free (log );
10296+ * logp = NULL ;
10297+ return err ;
10298+ }
10299+
10300+ static int get_reachability_groups (struct nvme_dev * dev , bool rgo , bool rae ,
10301+ struct nvme_reachability_groups_log * * logp )
10302+ {
10303+ int err ;
10304+ struct nvme_reachability_groups_log * log ;
10305+ __u64 log_len = sizeof (* log );
10306+ struct nvme_get_log_args args = {
10307+ .args_size = sizeof (args ),
10308+ .fd = dev_fd (dev ),
10309+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT ,
10310+ .lid = NVME_LOG_LID_REACHABILITY_GROUPS ,
10311+ .nsid = NVME_NSID_ALL ,
10312+ .lsp = rgo ,
10313+ .rae = rae ,
10314+ };
10315+
10316+ log = nvme_alloc (log_len );
10317+ if (!log )
10318+ return - ENOMEM ;
10319+
10320+ err = nvme_cli_get_log_reachability_groups (dev , rgo , rae , log_len , log );
10321+ if (err )
10322+ goto err_free ;
10323+
10324+ err = get_reachability_group_desc (dev , & args , log_len , & log );
10325+ if (err )
10326+ goto err_free ;
10327+
10328+ * logp = log ;
10329+ return 0 ;
10330+
10331+ err_free :
10332+ free (log );
10333+ return err ;
10334+ }
10335+
10336+ static int get_reachability_groups_log (int argc , char * * argv , struct command * cmd ,
10337+ struct plugin * plugin )
10338+ {
10339+ const char * desc = "Retrieve Reachability Groups Log, show it" ;
10340+ const char * rgo = "Return Groups Only" ;
10341+ nvme_print_flags_t flags ;
10342+ int err ;
10343+
10344+ _cleanup_free_ struct nvme_reachability_groups_log * log = NULL ;
10345+
10346+ _cleanup_nvme_dev_ struct nvme_dev * dev = NULL ;
10347+
10348+ struct config {
10349+ bool rgo ;
10350+ bool rae ;
10351+ };
10352+
10353+ struct config cfg = {
10354+ .rgo = false,
10355+ .rae = false,
10356+ };
10357+
10358+ NVME_ARGS (opts ,
10359+ OPT_FLAG ("groups-only" , 'g' , & cfg .rgo , rgo ),
10360+ OPT_FLAG ("rae" , 'r' , & cfg .rae , rae ));
10361+
10362+ err = parse_and_open (& dev , argc , argv , desc , opts );
10363+ if (err )
10364+ return err ;
10365+
10366+ err = validate_output_format (nvme_cfg .output_format , & flags );
10367+ if (err < 0 ) {
10368+ nvme_show_error ("Invalid output format" );
10369+ return err ;
10370+ }
10371+
10372+ err = get_reachability_groups (dev , cfg .rgo , cfg .rae , & log );
10373+ if (!err )
10374+ nvme_show_reachability_groups_log (log , flags );
10375+ else if (err > 0 )
10376+ nvme_show_status (err );
10377+ else
10378+ nvme_show_perror ("rotational media info log" );
10379+
10380+ return err ;
10381+ }
10382+
1025910383void register_extension (struct plugin * plugin )
1026010384{
1026110385 plugin -> parent = & nvme ;
0 commit comments