File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -531,6 +531,8 @@ void nvme_free_global_ctx(struct nvme_global_ctx *ctx)
531531 free (ctx -> config_file );
532532 free (ctx -> application );
533533 free (ctx );
534+
535+ nvme_getifaddrs (NULL ); /* Free cached I/F addresses */
534536}
535537
536538void nvme_root_release_fds (struct nvme_global_ctx * ctx )
@@ -1787,9 +1789,9 @@ static ctrl_match_t _candidate_init(struct candidate_args *candidate,
17871789
17881790 if (streq0 (transport , "tcp" )) {
17891791 /* For TCP we may need to access the interface map.
1790- * Let's retrieve and cache the map.
1792+ * Let's retrieve the (cached) map.
17911793 */
1792- if (getifaddrs (& candidate -> iface_list ) == -1 )
1794+ if (nvme_getifaddrs (& candidate -> iface_list ) == -1 )
17931795 candidate -> iface_list = NULL ;
17941796
17951797 candidate -> addreq = nvme_ipaddrs_eq ;
@@ -1813,7 +1815,10 @@ static ctrl_match_t _candidate_init(struct candidate_args *candidate,
18131815 */
18141816static void _candidate_free (struct candidate_args * candidate )
18151817{
1816- freeifaddrs (candidate -> iface_list ); /* This is NULL-safe */
1818+ /* iface_list points to cached data owned by nvme_getifaddrs().
1819+ * Do not free here. The memory will be released when we free the
1820+ * global context.
1821+ */
18171822}
18181823
18191824#define _cleanup_candidate_ __cleanup__(_candidate_free)
Original file line number Diff line number Diff line change @@ -1142,6 +1142,31 @@ bool nvme_iface_primary_addr_matches(const struct ifaddrs *iface_list, const cha
11421142
11431143#endif /* HAVE_NETDB */
11441144
1145+ int nvme_getifaddrs (struct ifaddrs * * ifap )
1146+ {
1147+ static struct ifaddrs * ifaddrs_cache ;
1148+ static bool ifaddrs_cached ;
1149+
1150+ if (!ifap ) {
1151+ freeifaddrs (ifaddrs_cache ); /* NULL-safe */
1152+ ifaddrs_cache = NULL ;
1153+ ifaddrs_cached = false;
1154+ return 0 ;
1155+ }
1156+
1157+ if (!ifaddrs_cached ) {
1158+ if (getifaddrs (& ifaddrs_cache ) == -1 ) {
1159+ ifaddrs_cache = NULL ;
1160+ * ifap = NULL ;
1161+ return -1 ;
1162+ }
1163+ ifaddrs_cached = true;
1164+ }
1165+
1166+ * ifap = ifaddrs_cache ;
1167+ return 0 ;
1168+ }
1169+
11451170void * __nvme_alloc (size_t len )
11461171{
11471172 size_t _len = round_up (len , 0x1000 );
Original file line number Diff line number Diff line change @@ -758,6 +758,21 @@ int nvme_uuid_find(struct nvme_id_uuid_list *uuid_list, const unsigned char uuid
758758 */
759759bool nvme_ipaddrs_eq (const char * addr1 , const char * addr2 );
760760
761+ /**
762+ * nvme_getifaddrs - Cached wrapper around getifaddrs()
763+ * @ifap: Output pointer to the cached interface address list. If
764+ * NULL, then free the cache.
765+ *
766+ * On the first call, this function invokes the POSIX getifaddrs()
767+ * and caches the result. Subsequent calls return the cached data.
768+ * The caller must NOT call freeifaddrs() on the returned data.
769+ * Use nvme_getifaddrs() with ifap set to NULL to release the
770+ * cache when done.
771+ *
772+ * Return: 0 on success, -1 on error (with errno set).
773+ */
774+ int nvme_getifaddrs (struct ifaddrs * * ifap );
775+
761776/**
762777 * nvme_iface_matching_addr - Get interface matching @addr
763778 * @iface_list: Interface list returned by getifaddrs()
You can’t perform that action at this time.
0 commit comments