Commit 001db1ea authored by kyuho.son's avatar kyuho.son Committed by Jim Harris
Browse files

nvmf: update mDNS PRR listener when discovery listener changes



Previously, user should stop and restart mDNS PRR to update the mDNS PRR listener
list. This requires some expensive avahi API calls, such as creating and deleting
avahi structures.

Now, when discovery subsystem listener changes, nvmf_tgt_update_mdns_prr
is called to update mDNS PRR listener.

Change-Id: I136fc4057136b59cfda158db3f3e29f34e4a7f4c
Signed-off-by: default avatarkyuho.son <kyuho.son@samsung.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/24169


Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent c7388789
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -154,6 +154,28 @@ avahi_entry_group_add_listeners(AvahiEntryGroup *avahi_entry_group,
	avahi_entry_group_commit(avahi_entry_group);
}

int
nvmf_tgt_update_mdns_prr(struct spdk_nvmf_tgt *tgt)
{
	int rc;

	if (nvmf_tgt_is_mdns_running(tgt) == false || g_avahi_entry_group == NULL) {
		SPDK_INFOLOG(nvmf,
			     "nvmf_tgt_update_mdns_prr is only supported when mDNS servier is running on target\n");
		return 0;
	}

	rc = avahi_entry_group_reset(g_avahi_entry_group);
	if (rc) {
		SPDK_ERRLOG("Failed to reset avahi_entry_group");
		return -EINVAL;
	}

	avahi_entry_group_add_listeners(g_avahi_entry_group, g_mdns_publish_ctx->subsystem);

	return 0;
}

static int
publish_pull_registration_request(AvahiClient *client, struct mdns_publish_ctx *publish_ctx)
{
@@ -261,5 +283,4 @@ nvmf_publish_mdns_prr(struct spdk_nvmf_tgt *tgt)
	publish_ctx->poller = SPDK_POLLER_REGISTER(nvmf_avahi_publish_iterate, publish_ctx, 100 * 1000);
	return 0;
}

#endif
+9 −0
Original line number Diff line number Diff line
@@ -583,6 +583,15 @@ int nvmf_publish_mdns_prr(struct spdk_nvmf_tgt *tgt);
 */
void nvmf_tgt_stop_mdns_prr(struct spdk_nvmf_tgt *tgt);

/**
 * Updates the listener list in the mDNS PRR (Pull Registration Request) for the NVMe-oF target.
 *
 * \param tgt The NVMe-oF target
 *
 * \return 0 on success, negative errno on failure
 */
int nvmf_tgt_update_mdns_prr(struct spdk_nvmf_tgt *tgt);

static inline struct spdk_nvmf_transport_poll_group *
nvmf_get_transport_poll_group(struct spdk_nvmf_poll_group *group,
			      struct spdk_nvmf_transport *transport)
+6 −0
Original line number Diff line number Diff line
@@ -70,4 +70,10 @@ void
nvmf_tgt_stop_mdns_prr(struct spdk_nvmf_tgt *tgt)
{
}

int
nvmf_tgt_update_mdns_prr(struct spdk_nvmf_tgt *tgt)
{
	return 0;
}
#endif /* !SPDK_CONFIG_AVAHI */
+14 −0
Original line number Diff line number Diff line
@@ -351,6 +351,9 @@ _nvmf_subsystem_remove_listener(struct spdk_nvmf_subsystem *subsystem,
	}

	TAILQ_REMOVE(&subsystem->listeners, listener, link);
	if (spdk_nvmf_subsystem_is_discovery(listener->subsystem)) {
		nvmf_tgt_update_mdns_prr(listener->subsystem->tgt);
	}
	nvmf_update_discovery_log(listener->subsystem->tgt, NULL);
	free(listener->ana_state);
	spdk_bit_array_clear(subsystem->used_listener_ids, listener->id);
