Commit 7efc7b83 authored by Pawel Wodkowski's avatar Pawel Wodkowski Committed by Jim Harris
Browse files

nvmf: add JSON config dump

parent 5cdc893f
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ struct spdk_nvmf_request;
struct spdk_nvmf_host;
struct spdk_nvmf_listener;
struct spdk_nvmf_poll_group;
struct spdk_json_write_ctx;

struct spdk_nvmf_tgt_opts {
	uint16_t max_queue_depth;
@@ -96,6 +97,13 @@ void spdk_nvmf_tgt_destroy(struct spdk_nvmf_tgt *tgt,
			   spdk_nvmf_tgt_destroy_done_fn cb_fn,
			   void *cb_arg);

/**
 * Write NVMe-oF target configuration into provided JSON context.
 * \param w JSON write context
 * \param tgt The NVMe-oF target
 */
void spdk_nvmf_tgt_write_config_json(struct spdk_json_write_ctx *w, struct spdk_nvmf_tgt *tgt);

/**
 * Function to be called once the target is listening.
 *
+20 −0
Original line number Diff line number Diff line
@@ -329,10 +329,30 @@ spdk_nvmf_subsystem_init(void)
	nvmf_tgt_advance_state();
}

static void
spdk_nvmf_subsystem_write_config_json(struct spdk_json_write_ctx *w, struct spdk_event *done_ev)
{
	spdk_json_write_array_begin(w);

	spdk_json_write_object_begin(w);
	spdk_json_write_named_string(w, "method", "set_nvmf_target_config");

	spdk_json_write_named_object_begin(w, "params");
	spdk_json_write_named_uint32(w, "acceptor_poll_rate", g_spdk_nvmf_tgt_conf->acceptor_poll_rate);
	spdk_json_write_object_end(w);
	spdk_json_write_object_end(w);

	spdk_nvmf_tgt_write_config_json(w, g_spdk_nvmf_tgt);
	spdk_json_write_array_end(w);

	spdk_event_call(done_ev);
}

static struct spdk_subsystem g_spdk_subsystem_nvmf = {
	.name = "nvmf",
	.init = spdk_nvmf_subsystem_init,
	.fini = spdk_nvmf_subsystem_fini,
	.write_config_json = spdk_nvmf_subsystem_write_config_json,
};

SPDK_SUBSYSTEM_REGISTER(g_spdk_subsystem_nvmf)
+135 −0
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@
#include "spdk/thread.h"
#include "spdk/nvmf.h"
#include "spdk/trace.h"
#include "spdk/endian.h"
#include "spdk/string.h"

#include "spdk_internal/log.h"

@@ -259,6 +261,139 @@ struct spdk_nvmf_tgt_listen_ctx {
	void *cb_arg;
};

static void
spdk_nvmf_write_subsystem_config_json(struct spdk_json_write_ctx *w,
				      struct spdk_nvmf_subsystem *subsystem)
{
	struct spdk_nvmf_host *host;
	struct spdk_nvmf_listener *listener;
	const struct spdk_nvme_transport_id *trid;
	struct spdk_nvmf_ns *ns;
	struct spdk_nvmf_ns_opts ns_opts;
	uint32_t max_namespaces;
	char uuid_str[SPDK_UUID_STRING_LEN];
	const char *trtype;
	const char *adrfam;

	if (spdk_nvmf_subsystem_get_type(subsystem) != SPDK_NVMF_SUBTYPE_NVME) {
		return;
	}

	/* { */
	spdk_json_write_object_begin(w);
	spdk_json_write_named_string(w, "method", "construct_nvmf_subsystem");

	/*     "params" : { */
	spdk_json_write_named_object_begin(w, "params");
	spdk_json_write_named_string(w, "nqn", spdk_nvmf_subsystem_get_nqn(subsystem));
	spdk_json_write_named_bool(w, "allow_any_host", spdk_nvmf_subsystem_get_allow_any_host(subsystem));

	/*         "listen_addresses" : [ */
	spdk_json_write_named_array_begin(w, "listen_addresses");
	for (listener = spdk_nvmf_subsystem_get_first_listener(subsystem); listener != NULL;
	     listener = spdk_nvmf_subsystem_get_next_listener(subsystem, listener)) {
		trid = spdk_nvmf_listener_get_trid(listener);

		trtype = spdk_nvme_transport_id_trtype_str(trid->trtype);
		adrfam = spdk_nvme_transport_id_adrfam_str(trid->adrfam);

		/*        { */
		spdk_json_write_object_begin(w);
		spdk_json_write_named_string(w, "trtype", trtype);
		if (adrfam) {
			spdk_json_write_named_string(w, "adrfam", adrfam);
		}

		spdk_json_write_named_string(w, "traddr", trid->traddr);
		spdk_json_write_named_string(w, "trsvcid", trid->trsvcid);
		spdk_json_write_object_end(w);
		/*        } */
	}
	spdk_json_write_array_end(w);
	/*         ] "listen_addresses" */

