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: Xiaodong Liu <xiaodong.liu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/444805
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Xiaodong Liu 2019-02-14 20:27:08 +08:00 committed by Jim Harris
parent d8f5fead29
commit 36e8c20fe9

View File

@ -355,10 +355,6 @@ _nbd_stop(struct spdk_nbd_disk *nbd)
spdk_bdev_close(nbd->bdev_desc); spdk_bdev_close(nbd->bdev_desc);
} }
if (nbd->nbd_path) {
free(nbd->nbd_path);
}
if (nbd->spdk_sp_fd >= 0) { if (nbd->spdk_sp_fd >= 0) {
close(nbd->spdk_sp_fd); close(nbd->spdk_sp_fd);
} }
@ -368,11 +364,18 @@ _nbd_stop(struct spdk_nbd_disk *nbd)
} }
if (nbd->dev_fd >= 0) { if (nbd->dev_fd >= 0) {
ioctl(nbd->dev_fd, NBD_CLEAR_QUE); /* Clear nbd device only if it is occupied by SPDK app */
ioctl(nbd->dev_fd, NBD_CLEAR_SOCK); 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); close(nbd->dev_fd);
} }
if (nbd->nbd_path) {
free(nbd->nbd_path);
}
if (nbd->nbd_poller) { if (nbd->nbd_poller) {
spdk_poller_unregister(&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; pthread_t tid;
int flag; 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 #ifdef NBD_FLAG_SEND_TRIM
rc = ioctl(ctx->nbd->dev_fd, NBD_SET_FLAGS, NBD_FLAG_SEND_TRIM); rc = ioctl(ctx->nbd->dev_fd, NBD_SET_FLAGS, NBD_FLAG_SEND_TRIM);
if (rc == -1) { if (rc == -1) {
@ -908,6 +933,7 @@ spdk_nbd_enable_kernel(void *arg)
struct spdk_nbd_start_ctx *ctx = arg; struct spdk_nbd_start_ctx *ctx = arg;
int rc; int rc;
/* Declare device setup by this process */
rc = ioctl(ctx->nbd->dev_fd, NBD_SET_SOCK, ctx->nbd->kernel_sp_fd); rc = ioctl(ctx->nbd->dev_fd, NBD_SET_SOCK, ctx->nbd->kernel_sp_fd);
if (rc == -1) { if (rc == -1) {
if (errno == EBUSY && ctx->polling_count-- > 0) { 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->received_io_list);
TAILQ_INIT(&nbd->executed_io_list); TAILQ_INIT(&nbd->executed_io_list);
/* Add nbd_disk to the end of disk list */ /* Make sure nbd_path is not used in this SPDK app */
rc = spdk_nbd_disk_register(nbd); if (spdk_nbd_disk_find_by_nbd_path(nbd->nbd_path)) {
if (rc != 0) { SPDK_NOTICELOG("%s is already exported\n", nbd->nbd_path);
rc = -EBUSY;
goto err; goto err;
} }
@ -1024,27 +1051,6 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path,
goto err; 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_INFOLOG(SPDK_LOG_NBD, "Enabling kernel access to bdev %s via %s\n",
spdk_bdev_get_name(bdev), nbd_path); spdk_bdev_get_name(bdev), nbd_path);