Commit 36e8c20f authored by Xiaodong Liu's avatar Xiaodong Liu Committed by Jim Harris
Browse files

nbd: avoid impact to device setup by other task



Use NBD_SET_SOCK to check whether the nbd device is setup
by other process or whether nbd kernel module is ready
before other nbd ioctl operations. This can avoid bad
influence to the nbd device setup by other process.

Change-Id: Ic12acbfddb8c4388e25731c39159b1ce559b8f23
Signed-off-by: default avatarXiaodong Liu <xiaodong.liu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/444805


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarPawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent d8f5fead
Loading
Loading
Loading
Loading
+36 −30
Original line number Diff line number Diff line
@@ -355,10 +355,6 @@ _nbd_stop(struct spdk_nbd_disk *nbd)
		spdk_bdev_close(nbd->bdev_desc);
	}

	if (nbd->nbd_path) {
		free(nbd->nbd_path);
	}

	if (nbd->spdk_sp_fd >= 0) {
		close(nbd->spdk_sp_fd);
	}
@@ -368,11 +364,18 @@ _nbd_stop(struct spdk_nbd_disk *nbd)
	}

	if (nbd->dev_fd >= 0) {
		/* Clear nbd device only if it is occupied by SPDK app */
		if (nbd->nbd_path && spdk_nbd_disk_find_by_nbd_path(nbd->nbd_path)) {
			ioctl(nbd->dev_fd, NBD_CLEAR_QUE);
			ioctl(nbd->dev_fd, NBD_CLEAR_SOCK);
		}
		close(nbd->dev_fd);
	}

	if (nbd->nbd_path) {
		free(nbd->nbd_path);
	}

	if (nbd->nbd_poller) {
		spdk_poller_unregister(&nbd->nbd_poller);
	}
@@ -854,6 +857,28 @@ spdk_nbd_start_complete(struct spdk_nbd_start_ctx *ctx)
	pthread_t	tid;
	int		flag;

	/* Add nbd_disk to the end of disk list */
	rc = spdk_nbd_disk_register(ctx->nbd);
	if (rc != 0) {
		SPDK_ERRLOG("Failed to register %s, it should not happen.\n", ctx->nbd->nbd_path);
		assert(false);
		goto err;
	}

	rc = ioctl(ctx->nbd->dev_fd, NBD_SET_BLKSIZE, spdk_bdev_get_block_size(ctx->nbd->bdev));
	if (rc == -1) {
		SPDK_ERRLOG("ioctl(NBD_SET_BLKSIZE) failed: %s\n", spdk_strerror(errno));
		rc = -errno;
		goto err;
	}

	rc = ioctl(ctx->nbd->dev_fd, NBD_SET_SIZE_BLOCKS, spdk_bdev_get_num_blocks(ctx->nbd->bdev));
	if (rc == -1) {
		SPDK_ERRLOG("ioctl(NBD_SET_SIZE_BLOCKS) failed: %s\n", spdk_strerror(errno));
		rc = -errno;
		goto err;
	}

#ifdef NBD_FLAG_SEND_TRIM
	rc = ioctl(ctx->nbd->dev_fd, NBD_SET_FLAGS, NBD_FLAG_SEND_TRIM);
	if (rc == -1) {
@@ -908,6 +933,7 @@ spdk_nbd_enable_kernel(void *arg)
	struct spdk_nbd_start_ctx *ctx = arg;
	int rc;

	/* Declare device setup by this process */
	rc = ioctl(ctx->nbd->dev_fd, NBD_SET_SOCK, ctx->nbd->kernel_sp_fd);
	if (rc == -1) {
		if (errno == EBUSY && ctx->polling_count-- > 0) {
@@ -1011,9 +1037,10 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path,
	TAILQ_INIT(&nbd->received_io_list);
	TAILQ_INIT(&nbd->executed_io_list);

	/* Add nbd_disk to the end of disk list */
	rc = spdk_nbd_disk_register(nbd);
	if (rc != 0) {
	/* Make sure nbd_path is not used in this SPDK app */
	if (spdk_nbd_disk_find_by_nbd_path(nbd->nbd_path)) {
		SPDK_NOTICELOG("%s is already exported\n", nbd->nbd_path);
		rc = -EBUSY;
		goto err;
	}

@@ -1024,27 +1051,6 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path,
		goto err;
	}

	rc = ioctl(nbd->dev_fd, NBD_SET_BLKSIZE, spdk_bdev_get_block_size(bdev));
	if (rc == -1) {
		SPDK_ERRLOG("ioctl(NBD_SET_BLKSIZE) failed: %s\n", spdk_strerror(errno));
		rc = -errno;
		goto err;
	}

	rc = ioctl(nbd->dev_fd, NBD_SET_SIZE_BLOCKS, spdk_bdev_get_num_blocks(bdev));
	if (rc == -1) {
		SPDK_ERRLOG("ioctl(NBD_SET_SIZE_BLOCKS) failed: %s\n", spdk_strerror(errno));
		rc = -errno;
		goto err;
	}

	rc = ioctl(nbd->dev_fd, NBD_CLEAR_SOCK);
	if (rc == -1) {
		SPDK_ERRLOG("ioctl(NBD_CLEAR_SOCK) failed: %s\n", spdk_strerror(errno));
		rc = -errno;
		goto err;
	}

	SPDK_INFOLOG(SPDK_LOG_NBD, "Enabling kernel access to bdev %s via %s\n",
		     spdk_bdev_get_name(bdev), nbd_path);