@@ -669,7 +669,7 @@ const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c)
669669
670670const char * nvme_ctrl_get_address (nvme_ctrl_t c )
671671{
672- return c -> address ;
672+ return c -> address ? c -> address : "" ;
673673}
674674
675675const char * nvme_ctrl_get_firmware (nvme_ctrl_t c )
@@ -977,16 +977,18 @@ struct nvme_ctrl *nvme_create_ctrl(nvme_root_t r,
977977 return c ;
978978}
979979
980- struct nvme_ctrl * nvme_lookup_ctrl (struct nvme_subsystem * s , const char * transport ,
981- const char * traddr , const char * host_traddr ,
982- const char * host_iface , const char * trsvcid )
980+ nvme_ctrl_t nvme_lookup_ctrl (nvme_subsystem_t s , const char * transport ,
981+ const char * traddr , const char * host_traddr ,
982+ const char * host_iface , const char * trsvcid ,
983+ nvme_ctrl_t p )
983984{
984985 nvme_root_t r = s -> h ? s -> h -> r : NULL ;
985986 struct nvme_ctrl * c ;
986987
987988 if (!s || !transport )
988989 return NULL ;
989- nvme_subsystem_for_each_ctrl (s , c ) {
990+ c = p ? nvme_subsystem_next_ctrl (s , p ) : nvme_subsystem_first_ctrl (s );
991+ for (; c != NULL ; c = nvme_subsystem_next_ctrl (s , c )) {
990992 if (strcmp (c -> transport , transport ))
991993 continue ;
992994 if (traddr && c -> traddr &&
@@ -1120,13 +1122,11 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance)
11201122 goto out_free_name ;
11211123 }
11221124
1123- if (strcmp (c -> transport , "loop" )) {
1124- c -> address = nvme_get_attr (path , "address" );
1125- if (!c -> address ) {
1126- errno = ENVME_CONNECT_INVAL_TR ;
1127- ret = -1 ;
1128- goto out_free_name ;
1129- }
1125+ c -> address = nvme_get_attr (path , "address" );
1126+ if (!c -> address && strcmp (c -> transport , "loop" )) {
1127+ errno = ENVME_CONNECT_INVAL_TR ;
1128+ ret = -1 ;
1129+ goto out_free_name ;
11301130 }
11311131
11321132 subsys_name = nvme_ctrl_lookup_subsystem_name (h -> r , name );
@@ -1166,7 +1166,7 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance)
11661166static nvme_ctrl_t nvme_ctrl_alloc (nvme_root_t r , nvme_subsystem_t s ,
11671167 const char * path , const char * name )
11681168{
1169- nvme_ctrl_t c ;
1169+ nvme_ctrl_t c , p ;
11701170 char * addr = NULL , * address = NULL , * a , * e ;
11711171 char * transport , * traddr = NULL , * trsvcid = NULL ;
11721172 char * host_traddr = NULL , * host_iface = NULL ;
@@ -1177,13 +1177,15 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_root_t r, nvme_subsystem_t s,
11771177 errno = ENXIO ;
11781178 return NULL ;
11791179 }
1180- if (!strcmp (transport , "loop" ))
1181- goto skip_address ;
11821180 /* Parse 'address' string into components */
11831181 addr = nvme_get_attr (path , "address" );
11841182 if (!addr ) {
11851183 char * rpath = NULL , * p = NULL , * _a = NULL ;
11861184
1185+ /* loop transport might not have an address */
1186+ if (!strcmp (transport , "loop" ))
1187+ goto skip_address ;
1188+
11871189 /* Older kernel don't support pcie transport addresses */
11881190 if (strcmp (transport , "pcie" )) {
11891191 free (transport );
@@ -1228,13 +1230,36 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_root_t r, nvme_subsystem_t s,
12281230 }
12291231 }
12301232skip_address :
1231- c = nvme_lookup_ctrl (s , transport , traddr ,
1232- host_traddr , host_iface , trsvcid );
1233+ p = NULL ;
1234+ do {
1235+ c = nvme_lookup_ctrl (s , transport , traddr ,
1236+ host_traddr , host_iface , trsvcid , p );
1237+ if (c ) {
1238+ if (!c -> name )
1239+ break ;
1240+ if (!strcmp (c -> name , name )) {
1241+ nvme_msg (r , LOG_DEBUG ,
1242+ "%s: found existing ctrl %s\n" ,
1243+ __func__ , c -> name );
1244+ break ;
1245+ }
1246+ nvme_msg (r , LOG_DEBUG , "%s: skipping ctrl %s\n" ,
1247+ __func__ , c -> name );
1248+ p = c ;
1249+ }
1250+ } while (c );
1251+ if (!c )
1252+ c = p ;
12331253 free (transport );
12341254 if (address )
12351255 free (address );
12361256 if (!c ) {
1237- errno = ENOMEM ;
1257+ if (!p ) {
1258+ nvme_msg (r , LOG_ERR , "%s: failed to lookup ctrl\n" ,
1259+ __func__ );
1260+ errno = ENODEV ;
1261+ } else
1262+ errno = ENOMEM ;
12381263 return NULL ;
12391264 }
12401265 c -> address = addr ;
@@ -1287,7 +1312,10 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name)
12871312 return NULL ;
12881313 }
12891314 subsysname = nvme_ctrl_lookup_subsystem_name (r , name );
1315+ /* subsysname might be NULL here */
12901316 s = nvme_lookup_subsystem (h , subsysname , subsysnqn );
1317+ if (subsysname )
1318+ free (subsysname );
12911319 free (subsysnqn );
12921320 if (!s ) {
12931321 free (path );
0 commit comments