diff --git a/open-iscsi-cxgb3i-support b/open-iscsi-cxgb3i-support new file mode 100644 index 0000000..699c0f7 --- /dev/null +++ b/open-iscsi-cxgb3i-support @@ -0,0 +1,362 @@ +commit 86b865b61d530188e3d6a59773ca7edbc8d30767 +Author: Hannes Reinecke +Date: Thu Nov 20 15:45:02 2008 +0100 + + cxgb3 iSCSI TOE support + + This patch enable cxgb3i iSCSI TOE support for open-iscsi. + + References: bnc#433500, FATE#304154 + + Signed-off-by: Karen Xie + Signed-off-by: Chandra Seetharaman + Signed-off-by: Hannes Reinecke + +diff --git a/doc/iscsiadm.8 b/doc/iscsiadm.8 +index b488ad5..8fe14d4 100644 +--- a/doc/iscsiadm.8 ++++ b/doc/iscsiadm.8 +@@ -63,10 +63,10 @@ specific hardware resource and instead allow the network or infinniband layer + to decide what to do. There is no need to create a iface config with the default + behavior. If you do not specify a iface, then the default behavior is used. + +-As mentioned above there is a special iface name default. There are two others +-bnx2i and iser, which does not bind the session to a specific card, but +-will bind the session to either the bnx2i or iser transport. These are +-experimental and the use is not supported as a stable interface yet. ++As mentioned above there is a special iface name default. There are three ++others -- cxgb3i, bnx2i and iser, which does not bind the session to a specific ++card, but will bind the session to the cxgb3i, bnx2i or iser transport. These ++are experimental and the use is not supported as a stable interface yet. + + In discovery mode multiple interfaces can be specific by passing in multiple + -I/--interface instances. For example, +diff --git a/etc/iface.example b/etc/iface.example +index 7fb7951..020b002 100644 +--- a/etc/iface.example ++++ b/etc/iface.example +@@ -20,6 +20,7 @@ + # - iser (Software iSCSI over infinniband + # - qla4xxx (Qlogic QLA4XXX HBAs) + # - bnx2i (Broadcom bnx iSCSI HBAs); ++# - cxgb3i (Chelsio cxgb S3 iSCSI HBAs); + # + #OPTIONAL: iface.initiatorname + # To use a initiator name other than the one set in +@@ -51,3 +52,13 @@ + + # Note you can only bind using one value. If you set multiple values + # the bahavior is not defined. ++ ++# For some transport (cxgb3i), a user could to set the private ip address for ++# the iscsi traffic for an network interface: ++# example: ++# - set iscsi ip on eth0 to be 102.50.50.101, eth0 needs to be up and be on ++# the same subnet. ++# iface.net_ifacename = eth0 ++# iface.ipaddress = 102.50.50.101 ++~ ++ +diff --git a/usr/idbm.c b/usr/idbm.c +index a7a1072..6f4ed12 100644 +--- a/usr/idbm.c ++++ b/usr/idbm.c +@@ -274,8 +274,8 @@ idbm_recinfo_node(node_rec_t *r, recinfo_t *ri) + */ + __recinfo_str("iface.hwaddress", ri, r, iface.hwaddress, IDBM_SHOW, + num, 1); +-// __recinfo_str("iface.ipaddress", ri, r, iface.ipaddress, +-// IDBM_SHOW, num); ++ __recinfo_str("iface.ipaddress", ri, r, iface.ipaddress, IDBM_SHOW, ++ num, 1); + __recinfo_str("iface.iscsi_ifacename", ri, r, iface.name, IDBM_SHOW, + num, 1); + __recinfo_str("iface.net_ifacename", ri, r, iface.netdev, IDBM_SHOW, +@@ -413,7 +413,7 @@ void idbm_recinfo_iface(iface_rec_t *r, recinfo_t *ri) + + __recinfo_str("iface.iscsi_ifacename", ri, r, name, IDBM_SHOW, num, 0); + __recinfo_str("iface.net_ifacename", ri, r, netdev, IDBM_SHOW, num, 1); +-// __recinfo_str("iface.ipaddress", ri, r, ipaddress, IDBM_SHOW, num, 1); ++ __recinfo_str("iface.ipaddress", ri, r, ipaddress, IDBM_SHOW, num, 1); + __recinfo_str("iface.hwaddress", ri, r, hwaddress, IDBM_SHOW, num, 1); + __recinfo_str("iface.transport_name", ri, r, transport_name, + IDBM_SHOW, num, 1); +diff --git a/usr/iface.c b/usr/iface.c +index 01b87da..3273197 100644 +--- a/usr/iface.c ++++ b/usr/iface.c +@@ -104,7 +104,7 @@ static void iface_init(struct iface_rec *iface) + void iface_setup_defaults(struct iface_rec *iface) + { + sprintf(iface->netdev, DEFAULT_NETDEV); +-// sprintf(iface->ipaddress, DEFAULT_IPADDRESS); ++ sprintf(iface->ipaddress, DEFAULT_IPADDRESS); + sprintf(iface->hwaddress, DEFAULT_HWADDRESS); + sprintf(iface->transport_name, DEFAULT_TRANSPORT); + iface_init(iface); +@@ -494,8 +494,8 @@ void iface_copy(struct iface_rec *dst, struct iface_rec *src) + strcpy(dst->name, src->name); + if (strlen(src->netdev)) + strcpy(dst->netdev, src->netdev); +-// if (strlen(src->ipaddress)) +-// strcpy(dst->ipaddress, src->ipaddress); ++ if (strlen(src->ipaddress)) ++ strcpy(dst->ipaddress, src->ipaddress); + if (strlen(src->hwaddress)) + strcpy(dst->hwaddress, src->hwaddress); + if (strlen(src->transport_name)) +@@ -594,6 +594,8 @@ int iface_print_tree(void *data, struct iface_rec *iface) + UNKNOWN_VALUE); + printf("\tHW Address: %s\n", + strlen(iface->hwaddress) ? iface->hwaddress : UNKNOWN_VALUE); ++ printf("\tIP Address: %s\n", ++ strlen(iface->ipaddress) ? iface->ipaddress : UNKNOWN_VALUE); + printf("\tNetdev: %s\n", + strlen(iface->netdev) ? iface->netdev : UNKNOWN_VALUE); + printf("\tInitiator Name: %s\n", +@@ -603,11 +605,12 @@ int iface_print_tree(void *data, struct iface_rec *iface) + + int iface_print_flat(void *data, struct iface_rec *iface) + { +- printf("%s %s,%s,%s,%s\n", ++ printf("%s %s,%s,%s,%s,%s\n", + strlen(iface->name) ? iface->name : UNKNOWN_VALUE, + strlen(iface->transport_name) ? iface->transport_name : + UNKNOWN_VALUE, + strlen(iface->hwaddress) ? iface->hwaddress : UNKNOWN_VALUE, ++ strlen(iface->ipaddress) ? iface->ipaddress : UNKNOWN_VALUE, + strlen(iface->netdev) ? iface->netdev : UNKNOWN_VALUE, + strlen(iface->iname) ? iface->iname : UNKNOWN_VALUE); + return 0; +diff --git a/usr/initiator.c b/usr/initiator.c +index 10cf050..8e95841 100644 +--- a/usr/initiator.c ++++ b/usr/initiator.c +@@ -1176,7 +1176,7 @@ mgmt_ipc_err_e iscsi_host_set_param(int host_no, int param, char *value) + return MGMT_IPC_OK; + } + +-#define MAX_SESSION_PARAMS 30 ++#define MAX_SESSION_PARAMS 31 + #define MAX_HOST_PARAMS 3 + + static void +@@ -1360,6 +1360,10 @@ setup_full_feature_phase(iscsi_conn_t *conn) + .param = ISCSI_PARAM_IFACE_NAME, + .value = session->nrec.iface.name, + .type = ISCSI_STRING, ++ }, { ++ .param = ISCSI_PARAM_INITIATOR_NAME, ++ .value = session->initiator_name, ++ .type = ISCSI_STRING, + }, + }; + +@@ -1946,6 +1950,54 @@ int session_is_running(node_rec_t *rec) + return 0; + } + ++static int iface_set_param(struct iscsi_transport *t, iface_rec_t *iface, ++ iscsi_session_t *session) ++{ ++ int rc = 0; ++ int netdev_set = strcasecmp(iface->netdev, DEFAULT_NETDEV); ++ int ipaddr_set = strcasecmp(iface->ipaddress, DEFAULT_IPADDRESS); ++ int hwaddr_set = strcasecmp(iface->hwaddress, DEFAULT_HWADDRESS); ++ int hostno; ++ iface_rec_t *iface_tmp; ++ ++ log_debug(3, "iface %s, dev %s, set ip %s, hw %s, tranport %s.\n", ++ iface->name, iface->netdev, iface->ipaddress, ++ iface->hwaddress, iface->transport_name); ++ ++ /* proceed only when netdev and either ipaddress or hwaddress is set */ ++ if (!netdev_set || (!ipaddr_set && !hwaddr_set)) ++ return 0; ++ ++ /* find out hostno via netdev */ ++ iface_tmp = calloc(1, sizeof(*iface_tmp)); ++ strcpy(iface_tmp->netdev, iface->netdev); ++ hostno = iscsi_sysfs_get_host_no_from_iface(iface_tmp, &rc); ++ free(iface_tmp); ++ if (rc) ++ return rc; ++ session->hostno = hostno; ++ ++ if (ipaddr_set) { ++ rc = __iscsi_host_set_param(t, session->hostno, ++ ISCSI_HOST_PARAM_IPADDRESS, ++ iface->ipaddress, ++ ISCSI_STRING); ++ if (rc) ++ return rc; ++ } ++ ++ if (hwaddr_set) { ++ rc = __iscsi_host_set_param(t, session->hostno, ++ ISCSI_HOST_PARAM_HWADDRESS, ++ iface->hwaddress, ++ ISCSI_STRING); ++ if (rc) ++ return rc; ++ } ++ ++ return 0; ++} ++ + int + session_login_task(node_rec_t *rec, queue_task_t *qtask) + { +@@ -2028,6 +2080,11 @@ session_login_task(node_rec_t *rec, queue_task_t *qtask) + conn = &session->conn[0]; + qtask->conn = conn; + ++ if (iface_set_param(t, &rec->iface, session)) { ++ __session_destroy(session); ++ return MGMT_IPC_ERR_LOGIN_FAILURE; ++ } ++ + conn->state = STATE_XPT_WAIT; + if (iscsi_conn_connect(conn, qtask)) { + __session_destroy(session); +diff --git a/usr/iscsi_sysfs.c b/usr/iscsi_sysfs.c +index cab3ec1..54b6ee6 100644 +--- a/usr/iscsi_sysfs.c ++++ b/usr/iscsi_sysfs.c +@@ -531,7 +531,7 @@ uint32_t iscsi_sysfs_get_host_no_from_iface(struct iface_rec *iface, int *rc) + else if (strlen(iface->ipaddress) && + strcasecmp(iface->ipaddress, DEFAULT_IPADDRESS)) + host_no = get_host_no_from_ipaddress(iface->ipaddress, &tmp_rc); +- else if(strlen(iface->netdev) && ++ else if (strlen(iface->netdev) && + strcasecmp(iface->netdev, DEFAULT_NETDEV)) + host_no = get_host_no_from_netdev(iface->netdev, &tmp_rc); + else +@@ -582,35 +582,78 @@ static int sysfs_read_iface(struct iface_rec *iface, int host_no, int sid) + log_debug(7, "could not read netdev for host%d\n", host_no); + } + +- ret = iscsi_sysfs_get_iscsi_host_param(host_no, "initiatorname", +- iface->iname, "%s\n"); +- if (ret) +- /* default iname is picked up later from initiatorname.iscsi */ +- log_debug(7, "Could not read initiatorname for host%d\n", +- host_no); +- + /* +- * this is on the session, because we support multiple bindings +- * per device. ++ * If we are looping over the hosts then we want to read the ++ * initiator name set at that level instead of the session ++ * level one, because if we created a iscsi port with a different ++ * iname then they will not match. + */ +- memset(iface->name, 0, sizeof(iface->name)); +- /* +- * this was added after 2.0.869 so we could be doing iscsi_tcp +- * session binding, but there may not be a ifacename set +- */ +- ret = iscsi_sysfs_get_session_param(sid, "ifacename", iface->name, +- "%s\n"); ++ ret = 1; ++ if (sid != -1) { ++ /* ++ * this is on the session, because we support multiple bindings ++ * per device. ++ */ ++ memset(iface->name, 0, sizeof(iface->name)); ++ /* ++ * this was added after 2.0.869 so we could be doing iscsi_tcp ++ * session binding, but there may not be a ifacename set ++ */ ++ ret = iscsi_sysfs_get_session_param(sid, "ifacename", ++ iface->name, "%s\n"); ++ /* if failed then look ifacename through binding tuple */ ++ if (ret) ++ log_debug(7, "could not read iface name for sid %u\n", ++ sid); ++ } ++ + if (ret) { +- log_debug(7, "could not read iface name for sid %u\n", sid); + /* +- * if the ifacename file is not there then we are using a older +- * kernel and can try to find the binding by the net info +- * which was used on these older kernels. +- */ ++ * if the ifacename file (will always not be for qla4xxx) ++ * is not there then we are using a older kernel and can ++ * try to find the binding by the net info which was ++ * used on these older kernels. If scanning hosts then ++ * we must go this route currently because we do not ++ * store the ifacename on the host for qla4xxx. ++ */ + if (iface_get_by_net_binding(iface, iface)) +- log_debug(7, "Could not find iface for session bound " +- "to:" iface_fmt "\n", iface_str(iface)); ++ log_debug(7, "Could not find iface for " ++ "session bound to:" iface_fmt "\n", ++ iface_str(iface)); ++ } ++ ++ ret = 1; ++ if (sid != 1) { ++ /* ++ * 2.0.870 we added the two inames to distinguish ++ * between one that may be set at the hba level ++ * as the default and one that we set for the iface ++ * so we could create a virtual initiator port. ++ */ ++ ret = iscsi_sysfs_get_session_param(sid, "initiatorname", ++ iface->iname, "%s\n"); ++ if (ret) ++ /* ++ * default iname is picked up later from ++ * initiatorname.iscsi ++ */ ++ log_debug(7, "Could not read initiatorname for " ++ "host%d\n", host_no); ++ /* drop through to older iface iname */ + } ++ ++ if (ret) { ++ ret = iscsi_sysfs_get_iscsi_host_param(host_no, "initiatorname", ++ iface->iname, "%s\n"); ++ if (ret) ++ /* ++ * default iname is picked up later from ++ * initiatorname.iscsi ++ */ ++ log_debug(7, "Could not read initiatorname for " ++ "host%d\n", host_no); ++ } ++ + return ret; + } + +diff --git a/usr/transport.c b/usr/transport.c +index c2edbcc..07b61db 100644 +--- a/usr/transport.c ++++ b/usr/transport.c +@@ -41,6 +41,13 @@ struct iscsi_transport_template iscsi_iser = { + .ep_disconnect = ktransport_ep_disconnect, + }; + ++struct iscsi_transport_template cxgb3i = { ++ .name = "cxgb3i", ++ .ep_connect = ktransport_ep_connect, ++ .ep_poll = ktransport_ep_poll, ++ .ep_disconnect = ktransport_ep_disconnect, ++}; ++ + struct iscsi_transport_template bnx2i = { + .name = "bnx2i", + .ep_connect = ktransport_ep_connect, +@@ -55,6 +62,7 @@ struct iscsi_transport_template qla4xxx = { + static struct iscsi_transport_template *iscsi_transport_templates[] = { + &iscsi_tcp, + &iscsi_iser, ++ &cxgb3i, + &bnx2i, + &qla4xxx, + NULL diff --git a/open-iscsi-no-pid-file b/open-iscsi-no-pid-file new file mode 100644 index 0000000..f6f9d9b --- /dev/null +++ b/open-iscsi-no-pid-file @@ -0,0 +1,68 @@ +commit 9d9425eb31ecc3d1501da83e8e9becaec441b4c7 +Author: Hannes Reinecke +Date: Thu Nov 20 15:40:10 2008 +0100 + + Do not use a pid file for start scripts + + open-iscsi works perfectly without a pid file. So don't create one. + + Signed-off-by: Hannes Reinecke + +diff --git a/etc/initd/boot.suse b/etc/initd/boot.suse +index 3e93cad..83875e2 100644 +--- a/etc/initd/boot.suse ++++ b/etc/initd/boot.suse +@@ -17,10 +17,9 @@ + ### END INIT INFO + + ISCSIADM=/sbin/iscsiadm +-PID_FILE=/var/run/iscsi.pid + CONFIG_FILE=/etc/iscsid.conf + DAEMON=/sbin/iscsid +-ARGS="-c $CONFIG_FILE -p $PID_FILE" ++ARGS="-c $CONFIG_FILE" + + # Source LSB init functions + . /etc/rc.status +diff --git a/etc/initd/initd.suse b/etc/initd/initd.suse +index 69b681b..11ee4d2 100644 +--- a/etc/initd/initd.suse ++++ b/etc/initd/initd.suse +@@ -16,11 +16,10 @@ + # + ### END INIT INFO + +-PID_FILE=/var/run/iscsi.pid + CONFIG_FILE=/etc/iscsi/iscsid.conf + DAEMON=/sbin/iscsid + ISCSIADM=/sbin/iscsiadm +-ARGS="-c $CONFIG_FILE -p $PID_FILE" ++ARGS="-c $CONFIG_FILE -n" + + # Source LSB init functions + . /etc/rc.status +@@ -105,7 +104,6 @@ iscsi_list_all_nodes() + + case "$1" in + start) +- [ ! -d /var/lib/iscsi ] && mkdir -p /var/lib/iscsi + if checkproc $DAEMON ; then + RETVAL=0 + else +@@ -122,15 +120,14 @@ case "$1" in + ;; + stop) + iscsi_umount_all_luns ++ echo -n "Stopping iSCSI initiator service: " + if iscsi_logout_all_nodes ; then + killproc -KILL $DAEMON + RETVAL=$? + else + RETVAL=1 + fi +- echo -n "Stopping iSCSI initiator service: " + if [ "$RETVAL" == "0" ]; then +- rm -f $PID_FILE + status=0 + modprobe -r iscsi_tcp + if [ "$?" -ne "0" -a "$?" -ne "1" ]; then diff --git a/open-iscsi.changes b/open-iscsi.changes index d00f8ff..1d5f8a6 100644 --- a/open-iscsi.changes +++ b/open-iscsi.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Nov 20 15:48:55 CET 2008 - hare@suse.de + +- Add cxgb3i support (bnc#433500, FATE#304154) +- No pid file from init scripts + ------------------------------------------------------------------- Thu Nov 13 11:38:30 CET 2008 - hare@suse.de diff --git a/open-iscsi.spec b/open-iscsi.spec index 25b995a..440bef0 100644 --- a/open-iscsi.spec +++ b/open-iscsi.spec @@ -26,7 +26,7 @@ Group: Productivity/Networking/Other PreReq: %fillup_prereq %insserv_prereq AutoReqProv: on Version: 2.0.870 -Release: 19 +Release: 20 Provides: linux-iscsi Obsoletes: linux-iscsi %define iscsi_release 865 @@ -54,6 +54,8 @@ Patch18: %{name}-update-suse-init-scripts Patch19: %{name}-set-LOCK_DIR-during-compilation Patch20: %{name}-add-mkinitrd-scriptlets Patch21: %{name}-install-mkinitrd-scriptlets +Patch22: %{name}-no-pid-file +Patch23: %{name}-cxgb3i-support BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -104,6 +106,8 @@ Authors: %patch19 -p1 %patch20 -p1 %patch21 -p1 +%patch22 -p1 +%patch23 -p1 %build %{__make} OPTFLAGS="${RPM_OPT_FLAGS} -DLOCK_DIR=\\\"/etc/iscsi\\\"" @@ -151,6 +155,9 @@ fi %doc %{_mandir}/man8/* %changelog +* Thu Nov 20 2008 hare@suse.de +- Add cxgb3i support (bnc#433500, FATE#304154) +- No pid file from init scripts * Thu Nov 13 2008 hare@suse.de - Update iscsi-gen-initiatorname to work with newer kernels (bnc#443509)