[iscsi-initiator-utils: 88/109] Resolves: #739843 #796574
Chris Leech
cleech at fedoraproject.org
Tue Dec 10 21:26:42 UTC 2013
commit 8012828d2aeccc469af32b26f06cd40d59cbfbee
Author: Mike Christie <michaelc at cs.wisc.edu>
Date: Thu Mar 22 04:28:19 2012 -0500
Resolves: #739843 #796574
iscsi-initiator-utils-add-rh-ver.patch | 2 +-
...i-initiator-utils-mod-iface-andport-fixes.patch | 1629 ++++++++++++++++++++
iscsi-initiator-utils.spec | 14 +-
3 files changed, 1641 insertions(+), 4 deletions(-)
---
diff --git a/iscsi-initiator-utils-add-rh-ver.patch b/iscsi-initiator-utils-add-rh-ver.patch
index 4d12de6..eb04ce7 100644
--- a/iscsi-initiator-utils-add-rh-ver.patch
+++ b/iscsi-initiator-utils-add-rh-ver.patch
@@ -5,7 +5,7 @@
* some other maintainer could merge a patch without going through us
*/
-#define ISCSI_VERSION_STR "2.0-872"
-+#define ISCSI_VERSION_STR "2.0-872.34.el6"
++#define ISCSI_VERSION_STR "2.0-872.37.el6"
#define ISCSI_VERSION_FILE "/sys/module/scsi_transport_iscsi/version"
#endif
diff --git a/iscsi-initiator-utils-mod-iface-andport-fixes.patch b/iscsi-initiator-utils-mod-iface-andport-fixes.patch
new file mode 100644
index 0000000..99294fc
--- /dev/null
+++ b/iscsi-initiator-utils-mod-iface-andport-fixes.patch
@@ -0,0 +1,1629 @@
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_if.h
+--- open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_if.h 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_if.h 2012-03-22 03:20:29.000000000 -0500
+@@ -270,7 +270,8 @@ struct iscsi_uevent {
+ } host_event;
+ struct msg_ping_comp {
+ uint32_t host_no;
+- uint32_t status;
++ uint32_t status; /* enum
++ * iscsi_ping_status_code */
+ uint32_t pid; /* unique ping id associated
+ with each ping request */
+ uint32_t data_size;
+@@ -515,6 +516,20 @@ enum iscsi_host_param {
+ #define ISCSI_HOST_NETDEV_NAME (1ULL << ISCSI_HOST_PARAM_NETDEV_NAME)
+ #define ISCSI_HOST_IPADDRESS (1ULL << ISCSI_HOST_PARAM_IPADDRESS)
+
++/* iSCSI PING status/error code */
++enum iscsi_ping_status_code {
++ ISCSI_PING_SUCCESS = 0,
++ ISCSI_PING_FW_DISABLED = 0x1,
++ ISCSI_PING_IPADDR_INVALID = 0x2,
++ ISCSI_PING_LINKLOCAL_IPV6_ADDR_INVALID = 0x3,
++ ISCSI_PING_TIMEOUT = 0x4,
++ ISCSI_PING_INVALID_DEST_ADDR = 0x5,
++ ISCSI_PING_OVERSIZE_PACKET = 0x6,
++ ISCSI_PING_ICMP_ERROR = 0x7,
++ ISCSI_PING_MAX_REQ_EXCEEDED = 0x8,
++ ISCSI_PING_NO_ARP_RECEIVED = 0x9,
++};
++
+ #define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
+ #define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
+
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_net_util.h open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_net_util.h
+--- open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_net_util.h 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_net_util.h 2012-03-22 03:29:53.000000000 -0500
+@@ -7,5 +7,6 @@ extern int net_get_transport_name_from_n
+ extern int net_get_netdev_from_hwaddress(char *hwaddress, char *netdev);
+ extern int net_setup_netdev(char *netdev, char *local_ip, char *mask,
+ char *gateway, char *remote_ip, int needs_bringup);
++extern int net_ifup_netdev(char *netdev);
+
+ #endif
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/config.h open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/config.h
+--- open-iscsi-2.0-872-rc4-bnx2i/iscsiuio/include/config.h 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/iscsiuio/include/config.h 2012-03-22 04:03:27.000000000 -0500
+@@ -59,6 +59,9 @@ typedef struct iface_rec {
+ * 1 = enable */
+ uint16_t mtu;
+ uint16_t port;
++ char port_state[ISCSI_MAX_STR_LEN];
++ char port_speed[ISCSI_MAX_STR_LEN];
++
+ /*
+ * TODO: we may have to make this bigger and interconnect
+ * specific for infinniband
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/libiscsi/libiscsi.c open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/libiscsi.c
+--- open-iscsi-2.0-872-rc4-bnx2i/libiscsi/libiscsi.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/libiscsi/libiscsi.c 2012-03-22 03:49:55.000000000 -0500
+@@ -626,12 +626,15 @@ int libiscsi_node_set_parameter(struct l
+ const char *parameter, const char *value)
+ {
+ int nr_found = 0, rc;
+- struct db_set_param set_param = {
+- .name = (char *)parameter,
+- .value = (char *)value,
+- };
++ LIST_HEAD(param_list);
++ struct user_param param;
+
+- CHECK(idbm_for_each_iface(&nr_found, &set_param, idbm_node_set_param,
++ INIT_LIST_HEAD(¶m.list);
++ param.name = (char *)parameter;
++ param.value = (char *)value;
++ list_add_tail(¶m.list, ¶m_list);
++
++ CHECK(idbm_for_each_iface(&nr_found, ¶m_list, idbm_node_set_param,
+ (char *)node->name, node->tpgt,
+ (char *)node->address, node->port))
+ if (nr_found == 0) {
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/config.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/config.h
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/config.h 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/config.h 2012-03-22 03:26:57.000000000 -0500
+@@ -229,6 +229,8 @@ typedef struct iface_rec {
+ * 1 = enable */
+ uint16_t mtu;
+ uint16_t port;
++ char port_state[ISCSI_MAX_STR_LEN];
++ char port_speed[ISCSI_MAX_STR_LEN];
+ /*
+ * TODO: we may have to make this bigger and interconnect
+ * specific for infinniband
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/host.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/host.c
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/host.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/host.c 2012-03-22 03:29:48.000000000 -0500
+@@ -174,6 +174,16 @@ static int print_host_iface(void *data,
+ iface->ipv6_router);
+ }
+
++ if (!strlen(iface->port_state))
++ printf("%sPort State: %s\n", prefix, UNKNOWN_VALUE);
++ else
++ printf("%sPort State: %s\n", prefix, iface->port_state);
++
++ if (!strlen(iface->port_speed))
++ printf("%sPort Speed: %s\n", prefix, UNKNOWN_VALUE);
++ else
++ printf("%sPort Speed: %s\n", prefix, iface->port_speed);
++
+ if (!iface->port)
+ printf("%sPort: %s\n", prefix, UNKNOWN_VALUE);
+ else
+@@ -285,6 +295,7 @@ int host_info_print(int info_level, uint
+ break;
+ }
+
++ transport_probe_for_offload();
+ err = iscsi_sysfs_for_each_host(&flags, &num_found,
+ host_info_print_tree);
+ break;
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.c
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.c 2012-03-22 03:27:12.000000000 -0500
+@@ -2358,70 +2358,83 @@ idbm_slp_defaults(struct iscsi_slp_confi
+ sizeof(struct iscsi_slp_config));
+ }
+
+-int idbm_parse_param(char *param, struct node_rec *rec)
++struct user_param *idbm_alloc_user_param(char *name, char *value)
+ {
+- char *name, *value;
+- recinfo_t *info;
+- int rc;
++ struct user_param *param;
+
+- name = param;
++ param = calloc(1, sizeof(*param));
++ if (!param)
++ return NULL;
+
+- value = strchr(param, '=');
+- if (!value) {
+- log_error("Invalid --param %s. Missing setting.\n", param);
+- return ISCSI_ERR_INVAL;
+- }
+- *value = '\0';
+- value++;
++ INIT_LIST_HEAD(¶m->list);
+
+- info = idbm_recinfo_alloc(MAX_KEYS);
+- if (!info) {
+- log_error("Could not allocate memory to setup params.\n");
+- return ISCSI_ERR_NOMEM;
+- }
++ param->name = strdup(name);
++ if (!param->name)
++ goto free_param;
+
+- idbm_recinfo_node(rec, info);
++ param->value = strdup(value);
++ if (!param->value)
++ goto free_name;
+
+- rc = idbm_rec_update_param(info, name, value, 0);
+- if (rc)
+- log_error("Could not set %s to %s. Check that %s is a "
+- "valid parameter.\n", name, value, name);
+- free(info);
+- return rc;
++ return param;
++
++free_name:
++ free(param->name);
++free_param:
++ free(param);
++ return NULL;
+ }
+
+-int idbm_node_set_param(void *data, node_rec_t *rec)
++int idbm_node_set_rec_from_param(struct list_head *params, node_rec_t *rec,
++ int verify)
+ {
+- struct db_set_param *param = data;
++ struct user_param *param;
+ recinfo_t *info;
+ int rc = 0;
+
++ if (list_empty(params))
++ return 0;
++
+ info = idbm_recinfo_alloc(MAX_KEYS);
+ if (!info)
+ return ISCSI_ERR_NOMEM;
+
+ idbm_recinfo_node(rec, info);
+
+- rc = idbm_verify_param(info, param->name);
+- if (rc)
+- goto free_info;
+-
+- rc = idbm_rec_update_param(info, param->name, param->value, 0);
+- if (rc)
+- goto free_info;
++ if (verify) {
++ list_for_each_entry(param, params, list) {
++ rc = idbm_verify_param(info, param->name);
++ if (rc)
++ goto free_info;
++ }
++ }
+
+- rc = idbm_rec_write(rec);
+- if (rc)
+- goto free_info;
++ list_for_each_entry(param, params, list) {
++ rc = idbm_rec_update_param(info, param->name, param->value, 0);
++ if (rc)
++ goto free_info;
++ }
+
+ free_info:
+ free(info);
+ return rc;
+ }
+
++int idbm_node_set_param(void *data, node_rec_t *rec)
++{
++ int rc;
++
++ rc = idbm_node_set_rec_from_param(data, rec, 1);
++ if (rc)
++ return rc;
++
++ return idbm_rec_write(rec);
++}
++
+ int idbm_discovery_set_param(void *data, discovery_rec_t *rec)
+ {
+- struct db_set_param *param = data;
++ struct list_head *params = data;
++ struct user_param *param;
+ recinfo_t *info;
+ int rc = 0;
+
+@@ -2431,13 +2444,17 @@ int idbm_discovery_set_param(void *data,
+
+ idbm_recinfo_discovery((discovery_rec_t *)rec, info);
+
+- rc = idbm_verify_param(info, param->name);
+- if (rc)
+- goto free_info;
++ list_for_each_entry(param, params, list) {
++ rc = idbm_verify_param(info, param->name);
++ if (rc)
++ goto free_info;
++ }
+
+- rc = idbm_rec_update_param(info, param->name, param->value, 0);
+- if (rc)
+- goto free_info;
++ list_for_each_entry(param, params, list) {
++ rc = idbm_rec_update_param(info, param->name, param->value, 0);
++ if (rc)
++ goto free_info;
++ }
+
+ rc = idbm_discovery_write((discovery_rec_t *)rec);
+ if (rc)
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.h
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.h 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.h 2012-03-22 03:48:10.000000000 -0500
+@@ -26,6 +26,7 @@
+ #include <sys/types.h>
+ #include "initiator.h"
+ #include "config.h"
++#include "list.h"
+
+ #define ISCSIVAR "/var/lib/iscsi/"
+
+@@ -82,7 +83,9 @@ typedef struct idbm {
+ discovery_rec_t drec_isns;
+ recinfo_t dinfo_isns[MAX_KEYS];
+ } idbm_t;
+-struct db_set_param {
++
++struct user_param {
++ struct list_head list;
+ char *name;
+ char *value;
+ };
+@@ -145,9 +148,11 @@ extern int idbm_discovery_read(discovery
+ extern int idbm_rec_read(node_rec_t *out_rec, char *target_name,
+ int tpgt, char *addr, int port,
+ struct iface_rec *iface);
+-extern int idbm_parse_param(char *param, struct node_rec *rec);
++extern int idbm_node_set_rec_from_param(struct list_head *params,
++ node_rec_t *rec, int verify);
+ extern int idbm_node_set_param(void *data, node_rec_t *rec);
+ extern int idbm_discovery_set_param(void *data, discovery_rec_t *rec);
++struct user_param *idbm_alloc_user_param(char *name, char *value);
+ extern void idbm_node_setup_defaults(node_rec_t *rec);
+ extern struct node_rec *idbm_find_rec_in_list(struct list_head *rec_list,
+ char *targetname, char *addr,
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.c
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/iface.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.c 2012-03-22 03:28:52.000000000 -0500
+@@ -169,7 +169,7 @@ free_conf:
+ int iface_conf_read(struct iface_rec *iface)
+ {
+ struct iface_rec *def_iface;
+- int rc;
++ int rc, retry = 0;
+
+ def_iface = iface_match_default(iface);
+ if (def_iface) {
+@@ -197,12 +197,24 @@ int iface_conf_read(struct iface_rec *if
+ return 0;
+ }
+
++retry_read:
+ rc = idbm_lock();
+ if (rc)
+ return rc;
+
+ rc = __iface_conf_read(iface);
+ idbm_unlock();
++
++ /*
++ * cmd was run before running -m iface, so force def bindings
++ * creation to see if that was the one requested
++ */
++ if (retry < 1 && rc == ISCSI_ERR_IDBM) {
++ iface_setup_host_bindings();
++ retry++;
++ goto retry_read;
++ }
++
+ return rc;
+ }
+
+@@ -277,11 +289,11 @@ free_conf:
+ return rc;
+ }
+
+-int iface_conf_update(struct db_set_param *param,
+- struct iface_rec *iface)
++int iface_conf_update(struct list_head *params, struct iface_rec *iface)
+ {
+ struct iface_rec *def_iface;
+ recinfo_t *info;
++ struct user_param *param;
+ int rc = 0;
+
+ def_iface = iface_match_default(iface);
+@@ -296,13 +308,18 @@ int iface_conf_update(struct db_set_para
+ return ISCSI_ERR_NOMEM;
+
+ idbm_recinfo_iface(iface, info);
+- rc = idbm_verify_param(info, param->name);
+- if (rc)
+- goto free_info;
+
+- rc = idbm_rec_update_param(info, param->name, param->value, 0);
+- if (rc)
+- goto free_info;
++ list_for_each_entry(param, params, list) {
++ rc = idbm_verify_param(info, param->name);
++ if (rc)
++ goto free_info;
++ }
++
++ list_for_each_entry(param, params, list) {
++ rc = idbm_rec_update_param(info, param->name, param->value, 0);
++ if (rc)
++ goto free_info;
++ }
+
+ rc = iface_conf_write(iface);
+ free_info:
+@@ -449,6 +466,7 @@ static int iface_setup_binding_from_kern
+ {
+ struct host_info *hinfo = data;
+ struct iface_rec iface;
++ char iface_path[PATH_MAX];
+
+ if (!strlen(hinfo->iface.hwaddress)) {
+ log_error("Invalid offload iSCSI host %u. Missing "
+@@ -474,7 +492,11 @@ static int iface_setup_binding_from_kern
+ hinfo->iface.transport_name, hinfo->iface.hwaddress);
+ }
+
+- if (iface_conf_read(&iface)) {
++ memset(iface_path, 0, sizeof(iface_path));
++ snprintf(iface_path, PATH_MAX, "%s/%s", IFACE_CONFIG_DIR,
++ iface.name);
++
++ if (access(iface_path, F_OK) != 0) {
+ /* not found so create it */
+ if (iface_conf_write(&iface)) {
+ log_error("Could not create default iface conf %s.",
+@@ -532,6 +554,8 @@ void iface_setup_host_bindings(void)
+ }
+ idbm_unlock();
+
++ transport_probe_for_offload();
++
+ if (iscsi_sysfs_for_each_host(NULL, &nr_found,
+ __iface_setup_host_bindings))
+ log_error("Could not scan scsi hosts. HW/OFFLOAD iscsi "
+@@ -869,7 +893,8 @@ void iface_link_ifaces(struct list_head
+ int iface_setup_from_boot_context(struct iface_rec *iface,
+ struct boot_context *context)
+ {
+- struct iscsi_transport *t;
++ struct iscsi_transport *t = NULL;
++ char transport_name[ISCSI_TRANSPORT_NAME_MAXLEN];
+ uint32_t hostno;
+ int rc;
+
+@@ -884,6 +909,12 @@ int iface_setup_from_boot_context(struct
+ return 0;
+ }
+ } else if (strlen(context->iface)) {
++ memset(transport_name, 0, ISCSI_TRANSPORT_NAME_MAXLEN);
++ /* make sure offload driver is loaded */
++ if (!net_get_transport_name_from_netdev(context->iface,
++ transport_name))
++ t = iscsi_sysfs_get_transport_by_name(transport_name);
++
+ hostno = iscsi_sysfs_get_host_no_from_hwaddress(context->mac,
+ &rc);
+ if (rc) {
+@@ -904,7 +935,8 @@ int iface_setup_from_boot_context(struct
+ /*
+ * set up for access through a offload card.
+ */
+- t = iscsi_sysfs_get_transport_by_hba(hostno);
++ if (!t)
++ t = iscsi_sysfs_get_transport_by_hba(hostno);
+ if (!t) {
+ log_error("Could not get transport for host%u. "
+ "Make sure the iSCSI driver is loaded.",
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iface.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.h
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/iface.h 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.h 2012-03-22 03:25:44.000000000 -0500
+@@ -26,7 +26,6 @@
+
+ struct iface_rec;
+ struct list_head;
+-struct db_set_param;
+ struct boot_context;
+
+ extern void iface_copy(struct iface_rec *dst, struct iface_rec *src);
+@@ -46,7 +45,7 @@ extern int iface_print_tree(void *data,
+ extern void iface_setup_host_bindings(void);
+ extern int iface_get_by_net_binding(struct iface_rec *pattern,
+ struct iface_rec *out_rec);
+-extern int iface_conf_update(struct db_set_param *set_param,
++extern int iface_conf_update(struct list_head *params,
+ struct iface_rec *iface);
+ extern int iface_conf_write(struct iface_rec *iface);
+ extern int iface_conf_delete(struct iface_rec *iface);
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator_common.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator_common.c
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/initiator_common.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator_common.c 2012-03-22 03:30:25.000000000 -0500
+@@ -35,6 +35,7 @@
+ #include "host.h"
+ #include "sysdeps.h"
+ #include "iscsi_err.h"
++#include "iscsi_net_util.h"
+
+ struct iscsi_session *session_find_by_sid(uint32_t sid)
+ {
+@@ -596,6 +597,8 @@ int iscsi_host_set_net_params(struct ifa
+ {
+ struct iscsi_transport *t = session->t;
+ int rc = 0;
++ char *netdev;
++ struct host_info hinfo;
+
+ log_debug(3, "setting iface %s, dev %s, set ip %s, hw %s, "
+ "transport %s.\n",
+@@ -612,6 +615,21 @@ int iscsi_host_set_net_params(struct ifa
+ return EINVAL;
+ }
+
++ /* these type of drivers need the netdev upd */
++ if (strlen(iface->netdev))
++ netdev = iface->netdev;
++ else {
++ memset(&hinfo, 0, sizeof(hinfo));
++ hinfo.host_no = session->hostno;
++ iscsi_sysfs_get_hostinfo_by_host_no(&hinfo);
++
++ netdev = hinfo.iface.netdev;
++ }
++
++ if (net_ifup_netdev(netdev))
++ log_warning("Could not brining up netdev %s. Try running "
++ "'ifup %s' first if login fails.", netdev, netdev);
++
+ rc = iscsi_set_net_config(t, session, iface);
+ if (rc != 0)
+ return rc;
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsiadm.c
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsiadm.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsiadm.c 2012-03-22 03:29:48.000000000 -0500
+@@ -1116,6 +1116,17 @@ do_sendtargets(discovery_rec_t *drec, st
+ free(iface);
+ continue;
+ }
++ /* check for transport name first to make sure it is loaded */
++ t = iscsi_sysfs_get_transport_by_name(iface->transport_name);
++ if (!t) {
++ log_error("Could not load transport %s."
++ "Dropping interface %s.",
++ iface->transport_name, iface->name);
++ list_del(&iface->list);
++ free(iface);
++ continue;
++ }
++
+ host_no = iscsi_sysfs_get_host_no_from_hwinfo(iface, &rc);
+ if (rc || host_no == -1) {
+ log_debug(1, "Could not match iface" iface_fmt " to "
+@@ -1124,18 +1135,6 @@ do_sendtargets(discovery_rec_t *drec, st
+ continue;
+ }
+
+- t = iscsi_sysfs_get_transport_by_hba(host_no);
+- if (!t) {
+- log_error("Could not match hostno %d to "
+- "transport. Dropping interface %s,"
+- iface_fmt " ,%s.",
+- host_no, iface->transport_name,
+- iface_str(iface), iface->ipaddress);
+- list_del(&iface->list);
+- free(iface);
+- continue;
+- }
+-
+ if (t->caps & CAP_SENDTARGETS_OFFLOAD) {
+ do_offload_sendtargets(drec, host_no, do_login);
+ list_del(&iface->list);
+@@ -1346,8 +1345,6 @@ get_chap:
+ goto exit_chap_info;
+ }
+
+- log_info("Valid CHAP Entries = %d\n", valid_chap_entries);
+-
+ crec = (struct iscsi_chap_rec *) (req_buf +
+ sizeof(struct iscsi_uevent));
+
+@@ -1440,13 +1437,45 @@ static int exec_host_chap_op(int op, int
+ return rc;
+ }
+
++static int verify_iface_params(struct list_head *params, struct node_rec *rec)
++{
++ struct user_param *param;
++
++ list_for_each_entry(param, params, list) {
++ if (!strcmp(param->name, IFACE_ISCSINAME)) {
++ log_error("Can not update "
++ "iface.iscsi_ifacename. Delete it, "
++ "and then create a new one.");
++ return ISCSI_ERR_INVAL;
++ }
++
++ if (iface_is_bound_by_hwaddr(&rec->iface) &&
++ !strcmp(param->name, IFACE_NETNAME)) {
++ log_error("Can not update interface binding "
++ "from hwaddress to net_ifacename. "
++ "You must delete the interface and "
++ "create a new one");
++ return ISCSI_ERR_INVAL;
++ }
++
++ if (iface_is_bound_by_netdev(&rec->iface) &&
++ !strcmp(param->name, IFACE_HWADDR)) {
++ log_error("Can not update interface binding "
++ "from net_ifacename to hwaddress. "
++ "You must delete the interface and "
++ "create a new one");
++ return ISCSI_ERR_INVAL;
++ }
++ }
++ return 0;
++}
++
+ /* TODO: merge iter helpers and clean them up, so we can use them here */
+ static int exec_iface_op(int op, int do_show, int info_level,
+ struct iface_rec *iface, uint32_t host_no,
+- char *name, char *value)
++ struct list_head *params)
+ {
+ struct host_info hinfo;
+- struct db_set_param set_param;
+ struct node_rec *rec = NULL;
+ int rc = 0;
+
+@@ -1502,7 +1531,7 @@ delete_fail:
+ iscsi_err_to_str(rc));
+ break;
+ case OP_UPDATE:
+- if (!iface || !name || !value) {
++ if (!iface || list_empty(params)) {
+ log_error("Update requires name, value, and iface.");
+ rc = ISCSI_ERR_INVAL;
+ break;
+@@ -1520,42 +1549,16 @@ delete_fail:
+ "sessions then log back in for the "
+ "new settings to take affect.");
+
+- if (!strcmp(name, IFACE_ISCSINAME)) {
+- log_error("Can not update "
+- "iface.iscsi_ifacename. Delete it, "
+- "and then create a new one.");
+- rc = ISCSI_ERR_INVAL;
+- break;
+- }
+-
+- if (iface_is_bound_by_hwaddr(&rec->iface) &&
+- !strcmp(name, IFACE_NETNAME)) {
+- log_error("Can not update interface binding "
+- "from hwaddress to net_ifacename. ");
+- log_error("You must delete the interface and "
+- "create a new one");
+- rc = ISCSI_ERR_INVAL;
+- break;
+- }
+-
+- if (iface_is_bound_by_netdev(&rec->iface) &&
+- !strcmp(name, IFACE_HWADDR)) {
+- log_error("Can not update interface binding "
+- "from net_ifacename to hwaddress. ");
+- log_error("You must delete the interface and "
+- "create a new one");
+- rc = ISCSI_ERR_INVAL;
++ rc = verify_iface_params(params, rec);
++ if (rc)
+ break;
+- }
+- set_param.name = name;
+- set_param.value = value;
+
+ /* pass rec's iface because it has the db values */
+- rc = iface_conf_update(&set_param, &rec->iface);
++ rc = iface_conf_update(params, &rec->iface);
+ if (rc)
+ goto update_fail;
+
+- rc = __for_each_matched_rec(0, rec, &set_param,
++ rc = __for_each_matched_rec(0, rec, params,
+ idbm_node_set_param);
+ if (rc == ISCSI_ERR_NO_OBJS_FOUND)
+ rc = 0;
+@@ -1638,14 +1641,62 @@ update_fail:
+ return rc;
+ }
+
++static int verify_node_params(struct list_head *params, struct node_rec *rec)
++{
++ struct user_param *param;
++
++ if (list_empty(params)) {
++ log_error("update requires name and value");
++ return ISCSI_ERR_INVAL;
++ }
++
++ list_for_each_entry(param, params, list) {
++ /* compat - old tools used node and iface transport name */
++ if (!strncmp(param->name, "iface.", 6) &&
++ strcmp(param->name, "iface.transport_name")) {
++ log_error("Cannot modify %s. Use iface mode to update "
++ "this value.", param->name);
++ return ISCSI_ERR_INVAL;
++ }
++
++ if (!strcmp(param->name, "node.transport_name")) {
++ free(param->name);
++ param->name = strdup("iface.transport_name");
++ if (!param->name) {
++ log_error("Could not allocate memory for "
++ "param.");
++ return ISCSI_ERR_NOMEM;
++ }
++ }
++ /*
++ * tmp hack - we added compat crap above for the transport,
++ * but want to fix Doran's issue in this release too. However
++ * his patch is too harsh on many settings and we do not have
++ * time to update apps so we have this tmp hack until we
++ * can settle on a good interface that distros can use
++ * and we can mark stable.
++ */
++ if (!strcmp(param->name, "iface.transport_name")) {
++ if (iscsi_check_for_running_session(rec)) {
++ log_warning("Cannot modify node/iface "
++ "transport name while a session "
++ "is using it. Log out the session "
++ "then update record.");
++ return ISCSI_ERR_SESS_EXISTS;
++ }
++ }
++ }
++
++ return 0;
++}
++
+ /* TODO cleanup arguments */
+ static int exec_node_op(int op, int do_login, int do_logout,
+ int do_show, int do_rescan, int do_stats,
+ int info_level, struct node_rec *rec,
+- char *name, char *value)
++ struct list_head *params)
+ {
+ int rc = 0;
+- struct db_set_param set_param;
+
+ if (rec)
+ log_debug(2, "%s: %s:%s node [%s,%s,%d] sid %u", __FUNCTION__,
+@@ -1708,46 +1759,11 @@ static int exec_node_op(int op, int do_l
+ }
+
+ if (op == OP_UPDATE) {
+- if (!name || !value) {
+- log_error("update requires name and value");
+- rc = ISCSI_ERR_INVAL;
+- goto out;
+- }
+-
+- /* compat - old tools used node and iface transport name */
+- if (!strncmp(name, "iface.", 6) &&
+- strcmp(name, "iface.transport_name")) {
+- log_error("Cannot modify %s. Use iface mode to update "
+- "this value.", name);
+- rc = ISCSI_ERR_INVAL;
++ rc = verify_node_params(params, rec);
++ if (rc)
+ goto out;
+- }
+
+- if (!strcmp(name, "node.transport_name"))
+- name = "iface.transport_name";
+- /*
+- * tmp hack - we added compat crap above for the transport,
+- * but want to fix Doran's issue in this release too. However
+- * his patch is too harsh on many settings and we do not have
+- * time to update apps so we have this tmp hack until we
+- * can settle on a good interface that distros can use
+- * and we can mark stable.
+- */
+- if (!strcmp(name, "iface.transport_name")) {
+- if (iscsi_check_for_running_session(rec)) {
+- log_warning("Cannot modify node/iface "
+- "transport name while a session "
+- "is using it. Log out the session "
+- "then update record.");
+- rc = ISCSI_ERR_SESS_EXISTS;
+- goto out;
+- }
+- }
+-
+- set_param.name = name;
+- set_param.value = value;
+-
+- rc = for_each_matched_rec(rec, &set_param, idbm_node_set_param);
++ rc = for_each_matched_rec(rec, params, idbm_node_set_param);
+ goto out;
+ } else if (op == OP_DELETE) {
+ rc = for_each_matched_rec(rec, NULL, delete_node);
+@@ -2002,7 +2018,7 @@ static int exec_discover(int disc_type,
+
+ static int exec_disc2_op(int disc_type, char *ip, int port,
+ struct list_head *ifaces, int info_level, int do_login,
+- int do_discover, int op, char *name, char *value,
++ int do_discover, int op, struct list_head *params,
+ int do_show)
+ {
+ struct discovery_rec drec;
+@@ -2081,16 +2097,12 @@ do_db_op:
+ if (rc)
+ log_error("Unable to delete record!");
+ } else if (op == OP_UPDATE) {
+- struct db_set_param set_param;
+-
+- if (!name || !value) {
++ if (list_empty(params)) {
+ log_error("Update requires name and value.");
+ rc = ISCSI_ERR_INVAL;
+ goto done;
+ }
+- set_param.name = name;
+- set_param.value = value;
+- rc = idbm_discovery_set_param(&set_param, &drec);
++ rc = idbm_discovery_set_param(params, &drec);
+ } else {
+ log_error("Operation is not supported.");
+ rc = ISCSI_ERR_INVAL;
+@@ -2102,7 +2114,7 @@ done:
+
+ static int exec_disc_op(int disc_type, char *ip, int port,
+ struct list_head *ifaces, int info_level, int do_login,
+- int do_discover, int op, char *name, char *value,
++ int do_discover, int op, struct list_head *params,
+ int do_show)
+ {
+ struct discovery_rec drec;
+@@ -2228,6 +2240,8 @@ static uint32_t parse_host_info(char *op
+
+ *rc = 0;
+ if (strstr(optarg, ":")) {
++ transport_probe_for_offload();
++
+ host_no = iscsi_sysfs_get_host_no_from_hwaddress(optarg,
+ &err);
+ if (err) {
+@@ -2245,13 +2259,46 @@ static uint32_t parse_host_info(char *op
+ return host_no;
+ }
+
++static char *iscsi_ping_stat_strs[] = {
++ /* ISCSI_PING_SUCCESS */
++ "success",
++ /* ISCSI_PING_FW_DISABLED */
++ "firmware disabled",
++ /* ISCSI_PING_IPADDR_INVALID */
++ "invalid IP address",
++ /* ISCSI_PING_LINKLOCAL_IPV6_ADDR_INVALID */
++ "invalid link local IPv6 address",
++ /* ISCSI_PING_TIMEOUT */
++ "timed out",
++ /* ISCSI_PING_INVALID_DEST_ADDR */
++ "invalid destination address",
++ /* ISCSI_PING_OVERSIZE_PACKET */
++ "oversized packet",
++ /* ISCSI_PING_ICMP_ERROR */
++ "ICMP error",
++ /* ISCSI_PING_MAX_REQ_EXCEEDED */
++ "Max request exceeded",
++ /* ISCSI_PING_NO_ARP_RECEIVED */
++ "No ARP response received",
++};
++
++static char *iscsi_ping_stat_to_str(uint32_t status)
++{
++ if (status < 0 || status > ISCSI_PING_NO_ARP_RECEIVED) {
++ log_error("Invalid ping status %u\n", status);
++ return NULL;
++ }
++
++ return iscsi_ping_stat_strs[status];
++}
++
+ static int exec_ping_op(struct iface_rec *iface, char *ip, int size, int count,
+ int interval)
+ {
+ int rc = ISCSI_ERR;
+ uint32_t iface_type = ISCSI_IFACE_TYPE_IPV4;
+ struct iscsi_transport *t = NULL;
+- uint32_t host_no;
++ uint32_t host_no, status = 0;
+ struct sockaddr_storage addr;
+ int i;
+
+@@ -2324,11 +2371,15 @@ static int exec_ping_op(struct iface_rec
+ * the iscsi if to send a ping, we can add a transport
+ * callout here.
+ */
++ status = 0;
+ rc = ipc->exec_ping(t->handle, host_no,
+ (struct sockaddr *)&addr, iface->iface_num,
+- iface_type, size);
+- if (!rc)
++ iface_type, size, &status);
++ if (!rc && !status)
+ printf("Ping %d completed\n", i);
++ else if (status)
++ printf("Ping %d failed: %s\n", i,
++ iscsi_ping_stat_to_str(status));
+ else
+ printf("Ping %d failed: %s\n", i, iscsi_err_to_str(rc));
+
+@@ -2357,7 +2408,10 @@ main(int argc, char **argv)
+ struct iface_rec *iface = NULL, *tmp;
+ struct node_rec *rec = NULL;
+ uint32_t host_no = -1;
++ struct user_param *param;
++ struct list_head params;
+
++ INIT_LIST_HEAD(¶ms);
+ INIT_LIST_HEAD(&ifaces);
+ /* do not allow ctrl-c for now... */
+ memset(&sa_old, 0, sizeof(struct sigaction));
+@@ -2499,6 +2553,18 @@ main(int argc, char **argv)
+ case 'h':
+ usage(0);
+ }
++
++ if (name && value) {
++ param = idbm_alloc_user_param(name, value);
++ if (!param) {
++ log_error("Cannot allocate memory for params.");
++ rc = ISCSI_ERR_NOMEM;
++ goto free_ifaces;
++ }
++ list_add_tail(¶m->list, ¶ms);
++ name = NULL;
++ value = NULL;
++ }
+ }
+
+ if (optopt) {
+@@ -2585,7 +2651,7 @@ main(int argc, char **argv)
+ ping_interval);
+ else
+ rc = exec_iface_op(op, do_show, info_level, iface,
+- host_no, name, value);
++ host_no, ¶ms);
+
+ break;
+ case MODE_DISCOVERYDB:
+@@ -2597,7 +2663,7 @@ main(int argc, char **argv)
+ }
+
+ rc = exec_disc2_op(type, ip, port, &ifaces, info_level,
+- do_login, do_discover, op, name, value,
++ do_login, do_discover, op, ¶ms,
+ do_show);
+ break;
+ case MODE_DISCOVERY:
+@@ -2609,7 +2675,7 @@ main(int argc, char **argv)
+ }
+
+ rc = exec_disc_op(type, ip, port, &ifaces, info_level,
+- do_login, do_discover, op, name, value,
++ do_login, do_discover, op, ¶ms,
+ do_show);
+ break;
+ case MODE_NODE:
+@@ -2653,7 +2719,7 @@ main(int argc, char **argv)
+
+ rc = exec_node_op(op, do_login, do_logout, do_show,
+ do_rescan, do_stats, info_level, rec,
+- name, value);
++ ¶ms);
+ break;
+ case MODE_SESSION:
+ if ((rc = verify_mode_params(argc, argv,
+@@ -2723,7 +2789,7 @@ main(int argc, char **argv)
+ /* drop down to node ops */
+ rc = exec_node_op(op, do_login, do_logout, do_show,
+ do_rescan, do_stats, info_level,
+- rec, name, value);
++ rec, ¶ms);
+ free_info:
+ free(info);
+ goto out;
+@@ -2737,7 +2803,7 @@ free_info:
+ if (do_logout || do_rescan || do_stats) {
+ rc = exec_node_op(op, do_login, do_logout,
+ do_show, do_rescan, do_stats,
+- info_level, NULL, name, value);
++ info_level, NULL, ¶ms);
+ goto out;
+ }
+
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid.c
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid.c 2012-03-22 03:25:35.000000000 -0500
+@@ -409,11 +409,6 @@ int main(int argc, char *argv[])
+ exit(ISCSI_ERR);
+ }
+
+- if (iscsi_sysfs_check_class_version()) {
+- log_close(log_pid);
+- exit(ISCSI_ERR);
+- }
+-
+ umask(0177);
+
+ mgmt_ipc_fd = -1;
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_ipc.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_ipc.h
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_ipc.h 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_ipc.h 2012-03-22 03:20:29.000000000 -0500
+@@ -137,7 +137,7 @@ struct iscsi_ipc {
+
+ int (*exec_ping) (uint64_t transport_handle, uint32_t host_no,
+ struct sockaddr *addr, uint32_t iface_num,
+- uint32_t iface_type, uint32_t size);
++ uint32_t iface_type, uint32_t size, uint32_t *status);
+
+ int (*get_chap) (uint64_t transport_handle, uint32_t host_no,
+ uint16_t chap_tbl_idx, uint32_t num_entries,
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_net_util.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_net_util.c
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_net_util.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_net_util.c 2012-03-22 03:29:53.000000000 -0500
+@@ -72,7 +72,7 @@ int net_get_transport_name_from_netdev(c
+ ifr.ifr_data = (caddr_t)&drvinfo;
+ err = ioctl(fd, SIOCETHTOOL, &ifr);
+ if (err < 0) {
+- log_error("Could not get driver.");
++ log_error("Could not get driver %s.", netdev);
+ err = errno;
+ goto close_sock;
+ }
+@@ -304,6 +304,59 @@ int net_setup_netdev(char *netdev, char
+ done:
+ close(sock);
+ return ret;
++}
++
++/**
++ * net_ifup_netdev - bring up network interface
++ * @netdev: netdevice to bring up.
++ */
++int net_ifup_netdev(char *netdev)
++{
++ struct ifreq ifr;
++ int sock;
++ int ret = 0;
++
++ if (!strlen(netdev)) {
++ log_error("No netdev name in fw entry.\n");
++ return EINVAL;
++ }
++
++ /* Create socket for making networking changes */
++ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
++ log_error("Could not open socket to manage network "
++ "(err %d - %s)", errno, strerror(errno));
++ return errno;
++ }
++
++ memset(&ifr, 0, sizeof(ifr));
++ strncpy(ifr.ifr_name, netdev, IFNAMSIZ);
++ if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
++ log_error("Could not bring up netdev %s (err %d - %s)",
++ netdev, errno, strerror(errno));
++ ret = errno;
++ goto done;
++ }
++
++ if (ifr.ifr_flags & IFF_UP) {
++ log_debug(3, "%s up\n", netdev);
++ goto done;
++ }
++
++ log_debug(3, "bringing %s up\n", netdev);
++
++ /* Bring up interface */
++ memset(&ifr, 0, sizeof(ifr));
++ strncpy(ifr.ifr_name, netdev, IFNAMSIZ);
++ ifr.ifr_flags = IFF_UP;
++ if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
++ log_error("Could not bring up netdev %s (err %d - %s)",
++ netdev, errno, strerror(errno));
++ ret = errno;
++ goto done;
++ }
++done:
++ close(sock);
++ return ret;
+ }
+
+
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsistart.c
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsistart.c 2012-03-22 03:29:42.000000000 -0500
+@@ -40,6 +40,7 @@
+ #include "log.h"
+ #include "iscsi_util.h"
+ #include "idbm.h"
++#include "idbm_fields.h"
+ #include "version.h"
+ #include "iscsi_sysfs.h"
+ #include "iscsi_settings.h"
+@@ -48,6 +49,7 @@
+ #include "sysdeps.h"
+ #include "iscsid_req.h"
+ #include "iscsi_err.h"
++#include "iface.h"
+
+ /* global config info */
+ /* initiator needs initiator name/alias */
+@@ -58,11 +60,6 @@ static node_rec_t config_rec;
+ static LIST_HEAD(targets);
+ static LIST_HEAD(user_params);
+
+-struct user_param {
+- struct list_head list;
+- char *param_string;
+-};
+-
+ static char program_name[] = "iscsistart";
+
+ /* used by initiator */
+@@ -145,11 +142,34 @@ static int apply_params(struct node_rec
+ rec->conn[0].timeo.noop_out_timeout = -1;
+
+ list_for_each_entry(param, &user_params, list) {
+- rc = idbm_parse_param(param->param_string, rec);
+- if (rc)
+- return rc;
++ /*
++ * user may not have passed in all params that were set by
++ * ibft/iscsi_boot, so clear out values that might conflict
++ * with user overrides
++ */
++ if (!strcmp(param->name, IFACE_NETNAME)) {
++ /* overriding netname so MAC will be for old netdev */
++ memset(rec->iface.hwaddress, 0,
++ sizeof(rec->iface.hwaddress));
++ } else if (!strcmp(param->name, IFACE_HWADDR)) {
++ /* overriding MAC so netdev will be for old MAC */
++ memset(rec->iface.netdev, 0, sizeof(rec->iface.netdev));
++ } else if (!strcmp(param->name, IFACE_TRANSPORTNAME)) {
++ /*
++ * switching drivers so all old binding info is no
++ * longer valid. Old values were either for offload
++ * and we are switching to software or the reverse,
++ * or switching types of cards (bnx2i to cxgb3i).
++ */
++ memset(&rec->iface, 0, sizeof(rec->iface));
++ iface_setup_defaults(&rec->iface);
++ }
+ }
+
++ rc = idbm_node_set_rec_from_param(&user_params, rec, 0);
++ if (rc)
++ return rc;
++
+ /*
+ * For root boot we could not change this in older versions so
+ * if user did not override then use the defaults.
+@@ -167,23 +187,32 @@ static int apply_params(struct node_rec
+ return 0;
+ }
+
+-static int alloc_param(char *param_string)
++static int parse_param(char *param_str)
+ {
+ struct user_param *param;
++ char *name, *value;
+
+- param = calloc(1, sizeof(*param));
+- if (!param) {
+- printf("Could not allocate for param.\n");
+- return ISCSI_ERR_NOMEM;
++ name = param_str;
++
++ value = strchr(param_str, '=');
++ if (!value) {
++ log_error("Invalid --param %s. Missing value.", param_str);
++ return ISCSI_ERR_INVAL;
++ }
++ *value = '\0';
++
++ value++;
++ if (!strlen(value)) {
++ log_error("Invalid --param %s. Missing value.", param_str);
++ return ISCSI_ERR_INVAL;
+ }
+
+- INIT_LIST_HEAD(¶m->list);
+- param->param_string = strdup(param_string);
+- if (!param->param_string) {
+- printf("Could not allocate for param.\n");
+- free(param);
++ param = idbm_alloc_user_param(name, value);
++ if (!param) {
++ log_error("Could not allocate memory for param.");
+ return ISCSI_ERR_NOMEM;
+ }
++
+ list_add(¶m->list, &user_params);
+ return 0;
+ }
+@@ -316,8 +345,6 @@ int main(int argc, char *argv[])
+ log_init(program_name, DEFAULT_AREA_SIZE, log_do_log_std, NULL);
+
+ sysfs_init();
+- if (iscsi_sysfs_check_class_version())
+- exit(ISCSI_ERR_SYSFS_LOOKUP);
+
+ while ((ch = getopt_long(argc, argv, "P:i:t:g:a:p:d:u:w:U:W:bNfvh",
+ long_options, &longindex)) >= 0) {
+@@ -399,7 +426,7 @@ int main(int argc, char *argv[])
+ fw_free_targets(&targets);
+ exit(0);
+ case 'P':
+- err = alloc_param(optarg);
++ err = parse_param(optarg);
+ if (err)
+ exit(err);
+ break;
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.c
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.c 2012-03-22 03:27:02.000000000 -0500
+@@ -532,6 +532,12 @@ static int iscsi_sysfs_read_iface(struct
+ ret = 0;
+ }
+
++ sysfs_get_str(host_id, ISCSI_HOST_SUBSYS, "port_state",
++ iface->port_state, sizeof(iface->port_state));
++
++ sysfs_get_str(host_id, ISCSI_HOST_SUBSYS, "port_speed",
++ iface->port_speed, sizeof(iface->port_speed));
++
+ /*
+ * this is on the session, because we support multiple bindings
+ * per device.
+@@ -1144,13 +1150,31 @@ static uint32_t get_target_no_from_sid(u
+
+ }
+
++int iscsi_sysfs_is_transport_loaded(char *transport_name)
++{
++ struct iscsi_transport *t;
++
++ /* sync up kernel and userspace */
++ read_transports();
++
++ /* check if the transport is loaded and matches */
++ list_for_each_entry(t, &transports, list) {
++ if (t->handle && !strncmp(t->name, transport_name,
++ ISCSI_TRANSPORT_NAME_MAXLEN))
++ return 1;
++ }
++
++ return 0;
++}
++
+ struct iscsi_transport *iscsi_sysfs_get_transport_by_name(char *transport_name)
+ {
+ struct iscsi_transport *t;
++ int retry = 0;
+
++retry:
+ /* sync up kernel and userspace */
+- if (read_transports())
+- return NULL;
++ read_transports();
+
+ /* check if the transport is loaded and matches */
+ list_for_each_entry(t, &transports, list) {
+@@ -1158,6 +1182,13 @@ struct iscsi_transport *iscsi_sysfs_get_
+ ISCSI_TRANSPORT_NAME_MAXLEN))
+ return t;
+ }
++
++ if (retry < 1) {
++ retry++;
++ if (!transport_load_kmod(transport_name))
++ goto retry;
++ }
++
+ return NULL;
+ }
+
+@@ -1366,40 +1397,3 @@ char *iscsi_sysfs_get_iscsi_kernel_versi
+ {
+ return sysfs_attr_get_value("/module/scsi_transport_iscsi", "version");
+ }
+-
+-int iscsi_sysfs_check_class_version(void)
+-{
+- char *version;
+- int i;
+-
+- version = iscsi_sysfs_get_iscsi_kernel_version();
+- if (!version)
+- goto fail;
+-
+- log_warning("transport class version %s. iscsid version %s",
+- version, ISCSI_VERSION_STR);
+-
+- for (i = 0; i < strlen(version); i++) {
+- if (version[i] == '-')
+- break;
+- }
+-
+- if (i == strlen(version))
+- goto fail;
+-
+- /*
+- * We want to make sure the release and interface are the same.
+- * It is ok for the svn versions to be different.
+- */
+- if (!strncmp(version, ISCSI_VERSION_STR, i) ||
+- /* support 2.6.18 */
+- !strncmp(version, "1.1", 3))
+- return 0;
+-
+-fail:
+- log_error( "Missing or Invalid version from %s. Make sure a up "
+- "to date scsi_transport_iscsi module is loaded and a up to"
+- "date version of iscsid is running. Exiting...",
+- ISCSI_VERSION_FILE);
+- return -1;
+-}
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.h
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_sysfs.h 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.h 2012-03-22 03:27:02.000000000 -0500
+@@ -36,7 +36,6 @@ struct iscsi_auth_config;
+
+ extern void free_transports(void);
+ extern char *iscsi_sysfs_get_iscsi_kernel_version(void);
+-extern int iscsi_sysfs_check_class_version(void);
+ extern int iscsi_sysfs_get_sessioninfo_by_id(struct session_info *info,
+ char *sys_session);
+ extern int iscsi_sysfs_session_has_leadconn(uint32_t sid);
+@@ -89,6 +88,7 @@ extern struct iscsi_transport *iscsi_sys
+ extern struct iscsi_transport *iscsi_sysfs_get_transport_by_session(char *sys_session);
+ extern struct iscsi_transport *iscsi_sysfs_get_transport_by_sid(uint32_t sid);
+ extern struct iscsi_transport *iscsi_sysfs_get_transport_by_name(char *transport_name);
++extern int iscsi_sysfs_is_transport_loaded(char *transport_name);
+ extern int iscsi_sysfs_session_supports_nop(int sid);
+ extern int iscsi_sysfs_session_user_created(int sid);
+
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_util.c
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_util.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_util.c 2012-03-22 03:25:40.000000000 -0500
+@@ -90,13 +90,16 @@ str_to_ipport(char *str, int *port, int
+
+ if (!strchr(ip, '.')) {
+ if (*ip == '[') {
++ /* IPv6 with [] */
+ if (!(sport = strchr(ip, ']')))
+ return NULL;
+ *sport++ = '\0';
+ ip++;
+ str = sport;
+- } else
++ } else if (!strchr(ip, ':'))
++ /* IPv6 no brackets and no port */
+ sport = NULL;
++ /* else hostname with domain info */
+ }
+
+ if (sport && (sport = strchr(str, ':'))) {
+@@ -178,7 +181,6 @@ char *strstrip(char *s)
+ char *cfg_get_string_param(char *pathname, const char *key)
+ {
+ FILE *f = NULL;
+- int len;
+ char *line, buffer[1024];
+ char *value = NULL, *param, *comment;
+
+@@ -187,7 +189,6 @@ char *cfg_get_string_param(char *pathnam
+ return NULL;
+ }
+
+- len = strlen(key);
+ if ((f = fopen(pathname, "r"))) {
+ while ((line = fgets(buffer, sizeof (buffer), f))) {
+ param = strstr(line, key);
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/Makefile 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile 2012-03-22 03:25:15.000000000 -0500
+@@ -33,7 +33,7 @@ endif
+ OPTFLAGS ?= -O2 -g
+ WARNFLAGS ?= -Wall -Wstrict-prototypes
+ CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -I../include -I. -I../utils/open-isns \
+- -D$(OSNAME) $(IPC_CFLAGS) -DISNS_ENABLE
++ -D$(OSNAME) $(IPC_CFLAGS) -DISNS_ENABLE
+ PROGRAMS = iscsid iscsiadm iscsistart
+
+ # libc compat files
+@@ -57,7 +57,7 @@ all: $(PROGRAMS)
+
+ iscsid: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(DISCOVERY_SRCS) \
+ iscsid.o session_mgmt.o discoveryd.o
+- $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns
++ $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns
+
+ iscsiadm: $(ISCSI_LIB_SRCS) $(DISCOVERY_SRCS) iscsiadm.o session_mgmt.o
+ $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/netlink.c
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/netlink.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/netlink.c 2012-03-22 03:20:29.000000000 -0500
+@@ -1085,13 +1085,15 @@ ksend_ping(uint64_t transport_handle, ui
+
+ static int kexec_ping(uint64_t transport_handle, uint32_t host_no,
+ struct sockaddr *addr, uint32_t iface_num,
+- uint32_t iface_type, uint32_t size)
++ uint32_t iface_type, uint32_t size, uint32_t *status)
+ {
+ struct pollfd pfd;
+ struct timeval ping_timer;
+ int timeout, fd, rc;
+ uint32_t pid;
+
++ *status = 0;
++
+ fd = ipc->ctldev_open();
+ if (fd < 0) {
+ log_error("Could not open netlink socket.");
+@@ -1151,10 +1153,8 @@ static int kexec_ping(uint64_t transport
+ if (pid != ping_event.pid)
+ continue;
+
+- if (ping_event.status == 0)
+- rc = 0;
+- else
+- rc = ISCSI_ERR;
++ rc = 0;
++ *status = ping_event.status;
+ break;
+ }
+
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/transport.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.c
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/transport.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.c 2012-03-22 03:27:02.000000000 -0500
+@@ -19,7 +19,17 @@
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <errno.h>
++#ifdef USE_KMOD
++#include <libkmod.h>
++#endif
++#include <net/if.h>
++#include <sys/ioctl.h>
++#include <sys/socket.h>
++#include <sys/types.h>
++#include <sys/wait.h>
+
++#include "sysdeps.h"
++#include "iscsi_err.h"
+ #include "initiator.h"
+ #include "transport.h"
+ #include "log.h"
+@@ -100,6 +110,151 @@ static struct iscsi_transport_template *
+ NULL
+ };
+
++int transport_probe_for_offload(void)
++{
++ struct if_nameindex *ifni;
++ char transport_name[ISCSI_TRANSPORT_NAME_MAXLEN];
++ int i, sockfd;
++ struct ifreq if_hwaddr;
++
++ ifni = if_nameindex();
++ if (!ifni) {
++ log_error("Could not search for transport modules: %s",
++ strerror(errno));
++ return ISCSI_ERR_TRANS_NOT_FOUND;
++ }
++
++ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
++ if (sockfd < 0) {
++ log_error("Could not open socket for ioctl: %s",
++ strerror(errno));
++ goto free_ifni;
++ }
++
++ for (i = 0; ifni[i].if_index && ifni[i].if_name; i++) {
++ struct if_nameindex *n = &ifni[i];
++
++ log_debug(6, "kmod probe found %s\n", n->if_name);
++
++ strlcpy(if_hwaddr.ifr_name, n->if_name, IFNAMSIZ);
++ if (ioctl(sockfd, SIOCGIFHWADDR, &if_hwaddr) < 0)
++ continue;
++
++ /* check for ARPHRD_ETHER (ethernet) */
++ if (if_hwaddr.ifr_hwaddr.sa_family != 1)
++ continue;
++
++ if (net_get_transport_name_from_netdev(n->if_name,
++ transport_name))
++ continue;
++
++ transport_load_kmod(transport_name);
++ }
++
++free_ifni:
++ if_freenameindex(ifni);
++ return 0;
++}
++
++/*
++ * Most distros still do not have wide libkmod use, so
++ * use modprobe for now
++ */
++#ifdef USE_KMOD
++int transport_load_kmod(char *transport_name)
++{
++ struct kmod_ctx *ctx;
++ struct kmod_module *mod;
++ int rc;
++
++ ctx = kmod_new(NULL, NULL);
++ if (!ctx) {
++ log_error("Could not load transport module %s. Out of "
++ "memory.", transport_name);
++ return ISCSI_ERR_NOMEM;
++ }
++
++ kmod_load_resources(ctx);
++
++ /*
++ * dumb dumb dumb - named iscsi_tcp and ib_iser differently from
++ * transport name
++ */
++ if (!strcmp(transport_name, "tcp"))
++ rc = kmod_module_new_from_name(ctx, "iscsi_tcp", &mod);
++ else if (!strcmp(transport_name, "iser"))
++ rc = kmod_module_new_from_name(ctx, "ib_iser", &mod);
++ else
++ rc = kmod_module_new_from_name(ctx, transport_name, &mod);
++ if (rc) {
++ log_error("Failed to load module %s.", transport_name);
++ rc = ISCSI_ERR_TRANS_NOT_FOUND;
++ goto unref_mod;
++ }
++
++ rc = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST,
++ NULL, NULL, NULL, NULL);
++ if (rc) {
++ log_error("Could not insert module %s. Kmod error %d",
++ transport_name, rc);
++ rc = ISCSI_ERR_TRANS_NOT_FOUND;
++ }
++ kmod_module_unref(mod);
++
++unref_mod:
++ kmod_unref(ctx);
++ return rc;
++}
++
++#else
++
++int transport_load_kmod(char *transport_name)
++{
++ char *cmdline[4];
++ pid_t pid;
++
++ cmdline[0] = "/sbin/modprobe";
++ cmdline[1] = "-qb";
++ cmdline[3] = NULL;
++
++ /*
++ * dumb dumb mistake - named iscsi_tcp and ib_iser differently from
++ * transport name
++ */
++ if (!strcmp(transport_name, "tcp"))
++ cmdline[2] = "iscsi_tcp";
++ else if (!strcmp(transport_name, "iser"))
++ cmdline[2] = "ib_iser";
++ else
++ cmdline[2] = transport_name;
++
++ if (iscsi_sysfs_is_transport_loaded(cmdline[2]))
++ return 0;
++
++ pid = fork();
++ if (pid == 0) {
++ if (execv("/sbin/modprobe", cmdline) < 0) {
++ log_error("Failed to load module %s: %s",
++ transport_name, strerror(errno));
++ exit(-errno);
++ }
++ exit(0);
++ } else if (pid < 0) {
++ log_error("Failed to fork process to load module %s: %s",
++ transport_name, strerror(errno));
++ return ISCSI_ERR_TRANS_NOT_FOUND;
++ }
++
++ if (waitpid(pid, NULL, 0) < 0) {
++ log_error("Failed to load module %s", transport_name);
++ return ISCSI_ERR_TRANS_NOT_FOUND;
++ }
++
++ return 0;
++}
++
++#endif
++
+ int set_transport_template(struct iscsi_transport *t)
+ {
+ struct iscsi_transport_template *tmpl;
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/transport.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.h
+--- open-iscsi-2.0-872-rc4-bnx2i/usr/transport.h 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.h 2012-03-22 03:21:42.000000000 -0500
+@@ -51,5 +51,7 @@ struct iscsi_transport {
+ };
+
+ extern int set_transport_template(struct iscsi_transport *t);
++extern int transport_load_kmod(char *transport_name);
++extern int transport_probe_for_offload(void);
+
+ #endif
+diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fw_entry.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fw_entry.c
+--- open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fw_entry.c 2012-03-22 03:20:09.000000000 -0500
++++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fw_entry.c 2012-03-22 03:27:49.000000000 -0500
+@@ -35,6 +35,8 @@
+ #include "idbm_fields.h"
+ #include "iscsi_net_util.h"
+ #include "iscsi_err.h"
++#include "config.h"
++#include "iface.h"
+
+ /**
+ * fw_setup_nics - setup nics (ethXs) based on ibft net info
+@@ -146,11 +148,19 @@ void fw_free_targets(struct list_head *l
+
+ static void dump_initiator(struct boot_context *context)
+ {
++ struct iface_rec iface;
++
++ memset(&iface, 0, sizeof(iface));
++ iface_setup_defaults(&iface);
++ iface_setup_from_boot_context(&iface, context);
++
+ if (strlen(context->initiatorname))
+ printf("%s = %s\n", IFACE_INAME, context->initiatorname);
+
+ if (strlen(context->isid))
+ printf("%s = %s\n", IFACE_ISID, context->isid);
++
++ printf("%s = %s\n", IFACE_TRANSPORTNAME, iface.transport_name);
+ }
+
+ static void dump_target(struct boot_context *context)
diff --git a/iscsi-initiator-utils.spec b/iscsi-initiator-utils.spec
index 523c79c..844a080 100644
--- a/iscsi-initiator-utils.spec
+++ b/iscsi-initiator-utils.spec
@@ -3,7 +3,7 @@
Summary: iSCSI daemon and utility programs
Name: iscsi-initiator-utils
Version: 6.2.0.872
-Release: 36%{?dist}
+Release: 37%{?dist}
Source0: http://people.redhat.com/mchristi/iscsi/rhel6.0/source/open-iscsi-2.0-872-rc4-bnx2i.tar.gz
Source1: iscsid.init
Source2: iscsidevs.init
@@ -37,8 +37,10 @@ Patch11: iscsi-initiator-utils-libiscsi-to-support-offload.patch
# sync to upstream commit f9f627fbf0fc96545931ae65aa2b6214841bfd4e to
# add iscsiadm ping and host chap support and fix default iface handling
Patch12: iscsi-initiator-utils-ping-and-chap.patch
+# sync to upstream 04b4a6699f63c4f0bab9523aae3efb8c909d6587
+Patch13: iscsi-initiator-utils-mod-iface-andport-fixes.patch
# add rhel version info to iscsi tools
-Patch13: iscsi-initiator-utils-add-rh-ver.patch
+Patch14: iscsi-initiator-utils-add-rh-ver.patch
Group: System Environment/Daemons
License: GPLv2+
@@ -79,7 +81,8 @@ developing applications that use %{name}.
%patch10 -p1 -b .Add-Netconfig-support-through-libiscsi
%patch11 -p1 -b .libiscsi-to-support-offload
%patch12 -p1 -b .ping-and-chap
-%patch13 -p1 -b .add-rh-ver
+%patch13 -p1 -b .mod-iface-andport-fixes
+%patch14 -p1 -b .add-rh-ver
%build
cd utils/open-isns
@@ -205,6 +208,11 @@ fi
%{_includedir}/libiscsi.h
%changelog
+* Thu Mar 22 2012 Mike Christie <mcrhsit at redhat.com> 6.2.0.872.37
+- 805467 Have iscsistart/iscsiadm bring up offload net interface.
+- 796574 Fix port handling when hostnames are used for portals.
+- 739843 Fix default iface setup handling.
+
* Mon Mar 5 2012 Mike Christie <mcrhsit at redhat.com> 6.2.0.872.36
- 740054 sync iscsiuio to 0.7.2.1
- 790609 Add ping and host chap support to iscsiadm
More information about the scm-commits
mailing list