Commit 2d30df9b authored by yupeng's avatar yupeng Committed by Tomasz Zawadzki
Browse files

bdev: add bdev_examine_bdev API



The bdev_examine_bdev api will examine a bdev explicitly. After
disabling the auto_examine feature, a user could call
bdev_examine_bdev to examine a specific bdev he/she wants.

Signed-off-by: default avatarPeng Yu <yupeng0921@gmail.com>
Change-Id: Ifbbfb6f667287669ddf6175b8208efee39762933
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3219


Community-CI: Mellanox Build Bot
Community-CI: Broadcom CI
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarMichael Haeuptle <michaelhaeuptle@gmail.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent f6727316
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -2,6 +2,11 @@

## v20.10: (Upcoming Release)

### bdev

A new API was added `bdev_examine_bdev` that allows users to examine a
bdev explicitly. It can be used only if auto_examine is disabled.

## v20.07: SPDK CSI driver, new accel_fw commands, I/O abort support

### accel
+8 −0
Original line number Diff line number Diff line
@@ -193,6 +193,14 @@ void spdk_bdev_get_opts(struct spdk_bdev_opts *opts);

int spdk_bdev_set_opts(struct spdk_bdev_opts *opts);

/**
 * Examine a block device explicitly
 *
 * \param name the name or alias of the block device
 * \return 0 if block device was examined successfully, suitable errno value otherwise
 */
int spdk_bdev_examine(const char *name);

/**
 * Block device initialization callback.
 *
+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk

SO_VER := 3
SO_MINOR := 0
SO_MINOR := 1

ifeq ($(CONFIG_VTUNE),y)
CFLAGS += -I$(CONFIG_VTUNE_DIR)/include -I$(CONFIG_VTUNE_DIR)/sdk/src/ittnotify
+50 −0
Original line number Diff line number Diff line
@@ -484,6 +484,54 @@ bdev_examine(struct spdk_bdev *bdev)
	}
}

int
spdk_bdev_examine(const char *name)
{
	struct spdk_bdev *bdev;
	struct spdk_bdev_examine_item *item;

	if (g_bdev_opts.bdev_auto_examine) {
		SPDK_ERRLOG("Manual examine is not allowed if auto examine is enabled");
		return -EINVAL;
	}

	if (bdev_examine_allowlist_check(name)) {
		SPDK_ERRLOG("Duplicate bdev name for manual examine: %s\n", name);
		return -EEXIST;
	}

	item = calloc(1, sizeof(*item));
	if (!item) {
		return -ENOMEM;
	}
	item->name = strdup(name);
	if (!item->name) {
		free(item);
		return -ENOMEM;
	}
	TAILQ_INSERT_TAIL(&g_bdev_examine_allowlist, item, link);

	bdev = spdk_bdev_get_by_name(name);
	if (bdev) {
		bdev_examine(bdev);
	}
	return 0;
}

static inline void
bdev_examine_allowlist_config_json(struct spdk_json_write_ctx *w)
{
	struct spdk_bdev_examine_item *item;
	TAILQ_FOREACH(item, &g_bdev_examine_allowlist, link) {
		spdk_json_write_object_begin(w);
		spdk_json_write_named_string(w, "method", "bdev_examine");
		spdk_json_write_named_object_begin(w, "params");
		spdk_json_write_named_string(w, "name", item->name);
		spdk_json_write_object_end(w);
		spdk_json_write_object_end(w);
	}
}

struct spdk_bdev *
spdk_bdev_first(void)
{
@@ -984,6 +1032,8 @@ spdk_bdev_subsystem_config_json(struct spdk_json_write_ctx *w)
	spdk_json_write_object_end(w);
	spdk_json_write_object_end(w);

	bdev_examine_allowlist_config_json(w);

	TAILQ_FOREACH(bdev_module, &g_bdev_mgr.bdev_modules, internal.tailq) {
		if (bdev_module->config_json) {
			bdev_module->config_json(w);
+45 −0
Original line number Diff line number Diff line
@@ -96,3 +96,48 @@ rpc_bdev_set_options(struct spdk_jsonrpc_request *request, const struct spdk_jso
}
SPDK_RPC_REGISTER("bdev_set_options", rpc_bdev_set_options, SPDK_RPC_STARTUP)
SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_set_options, set_bdev_options)

struct rpc_bdev_examine {
	char *name;
};

static void
free_rpc_bdev_examine(struct rpc_bdev_examine *r)
{
	free(r->name);
}

static const struct spdk_json_object_decoder rpc_examine_bdev_decoders[] = {
	{"name", offsetof(struct rpc_bdev_examine, name), spdk_json_decode_string},
};

static void
rpc_bdev_examine_bdev(struct spdk_jsonrpc_request *request,
		      const struct spdk_json_val *params)
{
	struct rpc_bdev_examine req = {NULL};
	struct spdk_json_write_ctx *w;
	int rc;

	if (spdk_json_decode_object(params, rpc_examine_bdev_decoders,
				    SPDK_COUNTOF(rpc_examine_bdev_decoders),
				    &req)) {
		SPDK_ERRLOG("spdk_json_decode_object() failed\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
						 "spdk_json_decode_object failed");
		goto cleanup;
	}

	rc = spdk_bdev_examine(req.name);
	if (rc != 0) {
		spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
		goto cleanup;
	}
	w = spdk_jsonrpc_begin_result(request);
	spdk_json_write_bool(w, true);
	spdk_jsonrpc_end_result(request, w);

cleanup:
	free_rpc_bdev_examine(&req);
}
SPDK_RPC_REGISTER("bdev_examine", rpc_bdev_examine_bdev, SPDK_RPC_RUNTIME)
Loading