From c4331b7523afccba5176797901209a9d03afa997 Mon Sep 17 00:00:00 2001 From: Ales Kozumplik 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