Blob Blame History Raw
From c4331b7523afccba5176797901209a9d03afa997 Mon Sep 17 00:00:00 2001
From: Ales Kozumplik <akozumpl@redhat.com>
Date: Thu, 18 Nov 2010 17:13:36 +0100
Subject: [PATCH] libiscsi: reimplement fw discovery so partial devices are used properly.

Related: rhbz#442980
---
 libiscsi/libiscsi.c |  120 ++++++++++++++++++++++++++++++--------------------
 1 files changed, 72 insertions(+), 48 deletions(-)

diff --git a/libiscsi/libiscsi.c b/libiscsi/libiscsi.c
index 19eae58..626e67c 100644
--- a/libiscsi/libiscsi.c
+++ b/libiscsi/libiscsi.c
@@ -93,6 +93,16 @@ void libiscsi_cleanup(struct libiscsi_context *context)
 	free(context);
 }
 
+static void free_iface_list(struct list_head *ifaces)
+{
+	struct iface_rec *iface, *tmp_iface;
+
+	list_for_each_entry_safe(iface, tmp_iface, ifaces, list) {
+		list_del(&iface->list);
+		free(iface);
+	}
+}
+
 static void free_rec_list(struct list_head *rec_list)
 {
 	struct node_rec *rec, *tmp;
@@ -188,69 +198,83 @@ leave:
 int libiscsi_discover_firmware(struct libiscsi_context *context,
 	int *nr_found, struct libiscsi_node **found_nodes)
 {
-	struct boot_context fw_entry;
-	struct node_rec rec;
+	struct list_head targets, ifaces, rec_list;
+	discovery_rec_t drec;
 	int rc = 0;
 
-	if (nr_found)
+	INIT_LIST_HEAD(&targets);
+	INIT_LIST_HEAD(&ifaces);
+	INIT_LIST_HEAD(&rec_list);
+	
+	if (nr_found) {
 		*nr_found = 0;
-	if (found_nodes)
+	}
+
+	if (found_nodes) {
 		*found_nodes = NULL;
+	}
 
-	memset(&fw_entry, 0, sizeof fw_entry);
-	rc = fw_get_entry(&fw_entry);
+	rc = fw_get_targets(&targets);
 	if (rc) {
-		strcpy(context->error_str, "Could not read fw values.");
+		log_error("%s: Could not get list of targets from firmware "
+			  "(err %d).\n", __func__, rc);
 		return rc;
 	}
 
-	memset(&rec, 0, sizeof rec);
-	idbm_node_setup_defaults(&rec);
-
-	strlcpy(rec.name, fw_entry.targetname, TARGET_NAME_MAXLEN);
-	rec.tpgt = 1;
-	strlcpy(rec.conn[0].address, fw_entry.target_ipaddr, NI_MAXHOST);
-	rec.conn[0].port = fw_entry.target_port;
-
-	iface_setup_defaults(&rec.iface);
-	strncpy(rec.iface.iname, fw_entry.initiatorname,
-		sizeof(fw_entry.initiatorname));
-	strncpy(rec.session.auth.username, fw_entry.chap_name,
-		sizeof(fw_entry.chap_name));
-	strncpy((char *)rec.session.auth.password, fw_entry.chap_password,
-		sizeof(fw_entry.chap_password));
-	strncpy(rec.session.auth.username_in, fw_entry.chap_name_in,
-		sizeof(fw_entry.chap_name_in));
-	strncpy((char *)rec.session.auth.password_in,
-		fw_entry.chap_password_in,
-		sizeof(fw_entry.chap_password_in));
-	rec.session.auth.password_length =
-				strlen((char *)fw_entry.chap_password);
-	rec.session.auth.password_in_length =
-				strlen((char *)fw_entry.chap_password_in);
-
-	CHECK(idbm_add_node(&rec, NULL, 1 /* overwrite */))
+	CHECK(iface_create_ifaces_from_boot_contexts(&ifaces, &targets));
+	
+	memset(&drec, 0, sizeof(drec));
+	drec.type = DISCOVERY_TYPE_FW;
+	rc = idbm_bind_ifaces_to_nodes(discovery_fw, &drec, &ifaces, &rec_list);
+	if (rc) {
+		log_error("%s: Could not determine target nodes from firmware "
+			  "(err %d).\n", __func__, rc);
+		goto leave;
+	}
+
+	int node_count = 0;
+	struct list_head *pos;
+	list_for_each(pos, &rec_list) {
+		++node_count;
+	}
 
-	if (nr_found)
-		*nr_found = 1;
+	struct libiscsi_node* new_nodes;
+	/* allocate enough space for all the nodes */
+	new_nodes = calloc(node_count, sizeof *new_nodes);
+	if (new_nodes == NULL) {
+		rc = ENOMEM;
+		log_error("%s: %s.\n", __func__, strerror(ENOMEM));
+		goto leave;
+	}
+
+	struct node_rec *rec;
+	struct libiscsi_node *new_node = new_nodes;
+	/* in one loop, add nodes to idbm and create libiscsi_node entries */
+	list_for_each_entry(rec, &rec_list, list) {
+		CHECK(idbm_add_node(rec, NULL, 1 /* overwrite */));
+
+		strlcpy(new_node->name, rec->name, LIBISCSI_VALUE_MAXLEN);
+		new_node->tpgt = rec->tpgt;
+		strlcpy(new_node->address, rec->conn[0].address, NI_MAXHOST);
+		new_node->port = rec->conn[0].port;
+
+		++new_node;
+	}
 
+	/* update output parameters */
+	if (nr_found) {
+		*nr_found = node_count;
+	}
 	if (found_nodes) {
-		*found_nodes = calloc(1, sizeof **found_nodes);
-		if (*found_nodes == NULL) {
-			snprintf(context->error_str,
-				 sizeof(context->error_str), strerror(ENOMEM));
-			rc = ENOMEM;
-			goto leave;
-		}
-		strlcpy((*found_nodes)[0].name, rec.name,
-			 LIBISCSI_VALUE_MAXLEN);
-		(*found_nodes)[0].tpgt = rec.tpgt;
-		strlcpy((*found_nodes)[0].address,
-			 rec.conn[0].address, NI_MAXHOST);
-		(*found_nodes)[0].port = rec.conn[0].port;
+		*found_nodes = new_nodes;
 	}
 
 leave:
+	fw_free_targets(&targets);
+
+	free_iface_list(&ifaces);
+	free_rec_list(&rec_list);
+
 	return rc;
 }
 
-- 
1.7.3.2