12796687dSParameswaran Krishnamurthy /* SPDX-License-Identifier: BSD-3-Clause 22796687dSParameswaran Krishnamurthy * Copyright (c) 2022 Dell Inc, or its subsidiaries. 32796687dSParameswaran Krishnamurthy * All rights reserved. 42796687dSParameswaran Krishnamurthy */ 52796687dSParameswaran Krishnamurthy 62796687dSParameswaran Krishnamurthy #include "spdk/stdinc.h" 72796687dSParameswaran Krishnamurthy #include "spdk/version.h" 82796687dSParameswaran Krishnamurthy 92796687dSParameswaran Krishnamurthy #include "spdk_internal/event.h" 102796687dSParameswaran Krishnamurthy 112796687dSParameswaran Krishnamurthy #include "spdk/assert.h" 122796687dSParameswaran Krishnamurthy #include "spdk/config.h" 132796687dSParameswaran Krishnamurthy #include "spdk/env.h" 142796687dSParameswaran Krishnamurthy #include "spdk/init.h" 152796687dSParameswaran Krishnamurthy #include "spdk/log.h" 162796687dSParameswaran Krishnamurthy #include "spdk/thread.h" 172796687dSParameswaran Krishnamurthy #include "spdk/trace.h" 182796687dSParameswaran Krishnamurthy #include "spdk/string.h" 192796687dSParameswaran Krishnamurthy #include "spdk/scheduler.h" 202796687dSParameswaran Krishnamurthy #include "spdk/rpc.h" 212796687dSParameswaran Krishnamurthy #include "spdk/util.h" 222796687dSParameswaran Krishnamurthy #include "spdk/nvme.h" 23*dd98a248SMehakjot Singh Sidhu #include "spdk/module/bdev/nvme.h" 242796687dSParameswaran Krishnamurthy #include "bdev_nvme.h" 252796687dSParameswaran Krishnamurthy 262796687dSParameswaran Krishnamurthy #ifdef SPDK_CONFIG_AVAHI 272796687dSParameswaran Krishnamurthy #include <avahi-client/client.h> 282796687dSParameswaran Krishnamurthy #include <avahi-client/lookup.h> 292796687dSParameswaran Krishnamurthy #include <avahi-common/simple-watch.h> 302796687dSParameswaran Krishnamurthy #include <avahi-common/malloc.h> 312796687dSParameswaran Krishnamurthy #include <avahi-common/error.h> 322796687dSParameswaran Krishnamurthy 332796687dSParameswaran Krishnamurthy static AvahiSimplePoll *g_avahi_simple_poll = NULL; 342796687dSParameswaran Krishnamurthy static AvahiClient *g_avahi_client = NULL; 352796687dSParameswaran Krishnamurthy 362796687dSParameswaran Krishnamurthy struct mdns_discovery_entry_ctx { 372796687dSParameswaran Krishnamurthy char name[256]; 382796687dSParameswaran Krishnamurthy struct spdk_nvme_transport_id trid; 392796687dSParameswaran Krishnamurthy struct spdk_nvme_ctrlr_opts drv_opts; 402796687dSParameswaran Krishnamurthy TAILQ_ENTRY(mdns_discovery_entry_ctx) tailq; 412796687dSParameswaran Krishnamurthy struct mdns_discovery_ctx *ctx; 422796687dSParameswaran Krishnamurthy }; 432796687dSParameswaran Krishnamurthy 442796687dSParameswaran Krishnamurthy struct mdns_discovery_ctx { 452796687dSParameswaran Krishnamurthy char *name; 462796687dSParameswaran Krishnamurthy char *svcname; 472796687dSParameswaran Krishnamurthy char *hostnqn; 482796687dSParameswaran Krishnamurthy AvahiServiceBrowser *sb; 492796687dSParameswaran Krishnamurthy struct spdk_poller *poller; 502796687dSParameswaran Krishnamurthy struct spdk_nvme_ctrlr_opts drv_opts; 51*dd98a248SMehakjot Singh Sidhu struct spdk_bdev_nvme_ctrlr_opts bdev_opts; 522796687dSParameswaran Krishnamurthy uint32_t seqno; 532796687dSParameswaran Krishnamurthy bool stop; 542796687dSParameswaran Krishnamurthy struct spdk_thread *calling_thread; 552796687dSParameswaran Krishnamurthy TAILQ_ENTRY(mdns_discovery_ctx) tailq; 562796687dSParameswaran Krishnamurthy TAILQ_HEAD(, mdns_discovery_entry_ctx) mdns_discovery_entry_ctxs; 572796687dSParameswaran Krishnamurthy }; 582796687dSParameswaran Krishnamurthy 592796687dSParameswaran Krishnamurthy TAILQ_HEAD(mdns_discovery_ctxs, mdns_discovery_ctx); 602796687dSParameswaran Krishnamurthy static struct mdns_discovery_ctxs g_mdns_discovery_ctxs = TAILQ_HEAD_INITIALIZER( 612796687dSParameswaran Krishnamurthy g_mdns_discovery_ctxs); 622796687dSParameswaran Krishnamurthy 632796687dSParameswaran Krishnamurthy static struct mdns_discovery_entry_ctx * 642796687dSParameswaran Krishnamurthy create_mdns_discovery_entry_ctx(struct mdns_discovery_ctx *ctx, struct spdk_nvme_transport_id *trid) 652796687dSParameswaran Krishnamurthy { 662796687dSParameswaran Krishnamurthy struct mdns_discovery_entry_ctx *new_ctx; 672796687dSParameswaran Krishnamurthy 682796687dSParameswaran Krishnamurthy assert(ctx); 692796687dSParameswaran Krishnamurthy assert(trid); 702796687dSParameswaran Krishnamurthy new_ctx = calloc(1, sizeof(*new_ctx)); 712796687dSParameswaran Krishnamurthy if (new_ctx == NULL) { 722796687dSParameswaran Krishnamurthy SPDK_ERRLOG("could not allocate new mdns_entry_ctx\n"); 732796687dSParameswaran Krishnamurthy return NULL; 742796687dSParameswaran Krishnamurthy } 752796687dSParameswaran Krishnamurthy 762796687dSParameswaran Krishnamurthy new_ctx->ctx = ctx; 772796687dSParameswaran Krishnamurthy memcpy(&new_ctx->trid, trid, sizeof(struct spdk_nvme_transport_id)); 782796687dSParameswaran Krishnamurthy snprintf(new_ctx->name, sizeof(new_ctx->name), "%s%u_nvme", ctx->name, ctx->seqno); 792796687dSParameswaran Krishnamurthy memcpy(&new_ctx->drv_opts, &ctx->drv_opts, sizeof(ctx->drv_opts)); 802796687dSParameswaran Krishnamurthy snprintf(new_ctx->drv_opts.hostnqn, sizeof(ctx->drv_opts.hostnqn), "%s", ctx->hostnqn); 812796687dSParameswaran Krishnamurthy ctx->seqno = ctx->seqno + 1; 822796687dSParameswaran Krishnamurthy return new_ctx; 832796687dSParameswaran Krishnamurthy } 842796687dSParameswaran Krishnamurthy 852796687dSParameswaran Krishnamurthy static void 862796687dSParameswaran Krishnamurthy mdns_bdev_nvme_start_discovery(void *_entry_ctx) 872796687dSParameswaran Krishnamurthy { 882796687dSParameswaran Krishnamurthy int status; 892796687dSParameswaran Krishnamurthy struct mdns_discovery_entry_ctx *entry_ctx = _entry_ctx; 902796687dSParameswaran Krishnamurthy 912796687dSParameswaran Krishnamurthy assert(_entry_ctx); 922796687dSParameswaran Krishnamurthy status = bdev_nvme_start_discovery(&entry_ctx->trid, entry_ctx->name, 932796687dSParameswaran Krishnamurthy &entry_ctx->ctx->drv_opts, 942796687dSParameswaran Krishnamurthy &entry_ctx->ctx->bdev_opts, 952796687dSParameswaran Krishnamurthy 0, true, NULL, NULL); 962796687dSParameswaran Krishnamurthy if (status) { 972796687dSParameswaran Krishnamurthy SPDK_ERRLOG("Error starting discovery for name %s addr %s port %s subnqn %s &trid %p\n", 982796687dSParameswaran Krishnamurthy entry_ctx->ctx->name, entry_ctx->trid.traddr, entry_ctx->trid.trsvcid, 992796687dSParameswaran Krishnamurthy entry_ctx->trid.subnqn, &entry_ctx->trid); 1002796687dSParameswaran Krishnamurthy } 1012796687dSParameswaran Krishnamurthy } 1022796687dSParameswaran Krishnamurthy 1032796687dSParameswaran Krishnamurthy static void 1042796687dSParameswaran Krishnamurthy free_mdns_discovery_entry_ctx(struct mdns_discovery_ctx *ctx) 1052796687dSParameswaran Krishnamurthy { 1067ed18ac6SJim Harris struct mdns_discovery_entry_ctx *entry_ctx, *tmp; 1072796687dSParameswaran Krishnamurthy 1082796687dSParameswaran Krishnamurthy if (!ctx) { 1092796687dSParameswaran Krishnamurthy return; 1102796687dSParameswaran Krishnamurthy } 1112796687dSParameswaran Krishnamurthy 1127ed18ac6SJim Harris TAILQ_FOREACH_SAFE(entry_ctx, &ctx->mdns_discovery_entry_ctxs, tailq, tmp) { 1137ed18ac6SJim Harris TAILQ_REMOVE(&ctx->mdns_discovery_entry_ctxs, entry_ctx, tailq); 1142796687dSParameswaran Krishnamurthy free(entry_ctx); 1152796687dSParameswaran Krishnamurthy } 1162796687dSParameswaran Krishnamurthy } 1172796687dSParameswaran Krishnamurthy 1182796687dSParameswaran Krishnamurthy static void 1192796687dSParameswaran Krishnamurthy free_mdns_discovery_ctx(struct mdns_discovery_ctx *ctx) 1202796687dSParameswaran Krishnamurthy { 1212796687dSParameswaran Krishnamurthy if (!ctx) { 1222796687dSParameswaran Krishnamurthy return; 1232796687dSParameswaran Krishnamurthy } 1242796687dSParameswaran Krishnamurthy 1252796687dSParameswaran Krishnamurthy free(ctx->name); 1262796687dSParameswaran Krishnamurthy free(ctx->svcname); 1272796687dSParameswaran Krishnamurthy free(ctx->hostnqn); 1282796687dSParameswaran Krishnamurthy avahi_service_browser_free(ctx->sb); 1292796687dSParameswaran Krishnamurthy free_mdns_discovery_entry_ctx(ctx); 1302796687dSParameswaran Krishnamurthy free(ctx); 1312796687dSParameswaran Krishnamurthy } 1322796687dSParameswaran Krishnamurthy 1332796687dSParameswaran Krishnamurthy /* get_key_val_avahi_resolve_txt - Search for the key string in the TXT received 1342796687dSParameswaran Krishnamurthy * from Avavi daemon and return its value. 1352796687dSParameswaran Krishnamurthy * input 1362796687dSParameswaran Krishnamurthy * txt: TXT returned by Ahavi daemon will be of format 1372796687dSParameswaran Krishnamurthy * "NQN=nqn.1988-11.com.dell:SFSS:1:20221122170722e8" "p=tcp foo" and the 1382796687dSParameswaran Krishnamurthy * AvahiStringList txt is a linked list with each node holding a 1392796687dSParameswaran Krishnamurthy * key-value pair like key:p value:tcp 1402796687dSParameswaran Krishnamurthy * 1412796687dSParameswaran Krishnamurthy * key: Key string to search in the txt list 1422796687dSParameswaran Krishnamurthy * output 1432796687dSParameswaran Krishnamurthy * Returns the value for the key or NULL if key is not present 1442796687dSParameswaran Krishnamurthy * Returned string needs to be freed with avahi_free() 1452796687dSParameswaran Krishnamurthy */ 1462796687dSParameswaran Krishnamurthy static char * 1472796687dSParameswaran Krishnamurthy get_key_val_avahi_resolve_txt(AvahiStringList *txt, const char *key) 1482796687dSParameswaran Krishnamurthy { 1492796687dSParameswaran Krishnamurthy char *k = NULL, *v = NULL; 1502796687dSParameswaran Krishnamurthy AvahiStringList *p = NULL; 1512796687dSParameswaran Krishnamurthy int r; 1522796687dSParameswaran Krishnamurthy 1532796687dSParameswaran Krishnamurthy if (!txt || !key) { 1542796687dSParameswaran Krishnamurthy return NULL; 1552796687dSParameswaran Krishnamurthy } 1562796687dSParameswaran Krishnamurthy 1572796687dSParameswaran Krishnamurthy p = avahi_string_list_find(txt, key); 1582796687dSParameswaran Krishnamurthy if (!p) { 1592796687dSParameswaran Krishnamurthy return NULL; 1602796687dSParameswaran Krishnamurthy } 1612796687dSParameswaran Krishnamurthy 1622796687dSParameswaran Krishnamurthy r = avahi_string_list_get_pair(p, &k, &v, NULL); 1632796687dSParameswaran Krishnamurthy if (r < 0) { 1642796687dSParameswaran Krishnamurthy return NULL; 1652796687dSParameswaran Krishnamurthy } 1662796687dSParameswaran Krishnamurthy 1672796687dSParameswaran Krishnamurthy avahi_free(k); 1682796687dSParameswaran Krishnamurthy return v; 1692796687dSParameswaran Krishnamurthy } 1702796687dSParameswaran Krishnamurthy 1712796687dSParameswaran Krishnamurthy static int 1722796687dSParameswaran Krishnamurthy get_spdk_nvme_transport_from_proto_str(char *protocol, enum spdk_nvme_transport_type *trtype) 1732796687dSParameswaran Krishnamurthy { 1742796687dSParameswaran Krishnamurthy int status = -1; 1752796687dSParameswaran Krishnamurthy 1762796687dSParameswaran Krishnamurthy if (!protocol || !trtype) { 1772796687dSParameswaran Krishnamurthy return status; 1782796687dSParameswaran Krishnamurthy } 1792796687dSParameswaran Krishnamurthy 1802796687dSParameswaran Krishnamurthy if (strcmp("tcp", protocol) == 0) { 1812796687dSParameswaran Krishnamurthy *trtype = SPDK_NVME_TRANSPORT_TCP; 1822796687dSParameswaran Krishnamurthy return 0; 1832796687dSParameswaran Krishnamurthy } 1842796687dSParameswaran Krishnamurthy 1852796687dSParameswaran Krishnamurthy return status; 1862796687dSParameswaran Krishnamurthy } 1872796687dSParameswaran Krishnamurthy 1882796687dSParameswaran Krishnamurthy static enum spdk_nvmf_adrfam 1892796687dSParameswaran Krishnamurthy get_spdk_nvme_adrfam_from_avahi_addr(const AvahiAddress *address) { 1902796687dSParameswaran Krishnamurthy 1912796687dSParameswaran Krishnamurthy if (!address) 1922796687dSParameswaran Krishnamurthy { 1932796687dSParameswaran Krishnamurthy /* Return ipv4 by default */ 1942796687dSParameswaran Krishnamurthy return SPDK_NVMF_ADRFAM_IPV4; 1952796687dSParameswaran Krishnamurthy } 1962796687dSParameswaran Krishnamurthy 1972796687dSParameswaran Krishnamurthy switch (address->proto) 1982796687dSParameswaran Krishnamurthy { 1992796687dSParameswaran Krishnamurthy case AVAHI_PROTO_INET: 2002796687dSParameswaran Krishnamurthy return SPDK_NVMF_ADRFAM_IPV4; 2012796687dSParameswaran Krishnamurthy case AVAHI_PROTO_INET6: 2022796687dSParameswaran Krishnamurthy return SPDK_NVMF_ADRFAM_IPV6; 2032796687dSParameswaran Krishnamurthy default: 2042796687dSParameswaran Krishnamurthy return SPDK_NVMF_ADRFAM_IPV4; 2052796687dSParameswaran Krishnamurthy } 2062796687dSParameswaran Krishnamurthy } 2072796687dSParameswaran Krishnamurthy 2082796687dSParameswaran Krishnamurthy static struct mdns_discovery_ctx * 2092796687dSParameswaran Krishnamurthy get_mdns_discovery_ctx_by_svcname(const char *svcname) 2102796687dSParameswaran Krishnamurthy { 2112796687dSParameswaran Krishnamurthy struct mdns_discovery_ctx *ctx = NULL, *tmp_ctx = NULL; 2122796687dSParameswaran Krishnamurthy 2132796687dSParameswaran Krishnamurthy if (!svcname) { 2142796687dSParameswaran Krishnamurthy return NULL; 2152796687dSParameswaran Krishnamurthy } 2162796687dSParameswaran Krishnamurthy 2172796687dSParameswaran Krishnamurthy TAILQ_FOREACH_SAFE(ctx, &g_mdns_discovery_ctxs, tailq, tmp_ctx) { 2182796687dSParameswaran Krishnamurthy if (strcmp(ctx->svcname, svcname) == 0) { 2192796687dSParameswaran Krishnamurthy return ctx; 2202796687dSParameswaran Krishnamurthy } 2212796687dSParameswaran Krishnamurthy } 2222796687dSParameswaran Krishnamurthy return NULL; 2232796687dSParameswaran Krishnamurthy } 2242796687dSParameswaran Krishnamurthy 2252796687dSParameswaran Krishnamurthy static void 22609eaba31SParameswaran Krishnamurthy mdns_resolve_handler( 22709eaba31SParameswaran Krishnamurthy AvahiServiceResolver *resolver, 22809eaba31SParameswaran Krishnamurthy AVAHI_GCC_UNUSED AvahiIfIndex intf, 22909eaba31SParameswaran Krishnamurthy AVAHI_GCC_UNUSED AvahiProtocol avahi_protocol, 23009eaba31SParameswaran Krishnamurthy AvahiResolverEvent resolve_event, 23109eaba31SParameswaran Krishnamurthy const char *svc_name, 23209eaba31SParameswaran Krishnamurthy const char *svc_type, 23309eaba31SParameswaran Krishnamurthy const char *svc_domain, 2342796687dSParameswaran Krishnamurthy const char *host_name, 23509eaba31SParameswaran Krishnamurthy const AvahiAddress *host_address, 2362796687dSParameswaran Krishnamurthy uint16_t port, 2372796687dSParameswaran Krishnamurthy AvahiStringList *txt, 23809eaba31SParameswaran Krishnamurthy AvahiLookupResultFlags result_flags, 23909eaba31SParameswaran Krishnamurthy AVAHI_GCC_UNUSED void *user_data) 2402796687dSParameswaran Krishnamurthy { 24109eaba31SParameswaran Krishnamurthy assert(resolver); 24209eaba31SParameswaran Krishnamurthy /* The handler gets called whenever a service has been resolved 24309eaba31SParameswaran Krishnamurthy successfully or timed out */ 24409eaba31SParameswaran Krishnamurthy switch (resolve_event) { 2452796687dSParameswaran Krishnamurthy case AVAHI_RESOLVER_FOUND: { 24609eaba31SParameswaran Krishnamurthy char ipaddr[SPDK_NVMF_TRADDR_MAX_LEN + 1], port_str[SPDK_NVMF_TRSVCID_MAX_LEN + 1], *str; 2472796687dSParameswaran Krishnamurthy struct spdk_nvme_transport_id *trid = NULL; 2482796687dSParameswaran Krishnamurthy char *subnqn = NULL, *proto = NULL; 2492796687dSParameswaran Krishnamurthy struct mdns_discovery_ctx *ctx = NULL; 2502796687dSParameswaran Krishnamurthy struct mdns_discovery_entry_ctx *entry_ctx = NULL; 2512796687dSParameswaran Krishnamurthy int status = -1; 2522796687dSParameswaran Krishnamurthy 2532796687dSParameswaran Krishnamurthy memset(ipaddr, 0, sizeof(ipaddr)); 2542796687dSParameswaran Krishnamurthy memset(port_str, 0, sizeof(port_str)); 25509eaba31SParameswaran Krishnamurthy SPDK_INFOLOG(bdev_nvme, "Service '%s' of type '%s' in domain '%s'\n", svc_name, svc_type, 25609eaba31SParameswaran Krishnamurthy svc_domain); 25709eaba31SParameswaran Krishnamurthy avahi_address_snprint(ipaddr, sizeof(ipaddr), host_address); 2582796687dSParameswaran Krishnamurthy snprintf(port_str, sizeof(port_str), "%d", port); 25909eaba31SParameswaran Krishnamurthy str = avahi_string_list_to_string(txt); 2602796687dSParameswaran Krishnamurthy SPDK_INFOLOG(bdev_nvme, 2612796687dSParameswaran Krishnamurthy "\t%s:%u (%s)\n" 2622796687dSParameswaran Krishnamurthy "\tTXT=%s\n" 2632796687dSParameswaran Krishnamurthy "\tcookie is %u\n" 2642796687dSParameswaran Krishnamurthy "\tis_local: %i\n" 2652796687dSParameswaran Krishnamurthy "\tour_own: %i\n" 2662796687dSParameswaran Krishnamurthy "\twide_area: %i\n" 2672796687dSParameswaran Krishnamurthy "\tmulticast: %i\n" 2682796687dSParameswaran Krishnamurthy "\tcached: %i\n", 2692796687dSParameswaran Krishnamurthy host_name, port, ipaddr, 27009eaba31SParameswaran Krishnamurthy str, 2712796687dSParameswaran Krishnamurthy avahi_string_list_get_service_cookie(txt), 27209eaba31SParameswaran Krishnamurthy !!(result_flags & AVAHI_LOOKUP_RESULT_LOCAL), 27309eaba31SParameswaran Krishnamurthy !!(result_flags & AVAHI_LOOKUP_RESULT_OUR_OWN), 27409eaba31SParameswaran Krishnamurthy !!(result_flags & AVAHI_LOOKUP_RESULT_WIDE_AREA), 27509eaba31SParameswaran Krishnamurthy !!(result_flags & AVAHI_LOOKUP_RESULT_MULTICAST), 27609eaba31SParameswaran Krishnamurthy !!(result_flags & AVAHI_LOOKUP_RESULT_CACHED)); 27709eaba31SParameswaran Krishnamurthy avahi_free(str); 2782796687dSParameswaran Krishnamurthy 27909eaba31SParameswaran Krishnamurthy ctx = get_mdns_discovery_ctx_by_svcname(svc_type); 2802796687dSParameswaran Krishnamurthy if (!ctx) { 28109eaba31SParameswaran Krishnamurthy SPDK_ERRLOG("Unknown Service '%s'\n", svc_type); 2822796687dSParameswaran Krishnamurthy break; 2832796687dSParameswaran Krishnamurthy } 2842796687dSParameswaran Krishnamurthy 2852796687dSParameswaran Krishnamurthy trid = (struct spdk_nvme_transport_id *) calloc(1, sizeof(struct spdk_nvme_transport_id)); 2862796687dSParameswaran Krishnamurthy if (!trid) { 2872796687dSParameswaran Krishnamurthy SPDK_ERRLOG(" Error allocating memory for trid\n"); 2882796687dSParameswaran Krishnamurthy break; 2892796687dSParameswaran Krishnamurthy } 29009eaba31SParameswaran Krishnamurthy trid->adrfam = get_spdk_nvme_adrfam_from_avahi_addr(host_address); 2912796687dSParameswaran Krishnamurthy if (trid->adrfam != SPDK_NVMF_ADRFAM_IPV4) { 2922796687dSParameswaran Krishnamurthy /* TODO: For now process only ipv4 addresses */ 2932796687dSParameswaran Krishnamurthy SPDK_INFOLOG(bdev_nvme, "trid family is not IPV4 %d\n", trid->adrfam); 2942796687dSParameswaran Krishnamurthy free(trid); 2952796687dSParameswaran Krishnamurthy break; 2962796687dSParameswaran Krishnamurthy } 2972796687dSParameswaran Krishnamurthy subnqn = get_key_val_avahi_resolve_txt(txt, "NQN"); 2982796687dSParameswaran Krishnamurthy if (!subnqn) { 2992796687dSParameswaran Krishnamurthy free(trid); 3002796687dSParameswaran Krishnamurthy SPDK_ERRLOG("subnqn received is empty for service %s\n", ctx->svcname); 3012796687dSParameswaran Krishnamurthy break; 3022796687dSParameswaran Krishnamurthy } 3032796687dSParameswaran Krishnamurthy proto = get_key_val_avahi_resolve_txt(txt, "p"); 3042796687dSParameswaran Krishnamurthy if (!proto) { 3052796687dSParameswaran Krishnamurthy free(trid); 3062796687dSParameswaran Krishnamurthy avahi_free(subnqn); 3072796687dSParameswaran Krishnamurthy SPDK_ERRLOG("Protocol not received for service %s\n", ctx->svcname); 3082796687dSParameswaran Krishnamurthy break; 3092796687dSParameswaran Krishnamurthy } 3102796687dSParameswaran Krishnamurthy status = get_spdk_nvme_transport_from_proto_str(proto, &trid->trtype); 3112796687dSParameswaran Krishnamurthy if (status) { 3122796687dSParameswaran Krishnamurthy free(trid); 3132796687dSParameswaran Krishnamurthy avahi_free(subnqn); 3142796687dSParameswaran Krishnamurthy avahi_free(proto); 3152796687dSParameswaran Krishnamurthy SPDK_ERRLOG("Unable to derive nvme transport type for service %s\n", ctx->svcname); 3162796687dSParameswaran Krishnamurthy break; 3172796687dSParameswaran Krishnamurthy } 3182796687dSParameswaran Krishnamurthy snprintf(trid->traddr, sizeof(trid->traddr), "%s", ipaddr); 3192796687dSParameswaran Krishnamurthy snprintf(trid->trsvcid, sizeof(trid->trsvcid), "%s", port_str); 3202796687dSParameswaran Krishnamurthy snprintf(trid->subnqn, sizeof(trid->subnqn), "%s", subnqn); 3212796687dSParameswaran Krishnamurthy TAILQ_FOREACH(entry_ctx, &ctx->mdns_discovery_entry_ctxs, tailq) { 3222796687dSParameswaran Krishnamurthy if (!spdk_nvme_transport_id_compare(trid, &entry_ctx->trid)) { 3232796687dSParameswaran Krishnamurthy SPDK_ERRLOG("mDNS discovery entry exists already. trid->traddr: %s trid->trsvcid: %s\n", 3242796687dSParameswaran Krishnamurthy trid->traddr, trid->trsvcid); 3252796687dSParameswaran Krishnamurthy free(trid); 3262796687dSParameswaran Krishnamurthy avahi_free(subnqn); 3272796687dSParameswaran Krishnamurthy avahi_free(proto); 32809eaba31SParameswaran Krishnamurthy avahi_service_resolver_free(resolver); 3290bd1ca9dSJim Harris return; 3302796687dSParameswaran Krishnamurthy } 3312796687dSParameswaran Krishnamurthy } 3322796687dSParameswaran Krishnamurthy entry_ctx = create_mdns_discovery_entry_ctx(ctx, trid); 3332796687dSParameswaran Krishnamurthy TAILQ_INSERT_TAIL(&ctx->mdns_discovery_entry_ctxs, entry_ctx, tailq); 3342796687dSParameswaran Krishnamurthy spdk_thread_send_msg(ctx->calling_thread, mdns_bdev_nvme_start_discovery, entry_ctx); 3352796687dSParameswaran Krishnamurthy free(trid); 3362796687dSParameswaran Krishnamurthy avahi_free(subnqn); 3372796687dSParameswaran Krishnamurthy avahi_free(proto); 3382796687dSParameswaran Krishnamurthy break; 3392796687dSParameswaran Krishnamurthy } 34009eaba31SParameswaran Krishnamurthy case AVAHI_RESOLVER_FAILURE: 34109eaba31SParameswaran Krishnamurthy SPDK_ERRLOG("(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", 34209eaba31SParameswaran Krishnamurthy svc_name, svc_type, svc_domain, 34309eaba31SParameswaran Krishnamurthy avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(resolver)))); 34409eaba31SParameswaran Krishnamurthy break; 3452796687dSParameswaran Krishnamurthy default: 34609eaba31SParameswaran Krishnamurthy SPDK_ERRLOG("Unknown Avahi resolver event: %d", resolve_event); 3472796687dSParameswaran Krishnamurthy } 34809eaba31SParameswaran Krishnamurthy avahi_service_resolver_free(resolver); 3492796687dSParameswaran Krishnamurthy } 3502796687dSParameswaran Krishnamurthy 3512796687dSParameswaran Krishnamurthy static void 35209eaba31SParameswaran Krishnamurthy mdns_browse_handler( 35309eaba31SParameswaran Krishnamurthy AvahiServiceBrowser *browser, 35409eaba31SParameswaran Krishnamurthy AvahiIfIndex intf, 35509eaba31SParameswaran Krishnamurthy AvahiProtocol avahi_protocol, 35609eaba31SParameswaran Krishnamurthy AvahiBrowserEvent browser_event, 35709eaba31SParameswaran Krishnamurthy const char *svc_name, 35809eaba31SParameswaran Krishnamurthy const char *svc_type, 35909eaba31SParameswaran Krishnamurthy const char *svc_domain, 36009eaba31SParameswaran Krishnamurthy AVAHI_GCC_UNUSED AvahiLookupResultFlags result_flags, 36109eaba31SParameswaran Krishnamurthy void *user_data) 3622796687dSParameswaran Krishnamurthy { 36309eaba31SParameswaran Krishnamurthy AvahiClient *client = user_data; 3642796687dSParameswaran Krishnamurthy 36509eaba31SParameswaran Krishnamurthy assert(browser); 36609eaba31SParameswaran Krishnamurthy /* The handler gets called whenever a new service becomes available 36709eaba31SParameswaran Krishnamurthy or removed from the LAN */ 36809eaba31SParameswaran Krishnamurthy switch (browser_event) { 3692796687dSParameswaran Krishnamurthy case AVAHI_BROWSER_NEW: 37009eaba31SParameswaran Krishnamurthy SPDK_DEBUGLOG(bdev_nvme, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", svc_name, 37109eaba31SParameswaran Krishnamurthy svc_type, 37209eaba31SParameswaran Krishnamurthy svc_domain); 3732796687dSParameswaran Krishnamurthy /* We ignore the returned resolver object. In the callback 3742796687dSParameswaran Krishnamurthy function we free it. If the server is terminated before 3752796687dSParameswaran Krishnamurthy the callback function is called the server will free 3762796687dSParameswaran Krishnamurthy the resolver for us. */ 37709eaba31SParameswaran Krishnamurthy if (!(avahi_service_resolver_new(client, intf, avahi_protocol, svc_name, svc_type, svc_domain, 37809eaba31SParameswaran Krishnamurthy AVAHI_PROTO_UNSPEC, 0, 37909eaba31SParameswaran Krishnamurthy mdns_resolve_handler, client))) { 38009eaba31SParameswaran Krishnamurthy SPDK_ERRLOG("Failed to resolve service '%s': %s\n", svc_name, 38109eaba31SParameswaran Krishnamurthy avahi_strerror(avahi_client_errno(client))); 3822796687dSParameswaran Krishnamurthy } 3832796687dSParameswaran Krishnamurthy break; 3842796687dSParameswaran Krishnamurthy case AVAHI_BROWSER_REMOVE: 38509eaba31SParameswaran Krishnamurthy SPDK_ERRLOG("(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", svc_name, svc_type, 38609eaba31SParameswaran Krishnamurthy svc_domain); 3872796687dSParameswaran Krishnamurthy /* On remove, we are not doing the automatic cleanup of connections 3882796687dSParameswaran Krishnamurthy * to the targets that were learnt from the CDC, for which remove event has 3892796687dSParameswaran Krishnamurthy * been received. If required, user can clear the connections manually by 3902796687dSParameswaran Krishnamurthy * invoking bdev_nvme_stop_discovery. We can implement the automatic cleanup 3912796687dSParameswaran Krishnamurthy * later, if there is a requirement in the future. 3922796687dSParameswaran Krishnamurthy */ 3932796687dSParameswaran Krishnamurthy break; 3942796687dSParameswaran Krishnamurthy case AVAHI_BROWSER_ALL_FOR_NOW: 3952796687dSParameswaran Krishnamurthy case AVAHI_BROWSER_CACHE_EXHAUSTED: 3962796687dSParameswaran Krishnamurthy SPDK_INFOLOG(bdev_nvme, "(Browser) %s\n", 39709eaba31SParameswaran Krishnamurthy browser_event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW"); 3982796687dSParameswaran Krishnamurthy break; 39909eaba31SParameswaran Krishnamurthy case AVAHI_BROWSER_FAILURE: 40009eaba31SParameswaran Krishnamurthy SPDK_ERRLOG("(Browser) Failure: %s\n", 40109eaba31SParameswaran Krishnamurthy avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(browser)))); 40209eaba31SParameswaran Krishnamurthy return; 4032796687dSParameswaran Krishnamurthy default: 40409eaba31SParameswaran Krishnamurthy SPDK_ERRLOG("Unknown Avahi browser event: %d", browser_event); 4052796687dSParameswaran Krishnamurthy } 4062796687dSParameswaran Krishnamurthy } 4072796687dSParameswaran Krishnamurthy 4082796687dSParameswaran Krishnamurthy static void 40909eaba31SParameswaran Krishnamurthy client_handler(AvahiClient *client, AvahiClientState avahi_state, AVAHI_GCC_UNUSED void *user_data) 4102796687dSParameswaran Krishnamurthy { 41109eaba31SParameswaran Krishnamurthy assert(client); 41209eaba31SParameswaran Krishnamurthy /* The handler gets called whenever the client or server state changes */ 41309eaba31SParameswaran Krishnamurthy if (avahi_state == AVAHI_CLIENT_FAILURE) { 41409eaba31SParameswaran Krishnamurthy SPDK_ERRLOG("Server connection failure: %s\n", avahi_strerror(avahi_client_errno(client))); 4152796687dSParameswaran Krishnamurthy } 4162796687dSParameswaran Krishnamurthy } 4172796687dSParameswaran Krishnamurthy 4182796687dSParameswaran Krishnamurthy static int 4192796687dSParameswaran Krishnamurthy bdev_nvme_avahi_iterate(void *arg) 4202796687dSParameswaran Krishnamurthy { 4212796687dSParameswaran Krishnamurthy struct mdns_discovery_ctx *ctx = arg; 4222796687dSParameswaran Krishnamurthy int rc; 4232796687dSParameswaran Krishnamurthy 4242796687dSParameswaran Krishnamurthy if (ctx->stop) { 4252796687dSParameswaran Krishnamurthy SPDK_INFOLOG(bdev_nvme, "Stopping avahi poller for service %s\n", ctx->svcname); 4262796687dSParameswaran Krishnamurthy spdk_poller_unregister(&ctx->poller); 4272796687dSParameswaran Krishnamurthy TAILQ_REMOVE(&g_mdns_discovery_ctxs, ctx, tailq); 4282796687dSParameswaran Krishnamurthy free_mdns_discovery_ctx(ctx); 4292796687dSParameswaran Krishnamurthy return SPDK_POLLER_IDLE; 4302796687dSParameswaran Krishnamurthy } 4312796687dSParameswaran Krishnamurthy 4322796687dSParameswaran Krishnamurthy if (g_avahi_simple_poll == NULL) { 4332796687dSParameswaran Krishnamurthy spdk_poller_unregister(&ctx->poller); 4342796687dSParameswaran Krishnamurthy return SPDK_POLLER_IDLE; 4352796687dSParameswaran Krishnamurthy } 4362796687dSParameswaran Krishnamurthy 4372796687dSParameswaran Krishnamurthy rc = avahi_simple_poll_iterate(g_avahi_simple_poll, 0); 4382796687dSParameswaran Krishnamurthy if (rc && rc != -EAGAIN) { 4392796687dSParameswaran Krishnamurthy SPDK_ERRLOG("avahi poll returned error for service: %s/n", ctx->svcname); 4402796687dSParameswaran Krishnamurthy return SPDK_POLLER_IDLE; 4412796687dSParameswaran Krishnamurthy } 4422796687dSParameswaran Krishnamurthy 4432796687dSParameswaran Krishnamurthy return SPDK_POLLER_BUSY; 4442796687dSParameswaran Krishnamurthy } 4452796687dSParameswaran Krishnamurthy 4462796687dSParameswaran Krishnamurthy static void 4472796687dSParameswaran Krishnamurthy start_mdns_discovery_poller(void *arg) 4482796687dSParameswaran Krishnamurthy { 4492796687dSParameswaran Krishnamurthy struct mdns_discovery_ctx *ctx = arg; 4502796687dSParameswaran Krishnamurthy 4512796687dSParameswaran Krishnamurthy assert(arg); 4522796687dSParameswaran Krishnamurthy TAILQ_INSERT_TAIL(&g_mdns_discovery_ctxs, ctx, tailq); 45310f90ccdSJim Harris ctx->poller = SPDK_POLLER_REGISTER(bdev_nvme_avahi_iterate, ctx, 100 * 1000); 4542796687dSParameswaran Krishnamurthy } 4552796687dSParameswaran Krishnamurthy 4562796687dSParameswaran Krishnamurthy int 4572796687dSParameswaran Krishnamurthy bdev_nvme_start_mdns_discovery(const char *base_name, 4582796687dSParameswaran Krishnamurthy const char *svcname, 4592796687dSParameswaran Krishnamurthy struct spdk_nvme_ctrlr_opts *drv_opts, 460*dd98a248SMehakjot Singh Sidhu struct spdk_bdev_nvme_ctrlr_opts *bdev_opts) 4612796687dSParameswaran Krishnamurthy { 4622796687dSParameswaran Krishnamurthy AvahiServiceBrowser *sb = NULL; 4632796687dSParameswaran Krishnamurthy int error; 4642796687dSParameswaran Krishnamurthy struct mdns_discovery_ctx *ctx; 4652796687dSParameswaran Krishnamurthy 4662796687dSParameswaran Krishnamurthy assert(base_name); 4672796687dSParameswaran Krishnamurthy assert(svcname); 4682796687dSParameswaran Krishnamurthy 4692796687dSParameswaran Krishnamurthy TAILQ_FOREACH(ctx, &g_mdns_discovery_ctxs, tailq) { 4702796687dSParameswaran Krishnamurthy if (strcmp(ctx->name, base_name) == 0) { 4712796687dSParameswaran Krishnamurthy SPDK_ERRLOG("mDNS discovery already running with name %s\n", base_name); 4722796687dSParameswaran Krishnamurthy return -EEXIST; 4732796687dSParameswaran Krishnamurthy } 4742796687dSParameswaran Krishnamurthy 4752796687dSParameswaran Krishnamurthy if (strcmp(ctx->svcname, svcname) == 0) { 4762796687dSParameswaran Krishnamurthy SPDK_ERRLOG("mDNS discovery already running for service %s\n", svcname); 4772796687dSParameswaran Krishnamurthy return -EEXIST; 4782796687dSParameswaran Krishnamurthy } 4792796687dSParameswaran Krishnamurthy } 4802796687dSParameswaran Krishnamurthy 4812796687dSParameswaran Krishnamurthy if (g_avahi_simple_poll == NULL) { 4822796687dSParameswaran Krishnamurthy 4832796687dSParameswaran Krishnamurthy /* Allocate main loop object */ 4842796687dSParameswaran Krishnamurthy if (!(g_avahi_simple_poll = avahi_simple_poll_new())) { 4852796687dSParameswaran Krishnamurthy SPDK_ERRLOG("Failed to create poll object for mDNS discovery for service: %s.\n", svcname); 4862796687dSParameswaran Krishnamurthy return -ENOMEM; 4872796687dSParameswaran Krishnamurthy } 4882796687dSParameswaran Krishnamurthy } 4892796687dSParameswaran Krishnamurthy 4902796687dSParameswaran Krishnamurthy if (g_avahi_client == NULL) { 4912796687dSParameswaran Krishnamurthy 4922796687dSParameswaran Krishnamurthy /* Allocate a new client */ 49309eaba31SParameswaran Krishnamurthy g_avahi_client = avahi_client_new(avahi_simple_poll_get(g_avahi_simple_poll), 0, client_handler, 4942796687dSParameswaran Krishnamurthy NULL, &error); 4952796687dSParameswaran Krishnamurthy /* Check whether creating the client object succeeded */ 4962796687dSParameswaran Krishnamurthy if (!g_avahi_client) { 4972796687dSParameswaran Krishnamurthy SPDK_ERRLOG("Failed to create mDNS client for service:%s Error: %s\n", svcname, 4982796687dSParameswaran Krishnamurthy avahi_strerror(error)); 4992796687dSParameswaran Krishnamurthy return -ENOMEM; 5002796687dSParameswaran Krishnamurthy } 5012796687dSParameswaran Krishnamurthy } 5022796687dSParameswaran Krishnamurthy 5032796687dSParameswaran Krishnamurthy /* Create the service browser */ 5042796687dSParameswaran Krishnamurthy if (!(sb = avahi_service_browser_new(g_avahi_client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, svcname, 50509eaba31SParameswaran Krishnamurthy NULL, 0, mdns_browse_handler, g_avahi_client))) { 5062796687dSParameswaran Krishnamurthy SPDK_ERRLOG("Failed to create service browser for service: %s Error: %s\n", svcname, 5072796687dSParameswaran Krishnamurthy avahi_strerror(avahi_client_errno(g_avahi_client))); 5082796687dSParameswaran Krishnamurthy return -ENOMEM; 5092796687dSParameswaran Krishnamurthy } 5102796687dSParameswaran Krishnamurthy 5112796687dSParameswaran Krishnamurthy ctx = calloc(1, sizeof(*ctx)); 5122796687dSParameswaran Krishnamurthy if (ctx == NULL) { 5132796687dSParameswaran Krishnamurthy SPDK_ERRLOG("Error creating mDNS discovery ctx for service: %s\n", svcname); 5142796687dSParameswaran Krishnamurthy avahi_service_browser_free(sb); 5152796687dSParameswaran Krishnamurthy return -ENOMEM; 5162796687dSParameswaran Krishnamurthy } 5172796687dSParameswaran Krishnamurthy 5182796687dSParameswaran Krishnamurthy ctx->svcname = strdup(svcname); 5192796687dSParameswaran Krishnamurthy if (ctx->svcname == NULL) { 5202796687dSParameswaran Krishnamurthy SPDK_ERRLOG("Error creating mDNS discovery ctx svcname for service: %s\n", svcname); 5212796687dSParameswaran Krishnamurthy free_mdns_discovery_ctx(ctx); 5222796687dSParameswaran Krishnamurthy avahi_service_browser_free(sb); 5232796687dSParameswaran Krishnamurthy return -ENOMEM; 5242796687dSParameswaran Krishnamurthy } 5252796687dSParameswaran Krishnamurthy ctx->name = strdup(base_name); 5262796687dSParameswaran Krishnamurthy if (ctx->name == NULL) { 5272796687dSParameswaran Krishnamurthy SPDK_ERRLOG("Error creating mDNS discovery ctx name for service: %s\n", svcname); 5282796687dSParameswaran Krishnamurthy free_mdns_discovery_ctx(ctx); 5292796687dSParameswaran Krishnamurthy avahi_service_browser_free(sb); 5302796687dSParameswaran Krishnamurthy return -ENOMEM; 5312796687dSParameswaran Krishnamurthy } 5322796687dSParameswaran Krishnamurthy memcpy(&ctx->drv_opts, drv_opts, sizeof(*drv_opts)); 5332796687dSParameswaran Krishnamurthy memcpy(&ctx->bdev_opts, bdev_opts, sizeof(*bdev_opts)); 5342796687dSParameswaran Krishnamurthy ctx->sb = sb; 5352796687dSParameswaran Krishnamurthy ctx->calling_thread = spdk_get_thread(); 5362796687dSParameswaran Krishnamurthy TAILQ_INIT(&ctx->mdns_discovery_entry_ctxs); 5372796687dSParameswaran Krishnamurthy /* Even if user did not specify hostnqn, we can still strdup("\0"); */ 5382796687dSParameswaran Krishnamurthy ctx->hostnqn = strdup(ctx->drv_opts.hostnqn); 5392796687dSParameswaran Krishnamurthy if (ctx->hostnqn == NULL) { 5402796687dSParameswaran Krishnamurthy SPDK_ERRLOG("Error creating mDNS discovery ctx hostnqn for service: %s\n", svcname); 5412796687dSParameswaran Krishnamurthy free_mdns_discovery_ctx(ctx); 5422796687dSParameswaran Krishnamurthy return -ENOMEM; 5432796687dSParameswaran Krishnamurthy } 5442796687dSParameswaran Krishnamurthy /* Start the poller for the Avahi client browser in g_bdev_nvme_init_thread */ 5452796687dSParameswaran Krishnamurthy spdk_thread_send_msg(g_bdev_nvme_init_thread, start_mdns_discovery_poller, ctx); 5462796687dSParameswaran Krishnamurthy return 0; 5472796687dSParameswaran Krishnamurthy } 5482796687dSParameswaran Krishnamurthy 5492796687dSParameswaran Krishnamurthy static void 5502796687dSParameswaran Krishnamurthy mdns_stop_discovery_entry(struct mdns_discovery_ctx *ctx) 5512796687dSParameswaran Krishnamurthy { 5522796687dSParameswaran Krishnamurthy struct mdns_discovery_entry_ctx *entry_ctx = NULL; 5532796687dSParameswaran Krishnamurthy 5542796687dSParameswaran Krishnamurthy assert(ctx); 5552796687dSParameswaran Krishnamurthy 5562796687dSParameswaran Krishnamurthy TAILQ_FOREACH(entry_ctx, &ctx->mdns_discovery_entry_ctxs, tailq) { 5572796687dSParameswaran Krishnamurthy bdev_nvme_stop_discovery(entry_ctx->name, NULL, NULL); 5582796687dSParameswaran Krishnamurthy } 5592796687dSParameswaran Krishnamurthy } 5602796687dSParameswaran Krishnamurthy 5612796687dSParameswaran Krishnamurthy int 5622796687dSParameswaran Krishnamurthy bdev_nvme_stop_mdns_discovery(const char *name) 5632796687dSParameswaran Krishnamurthy { 5642796687dSParameswaran Krishnamurthy struct mdns_discovery_ctx *ctx; 5652796687dSParameswaran Krishnamurthy 5662796687dSParameswaran Krishnamurthy assert(name); 5672796687dSParameswaran Krishnamurthy TAILQ_FOREACH(ctx, &g_mdns_discovery_ctxs, tailq) { 5682796687dSParameswaran Krishnamurthy if (strcmp(name, ctx->name) == 0) { 5692796687dSParameswaran Krishnamurthy if (ctx->stop) { 5702796687dSParameswaran Krishnamurthy return -EALREADY; 5712796687dSParameswaran Krishnamurthy } 5722796687dSParameswaran Krishnamurthy /* set stop to true to stop the mdns poller instance */ 5732796687dSParameswaran Krishnamurthy ctx->stop = true; 5742796687dSParameswaran Krishnamurthy mdns_stop_discovery_entry(ctx); 5752796687dSParameswaran Krishnamurthy return 0; 5762796687dSParameswaran Krishnamurthy } 5772796687dSParameswaran Krishnamurthy } 5782796687dSParameswaran Krishnamurthy 5792796687dSParameswaran Krishnamurthy return -ENOENT; 5802796687dSParameswaran Krishnamurthy } 5812796687dSParameswaran Krishnamurthy 5822796687dSParameswaran Krishnamurthy void 5832796687dSParameswaran Krishnamurthy bdev_nvme_get_mdns_discovery_info(struct spdk_jsonrpc_request *request) 5842796687dSParameswaran Krishnamurthy { 5852796687dSParameswaran Krishnamurthy struct mdns_discovery_ctx *ctx; 5862796687dSParameswaran Krishnamurthy struct mdns_discovery_entry_ctx *entry_ctx; 5872796687dSParameswaran Krishnamurthy struct spdk_json_write_ctx *w; 5882796687dSParameswaran Krishnamurthy 5892796687dSParameswaran Krishnamurthy w = spdk_jsonrpc_begin_result(request); 5902796687dSParameswaran Krishnamurthy spdk_json_write_array_begin(w); 5912796687dSParameswaran Krishnamurthy TAILQ_FOREACH(ctx, &g_mdns_discovery_ctxs, tailq) { 5922796687dSParameswaran Krishnamurthy spdk_json_write_object_begin(w); 5932796687dSParameswaran Krishnamurthy spdk_json_write_named_string(w, "name", ctx->name); 5942796687dSParameswaran Krishnamurthy spdk_json_write_named_string(w, "svcname", ctx->svcname); 5952796687dSParameswaran Krishnamurthy 5962796687dSParameswaran Krishnamurthy spdk_json_write_named_array_begin(w, "referrals"); 5972796687dSParameswaran Krishnamurthy TAILQ_FOREACH(entry_ctx, &ctx->mdns_discovery_entry_ctxs, tailq) { 5982796687dSParameswaran Krishnamurthy spdk_json_write_object_begin(w); 5992796687dSParameswaran Krishnamurthy spdk_json_write_named_string(w, "name", entry_ctx->name); 6002796687dSParameswaran Krishnamurthy spdk_json_write_named_object_begin(w, "trid"); 6012796687dSParameswaran Krishnamurthy nvme_bdev_dump_trid_json(&entry_ctx->trid, w); 6022796687dSParameswaran Krishnamurthy spdk_json_write_object_end(w); 6032796687dSParameswaran Krishnamurthy spdk_json_write_object_end(w); 6042796687dSParameswaran Krishnamurthy } 6052796687dSParameswaran Krishnamurthy spdk_json_write_array_end(w); 6062796687dSParameswaran Krishnamurthy 6072796687dSParameswaran Krishnamurthy spdk_json_write_object_end(w); 6082796687dSParameswaran Krishnamurthy } 6092796687dSParameswaran Krishnamurthy spdk_json_write_array_end(w); 6102796687dSParameswaran Krishnamurthy spdk_jsonrpc_end_result(request, w); 6112796687dSParameswaran Krishnamurthy } 6122796687dSParameswaran Krishnamurthy 6132796687dSParameswaran Krishnamurthy void 6142796687dSParameswaran Krishnamurthy bdev_nvme_mdns_discovery_config_json(struct spdk_json_write_ctx *w) 6152796687dSParameswaran Krishnamurthy { 6162796687dSParameswaran Krishnamurthy struct mdns_discovery_ctx *ctx; 6172796687dSParameswaran Krishnamurthy 6182796687dSParameswaran Krishnamurthy TAILQ_FOREACH(ctx, &g_mdns_discovery_ctxs, tailq) { 6192796687dSParameswaran Krishnamurthy spdk_json_write_object_begin(w); 6202796687dSParameswaran Krishnamurthy 6212796687dSParameswaran Krishnamurthy spdk_json_write_named_string(w, "method", "bdev_nvme_start_mdns_discovery"); 6222796687dSParameswaran Krishnamurthy 6232796687dSParameswaran Krishnamurthy spdk_json_write_named_object_begin(w, "params"); 6242796687dSParameswaran Krishnamurthy spdk_json_write_named_string(w, "name", ctx->name); 6252796687dSParameswaran Krishnamurthy spdk_json_write_named_string(w, "svcname", ctx->svcname); 6262796687dSParameswaran Krishnamurthy spdk_json_write_named_string(w, "hostnqn", ctx->hostnqn); 6272796687dSParameswaran Krishnamurthy spdk_json_write_object_end(w); 6282796687dSParameswaran Krishnamurthy 6292796687dSParameswaran Krishnamurthy spdk_json_write_object_end(w); 6302796687dSParameswaran Krishnamurthy } 6312796687dSParameswaran Krishnamurthy } 6322796687dSParameswaran Krishnamurthy 6332796687dSParameswaran Krishnamurthy #else /* SPDK_CONFIG_AVAHI */ 6342796687dSParameswaran Krishnamurthy 6352796687dSParameswaran Krishnamurthy int 6362796687dSParameswaran Krishnamurthy bdev_nvme_start_mdns_discovery(const char *base_name, 6372796687dSParameswaran Krishnamurthy const char *svcname, 6382796687dSParameswaran Krishnamurthy struct spdk_nvme_ctrlr_opts *drv_opts, 639*dd98a248SMehakjot Singh Sidhu struct spdk_bdev_nvme_ctrlr_opts *bdev_opts) 6402796687dSParameswaran Krishnamurthy { 6412796687dSParameswaran Krishnamurthy SPDK_ERRLOG("spdk not built with --with-avahi option\n"); 6422796687dSParameswaran Krishnamurthy return -ENOTSUP; 6432796687dSParameswaran Krishnamurthy } 6442796687dSParameswaran Krishnamurthy 6452796687dSParameswaran Krishnamurthy int 6462796687dSParameswaran Krishnamurthy bdev_nvme_stop_mdns_discovery(const char *name) 6472796687dSParameswaran Krishnamurthy { 6482796687dSParameswaran Krishnamurthy SPDK_ERRLOG("spdk not built with --with-avahi option\n"); 6492796687dSParameswaran Krishnamurthy return -ENOTSUP; 6502796687dSParameswaran Krishnamurthy } 6512796687dSParameswaran Krishnamurthy 6522796687dSParameswaran Krishnamurthy void 6532796687dSParameswaran Krishnamurthy bdev_nvme_get_mdns_discovery_info(struct spdk_jsonrpc_request *request) 6542796687dSParameswaran Krishnamurthy { 6552796687dSParameswaran Krishnamurthy SPDK_ERRLOG("spdk not built with --with-avahi option\n"); 6562796687dSParameswaran Krishnamurthy spdk_jsonrpc_send_error_response(request, -ENOTSUP, spdk_strerror(ENOTSUP)); 6572796687dSParameswaran Krishnamurthy } 6582796687dSParameswaran Krishnamurthy 6592796687dSParameswaran Krishnamurthy void 6602796687dSParameswaran Krishnamurthy bdev_nvme_mdns_discovery_config_json(struct spdk_json_write_ctx *w) 6612796687dSParameswaran Krishnamurthy { 6622796687dSParameswaran Krishnamurthy /* Empty function to be invoked, when SPDK is built without --with-avahi */ 6632796687dSParameswaran Krishnamurthy } 6642796687dSParameswaran Krishnamurthy 6652796687dSParameswaran Krishnamurthy #endif 666