@@ -1334,6 +1337,17 @@ _nvmf_subsystem_add_listener_done(void *ctx, int status)
	}

	TAILQ_INSERT_HEAD(&listener->subsystem->listeners, listener, link);

	if (spdk_nvmf_subsystem_is_discovery(listener->subsystem)) {
		status = nvmf_tgt_update_mdns_prr(listener->subsystem->tgt);
		if (status) {
			TAILQ_REMOVE(&listener->subsystem->listeners, listener, link);
			listener->cb_fn(listener->cb_arg, status);
			free(listener);
			return;
		}
	}

	nvmf_update_discovery_log(listener->subsystem->tgt, NULL);
	listener->cb_fn(listener->cb_arg, status);
}
+46 −3
Original line number Diff line number Diff line
@@ -81,6 +81,34 @@ function get_mdns_discovery_svcs() {
	$rpc_py -s $HOST_SOCK bdev_nvme_get_mdns_discovery_info | jq -r '.[].name' | sort | xargs
}

function check_mdns_request_exists() {
	local process=$1
	local ip=$2
	local port=$3
	local check_type=$4 # New argument to determine check type
	local output

	# Run command and store the output
	output="$(avahi-browse -t -r _nvme-disc._tcp -p)"
	readarray -t lines <<< "$output"

	for line in "${lines[@]}"; do
		if [[ "$line" == *"$process"* && "$line" == *"$ip"* && "$line" == *"$port"* ]]; then
			if [[ "$check_type" == "found" ]]; then
				return 0 # Return success if the combination is found
			else
				return 1 # Return failure if the combination is found
			fi
		fi
	done

	if [[ "$check_type" == "found" ]]; then
		return 1 # Return failure if the combination is not found
	else
		return 0 # Return success if the combination is not found
	fi
}

# Note that tests need to call get_notification_count and then check $notification_count,
# because if we use $(get_notification_count), the notify_id gets updated in the subshell.
notify_id=0
@@ -116,13 +144,20 @@ $rpc_py nvmf_subsystem_add_ns ${NQN2}0 null2
# port of the single listener on the target.
$rpc_py nvmf_subsystem_add_host ${NQN2}0 $HOST_NQN

#Publish discovery service
$rpc_py nvmf_publish_mdns_prr
sleep 5 # Wait a bit to make sure the discovery service has a chance to detect the changes

# Listener not found in the discovery service
check_mdns_request_exists spdk1 $NVMF_SECOND_TARGET_IP $DISCOVERY_PORT "not found"

$rpc_py nvmf_subsystem_add_listener $DISCOVERY_NQN -t $TEST_TRANSPORT -a $NVMF_SECOND_TARGET_IP \
	-s $DISCOVERY_PORT
$rpc_py nvmf_subsystem_add_listener ${NQN2}0 -t $TEST_TRANSPORT -a $NVMF_SECOND_TARGET_IP -s $NVMF_PORT
sleep 1 # Wait a bit to make sure the discovery service has a chance to detect the changes

#Publish discovery service
$rpc_py nvmf_publish_mdns_prr
sleep 5 # Wait a bit to make sure the discovery service has a chance to detect the changes
# Listener found in the discovery service
check_mdns_request_exists spdk1 $NVMF_SECOND_TARGET_IP $DISCOVERY_PORT "found"

[[ "$(get_mdns_discovery_svcs)" == "mdns" ]]
[[ $(get_discovery_ctrlrs) == "mdns0_nvme mdns1_nvme" ]]
@@ -192,6 +227,14 @@ NOT $rpc_py -s $HOST_SOCK bdev_nvme_start_mdns_discovery -b cdc -s _nvme-disc._t
[[ $(get_bdev_list) == "mdns0_nvme0n1 mdns0_nvme0n2 mdns1_nvme0n1 mdns1_nvme0n2" ]]
$rpc_py -s $HOST_SOCK bdev_nvme_stop_mdns_discovery -b mdns

# Listener found in the discovery service
check_mdns_request_exists spdk1 $NVMF_FIRST_TARGET_IP $DISCOVERY_PORT "found"
$rpc_py nvmf_subsystem_remove_listener $DISCOVERY_NQN -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP \
	-s $DISCOVERY_PORT
sleep 1 # Wait a bit to make sure the discovery service has a chance to detect the changes
# Removed listener is applied in the discovery service
check_mdns_request_exists spdk1 $NVMF_FIRST_TARGET_IP $DISCOVERY_PORT "not found"

$rpc_py nvmf_stop_mdns_prr

trap - SIGINT SIGTERM EXIT
Loading