nbd: avoid unlimited wait for device busy

The ioctl NBD_SET_SOCK can return EBUSY on conditions not
only the kernel module hasn't loaded entirely yet, but
also the nbd device is setup by another process, which will
lead the poller's infinite polling.
This patch will wait only 1 second if device is busy.

Change-Id: I8b1cfab725cba180f774a57ced3fa4ba81da2037
Signed-off-by: Xiaodong Liu <xiaodong.liu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/444804
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Xiaodong Liu 2019-02-15 18:31:51 +08:00 committed by Jim Harris
parent 968a56572f
commit d8f5fead29

View File

@ -49,7 +49,9 @@
#include "spdk_internal/log.h"
#include "spdk/queue.h"
#define GET_IO_LOOP_COUNT 16
#define GET_IO_LOOP_COUNT 16
#define NBD_BUSY_WAITING_MS 1000
#define NBD_BUSY_POLLING_INTERVAL_US 20000
enum nbd_io_state_t {
/* Receiving or ready to receive nbd request header */
@ -842,6 +844,7 @@ struct spdk_nbd_start_ctx {
spdk_nbd_start_cb cb_fn;
void *cb_arg;
struct spdk_poller *poller;
int polling_count;
};
static void
@ -907,15 +910,15 @@ spdk_nbd_enable_kernel(void *arg)
rc = ioctl(ctx->nbd->dev_fd, NBD_SET_SOCK, ctx->nbd->kernel_sp_fd);
if (rc == -1) {
if (errno == EBUSY) {
if (errno == EBUSY && ctx->polling_count-- > 0) {
if (ctx->poller == NULL) {
ctx->poller = spdk_poller_register(spdk_nbd_enable_kernel, ctx, 20000);
ctx->poller = spdk_poller_register(spdk_nbd_enable_kernel, ctx,
NBD_BUSY_POLLING_INTERVAL_US);
}
/* If the kernel is busy, check back later */
return 0;
}
SPDK_ERRLOG("ioctl(NBD_SET_SOCK) failed: %s\n", spdk_strerror(errno));
if (ctx->poller) {
spdk_poller_unregister(&ctx->poller);
@ -976,6 +979,7 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path,
ctx->nbd = nbd;
ctx->cb_fn = cb_fn;
ctx->cb_arg = cb_arg;
ctx->polling_count = NBD_BUSY_WAITING_MS * 1000ULL / NBD_BUSY_POLLING_INTERVAL_US;
rc = spdk_bdev_open(bdev, true, spdk_nbd_bdev_hot_remove, nbd, &nbd->bdev_desc);
if (rc != 0) {