Add synchronous function iscsi_discovery_sync()

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
This commit is contained in:
Ronnie Sahlberg
2016-10-05 20:27:24 -07:00
parent 4694c4ec95
commit d3ef192021
4 changed files with 110 additions and 13 deletions

View File

@@ -547,6 +547,17 @@ EXTERN int iscsi_logout_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
EXTERN int iscsi_logout_sync(struct iscsi_context *iscsi);
struct iscsi_target_portal {
struct iscsi_target_portal *next;
const char *portal;
};
struct iscsi_discovery_address {
struct iscsi_discovery_address *next;
const char *target_name;
struct iscsi_target_portal *portals;
};
/*
* Asynchronous call to perform an ISCSI discovery.
*
@@ -570,16 +581,23 @@ EXTERN int iscsi_logout_sync(struct iscsi_context *iscsi);
EXTERN int iscsi_discovery_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
void *private_data);
struct iscsi_target_portal {
struct iscsi_target_portal *next;
const char *portal;
};
/*
* Synchronous call to perform an ISCSI discovery.
*
* discoveries can only be done on connected and logged in discovery sessions.
*
* Returns:
* NULL if there was an error.
* struct iscsi_discovery_address* if the discovery was successfull.
* The data returned must be released by calling iscsi_free_discovery_data.
*/
EXTERN struct iscsi_discovery_address *iscsi_discovery_sync(
struct iscsi_context *iscsi);
struct iscsi_discovery_address {
struct iscsi_discovery_address *next;
const char *target_name;
struct iscsi_target_portal *portals;
};
/* Free the discovery data structures returned by iscsi_discovery_sync
*/
EXTERN void iscsi_free_discovery_data(struct iscsi_context *iscsi,
struct iscsi_discovery_address *da);
/*
* Asynchronous call to perform an ISCSI NOP-OUT call

View File

@@ -8,6 +8,8 @@ iscsi_destroy_context
iscsi_destroy_url
iscsi_disconnect
iscsi_discovery_async
iscsi_discovery_sync
iscsi_free_discovery_data
iscsi_full_connect_async
iscsi_full_connect_sync
iscsi_get_error

View File

@@ -6,6 +6,8 @@ iscsi_destroy_context
iscsi_destroy_url
iscsi_disconnect
iscsi_discovery_async
iscsi_discovery_sync
iscsi_free_discovery_data
iscsi_full_connect_async
iscsi_full_connect_sync
iscsi_get_error

View File

@@ -42,15 +42,16 @@
#include "scsi-lowlevel.h"
struct iscsi_sync_state {
int finished;
int status;
struct scsi_task *task;
int finished;
int status;
void *ptr;
struct scsi_task *task;
};
static void
event_loop(struct iscsi_context *iscsi, struct iscsi_sync_state *state)
{
struct pollfd pfd;
struct pollfd pfd;
int ret;
while (state->finished == 0) {
@@ -1768,3 +1769,77 @@ iscsi_modesense10_sync(struct iscsi_context *iscsi, int lun, int llbaa, int dbd,
return state.task;
}
void iscsi_free_discovery_data(struct iscsi_context *iscsi _U_,
struct iscsi_discovery_address *da)
{
while (da) {
struct iscsi_discovery_address *danext = da->next;
while (da->portals) {
struct iscsi_target_portal *ponext = da->portals->next;
free(discard_const(da->portals->portal));
free(da->portals);
da->portals = ponext;
}
free(discard_const(da->target_name));
free(da);
da = danext;
}
}
static void
iscsi_discovery_cb(struct iscsi_context *iscsi _U_, int status,
void *command_data, void *private_data)
{
struct iscsi_sync_state *state = private_data;
struct iscsi_discovery_address *da;
struct iscsi_discovery_address *dahead = NULL;
struct iscsi_target_portal *po;
for (da = command_data; da != NULL; da = da->next) {
struct iscsi_discovery_address *datmp;
datmp = malloc(sizeof(struct iscsi_discovery_address));
memset(datmp, 0, sizeof(struct iscsi_discovery_address));
datmp->target_name = strdup(da->target_name);
datmp->next = dahead;
dahead = datmp;
for (po = da->portals; po != NULL; po = po->next) {
struct iscsi_target_portal *potmp;
potmp = malloc(sizeof(struct iscsi_target_portal));
memset(potmp, 0, sizeof(struct iscsi_target_portal));
potmp->portal = strdup(po->portal);
potmp->next = dahead->portals;
dahead->portals = potmp;
}
}
if (state != NULL) {
state->status = status;
state->finished = 1;
state->ptr = dahead;
}
}
struct iscsi_discovery_address *
iscsi_discovery_sync(struct iscsi_context *iscsi)
{
struct iscsi_sync_state state;
memset(&state, 0, sizeof(state));
if (iscsi_discovery_async(iscsi, iscsi_discovery_cb, &state) != 0) {
iscsi_set_error(iscsi, "Failed to run discovery. %s",
iscsi_get_error(iscsi));
printf("async discovery call failed\n");
return NULL;
}
event_loop(iscsi, &state);
return state.ptr;
}