Discovery: Create a list of portals for each discovered target.
Some targets return multiple TargetAddress for individual targets. Create a linked list of addresses for each target instead of failing the discovery process when this happens.
This commit is contained in:
@@ -566,13 +566,13 @@ void discovery_cb(struct iscsi_context *iscsi, int status, void *command_data, v
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(addr=command_data; addr; addr=addr->next) {
|
for(addr=command_data; addr; addr=addr->next) {
|
||||||
printf("Target:%s Address:%s\n", addr->target_name, addr->target_address);
|
printf("Target:%s Address:%s\n", addr->target_name, addr->portals->portal);
|
||||||
}
|
}
|
||||||
|
|
||||||
addr=command_data;
|
addr=command_data;
|
||||||
clnt->has_discovered_target = 1;
|
clnt->has_discovered_target = 1;
|
||||||
clnt->target_name = strdup(addr->target_name);
|
clnt->target_name = strdup(addr->target_name);
|
||||||
clnt->target_address = strdup(addr->target_address);
|
clnt->target_address = strdup(addr->portals->portal);
|
||||||
|
|
||||||
|
|
||||||
printf("discovery complete, send logout command\n");
|
printf("discovery complete, send logout command\n");
|
||||||
|
|||||||
@@ -474,10 +474,15 @@ EXTERN int iscsi_logout_sync(struct iscsi_context *iscsi);
|
|||||||
EXTERN int iscsi_discovery_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
EXTERN int iscsi_discovery_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||||
void *private_data);
|
void *private_data);
|
||||||
|
|
||||||
|
struct iscsi_target_portal {
|
||||||
|
struct iscsi_target_portal *next;
|
||||||
|
const char *portal;
|
||||||
|
};
|
||||||
|
|
||||||
struct iscsi_discovery_address {
|
struct iscsi_discovery_address {
|
||||||
struct iscsi_discovery_address *next;
|
struct iscsi_discovery_address *next;
|
||||||
const char *target_name;
|
const char *target_name;
|
||||||
const char *target_address;
|
struct iscsi_target_portal *portals;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -93,8 +93,15 @@ iscsi_free_discovery_addresses(struct iscsi_context *iscsi, struct iscsi_discove
|
|||||||
iscsi_free(iscsi, discard_const(addresses->target_name));
|
iscsi_free(iscsi, discard_const(addresses->target_name));
|
||||||
addresses->target_name = NULL;
|
addresses->target_name = NULL;
|
||||||
|
|
||||||
iscsi_free(iscsi, discard_const(addresses->target_address));
|
while (addresses->portals != NULL) {
|
||||||
addresses->target_address = NULL;
|
struct iscsi_target_portal *next_portal = addresses->portals->next;
|
||||||
|
|
||||||
|
iscsi_free(iscsi, discard_const(addresses->portals->portal));
|
||||||
|
iscsi_free(iscsi, discard_const(addresses->portals));
|
||||||
|
|
||||||
|
addresses->portals = next_portal;
|
||||||
|
}
|
||||||
|
addresses->portals = NULL;
|
||||||
|
|
||||||
addresses->next = NULL;
|
addresses->next = NULL;
|
||||||
iscsi_free(iscsi, addresses);
|
iscsi_free(iscsi, addresses);
|
||||||
@@ -168,7 +175,9 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
target->next = targets;
|
target->next = targets;
|
||||||
targets = target;
|
targets = target;
|
||||||
} else if (!strncmp((char *)ptr, "TargetAddress=", 14)) {
|
} else if (!strncmp((char *)ptr, "TargetAddress=", 14)) {
|
||||||
if (targets == NULL || targets->target_address != NULL) {
|
struct iscsi_target_portal *portal;
|
||||||
|
|
||||||
|
if (targets == NULL) {
|
||||||
iscsi_set_error(iscsi, "Invalid discovery "
|
iscsi_set_error(iscsi, "Invalid discovery "
|
||||||
"reply");
|
"reply");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
@@ -176,8 +185,21 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
iscsi_free_discovery_addresses(iscsi, targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
targets->target_address = iscsi_strdup(iscsi, (char *)ptr+14);
|
portal = iscsi_zmalloc(iscsi, sizeof(struct iscsi_target_portal));
|
||||||
if (targets->target_address == NULL) {
|
if (portal == NULL) {
|
||||||
|
iscsi_set_error(iscsi, "Failed to malloc "
|
||||||
|
"portal structure");
|
||||||
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
portal->next = targets->portals;
|
||||||
|
targets->portals = portal;
|
||||||
|
|
||||||
|
portal->portal = iscsi_strdup(iscsi, (char *)ptr+14);
|
||||||
|
if (portal->portal == NULL) {
|
||||||
iscsi_set_error(iscsi, "Failed to allocate "
|
iscsi_set_error(iscsi, "Failed to allocate "
|
||||||
"data for new discovered "
|
"data for new discovered "
|
||||||
"target address");
|
"target address");
|
||||||
|
|||||||
@@ -256,13 +256,18 @@ void discovery_cb(struct iscsi_context *iscsi, int status, void *command_data, v
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(addr=command_data; addr; addr=addr->next) {
|
for(addr=command_data; addr; addr=addr->next) {
|
||||||
if (useurls == 1 && showluns == 0) {
|
struct iscsi_target_portal *portal = addr->portals;
|
||||||
printf("iscsi://%s/%s/0\n", addr->target_address, addr->target_name);
|
|
||||||
} else {
|
while (portal != NULL) {
|
||||||
printf("Target:%s Portal:%s\n", addr->target_name, addr->target_address);
|
if (useurls == 1 && showluns == 0) {
|
||||||
}
|
printf("iscsi://%s/%s/0\n", portal->portal, addr->target_name);
|
||||||
if (showluns != 0) {
|
} else {
|
||||||
list_luns(private_data, addr->target_name, addr->target_address);
|
printf("Target:%s Portal:%s\n", addr->target_name, portal->portal);
|
||||||
|
}
|
||||||
|
if (showluns != 0) {
|
||||||
|
list_luns(private_data, addr->target_name, portal->portal);
|
||||||
|
}
|
||||||
|
portal = portal->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user