diff --git a/examples/iscsiclient.c b/examples/iscsiclient.c index 34838d9..f89f2b3 100644 --- a/examples/iscsiclient.c +++ b/examples/iscsiclient.c @@ -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) { - 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; clnt->has_discovered_target = 1; 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"); diff --git a/include/iscsi.h b/include/iscsi.h index 4878166..4ab658d 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -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, void *private_data); +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; - const char *target_address; + struct iscsi_target_portal *portals; }; /* diff --git a/lib/discovery.c b/lib/discovery.c index fe1ba4f..2cbcf62 100644 --- a/lib/discovery.c +++ b/lib/discovery.c @@ -93,8 +93,15 @@ iscsi_free_discovery_addresses(struct iscsi_context *iscsi, struct iscsi_discove iscsi_free(iscsi, discard_const(addresses->target_name)); addresses->target_name = NULL; - iscsi_free(iscsi, discard_const(addresses->target_address)); - addresses->target_address = NULL; + while (addresses->portals != 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; iscsi_free(iscsi, addresses); @@ -168,7 +175,9 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, target->next = targets; targets = target; } 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 " "reply"); 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); return -1; } - targets->target_address = iscsi_strdup(iscsi, (char *)ptr+14); - if (targets->target_address == NULL) { + portal = iscsi_zmalloc(iscsi, sizeof(struct iscsi_target_portal)); + 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 " "data for new discovered " "target address"); diff --git a/src/iscsi-ls.c b/src/iscsi-ls.c index a7f9013..515eba4 100644 --- a/src/iscsi-ls.c +++ b/src/iscsi-ls.c @@ -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) { - if (useurls == 1 && showluns == 0) { - printf("iscsi://%s/%s/0\n", addr->target_address, addr->target_name); - } else { - printf("Target:%s Portal:%s\n", addr->target_name, addr->target_address); - } - if (showluns != 0) { - list_luns(private_data, addr->target_name, addr->target_address); + struct iscsi_target_portal *portal = addr->portals; + + while (portal != NULL) { + if (useurls == 1 && showluns == 0) { + printf("iscsi://%s/%s/0\n", portal->portal, addr->target_name); + } else { + 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; } }