	/*         "hosts" : [ */
	spdk_json_write_named_array_begin(w, "hosts");
	for (host = spdk_nvmf_subsystem_get_first_host(subsystem); host != NULL;
	     host = spdk_nvmf_subsystem_get_next_host(subsystem, host)) {
		spdk_json_write_named_string(w, "nqn", spdk_nvmf_host_get_nqn(host));
	}
	spdk_json_write_array_end(w);
	/*         ] "hosts" */

	spdk_json_write_named_string(w, "serial_number", spdk_nvmf_subsystem_get_sn(subsystem));

	max_namespaces = spdk_nvmf_subsystem_get_max_namespaces(subsystem);
	if (max_namespaces != 0) {
		spdk_json_write_named_uint32(w, "max_namespaces", max_namespaces);
	}

	/*         "namespaces" : [ */
	spdk_json_write_named_array_begin(w, "namespaces");
	for (ns = spdk_nvmf_subsystem_get_first_ns(subsystem); ns != NULL;
	     ns = spdk_nvmf_subsystem_get_next_ns(subsystem, ns)) {
		spdk_nvmf_ns_get_opts(ns, &ns_opts, sizeof(ns_opts));

		/*         { */
		spdk_json_write_object_begin(w);
		spdk_json_write_named_uint32(w, "nsid", spdk_nvmf_ns_get_id(ns));
		spdk_json_write_named_string(w, "bdev_name", spdk_bdev_get_name(spdk_nvmf_ns_get_bdev(ns)));

		if (!spdk_mem_all_zero(ns_opts.nguid, sizeof(ns_opts.nguid))) {
			SPDK_STATIC_ASSERT(sizeof(ns_opts.nguid) == sizeof(uint64_t) * 2, "size mismatch");
			spdk_json_write_named_string_fmt(w, "nguid", "%016"PRIX64"%016"PRIX64, from_be64(&ns_opts.nguid[0]),
							 from_be64(&ns_opts.nguid[8]));
		}

		if (!spdk_mem_all_zero(ns_opts.eui64, sizeof(ns_opts.eui64))) {
			SPDK_STATIC_ASSERT(sizeof(ns_opts.eui64) == sizeof(uint64_t), "size mismatch");
			spdk_json_write_named_string_fmt(w, "eui64", "%016"PRIX64, from_be64(&ns_opts.eui64));
		}

		if (!spdk_mem_all_zero(&ns_opts.uuid, sizeof(ns_opts.uuid))) {
			spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &ns_opts.uuid);
			spdk_json_write_named_string(w, "uuid",  uuid_str);
		}
		/*         } */
		spdk_json_write_object_end(w);
	}

	/*         ] "namespaces" */
	spdk_json_write_array_end(w);

	/*     } "params" */
	spdk_json_write_object_end(w);

	/* } */
	spdk_json_write_object_end(w);
}

void
spdk_nvmf_tgt_write_config_json(struct spdk_json_write_ctx *w, struct spdk_nvmf_tgt *tgt)
{
	struct spdk_nvmf_subsystem *subsystem;

	spdk_json_write_object_begin(w);
	spdk_json_write_named_string(w, "method", "set_nvmf_target_options");

	spdk_json_write_named_object_begin(w, "params");
	spdk_json_write_named_uint32(w, "max_queue_depth", tgt->opts.max_queue_depth);
	spdk_json_write_named_uint32(w, "max_qpairs_per_ctrlr", tgt->opts.max_qpairs_per_ctrlr);
	spdk_json_write_named_uint32(w, "in_capsule_data_size", tgt->opts.in_capsule_data_size);
	spdk_json_write_named_uint32(w, "max_io_size", tgt->opts.max_io_size);
	spdk_json_write_named_uint32(w, "max_subsystems", tgt->opts.max_subsystems);
	spdk_json_write_named_uint32(w, "io_unit_size", tgt->opts.io_unit_size);
	spdk_json_write_object_end(w);

	spdk_json_write_object_end(w);

	subsystem = spdk_nvmf_subsystem_get_first(tgt);
	while (subsystem) {
		spdk_nvmf_write_subsystem_config_json(w, subsystem);
		subsystem = spdk_nvmf_subsystem_get_next(subsystem);
	}
}

static void
spdk_nvmf_tgt_listen_done(struct spdk_io_channel_iter *i, int status)
{