bdev/iSCSI: Make the connection connect in async mode.
Change-Id: I9d3b56ed908273c6853014241a28237f8d077cfa Signed-off-by: Ziye Yang <optimistyzy@gmail.com> Reviewed-on: https://review.gerrithub.io/405537 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
3ed915618f
commit
ec5cf8a221
@ -55,6 +55,10 @@ struct bdev_iscsi_lun;
|
|||||||
|
|
||||||
static int bdev_iscsi_initialize(void);
|
static int bdev_iscsi_initialize(void);
|
||||||
static TAILQ_HEAD(, bdev_iscsi_lun) g_iscsi_lun_head = TAILQ_HEAD_INITIALIZER(g_iscsi_lun_head);
|
static TAILQ_HEAD(, bdev_iscsi_lun) g_iscsi_lun_head = TAILQ_HEAD_INITIALIZER(g_iscsi_lun_head);
|
||||||
|
static TAILQ_HEAD(, bdev_iscsi_conn_req) g_iscsi_conn_req = TAILQ_HEAD_INITIALIZER(
|
||||||
|
g_iscsi_conn_req);
|
||||||
|
static struct spdk_poller *g_conn_poller = NULL;
|
||||||
|
static bool g_module_is_initialized;
|
||||||
|
|
||||||
struct bdev_iscsi_io {
|
struct bdev_iscsi_io {
|
||||||
struct spdk_thread *submit_td;
|
struct spdk_thread *submit_td;
|
||||||
@ -82,15 +86,30 @@ struct bdev_iscsi_io_channel {
|
|||||||
struct bdev_iscsi_lun *lun;
|
struct bdev_iscsi_lun *lun;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bdev_iscsi_conn_req {
|
||||||
|
struct iscsi_url *url;
|
||||||
|
char *bdev_name;
|
||||||
|
struct iscsi_context *context;
|
||||||
|
TAILQ_ENTRY(bdev_iscsi_conn_req) link;
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bdev_iscsi_get_ctx_size(void)
|
bdev_iscsi_get_ctx_size(void)
|
||||||
{
|
{
|
||||||
return sizeof(struct bdev_iscsi_io);
|
return sizeof(struct bdev_iscsi_io);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bdev_iscsi_remove_conn_req(struct bdev_iscsi_conn_req *req)
|
||||||
|
{
|
||||||
|
TAILQ_REMOVE(&g_iscsi_conn_req, req, link);
|
||||||
|
free(req);
|
||||||
|
}
|
||||||
|
|
||||||
static void bdev_iscsi_finish(void)
|
static void bdev_iscsi_finish(void)
|
||||||
{
|
{
|
||||||
struct bdev_iscsi_lun *lun;
|
struct bdev_iscsi_lun *lun;
|
||||||
|
struct bdev_iscsi_conn_req *req, *tmp;
|
||||||
|
|
||||||
while (!TAILQ_EMPTY(&g_iscsi_lun_head)) {
|
while (!TAILQ_EMPTY(&g_iscsi_lun_head)) {
|
||||||
lun = TAILQ_FIRST(&g_iscsi_lun_head);
|
lun = TAILQ_FIRST(&g_iscsi_lun_head);
|
||||||
@ -99,6 +118,14 @@ static void bdev_iscsi_finish(void)
|
|||||||
iscsi_destroy_context(lun->context);
|
iscsi_destroy_context(lun->context);
|
||||||
iscsi_destroy_url(lun->url);
|
iscsi_destroy_url(lun->url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAILQ_FOREACH_SAFE(req, &g_iscsi_conn_req, link, tmp) {
|
||||||
|
bdev_iscsi_remove_conn_req(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_conn_poller) {
|
||||||
|
spdk_poller_unregister(&g_conn_poller);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct spdk_bdev_module g_iscsi_bdev_module = {
|
static struct spdk_bdev_module g_iscsi_bdev_module = {
|
||||||
@ -106,6 +133,7 @@ static struct spdk_bdev_module g_iscsi_bdev_module = {
|
|||||||
.module_init = bdev_iscsi_initialize,
|
.module_init = bdev_iscsi_initialize,
|
||||||
.module_fini = bdev_iscsi_finish,
|
.module_fini = bdev_iscsi_finish,
|
||||||
.get_ctx_size = bdev_iscsi_get_ctx_size,
|
.get_ctx_size = bdev_iscsi_get_ctx_size,
|
||||||
|
.async_init = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
SPDK_BDEV_MODULE_REGISTER(&g_iscsi_bdev_module);
|
SPDK_BDEV_MODULE_REGISTER(&g_iscsi_bdev_module);
|
||||||
@ -218,7 +246,7 @@ bdev_iscsi_poll(void *arg)
|
|||||||
{
|
{
|
||||||
struct bdev_iscsi_io_channel *ch = arg;
|
struct bdev_iscsi_io_channel *ch = arg;
|
||||||
struct bdev_iscsi_lun *lun = ch->lun;
|
struct bdev_iscsi_lun *lun = ch->lun;
|
||||||
struct pollfd pfd;
|
struct pollfd pfd = {};
|
||||||
|
|
||||||
pfd.fd = iscsi_get_fd(lun->context);
|
pfd.fd = iscsi_get_fd(lun->context);
|
||||||
pfd.events = iscsi_which_events(lun->context);
|
pfd.events = iscsi_which_events(lun->context);
|
||||||
@ -426,20 +454,123 @@ error_return:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct bdev_iscsi_conn_req *
|
||||||
|
bdev_iscsi_allocate_conn_req(struct iscsi_context *context, char *bdev_name, struct iscsi_url *url)
|
||||||
|
{
|
||||||
|
struct bdev_iscsi_conn_req *req;
|
||||||
|
|
||||||
|
req = calloc(1, sizeof(struct bdev_iscsi_conn_req));
|
||||||
|
if (!req) {
|
||||||
|
SPDK_ERRLOG("Cannot allocate pointer of struct bdev_iscsi_conn_req\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
req->bdev_name = bdev_name;
|
||||||
|
req->url = url;
|
||||||
|
req->context = context;
|
||||||
|
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_bdev_iscsi_set_module_init(void)
|
||||||
|
{
|
||||||
|
spdk_bdev_module_init_done(&g_iscsi_bdev_module);
|
||||||
|
g_module_is_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bdev_iscsi_set_module_init(void)
|
||||||
|
{
|
||||||
|
if (!g_module_is_initialized && TAILQ_EMPTY(&g_iscsi_conn_req)) {
|
||||||
|
_bdev_iscsi_set_module_init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
iscsi_readcapacity16_cb(struct iscsi_context *iscsi, int status,
|
||||||
|
void *command_data, void *private_data)
|
||||||
|
{
|
||||||
|
struct bdev_iscsi_conn_req *req = private_data;
|
||||||
|
struct scsi_readcapacity16 *readcap16;
|
||||||
|
struct spdk_bdev *bdev;
|
||||||
|
struct scsi_task *task = command_data;
|
||||||
|
|
||||||
|
if (status != SPDK_SCSI_STATUS_GOOD) {
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
readcap16 = scsi_datain_unmarshall(task);
|
||||||
|
bdev = create_iscsi_lun(req->context, req->url, req->bdev_name,
|
||||||
|
readcap16->returned_lba + 1, readcap16->block_length);
|
||||||
|
if (!bdev) {
|
||||||
|
SPDK_ERRLOG("Unable to create iscsi bdev\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ret:
|
||||||
|
scsi_free_scsi_task(task);
|
||||||
|
bdev_iscsi_remove_conn_req(req);
|
||||||
|
bdev_iscsi_set_module_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
iscsi_connect_cb(struct iscsi_context *iscsi, int status,
|
||||||
|
void *command_data, void *private_data)
|
||||||
|
{
|
||||||
|
struct bdev_iscsi_conn_req *req = private_data;
|
||||||
|
struct scsi_task *task;
|
||||||
|
|
||||||
|
if (status != SPDK_SCSI_STATUS_GOOD) {
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
task = iscsi_readcapacity16_task(iscsi, 0, iscsi_readcapacity16_cb, req);
|
||||||
|
if (task) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ret:
|
||||||
|
bdev_iscsi_remove_conn_req(req);
|
||||||
|
bdev_iscsi_set_module_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
iscsi_bdev_conn_poll(void *arg)
|
||||||
|
{
|
||||||
|
struct bdev_iscsi_conn_req *req, *tmp;
|
||||||
|
struct pollfd pfd;
|
||||||
|
|
||||||
|
TAILQ_FOREACH_SAFE(req, &g_iscsi_conn_req, link, tmp) {
|
||||||
|
pfd.fd = iscsi_get_fd(req->context);
|
||||||
|
pfd.events = iscsi_which_events(req->context);
|
||||||
|
pfd.revents = 0;
|
||||||
|
if (poll(&pfd, 1, 0) < 0) {
|
||||||
|
SPDK_ERRLOG("poll failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pfd.revents != 0) {
|
||||||
|
if (iscsi_service(req->context, pfd.revents) < 0) {
|
||||||
|
SPDK_ERRLOG("iscsi_service failed: %s\n", iscsi_get_error(req->context));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bdev_iscsi_initialize(void)
|
bdev_iscsi_initialize(void)
|
||||||
{
|
{
|
||||||
struct spdk_conf_section *sp;
|
struct spdk_conf_section *sp;
|
||||||
struct iscsi_context *context;
|
struct iscsi_context *context;
|
||||||
struct iscsi_url *url;
|
struct iscsi_url *url;
|
||||||
struct spdk_bdev *bdev;
|
|
||||||
struct scsi_task *task;
|
|
||||||
struct scsi_readcapacity16 *readcap16;
|
|
||||||
char *val, *bdev_name, *initiator_iqn;
|
char *val, *bdev_name, *initiator_iqn;
|
||||||
|
struct bdev_iscsi_conn_req *req;
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
|
||||||
sp = spdk_conf_find_section(NULL, "iSCSI_Initiator");
|
sp = spdk_conf_find_section(NULL, "iSCSI_Initiator");
|
||||||
if (sp == NULL) {
|
if (sp == NULL) {
|
||||||
|
_bdev_iscsi_set_module_init();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,28 +604,28 @@ bdev_iscsi_initialize(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req = bdev_iscsi_allocate_conn_req(context, bdev_name, url);
|
||||||
|
if (!req) {
|
||||||
|
_bdev_iscsi_set_module_init();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
iscsi_set_session_type(context, ISCSI_SESSION_NORMAL);
|
iscsi_set_session_type(context, ISCSI_SESSION_NORMAL);
|
||||||
iscsi_set_header_digest(context, ISCSI_HEADER_DIGEST_NONE);
|
iscsi_set_header_digest(context, ISCSI_HEADER_DIGEST_NONE);
|
||||||
rc = iscsi_full_connect_sync(context, url->portal, url->lun);
|
rc = iscsi_full_connect_async(context, url->portal, url->lun, iscsi_connect_cb, req);
|
||||||
if (rc != 0) {
|
if (rc < 0) {
|
||||||
SPDK_ERRLOG("could not login\n");
|
free(req);
|
||||||
break;
|
SPDK_ERRLOG("Failed to connect provided URL=%s, will ignore it\n", val);
|
||||||
}
|
continue;
|
||||||
|
|
||||||
task = iscsi_readcapacity16_sync(context, 0);
|
|
||||||
readcap16 = scsi_datain_unmarshall(task);
|
|
||||||
scsi_free_scsi_task(task);
|
|
||||||
|
|
||||||
bdev = create_iscsi_lun(context, url, bdev_name,
|
|
||||||
readcap16->returned_lba + 1, readcap16->block_length);
|
|
||||||
if (!bdev) {
|
|
||||||
SPDK_ERRLOG("Unable to create iscsi bdev\n");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAILQ_INSERT_TAIL(&g_iscsi_conn_req, req, link);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!TAILQ_EMPTY(&g_iscsi_conn_req)) {
|
||||||
|
g_conn_poller = spdk_poller_register(iscsi_bdev_conn_poll, NULL, 0);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user