Commit 09eaba31 authored by Parameswaran Krishnamurthy's avatar Parameswaran Krishnamurthy Committed by Tomasz Zawadzki
Browse files

bdev/nvme: restructure mdns handlers



Change-Id: I74894cf1a869489c36fe9f7e0cbc1a20e1bfd6a6
Signed-off-by: default avatarParameswaran Krishnamurthy <parameswaran.krishna@dell.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/21481


Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Reviewed-by: default avatarBoris Glimcher <Boris.Glimcher@emc.com>
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
parent 19a11e7e
Loading
Loading
Loading
Loading
+77 −70
Original line number Diff line number Diff line
@@ -222,31 +222,27 @@ get_mdns_discovery_ctx_by_svcname(const char *svcname)
}

static void
mdns_resolve_callback(
	AvahiServiceResolver *r,
	AVAHI_GCC_UNUSED AvahiIfIndex interface,
	AVAHI_GCC_UNUSED AvahiProtocol protocol,
	AvahiResolverEvent event,
	const char *name,
	const char *type,
	const char *domain,
mdns_resolve_handler(
	AvahiServiceResolver *resolver,
	AVAHI_GCC_UNUSED AvahiIfIndex intf,
	AVAHI_GCC_UNUSED AvahiProtocol avahi_protocol,
	AvahiResolverEvent resolve_event,
	const char *svc_name,
	const char *svc_type,
	const char *svc_domain,
	const char *host_name,
	const AvahiAddress *address,
	const AvahiAddress *host_address,
	uint16_t port,
	AvahiStringList *txt,
	AvahiLookupResultFlags flags,
	AVAHI_GCC_UNUSED void *userdata)
	AvahiLookupResultFlags result_flags,
	AVAHI_GCC_UNUSED void *user_data)
{
	assert(r);
	/* Called whenever a service has been resolved successfully or timed out */
	switch (event) {
	case AVAHI_RESOLVER_FAILURE:
		SPDK_ERRLOG("(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n",
			    name, type, domain,
			    avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
		break;
	assert(resolver);
	/* The handler gets called whenever a service has been resolved
	   successfully or timed out */
	switch (resolve_event) {
	case AVAHI_RESOLVER_FOUND: {
		char ipaddr[SPDK_NVMF_TRADDR_MAX_LEN + 1], port_str[SPDK_NVMF_TRSVCID_MAX_LEN + 1], *t;
		char ipaddr[SPDK_NVMF_TRADDR_MAX_LEN + 1], port_str[SPDK_NVMF_TRSVCID_MAX_LEN + 1], *str;
		struct spdk_nvme_transport_id *trid = NULL;
		char *subnqn = NULL, *proto = NULL;
		struct mdns_discovery_ctx *ctx = NULL;
@@ -255,10 +251,11 @@ mdns_resolve_callback(

		memset(ipaddr, 0, sizeof(ipaddr));
		memset(port_str, 0, sizeof(port_str));
		SPDK_INFOLOG(bdev_nvme, "Service '%s' of type '%s' in domain '%s'\n", name, type, domain);
		avahi_address_snprint(ipaddr, sizeof(ipaddr), address);
		SPDK_INFOLOG(bdev_nvme, "Service '%s' of type '%s' in domain '%s'\n", svc_name, svc_type,
			     svc_domain);
		avahi_address_snprint(ipaddr, sizeof(ipaddr), host_address);
		snprintf(port_str, sizeof(port_str), "%d", port);
		t = avahi_string_list_to_string(txt);
		str = avahi_string_list_to_string(txt);
		SPDK_INFOLOG(bdev_nvme,
			     "\t%s:%u (%s)\n"
			     "\tTXT=%s\n"
@@ -269,18 +266,18 @@ mdns_resolve_callback(
			     "\tmulticast: %i\n"
			     "\tcached: %i\n",
			     host_name, port, ipaddr,
			     t,
			     str,
			     avahi_string_list_get_service_cookie(txt),
			     !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
			     !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN),
			     !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
			     !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
			     !!(flags & AVAHI_LOOKUP_RESULT_CACHED));
		avahi_free(t);

		ctx = get_mdns_discovery_ctx_by_svcname(type);
			     !!(result_flags & AVAHI_LOOKUP_RESULT_LOCAL),
			     !!(result_flags & AVAHI_LOOKUP_RESULT_OUR_OWN),
			     !!(result_flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
			     !!(result_flags & AVAHI_LOOKUP_RESULT_MULTICAST),
			     !!(result_flags & AVAHI_LOOKUP_RESULT_CACHED));
		avahi_free(str);

		ctx = get_mdns_discovery_ctx_by_svcname(svc_type);
		if (!ctx) {
			SPDK_ERRLOG("Unknown Service '%s'\n", type);
			SPDK_ERRLOG("Unknown Service '%s'\n", svc_type);
			break;
		}

@@ -289,7 +286,7 @@ mdns_resolve_callback(
			SPDK_ERRLOG(" Error allocating memory for trid\n");
			break;
		}
		trid->adrfam = get_spdk_nvme_adrfam_from_avahi_addr(address);
		trid->adrfam = get_spdk_nvme_adrfam_from_avahi_addr(host_address);
		if (trid->adrfam != SPDK_NVMF_ADRFAM_IPV4) {
			/* TODO: For now process only ipv4 addresses */
			SPDK_INFOLOG(bdev_nvme, "trid family is not IPV4 %d\n", trid->adrfam);
@@ -327,7 +324,7 @@ mdns_resolve_callback(
				free(trid);
				avahi_free(subnqn);
				avahi_free(proto);
				avahi_service_resolver_free(r);
				avahi_service_resolver_free(resolver);
				return;
			}
		}
@@ -339,47 +336,53 @@ mdns_resolve_callback(
		avahi_free(proto);
		break;
	}
	case AVAHI_RESOLVER_FAILURE:
		SPDK_ERRLOG("(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n",
			    svc_name, svc_type, svc_domain,
			    avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(resolver))));
		break;
	default:
		SPDK_ERRLOG("Unknown Avahi resolver event: %d", event);
		SPDK_ERRLOG("Unknown Avahi resolver event: %d", resolve_event);
	}
	avahi_service_resolver_free(r);
	avahi_service_resolver_free(resolver);
}

static void
mdns_browse_callback(
	AvahiServiceBrowser *b,
	AvahiIfIndex interface,
	AvahiProtocol protocol,
	AvahiBrowserEvent event,
	const char *name,
	const char *type,
	const char *domain,
	AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
	void *userdata)
mdns_browse_handler(
	AvahiServiceBrowser *browser,
	AvahiIfIndex intf,
	AvahiProtocol avahi_protocol,
	AvahiBrowserEvent browser_event,
	const char *svc_name,
	const char *svc_type,
	const char *svc_domain,
	AVAHI_GCC_UNUSED AvahiLookupResultFlags result_flags,
	void *user_data)
{
	AvahiClient *c = userdata;
	AvahiClient *client = user_data;

	assert(b);
	/* Called whenever a new services becomes available on the LAN or is removed from the LAN */
	switch (event) {
	case AVAHI_BROWSER_FAILURE:
		SPDK_ERRLOG("(Browser) Failure: %s\n",
			    avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))));
		return;
	assert(browser);
	/* The handler gets called whenever a new service becomes available
	   or removed from the LAN */
	switch (browser_event) {
	case AVAHI_BROWSER_NEW:
		SPDK_DEBUGLOG(bdev_nvme, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type,
			      domain);
		SPDK_DEBUGLOG(bdev_nvme, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", svc_name,
			      svc_type,
			      svc_domain);
		/* We ignore the returned resolver object. In the callback
		   function we free it. If the server is terminated before
		   the callback function is called the server will free
		   the resolver for us. */
		if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0,
						 mdns_resolve_callback, c))) {
			SPDK_ERRLOG("Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c)));
		if (!(avahi_service_resolver_new(client, intf, avahi_protocol, svc_name, svc_type, svc_domain,
						 AVAHI_PROTO_UNSPEC, 0,
						 mdns_resolve_handler, client))) {
			SPDK_ERRLOG("Failed to resolve service '%s': %s\n", svc_name,
				    avahi_strerror(avahi_client_errno(client)));
		}
		break;
	case AVAHI_BROWSER_REMOVE:
		SPDK_ERRLOG("(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
		SPDK_ERRLOG("(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", svc_name, svc_type,
			    svc_domain);
		/* On remove, we are not doing the automatic cleanup of connections
		 * to the targets that were learnt from the CDC, for which remove event has
		 * been received. If required, user can clear the connections manually by
@@ -390,20 +393,24 @@ mdns_browse_callback(
	case AVAHI_BROWSER_ALL_FOR_NOW:
	case AVAHI_BROWSER_CACHE_EXHAUSTED:
		SPDK_INFOLOG(bdev_nvme, "(Browser) %s\n",
			     event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
			     browser_event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
		break;
	case AVAHI_BROWSER_FAILURE:
		SPDK_ERRLOG("(Browser) Failure: %s\n",
			    avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(browser))));
		return;
	default:
		SPDK_ERRLOG("Unknown Avahi browser event: %d", event);
		SPDK_ERRLOG("Unknown Avahi browser event: %d", browser_event);
	}
}

static void
client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void *userdata)
client_handler(AvahiClient *client, AvahiClientState avahi_state, AVAHI_GCC_UNUSED void *user_data)
{
	assert(c);
	/* Called whenever the client or server state changes */
	if (state == AVAHI_CLIENT_FAILURE) {
		SPDK_ERRLOG("Server connection failure: %s\n", avahi_strerror(avahi_client_errno(c)));
	assert(client);
	/* The handler gets called whenever the client or server state changes */
	if (avahi_state == AVAHI_CLIENT_FAILURE) {
		SPDK_ERRLOG("Server connection failure: %s\n", avahi_strerror(avahi_client_errno(client)));
	}
}

@@ -482,7 +489,7 @@ bdev_nvme_start_mdns_discovery(const char *base_name,
	if (g_avahi_client == NULL) {

		/* Allocate a new client */
		g_avahi_client = avahi_client_new(avahi_simple_poll_get(g_avahi_simple_poll), 0, client_callback,
		g_avahi_client = avahi_client_new(avahi_simple_poll_get(g_avahi_simple_poll), 0, client_handler,
						  NULL, &error);
		/* Check whether creating the client object succeeded */
		if (!g_avahi_client) {
@@ -494,7 +501,7 @@ bdev_nvme_start_mdns_discovery(const char *base_name,

	/* Create the service browser */
	if (!(sb = avahi_service_browser_new(g_avahi_client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, svcname,
					     NULL, 0, mdns_browse_callback, g_avahi_client))) {
					     NULL, 0, mdns_browse_handler, g_avahi_client))) {
		SPDK_ERRLOG("Failed to create service browser for service: %s Error: %s\n", svcname,
			    avahi_strerror(avahi_client_errno(g_avahi_client)));
		return -ENOMEM;