Blob Blame History Raw
From 3f8029f837ef6680e280eb700d5930c1b38dbc27 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 7 Apr 2016 13:33:14 +0200
Subject: [PATCH 1/2] Discovery: return multiple portals for the same
 discovered target

RH-Author: Paolo Bonzini <pbonzini@redhat.com>
Message-id: <1460035995-9887-2-git-send-email-pbonzini@redhat.com>
Patchwork-id: 69977
O-Subject: [RHEL7.3 libiscsi PATCH 1/2] Discovery: return multiple portals for the same discovered target
Bugzilla: 1266523
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>

Some targets return multiple TargetAddress for individual targets.
Upstream added a list of addresses for each target, here we do not
want to break the ABI and thus return the same target name multiple
times.  Either way, failing the discovery is wrong.

The patch is very different from upstream commit
354f00fd4f63abec86ed0b9b64db1933936283b0, but the effect on
the operation of iscsi-ls is the same.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 lib/discovery.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/lib/discovery.c b/lib/discovery.c
index b5d918b..e504cf8 100644
--- a/lib/discovery.c
+++ b/lib/discovery.c
@@ -162,7 +162,7 @@ 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) {
+			if (targets == NULL) {
 				iscsi_set_error(iscsi, "Invalid discovery "
 						"reply");
 				pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
@@ -170,6 +170,34 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
 				iscsi_free_discovery_addresses(iscsi, targets);
 				return -1;
 			}
+			if (targets->target_address != NULL) {
+				struct iscsi_discovery_address *target;
+
+				target = iscsi_zmalloc(iscsi, sizeof(struct iscsi_discovery_address));
+				if (target == NULL) {
+					iscsi_set_error(iscsi, "Failed to allocate "
+							"data for new discovered "
+							"target");
+					pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
+						      pdu->private_data);
+					iscsi_free_discovery_addresses(iscsi, targets);
+					return -1;
+				}
+				target->target_name = iscsi_strdup(iscsi, targets->target_name);
+				if (target->target_name == NULL) {
+					iscsi_set_error(iscsi, "Failed to allocate "
+							"data for new discovered "
+							"target name");
+					pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
+						      pdu->private_data);
+					iscsi_free(iscsi, target);
+					target = NULL;
+					iscsi_free_discovery_addresses(iscsi, targets);
+					return -1;
+				}
+				target->next = targets;
+				targets = target;
+			}
 			targets->target_address = iscsi_strdup(iscsi, (char *)ptr+14);
 			if (targets->target_address == NULL) {
 				iscsi_set_error(iscsi, "Failed to allocate "
-- 
1.8.3.1