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 (master)
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/447598
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Xiaodong Liu 2019-02-15 18:31:51 +08:00 committed by Darek Stojaczyk
parent d2e533c642
commit a629b17d51

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 */
@ -845,6 +847,7 @@ struct spdk_nbd_start_ctx {
spdk_nbd_start_cb cb_fn;
void *cb_arg;
struct spdk_poller *poller;
int polling_count;
};
static void
@ -933,15 +936,15 @@ spdk_nbd_enable_kernel(void *arg)
/* 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) {
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);
@ -1002,6 +1005,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) {