diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/Changelog open-iscsi-2.0-872-rc4-bnx2i.work/Changelog --- open-iscsi-2.0-872-rc4-bnx2i/Changelog 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/Changelog 2011-02-24 19:54:10.000000000 -0600 @@ -1,132 +1,114 @@ -open-iscsi-2.0-871 - open-iscsi-2.0.870 +open-iscsi-2.0-872 - open-iscsi-2.0.871 -Boaz Harrosh (1): - open-iscsi: Makefile: separate out user: and kernel: make targets +Avi Kaplan (2): + Remove unused field iscsi_conn from struct iscsi_sw_tcp_conn + Change restore_callbacks argument iscsi_sw_tcp_conn to iscsi_conn Erez Zilber (1): - Add Module.markers to .gitignore + Fix 2.6.14-23_compat.patch to support all RHEL 5.X versions -Karen Xie (2): - userspace - add new transport cxgb3i - userspace - setting interface ip address - -Mike Christie (84): - iscsid: fix relogin retry handling - iscsid idbm: print out header and tail to seperate records - ibft: add support to use iscsi_ibft module and log into all portals found in firmware - fwparam: rm unused filepath argument - iscsid idbm: move record strings to header - iscsiadm: discovery mode supports the --show - iscsiadm: have fw discovery handle --op arguments - iscsiadm: fix output ordering - iscsi modules: fix compilation - iscsid/iscsiadm: fix strto* usage - iscsid: fix logout response and time2wait handling - iscsiadm: remove default bnx2i iface - iscsid/iscsiadm: support multiple inititor names per host. - iscsiadm: print session and session info running through ifaces in iface mode - iscsid: update transport handle - idbm: have idbm_rec_update_param update the value string of the matching rec_info - iscsi mod: sync up kernel modules with 2.6.29 - iscsi mod: 2.6.27 compat - iscsi mod: 2.6.26 compat - iscsi mod: 2.6.24-25 compat - iscsi mod: 2.6.20-23 compat - iscsi mod: 2.6.14-19 compat - iscsi mod: fix up 2.6.14-19 compat patch - iscsi mod iscsi_tcp: compat fix for pI4/pI6 - build: add a make user - iscsi tools: fix chap - PATCH: iscsi tools: do not use exit() - PATCH: fix iBFT firmware reading with newer kernels - 2.6.29-rc libiscsi: Fix scsi command timeout oops in iscsi_eh_timed_out - iscsi mod: 2.6.14-19 compat - iscsi tools: convert from strncat to strlcat - iscsi tools: convert from strncpy to strlcpy - iscsi tool make: add notification that iscsi start was made - iscsid: Fix up connection failed messages - docs: fix up iscsiadm man page iface info - iscsi tools: update version in preparation for new release - iscsid: flush sysfs cache. - iscsid: mv event loop code to new file - docs: update readme with libiscsi_tcp info - - - - -------------------------------------------------------------------- -open-iscsi-2.0-870 - open-iscsi-2.0.869 - -Doron Shoham (1): - log.c: add error messages when allocation shared memory - -Erez Zilber (2): - Minor fixes in iscsi_discovery documentation - rm unused variable in fw_entry.c - -Hannes Reinecke (1): - Add SLES10 SP2 compat - -Hans de Goede (1): - PATCH: add error checking to iscsi discovery db lock creation - -Mike Christie (58): - change mgmt_ipc to logout by sid - iscsi class/if kernel: add ifacename attr - add ifacename support tools - rm db param - rm num_transports from sysfs header. - Add bind by initiatorname - break up iface code and add default iser, tcp/default and bnx2i ifaces - Use startup definition in util.c. - set header digests to off by default - fix compile warning for missing iface.h - User 64 bit params mask. - Do not allow iface setting to be changed in node mode. - Fix bad merge. User iscsi param masks instead of params. - Support mutlple ifaces with the same binding (lack of binding). - Release transport entry when the transport is unloaded - Fix ep_disconnect handling of invalid ep - libiscsi: Fix nop timeout handling - libiscsi: fix recv tmo - Revert Release-transport-entry-when-the-transport-is-unload.patch - pass ep to session creation - Fix iser create bound session compat - fix compilation on Fedora 9 - Fix sysfs handling of block:sdX and scsi bus changes - Only autobind to ifaces with transport = tcp - Increase login retry for iscsistart. - Sync kernel modules to scsi-misc for 2.6.27. - Update 2.6.14 - 2.6.19 compat patch - Update 2.6.20 - 2.6.24 patch - Update 2.6.24 - 2.6.25 patch - iscsid: don't print enosys errors. - libiscsi: support older tools that did not set can_queue/cmds_max - Fix transport_name compat support. - Fix idbm iscsid segfault when accsing ifaces - Fix discovery and autobinding - fix ipv6 login redirect support. - Fix login redirect failure handling. - remove sysfs_file - fix dynamic tpgt support. - Bump version for new release. - Add compat patch for RHEL 5.2 - iscsid: adjust requested settings for user - Sync kernel modules with 2.6.27 - Add 2.6.26 compat support - Add Makefile support for 2.6.26 compat patch - Add .gitignore files - Revert broken SLES 10 compat patch. - iscsi conf: increase default login max - iscsi conf: partially revert increase default login max change - modify initial login retry max - libiscsi: fix data corruption when target has to resend data-in packets - iscsi class: fix endpoint id handling - handle ISCSI_ERR_INVALID_HOST - iscsi_tcp: return a descriptive error value during connection errors - libiscsi: fix locking in iscsi_eh_device_reset - update 2.6.14-19_compat.patch - update 2.6.20-21_compat.patch - update 2.6.24_compat.patch - Fix initiator.c compile warning +Hannes Reinecke (2): + Allow update of discovery records. + Update 2.6.27_compat.patch for SLES 11 + +Mike Christie (91): + Don't kill iscsid if logout from all nodes fail + iscsid: fix ISCSI_ERR_INVALID_HOST err handling + iscsid: add flag to indicate if driver needs iscsid to set ip + iscsid: add be2iscsi template + iscsid be2iscsi: add more driver limits + iscsid: start iscsid automatically when needed + iscsid: fix segfault during session sync up + iscsiadm: fix discovery record use + iscsi mod: sync to linux-2.6-iscsi tree's 2.6.33 feature window patches + iscsid: handle new replacement_timeout values + iscsi tools: support tgt reset timeout + iscsi-iname: fix misleading help description + iscsid: fix iferror log message + iscsi mod: Update 2.6.14-23_compat.patch patch + iscsiadm: fix login/logout message + do not use a semarg in shared-mem for semop calls + Fix wrong logs in log.c + update 2.6.26 compat patch + iscsi tools: Allow empty username for CHAP + iscsi ibft/boot: fix net dev loopup + iscsistart option to bring up NICs using configuration in iBFT. + ibft boot: mv setup nics to fw_entry.c so iscsiadm can use it + iscsistart ibft: fix fwparam network cmd + iscsid be2iscsi: don't set set_host_ip + iscsi tools: merge functions to get net iface name from mac address + ibft boot: do not setup nic if offload can be used + iscsistart ibft boot: setup iscsi offload during boot + ibft boot: remove be2iscsi + iscsi tools: idbm/fw function cleanup + iscsi tool: trivial fixes + ibft boot: add offload ibft support to iscsiadm + iscsiadm: only do auto iface setup when iface mode is run + ibft boot: add iscsiadm offload ibft rec support + doc: add iscsistart man page + doc: add iscsi-iname man page + ibft boot: fix dev to iface matching + offload boot: turn off + iscsi tools: nic setup cleanup + iscsi tools: fix compile errors + iscsi kern: fix 2.6.27 compat patch + iscsiadm: add nonpersistent mode to discovery mode + iscsi tool: mv idbm_node_setup_defaults to idbm.c + iscsi tools: cleanup get_global_string_param use + iscsi tools: make config file parser a little smarter. + iscsiadm: mv session management functions to new file + st discovery: fix reopen max handling + iscsid: have iscsid watch for new portals using sendtargets + iscsi tools: mv iscsid request helpers to its own file + iscsi tools: add str prefix to strings.c functions + iscsi tools: use open-isns services + iscsi tools: add MaxXmitDataSegmentLength param + iscsi tools: do not exit on mem alloc failures during discovery + Fix makefile cleanup + iscsid: add isns discovery daemon and SCN support + iscsid: support discovery daemon auto logout + isns: fix compilation + iscsi tools: fix null sysfs string handling + iscsi tools: fix compilation on s390 + Update version number to 872 + iscsi tools: fix MaxXmitDataSegmentLength=0 handling + be2iscsi iscsi tool: fix MaxXmitDataSegmentLength handling + iscsi tools: be2iscsi: fix initial_r2t_en handling + iscsi tools: prep for userspace libiscsi + iscsi tools: add log_info helper + iscsi tools: fix port handling for iscsiadm commands + iscsi tools: fix port handling for iscsiadm commands take 2 + iscsid: fix discoveryd shutdown + iscsi scripts: use iscsiadm -k to shutdown daemon + iscsiadm: fix discovery record management + iscsid: fix sendtargets discovery daemon CHAP handling + iscsiadm: mv disc code to new function + iscsiadm: fix disc port handling + iscsiadm: add new discovery mode + iscsiadm: add isns db support + iscsiadm: cleanup default port handling + iscsid: use isns discovery rec for isns discoveryd setttings + iscsiadm: fix iface mode ENODEV handling + iscsiadm: mark discovery mode as depreciated + sync to upstream + 2.6.33 - 34 kernel compat patch + 2.6.28 - 32 kernel compat patch + 2.6.27 kernel compat patch + 2.6.26 kernel compat patch + 2.6.24 - 25 kernel compat patch + 2.6.14 - 23 kernel compat patch + iscsiadm: fix discovery2 db op return value + iscsiadm: print isns recs in discovery mode + iscsi boot: add support for iscsi boot sysfs module + iscsiadm: rename discovery2 mode as discoverydb + iscsiadm: fix boot code compile error + iscsiadm: fix iface update/delete return value fix + +Ritesh Raj Sarraf (3): + fix some spelling errors reported by lintian + minor manpage updates + Fix CVE-2009-1297 + +Wulf C. Krueger (1): + Use DESTDIR when generating an InitiatorName. diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/doc/iscsiadm.8 open-iscsi-2.0-872-rc4-bnx2i.work/doc/iscsiadm.8 --- open-iscsi-2.0-872-rc4-bnx2i/doc/iscsiadm.8 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/doc/iscsiadm.8 2011-02-24 19:54:10.000000000 -0600 @@ -49,7 +49,13 @@ print debugging information. Valid value display help text and exit .TP -\fB\-I\fR, \fB\-\-interface\fI[iface]\fR +\fB\-H\fR, \fB\-\-host=\fI[hostno]\fR +The host agrument specifies the SCSI host to use for the operation. The +hostno value is the host number assigned to the host by the kernel's +scsi layer. + +.TP +\fB\-I\fR, \fB\-\-interface=\fI[iface]\fR The interface argument specifies the iSCSI interface to use for the operation. iSCSI interfaces (iface) are defined in /etc/iscsi/ifaces. For hardware iSCSI (qla4xxx) the iface config must have the hardware address @@ -294,6 +300,152 @@ or SendTargets (st) discovery type. An SLP implementation is under development. +.SH EXIT STATUS + +On success 0 is returned. On error one of the return codes below will +be returned. + +Commands that operation on multiple objects (sessions, records, etc), +iscsiadm/iscsistart will return the first error that is encountered. +iscsiadm/iscsistart will attempt to execute the operation on the objects it +can. If no objects are found ISCSI_ERR_NO_OBJS_FOUND is returned. + + +.TP +.B +0 +ISCSI_SUCCESS - command executed successfully. + +.TP +.B +1 +ISCSI_ERR - generic error code. + +.TP +.B +2 +ISCSI_ERR_SESS_NOT_FOUND - session could not be found. + +.TP +.B +3 +ISCSI_ERR_NOMEM - could not allocate resource for operation. +.TP +.B +4 +ISCSI_ERR_TRANS - connect problem caused operation to fail. + +.TP +.B +5 +ISCSI_ERR_LOGIN - generic iSCSI login failure. + +.TP +.B +6 +ISCSI_ERR_IDBM - error accessing/managing iSCSI DB. + +.TP +.B +7 +ISCSI_ERR_INVAL - invalid argument. + +.TP +.B +8 +ISCSI_ERR_TRANS_TIMEOUT - connection timer exired while trying to connect. + +.TP +.B +9 +ISCSI_ERR_INTERNAL - generic internal iscsid/kernel failure. + +.TP +.B +10 +ISCSI_ERR_LOGOUT - iSCSI logout failed. + +.TP +.B +11 +ISCSI_ERR_PDU_TIMEOUT - iSCSI PDU timedout. + +.TP +.B +12 +ISCSI_ERR_TRANS_NOT_FOUND - iSCSI transport module not loaded in kernel or iscsid. + +.TP +.B +13 +ISCSI_ERR_ACCESS - did not have proper OS permissions to access iscsid or execute iscsiadm command. + +.TP +.B +14 +ISCSI_ERR_TRANS_CAPS - transport module did not support operation. + +.TP +.B +15 +ISCSI_ERR_SESS_EXISTS - session is logged in. + +.TP +.B +16 +ISCSI_ERR_INVALID_MGMT_REQ - invalid IPC MGMT request. + +.TP +.B +17 +ISCSI_ERR_ISNS_UNAVAILABLE - iSNS service is not supported. + +.TP +.B +18 +ISCSI_ERR_ISCSID_COMM_ERR - a read/write to iscsid failed. + +.TP +.B +19 +ISCSI_ERR_FATAL_LOGIN - fatal iSCSI login error. + +.TP +.B +20 +ISCSI_ERR_ISCSID_NOTCONN - could ont connect to iscsid. + +.TP +.B +21 +ISCSI_ERR_NO_OBJS_FOUND - no records/targets/sessions/portals found to execute operation on. + +.TP +.B +22 +ISCSI_ERR_SYSFS_LOOKUP - could not lookup object in sysfs. + +.TP +.B +23 +ISCSI_ERR_HOST_NOT_FOUND - could not lookup host. + +.TP +.B +24 +ISCSI_ERR_LOGIN_AUTH_FAILED - login failed due to authorization failure. + +.TP +.B +25 +ISCSI_ERR_ISNS_QUERY - iSNS query failure. + +.TP +.B +26 +ISCSI_ERR_ISNS_REG_FAILED - iSNS registration/deregistration failed. + + .SH EXAMPLES .nf diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/etc/initd/initd.suse open-iscsi-2.0-872-rc4-bnx2i.work/etc/initd/initd.suse --- open-iscsi-2.0-872-rc4-bnx2i/etc/initd/initd.suse 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/etc/initd/initd.suse 2011-02-24 19:54:10.000000000 -0600 @@ -30,7 +30,7 @@ iscsi_login_all_nodes() { echo -n "Setting up iSCSI targets: " $ISCSIADM -m node --loginall=automatic 2> /dev/null - if [ $? == 19 ] ; then + if [ $? == 21 ] ; then rc_failed 6 fi rc_status -v @@ -41,7 +41,7 @@ iscsi_logout_all_nodes() echo -n "Closing all iSCSI connections: " # Logout from all sessions marked automatic if ! $ISCSIADM -m node --logoutall=automatic 2> /dev/null; then - if [ $? == 19 ] ; then + if [ $? == 21 ] ; then RETVAL=6 else RETVAL=1 diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_err.h open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_err.h --- open-iscsi-2.0-872-rc4-bnx2i/include/iscsi_err.h 1969-12-31 18:00:00.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_err.h 2011-02-24 19:54:10.000000000 -0600 @@ -0,0 +1,69 @@ +/* + * Return codes used by iSCSI tools. + */ +#ifndef _ISCSI_ERR_ +#define _ISCSI_ERR_ + +enum { + ISCSI_SUCCESS = 0, + /* Generic error */ + ISCSI_ERR = 1, + /* session could not be found */ + ISCSI_ERR_SESS_NOT_FOUND = 2, + /* Could not allocate resource for operation */ + ISCSI_ERR_NOMEM = 3, + /* Transport error caused operation to fail */ + ISCSI_ERR_TRANS = 4, + /* Generic login failure */ + ISCSI_ERR_LOGIN = 5, + /* Error accessing/managing iSCSI DB */ + ISCSI_ERR_IDBM = 6, + /* Invalid argument */ + ISCSI_ERR_INVAL = 7, + /* Connection timer exired while trying to connect */ + ISCSI_ERR_TRANS_TIMEOUT = 8, + /* Generic internal iscsid failure */ + ISCSI_ERR_INTERNAL = 9, + /* Logout failed */ + ISCSI_ERR_LOGOUT = 10, + /* iSCSI PDU timedout */ + ISCSI_ERR_PDU_TIMEOUT = 11, + /* iSCSI transport module not loaded in kernel or iscsid */ + ISCSI_ERR_TRANS_NOT_FOUND = 12, + /* Permission denied */ + ISCSI_ERR_ACCESS = 13, + /* Transport module did not support operation */ + ISCSI_ERR_TRANS_CAPS = 14, + /* Session is logged in */ + ISCSI_ERR_SESS_EXISTS = 15, + /* Invalid IPC MGMT request */ + ISCSI_ERR_INVALID_MGMT_REQ = 16, + /* iSNS service is not supported */ + ISCSI_ERR_ISNS_UNAVAILABLE = 17, + /* A read/write to iscsid failed */ + ISCSI_ERR_ISCSID_COMM_ERR = 18, + /* Fatal login error */ + ISCSI_ERR_FATAL_LOGIN = 19, + /* Could ont connect to iscsid */ + ISCSI_ERR_ISCSID_NOTCONN = 20, + /* No records/targets/sessions/portals found to execute operation on */ + ISCSI_ERR_NO_OBJS_FOUND = 21, + /* Could not lookup object in sysfs */ + ISCSI_ERR_SYSFS_LOOKUP = 22, + /* Could not lookup host */ + ISCSI_ERR_HOST_NOT_FOUND = 23, + /* Login failed due to authorization failure */ + ISCSI_ERR_LOGIN_AUTH_FAILED = 24, + /* iSNS query failure */ + ISCSI_ERR_ISNS_QUERY = 25, + /* iSNS registration/deregistration failed */ + ISCSI_ERR_ISNS_REG_FAILED = 26, + + /* Always last. Indicates end of error code space */ + ISCSI_MAX_ERR_VAL, +} iscsi_err; + +extern void iscsi_err_print_msg(int err); +extern char *iscsi_err_to_str(int err); + +#endif 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/include/iscsi_if.h 2011-02-24 19:54:10.000000000 -0600 @@ -65,6 +65,8 @@ enum iscsi_uevent_e { ISCSI_UEVENT_PATH_UPDATE = UEVENT_BASE + 20, + ISCSI_UEVENT_MAX = ISCSI_UEVENT_PATH_UPDATE, + /* up events */ ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2, @@ -75,6 +77,8 @@ enum iscsi_uevent_e { ISCSI_KEVENT_PATH_REQ = KEVENT_BASE + 7, ISCSI_KEVENT_IF_DOWN = KEVENT_BASE + 8, + + ISCSI_KEVENT_MAX = ISCSI_KEVENT_IF_DOWN, }; enum iscsi_tgt_dscvr { @@ -386,7 +390,7 @@ enum iscsi_host_param { #define CAP_HDRDGST 0x10 #define CAP_DATADGST 0x20 #define CAP_MULTI_CONN 0x40 -#define CAP_TEXT_NEGO 0x80 +#define CAP_TEXT_NEGO 0x80 /* support for text requests */ #define CAP_MARKERS 0x100 #define CAP_FW_DB 0x200 #define CAP_SENDTARGETS_OFFLOAD 0x400 /* offload discovery process */ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/actor.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/actor.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/actor.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/actor.c 2011-02-24 19:54:10.000000000 -0600 @@ -113,14 +113,13 @@ actor_schedule_private(actor_t *thread, * state to scheduled, else add current time to ttschedule and * insert in the queue at the correct point */ if (delay_time == 0) { - if (poll_in_progress) { + /* For head addition, it must go onto the head of the + actor_list regardless if poll is in progress or not + */ + if (poll_in_progress && !head) { thread->state = ACTOR_POLL_WAITING; - if (head) - list_add(&thread->list, - &poll_list); - else - list_add_tail(&thread->list, - &poll_list); + list_add_tail(&thread->list, + &poll_list); } else { thread->state = ACTOR_SCHEDULED; if (head) 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/config.h 2011-02-24 19:54:10.000000000 -0600 @@ -141,7 +141,8 @@ struct iscsi_sendtargets_config { int discoveryd_poll_inval; struct iscsi_auth_config auth; struct iscsi_connection_timeout_config conn_timeo; - struct iscsi_conn_operational_config iscsi; + struct iscsi_conn_operational_config conn_conf; + struct iscsi_session_operational_config session_conf; }; struct iscsi_isns_config { diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgb3i.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgb3i.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/cxgb3i.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgb3i.c 1969-12-31 18:00:00.000000000 -0600 @@ -1,24 +0,0 @@ -/* - * cxgb3i helpers - * - * Copyright (C) 2006 Mike Christie - * Copyright (C) 2006 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ -#include "initiator.h" - -void cxgb3i_create_conn(struct iscsi_conn *conn) -{ - /* card can handle up to 15360 bytes */ - if (conn->max_recv_dlength > 8192) - conn->max_recv_dlength = 8192; -} diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgb3i.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgb3i.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/cxgb3i.h 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgb3i.h 1969-12-31 18:00:00.000000000 -0600 @@ -1,8 +0,0 @@ -#ifndef CXGB3I_TRANSPORT -#define CXGB3I_TRANSPORT - -struct iscsi_conn; - -extern void cxgb3i_create_conn(struct iscsi_conn *conn); - -#endif diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgbi.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgbi.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/cxgbi.c 1969-12-31 18:00:00.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgbi.c 2011-02-24 19:54:10.000000000 -0600 @@ -0,0 +1,24 @@ +/* + * cxgb3i/cxgb4i helpers + * + * Copyright (C) 2006 Mike Christie + * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include "initiator.h" + +void cxgbi_create_conn(struct iscsi_conn *conn) +{ + /* card can handle up to 15360 bytes */ + if (conn->max_recv_dlength > 8192) + conn->max_recv_dlength = 8192; +} diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/cxgbi.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgbi.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/cxgbi.h 1969-12-31 18:00:00.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/cxgbi.h 2011-02-24 19:54:10.000000000 -0600 @@ -0,0 +1,8 @@ +#ifndef CXGBI_TRANSPORT +#define CXGBI_TRANSPORT + +struct iscsi_conn; + +extern void cxgbi_create_conn(struct iscsi_conn *conn); + +#endif diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/discovery.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/discovery.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/discovery.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/discovery.c 2011-02-24 19:54:35.000000000 -0600 @@ -43,6 +43,12 @@ #include "fw_context.h" #include "iscsid_req.h" #include "iscsi_util.h" +#include "transport.h" +#include "iscsi_sysfs.h" +#include "iscsi_ipc.h" +#include "iface.h" +#include "iscsi_timer.h" +#include "iscsi_err.h" /* libisns includes */ #include "isns.h" #include "paths.h" @@ -54,10 +60,9 @@ #define DISCOVERY_NEED_RECONNECT 0xdead0001 -static int rediscover = 0; - static char initiator_name[TARGET_NAME_MAXLEN + 1]; static char initiator_alias[TARGET_NAME_MAXLEN + 1]; +static struct iscsi_ev_context ipc_ev_context; static int request_initiator_name(void) { @@ -75,7 +80,7 @@ static int request_initiator_name(void) rc = iscsid_exec_req(&req, &rsp, 1); if (rc) - return EIO; + return rc; if (rsp.u.config.var[0] != '\0') strcpy(initiator_name, rsp.u.config.var); @@ -107,14 +112,14 @@ int discovery_isns_set_servername(char * if (port > USHRT_MAX) { log_error("Invalid port %d\n", port); - return EINVAL; + return ISCSI_ERR_INVAL; } /* 5 for port and 1 for colon and 1 for null */ len = strlen(address) + 7; server = calloc(1, len); if (!server) - return ENOMEM; + return ISCSI_ERR_NOMEM; snprintf(server, len, "%s:%d", address, port); isns_assign_string(&isns_config.ic_server_name, server); @@ -136,11 +141,11 @@ int discovery_isns_query(struct discover isns_config.ic_security = 0; source = isns_source_create_iscsi(iname); if (!source) - return ENOMEM; + return ISCSI_ERR_NOMEM; clnt = isns_create_client(NULL, iname); if (!clnt) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto free_src; } @@ -158,7 +163,7 @@ int discovery_isns_query(struct discover qry = isns_create_query2(clnt, &key_attrs, source); if (!qry) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto free_clnt; } @@ -177,11 +182,11 @@ int discovery_isns_query(struct discover break; case ISNS_SOURCE_UNKNOWN: /* server requires that we are registered but we are not */ - rc = ENOENT; + rc = ISCSI_ERR_ISNS_REG_FAILED; goto free_query; default: log_error("iSNS discovery failed: %s", isns_strerror(status)); - rc = EIO; + rc = ISCSI_ERR_ISNS_QUERY; goto free_query; } @@ -189,7 +194,7 @@ int discovery_isns_query(struct discover if (status) { log_error("Unable to extract object list from query " "response: %s\n", isns_strerror(status)); - rc = EIO; + rc = ISCSI_ERR; goto free_query; } @@ -239,7 +244,7 @@ int discovery_isns_query(struct discover rec = calloc(1, sizeof(*rec)); if (!rec) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto destroy_list; } @@ -291,11 +296,11 @@ static int discovery_isns_reg_node(const source = isns_source_create_iscsi(iname); if (!source) - return ENOMEM; + return ISCSI_ERR_NOMEM; clnt = isns_create_client(NULL, iname); if (!clnt) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto free_src; } @@ -303,7 +308,7 @@ static int discovery_isns_reg_node(const ISNS_DEVICE_DEREGISTER, source, NULL); if (!reg) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto free_clnt; } @@ -318,7 +323,7 @@ static int discovery_isns_reg_node(const log_error("Could not %s %s with iSNS server: %s.", reg ? "register" : "deregister", iname, isns_strerror(status)); - rc = EIO; + rc = ISCSI_ERR_ISNS_REG_FAILED; } else log_debug(1, "%s %s with iSNS server successful.", op_reg ? "register" : "deregister", iname); @@ -339,11 +344,17 @@ int discovery_isns(void *data, struct if if (iface && strlen(iface->iname)) iname = iface->iname; else { - if (request_initiator_name() || initiator_name[0] == '\0') { + rc = request_initiator_name(); + if (rc) { log_error("Cannot perform discovery. Initiatorname " "required."); - return EINVAL; + return rc; + } else if (initiator_name[0] == '\0') { + log_error("Cannot perform discovery. Invalid " + "Initiatorname."); + return ISCSI_ERR_INVAL; } + iname = initiator_name; } @@ -352,7 +363,7 @@ int discovery_isns(void *data, struct if return rc; retry: rc = discovery_isns_query(drec, iname, NULL, rec_list); - if (!registered && rc == ENOENT) { + if (!registered && rc == ISCSI_ERR_ISNS_REG_FAILED) { rc = discovery_isns_reg_node(iname, 1); if (!rc) { registered = 1; @@ -396,7 +407,7 @@ int discovery_fw(void *data, struct ifac if (!rec) { log_error("Could not convert firmware info to " "node record.\n"); - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto free_targets; } rec->disc_type = drec->type; @@ -428,10 +439,10 @@ int discovery_offload_sendtargets(int ho /* resolve the DiscoveryAddress to an IP address */ sprintf(default_port, "%d", drec->port); - if (resolve_address(drec->address, default_port, &ss)) { - log_error("Cannot resolve host name %s.", drec->address); - return EIO; - } + rc = resolve_address(drec->address, default_port, &ss); + if (rc) + return rc; + req.u.st.ss = ss; /* @@ -447,8 +458,8 @@ int discovery_offload_sendtargets(int ho if (rc) { log_error("Could not offload sendtargets to %s.\n", drec->address); - iscsid_handle_error(rc); - return EIO; + iscsi_err_print_msg(rc); + return rc; } return 0; @@ -490,15 +501,12 @@ request_targets(iscsi_session_t *session if (!iscsi_add_text(hdr, data, sizeof (data), "SendTargets", "All")) { log_error("failed to add SendTargets text key"); - exit(1); + return 0; } text.ttt = ISCSI_RESERVED_TAG; text.flags = ISCSI_FLAG_CMD_FINAL; - if (++session->itt == ISCSI_RESERVED_TAG) - session->itt = 1; - if (!iscsi_io_send_pdu(&session->conn[0], hdr, ISCSI_DIGEST_NONE, data, ISCSI_DIGEST_NONE, session->conn[0].active_timeout)) { log_error("failed to send SendTargets PDU"); @@ -527,9 +535,6 @@ iterate_targets(iscsi_session_t *session text.ttt = ttt; text.flags = ISCSI_FLAG_CMD_FINAL; - if (++session->itt == ISCSI_RESERVED_TAG) - session->itt = 1; - if (!iscsi_io_send_pdu(&session->conn[0], pdu, ISCSI_DIGEST_NONE, data, ISCSI_DIGEST_NONE, session->conn[0].active_timeout)) { log_error("failed to send empty text PDU"); @@ -543,19 +548,13 @@ static int add_portal(struct list_head * char *targetname, char *address, char *port, char *tag) { struct sockaddr_storage ss; - char host[NI_MAXHOST]; struct node_rec *rec; - /* resolve the address, in case it was a DNS name */ if (resolve_address(address, port, &ss)) { log_error("cannot resolve %s", address); return 0; } - /* convert the resolved name to text */ - getnameinfo((struct sockaddr *) &ss, sizeof(ss), - host, sizeof(host), NULL, 0, NI_NUMERICHOST); - rec = calloc(1, sizeof(*rec)); if (!rec) return 0; @@ -582,7 +581,7 @@ static int add_portal(struct list_head * static int add_target_record(char *name, char *end, discovery_rec_t *drec, - struct list_head *rec_list, char *default_port) + struct list_head *rec_list) { char *text = NULL; char *nul = name; @@ -625,11 +624,16 @@ add_target_record(char *name, char *end, log_error("no default address known for target %s", name); return 0; - } else if (!add_portal(rec_list, drec, name, drec->address, - default_port, NULL)) { - log_error("failed to add default portal, ignoring " - "target %s", name); - return 0; + } else { + char default_port[NI_MAXSERV]; + + sprintf(default_port, "%d", drec->port); + if (!add_portal(rec_list, drec, name, drec->address, + default_port, NULL)) { + log_error("failed to add default portal, " + "ignoring target %s", name); + return 0; + } } /* finished adding the default */ return 1; @@ -681,8 +685,7 @@ add_target_record(char *name, char *end, static int process_sendtargets_response(struct str_buffer *sendtargets, int final, discovery_rec_t *drec, - struct list_head *rec_list, - char *default_port) + struct list_head *rec_list) { char *start = str_buffer_data(sendtargets); char *text = start; @@ -733,8 +736,7 @@ process_sendtargets_response(struct str_ * "TargetName=" prefix. */ if (!add_target_record(record + 11, text, - drec, rec_list, - default_port)) { + drec, rec_list)) { log_error( "failed to add target record"); str_truncate_buffer(sendtargets, 0); @@ -762,7 +764,7 @@ process_sendtargets_response(struct str_ "line %s", record, record); if (add_target_record (record + 11, text, - drec, rec_list, default_port)) { + drec, rec_list)) { num_targets++; record = NULL; str_truncate_buffer(sendtargets, 0); @@ -792,110 +794,47 @@ process_sendtargets_response(struct str_ return 1; } -static void -clear_timer(struct timeval *timer) -{ - memset(timer, 0, sizeof (*timer)); -} - -/* set timer to now + seconds */ -static void -set_timer(struct timeval *timer, int seconds) -{ - if (timer) { - memset(timer, 0, sizeof (*timer)); - gettimeofday(timer, NULL); - - timer->tv_sec += seconds; - } -} - -static int -timer_expired(struct timeval *timer) -{ - struct timeval now; - - /* no timer, can't have expired */ - if ((timer == NULL) || ((timer->tv_sec == 0) && (timer->tv_usec == 0))) - return 0; - - memset(&now, 0, sizeof (now)); - gettimeofday(&now, NULL); - - if (now.tv_sec > timer->tv_sec) - return 1; - if ((now.tv_sec == timer->tv_sec) && (now.tv_usec >= timer->tv_usec)) - return 1; - return 0; -} - -static int -msecs_until(struct timeval *timer) +static void iscsi_free_session(struct iscsi_session *session) { - struct timeval now; - int msecs; - long partial; - - /* no timer, can't have expired, infinite time til it expires */ - if ((timer == NULL) || ((timer->tv_sec == 0) && (timer->tv_usec == 0))) - return -1; - - memset(&now, 0, sizeof (now)); - gettimeofday(&now, NULL); - - /* already expired? */ - if (now.tv_sec > timer->tv_sec) - return 0; - if ((now.tv_sec == timer->tv_sec) && (now.tv_usec >= timer->tv_usec)) - return 0; - - /* not expired yet, do the math */ - partial = timer->tv_usec - now.tv_usec; - if (partial < 0) { - partial += 1000 * 1000; - msecs = (partial + 500) / 1000; - msecs += (timer->tv_sec - now.tv_sec - 1) * 1000; - } else { - msecs = (partial + 500) / 1000; - msecs += (timer->tv_sec - now.tv_sec) * 1000; - } - - return msecs; + list_del_init(&session->list); + free(session); } static iscsi_session_t * -init_new_session(struct iscsi_sendtargets_config *config, - struct iface_rec *iface) +iscsi_alloc_session(struct iscsi_sendtargets_config *config, + struct iface_rec *iface, int *rc) { iscsi_session_t *session; + *rc = 0; + session = calloc(1, sizeof (*session)); - if (session == NULL) - goto done; + if (session == NULL) { + *rc = ISCSI_ERR_NOMEM; + return NULL; + } + + session->t = iscsi_sysfs_get_transport_by_name(iface->transport_name); + if (!session->t) { + log_error("iSCSI driver %s is not loaded. Load the module " + "then retry the command.\n", iface->transport_name); + *rc = ISCSI_ERR_TRANS_NOT_FOUND; + goto fail; + } + INIT_LIST_HEAD(&session->list); /* initialize the session's leading connection */ + session->conn[0].id = 0; session->conn[0].socket_fd = -1; + session->conn[0].session = session; session->conn[0].login_timeout = config->conn_timeo.login_timeout; session->conn[0].auth_timeout = config->conn_timeo.auth_timeout; session->conn[0].active_timeout = config->conn_timeo.active_timeout; - session->conn[0].hdrdgst_en = ISCSI_DIGEST_NONE; - session->conn[0].datadgst_en = ISCSI_DIGEST_NONE; - - session->conn[0].max_recv_dlength = - config->iscsi.MaxRecvDataSegmentLength; - if (session->conn[0].max_recv_dlength < ISCSI_MIN_MAX_RECV_SEG_LEN || - session->conn[0].max_recv_dlength > ISCSI_MAX_MAX_RECV_SEG_LEN) { - log_error("Invalid iscsi.MaxRecvDataSegmentLength. Must be " - "within %u and %u. Setting to %u.", - ISCSI_MIN_MAX_RECV_SEG_LEN, - ISCSI_MAX_MAX_RECV_SEG_LEN, - DEF_INI_DISC_MAX_RECV_SEG_LEN); - session->conn[0].max_recv_dlength = - DEF_INI_DISC_MAX_RECV_SEG_LEN; - } - session->conn[0].max_xmit_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN; - + session->conn[0].noop_out_timeout = 0; + session->conn[0].noop_out_interval = 0; session->reopen_cnt = config->reopen_max + 1; + iscsi_copy_operational_params(&session->conn[0], &config->session_conf, + &config->conn_conf); /* OUI and uniqifying number */ session->isid[0] = DRIVER_ISID_0; @@ -905,111 +844,41 @@ init_new_session(struct iscsi_sendtarget session->isid[4] = 0; session->isid[5] = 0; - request_initiator_name(); - if (iface && strlen(iface->iname)) { strcpy(initiator_name, iface->iname); /* MNC TODO add iface alias */ } else { - if (initiator_name[0] == '\0') { + *rc = request_initiator_name(); + if (*rc) { log_error("Cannot perform discovery. Initiatorname " "required."); - free(session); - return NULL; + goto fail; + } else if (initiator_name[0] == '\0') { + log_error("Cannot perform discovery. Invalid " + "Initiatorname."); + *rc = ISCSI_ERR_INVAL; + goto fail; } } + iface_copy(&session->nrec.iface, iface); session->initiator_name = initiator_name; session->initiator_alias = initiator_alias; session->portal_group_tag = PORTAL_GROUP_TAG_UNKNOWN; session->type = ISCSI_SESSION_TYPE_DISCOVERY; -done: - return session; -} + session->id = -1; + /* setup authentication variables for the session*/ + *rc = iscsi_setup_authentication(session, &config->auth); + if (*rc) + goto fail; -static int -setup_authentication(iscsi_session_t *session, - discovery_rec_t *drec, - struct iscsi_sendtargets_config *config) -{ - int rc; - - rc = 1; - - /* if we have any incoming credentials, we insist on authenticating - * the target or not logging in at all - */ - if (config->auth.username_in[0] - || config->auth.password_in_length) { - session->bidirectional_auth = 1; - - /* sanity check the config */ - if (config->auth.password_length == 0) { - log_error( - "discovery process to %s:%d has incoming " - "authentication credentials but has no outgoing " - "credentials configured", - drec->address, drec->port); - log_error( - "discovery process to %s:%d exiting, bad " - "configuration", - drec->address, drec->port); - rc = 0; - goto done; - } - } else { - /* no or 1-way authentication */ - session->bidirectional_auth = 0; - } - - /* copy in whatever credentials we have */ - strlcpy(session->username, config->auth.username, - sizeof (session->username)); - session->username[sizeof (session->username) - 1] = '\0'; - if ((session->password_length = config->auth.password_length)) - memcpy(session->password, config->auth.password, - session->password_length); - - strlcpy(session->username_in, config->auth.username_in, - sizeof (session->username_in)); - session->username_in[sizeof (session->username_in) - 1] = '\0'; - if ((session->password_in_length = - config->auth.password_in_length)) - memcpy(session->password_in, config->auth.password_in, - session->password_in_length); - - if (session->password_length || session->password_in_length) { - /* setup the auth buffers */ - session->auth_buffers[0].address = &session->auth_client_block; - session->auth_buffers[0].length = - sizeof (session->auth_client_block); - session->auth_buffers[1].address = - &session->auth_recv_string_block; - session->auth_buffers[1].length = - sizeof (session->auth_recv_string_block); - - session->auth_buffers[2].address = - &session->auth_send_string_block; - session->auth_buffers[2].length = - sizeof (session->auth_send_string_block); - - session->auth_buffers[3].address = - &session->auth_recv_binary_block; - session->auth_buffers[3].length = - sizeof (session->auth_recv_binary_block); - - session->auth_buffers[4].address = - &session->auth_send_binary_block; - session->auth_buffers[4].length = - sizeof (session->auth_send_binary_block); + list_add_tail(&session->list, &session->t->sessions); + return session; - session->num_auth_buffers = 5; - } else { - session->num_auth_buffers = 0; - } - done: - return(rc); +fail: + free(session); + return NULL; } static int @@ -1018,7 +887,6 @@ process_recvd_pdu(struct iscsi_hdr *pdu, struct list_head *rec_list, iscsi_session_t *session, struct str_buffer *sendtargets, - char *default_port, int *active, int *valid_text, char *data) @@ -1063,8 +931,7 @@ process_recvd_pdu(struct iscsi_hdr *pdu, process_sendtargets_response(sendtargets, final, drec, - rec_list, - default_port); + rec_list); if (final) { /* SendTargets exchange is now complete @@ -1096,11 +963,9 @@ process_recvd_pdu(struct iscsi_hdr *pdu, } /* - * Make a best effort to logout the session, then disconnect the - * socket. + * Make a best effort to logout the session. */ -static void -iscsi_logout_and_disconnect(iscsi_session_t * session) +static void iscsi_logout(iscsi_session_t * session) { struct iscsi_logout logout_req; struct iscsi_logout_rsp logout_resp; @@ -1128,7 +993,7 @@ iscsi_logout_and_disconnect(iscsi_sessio if (!rc) { log_error( "iscsid: iscsi_logout - failed to send logout PDU."); - goto done; + return; } /* @@ -1138,117 +1003,278 @@ iscsi_logout_and_disconnect(iscsi_sessio rc = iscsi_io_recv_pdu(&session->conn[0], (struct iscsi_hdr *)&logout_resp, ISCSI_DIGEST_NONE, NULL, 0, ISCSI_DIGEST_NONE, 1); - if (!rc) { + if (rc < 0) { log_error("iscsid: logout - failed to receive logout resp"); - goto done; + return; } if (logout_resp.response != ISCSI_LOGOUT_SUCCESS) { log_error("iscsid: logout failed - response = 0x%x", logout_resp.response); } +} + +static void iscsi_destroy_session(struct iscsi_session *session) +{ + struct iscsi_transport *t = session->t; + struct iscsi_conn *conn = &session->conn[0]; + int rc; + + if (session->id == -1) + return; + + if (!(t->caps & CAP_TEXT_NEGO)) { + iscsi_io_disconnect(&session->conn[0]); + goto done; + } + + log_debug(2, "%s ep disconnect", __FUNCTION__); + t->template->ep_disconnect(conn); + + log_debug(2, "stop conn"); + rc = ipc->stop_conn(session->t->handle, session->id, + conn->id, STOP_CONN_TERM); + if (rc) { + log_error("Could not stop conn %d:%d cleanly (err %d)\n", + session->id, conn->id, rc); + goto done; + } + log_debug(2, "%s destroy conn", __FUNCTION__); + rc = ipc->destroy_conn(session->t->handle, session->id, conn->id); + if (rc) { + log_error("Could not safely destroy conn %d:%d (err %d)", + session->id, conn->id, rc); + goto done; + } + + log_debug(2, "%s destroy session", __FUNCTION__); + rc = ipc->destroy_session(session->t->handle, session->id); + if (rc) + log_error("Could not safely destroy session %d (err %d)", + session->id, rc); done: - /* - * Close the socket. - */ - iscsi_io_disconnect(&session->conn[0]); + if (conn->socket_fd >= 0) { + ipc->ctldev_close(); + conn->socket_fd = -1; + } + session->id = -1; } -int discovery_sendtargets(void *fndata, struct iface_rec *iface, - struct list_head *rec_list) +static int iscsi_create_leading_conn(struct iscsi_session *session) { - discovery_rec_t *drec = fndata; - iscsi_session_t *session; - struct pollfd pfd; - struct iscsi_hdr pdu_buffer; - struct iscsi_hdr *pdu = &pdu_buffer; - char *data = NULL; - int active = 0, valid_text = 0; - struct timeval connection_timer; - int timeout; - int rc; - struct str_buffer sendtargets; - uint8_t status_class = 0, status_detail = 0; - unsigned int login_failures = 0, data_len; - int login_delay = 0; - struct sockaddr_storage ss; - char host[NI_MAXHOST], serv[NI_MAXSERV], default_port[NI_MAXSERV]; - struct iscsi_sendtargets_config *config = &drec->u.sendtargets; + struct iface_rec *iface = &session->nrec.iface; + struct iscsi_transport *t = session->t; + struct iscsi_conn *conn = &session->conn[0]; + uint32_t host_no; + int rc, sleep_count = 0; - /* initial setup */ - log_debug(1, "starting sendtargets discovery, address %s:%d, ", - drec->address, drec->port); - memset(&pdu_buffer, 0, sizeof (pdu_buffer)); - clear_timer(&connection_timer); + if (!(t->caps & CAP_TEXT_NEGO)) { + /* + * If the LLD does not support TEXT PDUs then we do + * discovery in userspace. + */ + session->use_ipc = 0; - /* allocate a new session, and initialize default values */ - session = init_new_session(config, iface); - if (session == NULL) { - log_error("Discovery process to %s:%d failed to " - "create a discovery session.", - drec->address, drec->port); - return 1; + if (!iscsi_io_connect(conn)) + return ISCSI_ERR_TRANS; + + session->id = 1; + return 0; } + session->use_ipc = 1; - log_debug(4, "sendtargets discovery to %s:%d using " - "isid 0x%02x%02x%02x%02x%02x%02x", - drec->address, drec->port, session->isid[0], - session->isid[1], session->isid[2], session->isid[3], - session->isid[4], session->isid[5]); + /* + * for software this is the tcp socket fd set in iscsi_io_connect + * and for offload this is the iscsi netlink socket fd + */ + conn->socket_fd = ipc->ctldev_open(); + if (conn->socket_fd < 0) { + log_error("Could not open netlink interface (err %d)\n", + errno); + return ISCSI_ERR_INTERNAL; + } - /* allocate data buffers for SendTargets data */ - data = malloc(session->conn[0].max_recv_dlength); - if (!data) { - rc = 1; - goto free_session; + host_no = iscsi_sysfs_get_host_no_from_hwinfo(iface, &rc); + if (!rc) { + /* + * if the netdev or mac was set, then we are going to want + * to want to bind the all the conns/eps to a specific host + * if offload is used. + */ + session->conn[0].bind_ep = 1; + session->hostno = host_no; } - data_len = session->conn[0].max_recv_dlength; - str_init_buffer(&sendtargets, 0); + rc = iscsi_host_set_net_params(iface, session); + if (rc) { + log_error("Could not set host net params (err %d)\n", + rc); + rc = ISCSI_ERR_INTERNAL; + goto close_ipc; + } + + /* create interconnect endpoint */ + log_debug(2, "%s discovery ep connect\n", __FUNCTION__); + rc = t->template->ep_connect(conn, 1); + if (rc < 0) { + rc = ISCSI_ERR_TRANS; + goto close_ipc; + } + + do { + rc = t->template->ep_poll(conn, 1); + if (rc < 0) { + rc = ISCSI_ERR_TRANS; + goto disconnect; + } else if (rc == 0) { + if (sleep_count == conn->login_timeout) { + rc = ISCSI_ERR_TRANS_TIMEOUT; + goto disconnect; + } + sleep_count++; + sleep(1); + } else + break; + } while (1); - sprintf(default_port, "%d", drec->port); - /* resolve the DiscoveryAddress to an IP address */ - if (resolve_address(drec->address, default_port, &ss)) { - log_error("cannot resolve host name %s", drec->address); - rc = 1; - goto free_sendtargets; + log_debug(2, "%s discovery create session\n", __FUNCTION__); + /* create kernel structs */ + rc = ipc->create_session(session->t->handle, + conn->transport_ep_handle, 1, 32, 1, + &session->id, &host_no); + if (rc) { + log_error("Could not create kernel session (err %d).\n", rc); + rc = ISCSI_ERR_INTERNAL; + goto disconnect; + } + log_debug(2, "%s discovery created session %u\n", __FUNCTION__, + session->id); + session->isid[3] = session->id; + + log_debug(2, "%s discovery create conn\n", __FUNCTION__); + rc = ipc->create_conn(t->handle, session->id, conn->id, &conn->id); + if (rc) { + log_error("Could not create connection (err %d)", rc); + rc = ISCSI_ERR_INTERNAL; + goto disconnect; + } + + log_debug(2, "%s discovery bind conn\n", __FUNCTION__); + if (ipc->bind_conn(t->handle, session->id, conn->id, + conn->transport_ep_handle, (conn->id == 0), &rc) || + rc) { + log_error("Could not bind conn %d:%d to session %d, " + "(err %d)", session->id, conn->id, + session->id, rc); + rc = ISCSI_ERR_INTERNAL; + goto disconnect; } - log_debug(4, "discovery timeouts: login %d, reopen_cnt %d, auth %d.", - session->conn[0].login_timeout, session->reopen_cnt, - session->conn[0].auth_timeout); + /* all set */ + return 0; - /* setup authentication variables for the session*/ - rc = setup_authentication(session, drec, config); - if (rc == 0) { - rc = 1; - goto free_sendtargets; +disconnect: + t->template->ep_disconnect(conn); + + if (session->id != -1 && + iscsi_sysfs_session_has_leadconn(session->id)) { + if (ipc->destroy_conn(session->t->handle, session->id, + conn->id)) + log_error("Could not safely destroy connection %d:%d", + session->id, conn->id); + } + + if (session->id != -1) { + if (ipc->destroy_session(session->t->handle, session->id)) + log_error("Could not safely destroy session %d", + session->id); + session->id = -1; + } + +close_ipc: + if (conn->socket_fd >= 0) { + ipc->ctldev_close(); + conn->socket_fd = -1; + } + + log_error("Connection to discovery portal %s failed: %s", + conn->host, iscsi_err_to_str(rc)); + return rc; +} + +static struct iscsi_ev_context * +iscsi_ev_context_get(struct iscsi_conn *conn, int ev_size) +{ + log_debug(2, "%s: ev_size %d\n", __FUNCTION__, ev_size); + + ipc_ev_context.data = calloc(1, ev_size); + if (!ipc_ev_context.data) + return NULL; + + return &ipc_ev_context; +} + +static void iscsi_ev_context_put(struct iscsi_ev_context *ev_context) +{ + if (ev_context->data) + free(ev_context->data); + ev_context->data = NULL; +} + +static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context, + struct iscsi_conn *conn, unsigned long tmo, + int event) +{ + if (event == EV_CONN_RECV_PDU) { + conn->recv_context = ev_context; + return 0; } + return -EIO; +} + +static struct iscsi_ipc_ev_clbk ipc_clbk = { + .get_ev_context = iscsi_ev_context_get, + .put_ev_context = iscsi_ev_context_put, + .sched_ev_context = iscsi_sched_ev_context, +}; + +static int iscsi_create_session(struct iscsi_session *session, + struct iscsi_sendtargets_config *config, + char *data, unsigned int data_len) +{ + struct iscsi_conn *conn = &session->conn[0]; + int login_status, rc = 0, login_delay = 0; + uint8_t status_class = 0, status_detail = 0; + unsigned int login_failures = 0; + char serv[NI_MAXSERV]; + struct iscsi_transport *t = session->t; + set_address: /* * copy the saved address to the session, * undoing any temporary redirect */ - session->conn[0].saddr = ss; + conn->saddr = conn->failback_saddr; reconnect: - + /* fix decrement and test */ if (--session->reopen_cnt < 0) { - log_error("connection login retries (reopen_max %d) exceeded", + log_error("connection login retries (reopen_max) %d exceeded", config->reopen_max); - rc = 1; - goto free_sendtargets; + goto login_failed; } redirect_reconnect: - - iscsi_io_disconnect(&session->conn[0]); - session->cmdsn = 1; session->itt = 1; session->portal_group_tag = PORTAL_GROUP_TAG_UNKNOWN; + /* + * On reconnect, just destroy the kernel structs and start over. + */ + iscsi_destroy_session(session); + /* slowly back off the frequency of login attempts */ if (login_failures == 0) login_delay = 0; @@ -1263,47 +1289,44 @@ redirect_reconnect: else login_delay = 60; /* after 2 minutes, try once a minute */ + getnameinfo((struct sockaddr *) &conn->saddr, + sizeof(conn->saddr), conn->host, + sizeof(conn->host), serv, sizeof(serv), + NI_NUMERICHOST|NI_NUMERICSERV); + if (login_delay) { - log_debug(4, "discovery session to %s:%d sleeping for %d " + log_debug(4, "discovery session to %s:%s sleeping for %d " "seconds before next login attempt", - drec->address, drec->port, login_delay); + conn->host, serv, login_delay); sleep(login_delay); } - - getnameinfo((struct sockaddr *) &session->conn[0].saddr, - sizeof(session->conn[0].saddr), host, - sizeof(host), serv, sizeof(serv), - NI_NUMERICHOST|NI_NUMERICSERV); - - if (!iscsi_io_connect(&session->conn[0])) { - log_error("connection to discovery address %s " - "failed", host); - + rc = iscsi_create_leading_conn(session); + if (rc) { login_failures++; - /* If a temporary redirect sent us to something unreachable, - * we want to go back to the original IP address, so make sure - * we reset the session's IP. - */ - goto set_address; + goto reconnect; } - log_debug(1, "connected to discovery address %s", host); + log_debug(1, "connected to discovery address %s", conn->host); - log_debug(4, "discovery session to %s:%d starting iSCSI login on fd %d", - drec->address, drec->port, session->conn[0].socket_fd); + log_debug(4, "discovery session to %s:%s starting iSCSI login", + conn->host, serv); - /* In case of discovery, we using socket's descriptor as ctrl. */ - session->ctrl_fd = session->conn[0].socket_fd; - session->conn[0].session = session; + /* + * Need to re-init settings because a previous login could + * have set them to what was negotiated for. + */ + iscsi_copy_operational_params(&session->conn[0], &config->session_conf, + &config->conn_conf); status_class = 0; status_detail = 0; + rc = ISCSI_ERR_LOGIN; memset(data, 0, data_len); - rc = iscsi_login(session, 0, data, data_len, - &status_class, &status_detail); + login_status = iscsi_login(session, 0, data, data_len, + &status_class, &status_detail); - switch (rc) { + switch (login_status) { case LOGIN_OK: case LOGIN_REDIRECT: break; @@ -1311,8 +1334,7 @@ redirect_reconnect: case LOGIN_IO_ERROR: case LOGIN_REDIRECTION_FAILED: /* try again */ - log_warning("retrying discovery login to %s", host); - iscsi_io_disconnect(&session->conn[0]); + log_warning("retrying discovery login to %s", conn->host); login_failures++; goto set_address; @@ -1322,16 +1344,16 @@ redirect_reconnect: case LOGIN_AUTHENTICATION_FAILED: case LOGIN_VERSION_MISMATCH: case LOGIN_INVALID_PDU: - log_error("discovery login to %s failed, giving up", host); - iscsi_io_disconnect(&session->conn[0]); - rc = 1; - goto free_sendtargets; + log_error("discovery login to %s failed, giving up %d", + conn->host, login_status); + rc = ISCSI_ERR_FATAL_LOGIN; + goto login_failed; } /* check the login status */ switch (status_class) { case ISCSI_STATUS_CLS_SUCCESS: - log_debug(4, "discovery login success to %s", host); + log_debug(4, "discovery login success to %s", conn->host); login_failures = 0; break; case ISCSI_STATUS_CLS_REDIRECT: @@ -1343,14 +1365,16 @@ redirect_reconnect: case ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP: log_warning( "discovery login temporarily redirected to " - "%s port %s", host, serv); + "%s port %s", conn->host, serv); goto redirect_reconnect; case ISCSI_LOGIN_STATUS_TGT_MOVED_PERM: log_warning( "discovery login permanently redirected to " - "%s port %s", host, serv); + "%s port %s", conn->host, serv); /* make the new address permanent */ - ss = session->conn[0].saddr; + memset(&conn->failback_saddr, 0, + sizeof(struct sockaddr_storage)); + conn->failback_saddr = conn->saddr; goto redirect_reconnect; default: log_error( @@ -1361,32 +1385,130 @@ redirect_reconnect: } break; case ISCSI_STATUS_CLS_INITIATOR_ERR: - log_error( - "discovery login to %s rejected: " - "initiator error (%02x/%02x), non-retryable, giving up", - host, status_class, status_detail); - iscsi_io_disconnect(&session->conn[0]); - rc = 1; - goto free_sendtargets; + switch (status_detail) { + case ISCSI_LOGIN_STATUS_AUTH_FAILED: + case ISCSI_LOGIN_STATUS_TGT_FORBIDDEN: + log_error("discovery login to %s rejected: " + "initiator failed authorization\n", + conn->host); + rc = ISCSI_ERR_LOGIN_AUTH_FAILED; + goto login_failed; + default: + log_error("discovery login to %s rejected: initiator " + "error (%02x/%02x), non-retryable, giving up", + conn->host, status_class, status_detail); + rc = ISCSI_ERR_FATAL_LOGIN; + } + goto login_failed; case ISCSI_STATUS_CLS_TARGET_ERR: log_error( "discovery login to %s rejected: " "target error (%02x/%02x)", - host, status_class, status_detail); - iscsi_io_disconnect(&session->conn[0]); + conn->host, status_class, status_detail); login_failures++; goto reconnect; default: log_error( "discovery login to %s failed, response " "with unknown status class 0x%x, detail 0x%x", - host, + conn->host, status_class, status_detail); - iscsi_io_disconnect(&session->conn[0]); login_failures++; goto reconnect; } + if (!(t->caps & CAP_TEXT_NEGO)) + return 0; + + log_debug(2, "%s discovery set params\n", __FUNCTION__); + rc = iscsi_session_set_params(conn); + if (rc) { + log_error("Could not set iscsi params for conn %d:%d (err " + "%d)\n", session->id, conn->id, rc); + rc = ISCSI_ERR_INTERNAL; + goto login_failed; + } + + log_debug(2, "%s discovery start conn\n", __FUNCTION__); + if (ipc->start_conn(t->handle, session->id, conn->id, &rc) || rc) { + log_error("Cannot start conn %d:%d (err %d)", + session->id, conn->id, rc); + rc = ISCSI_ERR_INTERNAL; + goto login_failed; + } + + return 0; + +login_failed: + iscsi_destroy_session(session); + return rc; +} + +int discovery_sendtargets(void *fndata, struct iface_rec *iface, + struct list_head *rec_list) +{ + discovery_rec_t *drec = fndata; + iscsi_session_t *session; + struct pollfd pfd; + struct iscsi_hdr pdu_buffer; + struct iscsi_hdr *pdu = &pdu_buffer; + char *data = NULL; + int active = 0, valid_text = 0; + struct timeval connection_timer; + int timeout; + int rc = 0; + struct str_buffer sendtargets; + unsigned int data_len; + struct iscsi_sendtargets_config *config = &drec->u.sendtargets; + + /* initial setup */ + log_debug(1, "starting sendtargets discovery, address %s:%d, ", + drec->address, drec->port); + memset(&pdu_buffer, 0, sizeof (pdu_buffer)); + iscsi_timer_clear(&connection_timer); + + /* allocate a new session, and initialize default values */ + session = iscsi_alloc_session(config, iface, &rc); + if (rc) + return rc; + + ipc_ev_context.conn = &session->conn[0]; + ipc_register_ev_callback(&ipc_clbk); + + log_debug(4, "sendtargets discovery to %s:%d using " + "isid 0x%02x%02x%02x%02x%02x%02x", + drec->address, drec->port, session->isid[0], + session->isid[1], session->isid[2], session->isid[3], + session->isid[4], session->isid[5]); + + /* allocate data buffers for SendTargets data */ + data = malloc(session->conn[0].max_recv_dlength); + if (!data) { + rc = ISCSI_ERR_NOMEM; + goto free_session; + } + data_len = session->conn[0].max_recv_dlength; + + str_init_buffer(&sendtargets, 0); + + /* resolve the DiscoveryAddress to an IP address */ + rc = iscsi_setup_portal(&session->conn[0], drec->address, + drec->port); + if (rc) { + log_error("cannot resolve host name %s", drec->address); + goto free_sendtargets; + } + + log_debug(4, "discovery timeouts: login %d, reopen_cnt %d, auth %d.", + session->conn[0].login_timeout, session->reopen_cnt, + session->conn[0].auth_timeout); + +reconnect: + rc = iscsi_create_session(session, &drec->u.sendtargets, + data, data_len); + if (rc) + goto free_sendtargets; + /* reinitialize */ str_truncate_buffer(&sendtargets, 0); @@ -1397,7 +1519,7 @@ redirect_reconnect: active = 1; /* set timeouts */ - set_timer(&connection_timer, session->conn[0].active_timeout); + iscsi_timer_set(&connection_timer, session->conn[0].active_timeout); /* prepare to poll */ memset(&pfd, 0, sizeof (pfd)); @@ -1405,7 +1527,7 @@ redirect_reconnect: pfd.events = POLLIN | POLLPRI; repoll: - timeout = msecs_until(&connection_timer); + timeout = iscsi_timer_msecs_until(&connection_timer); /* block until we receive a PDU, a TCP FIN, a TCP RST, * or a timeout */ @@ -1422,31 +1544,30 @@ repoll: "discovery process to %s:%d returned from poll, rc %d", drec->address, drec->port, rc); - if (timer_expired(&connection_timer)) { - log_warning("discovery session to %s:%d session " - "logout, connection timer expired", + if (iscsi_timer_expired(&connection_timer)) { + log_warning("Discovery session to %s:%d timed out.", drec->address, drec->port); - iscsi_logout_and_disconnect(session); - rc = 1; - goto free_sendtargets; + rc = ISCSI_ERR_TRANS_TIMEOUT; + goto reconnect; } if (rc > 0) { if (pfd.revents & (POLLIN | POLLPRI)) { - timeout = msecs_until(&connection_timer); + timeout = iscsi_timer_msecs_until(&connection_timer); - memset(data, 0, data_len); - if (!iscsi_io_recv_pdu(&session->conn[0], - pdu, ISCSI_DIGEST_NONE, data, - data_len, ISCSI_DIGEST_NONE, - timeout)) { + rc = iscsi_io_recv_pdu(&session->conn[0], + pdu, ISCSI_DIGEST_NONE, data, + data_len, ISCSI_DIGEST_NONE, + timeout); + if (rc == -EAGAIN) + goto repoll; + else if (rc < 0) { log_debug(1, "discovery session to " "%s:%d failed to recv a PDU " "response, terminating", drec->address, drec->port); - iscsi_io_disconnect(&session->conn[0]); - rc = 1; + rc = ISCSI_ERR_PDU_TIMEOUT; goto free_sendtargets; } @@ -1455,14 +1576,13 @@ repoll: */ rc = process_recvd_pdu(pdu, drec, rec_list, session, &sendtargets, - default_port, &active, &valid_text, data); if (rc == DISCOVERY_NEED_RECONNECT) goto reconnect; /* reset timers after receiving a PDU */ if (active) { - set_timer(&connection_timer, + iscsi_timer_set(&connection_timer, session->conn[0].active_timeout); goto repoll; } @@ -1472,8 +1592,7 @@ repoll: log_warning("discovery session to %s:%d " "terminating after hangup", drec->address, drec->port); - iscsi_io_disconnect(&session->conn[0]); - rc = 1; + rc = ISCSI_ERR_TRANS; goto free_sendtargets; } @@ -1489,18 +1608,9 @@ repoll: goto reconnect; } } else if (rc < 0) { - if (errno == EINTR) { - /* if we got SIGHUP, reconnect and rediscover */ - if (rediscover) { - rediscover = 0; - log_debug(1, "rediscovery requested"); - goto reconnect; - } - } else { - log_error("poll error"); - rc = 1; - goto free_sendtargets; - } + log_error("poll error"); + rc = ISCSI_ERR; + goto free_sendtargets; } log_debug(1, "discovery process to %s:%d exiting", @@ -1510,8 +1620,9 @@ repoll: free_sendtargets: str_free_buffer(&sendtargets); free(data); + iscsi_destroy_session(session); free_session: - free(session); + iscsi_free_session(session); return rc; } diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/discoveryd.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/discoveryd.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/discoveryd.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/discoveryd.c 2011-02-24 19:54:10.000000000 -0600 @@ -44,6 +44,7 @@ #include "isns.h" #include "paths.h" #include "message.h" +#include "iscsi_err.h" #define DISC_DEF_POLL_INVL 30 @@ -242,12 +243,12 @@ static int isns_build_objs(isns_portal_i nportals = isns_get_nr_portals(); log_debug(4, "got %d portals", nportals); if (!nportals) - return ENODEV; + return ISCSI_ERR_NO_OBJS_FOUND; iflist = calloc(nportals, sizeof(isns_portal_info_t)); if (!iflist) { log_error("Unable to allocate %d portals.", nportals); - return ENOMEM; + return ISCSI_ERR_NOMEM; } nportals = isns_enumerate_portals(iflist, nportals); @@ -255,7 +256,7 @@ static int isns_build_objs(isns_portal_i log_error("Unable to enumerate portals - " "no usable interfaces found\n"); free(iflist); - return ENODEV; + return ISCSI_ERR_NO_OBJS_FOUND; } for (i = 0; i < nportals; ++i) { iflist[i].addr.sin6_port = portal_info->addr.sin6_port; @@ -267,7 +268,7 @@ static int isns_build_objs(isns_portal_i if (!isns_entity_id) { isns_entity_id = calloc(1, 256); if (!isns_entity_id) - return ENOMEM; + return ISCSI_ERR_NOMEM; rc = getnameinfo((struct sockaddr *) &portal_info->addr, sizeof(portal_info->addr), @@ -277,14 +278,14 @@ static int isns_build_objs(isns_portal_i isns_entity_id = NULL; log_error("Could not get hostname for EID."); - return EIO; + return ISCSI_ERR; } } entity = isns_create_entity(ISNS_ENTITY_PROTOCOL_ISCSI, isns_entity_id); if (!entity) { log_error("Could not create iSNS entity."); - return ENOMEM; + return ISCSI_ERR_NOMEM; } isns_object_list_append(objs, entity); @@ -293,14 +294,14 @@ static int isns_build_objs(isns_portal_i portal = isns_create_portal(portal_info, entity); if (!portal) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto fail; } isns_object_list_append(objs, portal); if (!isns_object_set_uint32(portal, ISNS_TAG_SCN_PORT, isns_portal_tcpudp_port(portal_info))) { - rc = EINVAL; + rc = ISCSI_ERR_INVAL; goto fail; } } @@ -310,7 +311,7 @@ static int isns_build_objs(isns_portal_i ISNS_ISCSI_INITIATOR_MASK, NULL); if (!inode) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto fail; } isns_object_list_append(objs, inode); @@ -366,7 +367,6 @@ static int isns_disc_new_portals(const c qry_data.targetname = targetname; qry_data.iname = iname; -log_error("isns_disc_new_portals"); iface_link_ifaces(&ifaces); rc = idbm_bind_ifaces_to_nodes(isns_query_node, &qry_data, &ifaces, &rec_list); @@ -559,7 +559,7 @@ static int isns_setup_registration_refre log_error("Unable to extract object list from " "registration response: %s\n", isns_strerror(status)); - return EIO; + return ISCSI_ERR; } for (i = 0; i < objs.iol_count; ++i) { @@ -578,7 +578,7 @@ static int isns_setup_registration_refre refresh_data = calloc(1, sizeof(*refresh_data)); if (!refresh_data) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto free_objs; } INIT_LIST_HEAD(&refresh_data->list); @@ -654,7 +654,7 @@ static int isns_register_objs(isns_clien reg = isns_create_registration(clnt, entity); if (!reg) - return ENOMEM; + return ISCSI_ERR_NOMEM; for (i = 0; i < objs->iol_count; ++i) isns_registration_add_object(reg, objs->iol_data[i]); @@ -664,7 +664,7 @@ static int isns_register_objs(isns_clien if (status != ISNS_SUCCESS) { log_error("Could not register with iSNS server: %s", isns_strerror(status)); - rc = EIO; + rc = ISCSI_ERR; goto free_reg; } log_debug(4, "Registered objs"); @@ -687,7 +687,7 @@ static int isns_register_objs(isns_clien if (!reg) { isns_cancel_refresh_timers(); - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto done; } @@ -703,7 +703,7 @@ static int isns_register_objs(isns_clien */ if (poll_inval < 0) { isns_cancel_refresh_timers(); - rc = EIO; + rc = ISCSI_ERR; break; } } @@ -727,7 +727,7 @@ static int isns_scn_register(isns_socket clnt = isns_create_default_client(NULL); if (!clnt) { log_error("iSNS setup failed. Could not connect to server."); - return ENOTCONN; + return ISCSI_ERR_TRANS; } isns_socket_set_disconnect_fatal(clnt->ic_socket); @@ -735,7 +735,7 @@ static int isns_scn_register(isns_socket if (!isns_socket_get_portal_info(svr_sock, &portal_info)) { log_error("Could not get portal info for iSNS registration."); - rc = ENODEV; + rc = ISCSI_ERR_NO_OBJS_FOUND; goto destroy_clnt; } @@ -797,7 +797,7 @@ static int isns_create_node_list(const c if (def_iname) { node = isns_create_node(def_iname); if (!node) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto fail; } list_add_tail(&node->list, &isns_initiators); @@ -808,7 +808,7 @@ static int isns_create_node_list(const c !isns_lookup_node(iface->iname)) { node = isns_create_node(iface->iname); if (!node) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto fail; } list_add_tail(&node->list, &isns_initiators); @@ -943,7 +943,7 @@ static int isns_eventd(const char *def_i isns_create_node_list(def_iname); if (list_empty(&isns_initiators)) { log_error("iSNS registration failed. Initiatorname not set."); - return EINVAL; + return ISCSI_ERR_INVAL; } /* use def_iname or if not set the first iface's iname for the src */ @@ -955,7 +955,7 @@ static int isns_eventd(const char *def_i isns_config.ic_control_socket = ISNS_EVENTD_CTL; if (discovery_isns_set_servername(disc_addr, port)) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto fail; } @@ -964,13 +964,13 @@ static int isns_eventd(const char *def_i db = isns_db_open(NULL); if (!db) { log_error("iSNS setup failed. Could not create db."); - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto fail; } svr = isns_create_server(node->source, db, &isns_callback_service_ops); if (!svr) { log_error("iSNS setup failed. Could not create server."); - rc = ENOTCONN; + rc = ISCSI_ERR_TRANS; goto fail; } isns_server_set_scn_callback(svr, isns_scn_callback); @@ -978,7 +978,7 @@ static int isns_eventd(const char *def_i svr_sock = isns_create_server_socket(NULL, NULL, AF_INET6, SOCK_DGRAM); if (!svr_sock) { log_error("iSNS setup failed. Could not create server socket."); - rc = ENOTCONN; + rc = ISCSI_ERR_TRANS; goto fail; } @@ -1077,7 +1077,7 @@ static int st_start(void *data, struct d log_debug(1, "st_start %s:%d %d", drec->address, drec->port, drec->u.sendtargets.use_discoveryd); if (!drec->u.sendtargets.use_discoveryd) - return ENOSYS; + return ISCSI_ERR_INVAL; fork_disc(NULL, drec, drec->u.sendtargets.discoveryd_poll_inval, do_st_disc_and_login); @@ -1094,7 +1094,7 @@ static int isns_start(void *data, struct log_debug(1, "isns_start %s:%d %d", drec->address, drec->port, drec->u.isns.use_discoveryd); if (!drec->u.isns.use_discoveryd) - return ENOSYS; + return ISCSI_ERR_INVAL; fork_disc(data, drec, drec->u.isns.discoveryd_poll_inval, start_isns); return 0; diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/event_poll.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/event_poll.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/event_poll.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/event_poll.c 2011-02-24 19:54:10.000000000 -0600 @@ -35,6 +35,7 @@ #include "iscsi_ipc.h" #include "actor.h" #include "initiator.h" +#include "iscsi_err.h" static int reap_count; @@ -174,5 +175,5 @@ void event_loop(struct iscsi_ipc *ipc, i sysfs_cleanup(); } if (shutdown_qtask) - mgmt_ipc_write_rsp(shutdown_qtask, MGMT_IPC_OK); + mgmt_ipc_write_rsp(shutdown_qtask, ISCSI_SUCCESS); } 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/host.c 2011-02-24 19:54:10.000000000 -0600 @@ -33,6 +33,7 @@ #include "transport.h" #include "initiator.h" #include "iface.h" +#include "iscsi_err.h" static int match_host_to_session(void *data, struct session_info *info) { @@ -200,13 +201,16 @@ int host_info_print(int info_level, uint break; default: log_error("Invalid info level %d. Try 0 - 4.", info_level); - return EINVAL; + return ISCSI_ERR_INVAL; } if (err) { - log_error("Can not get list of iSCSI hosts (%d)", err); + log_error("Can not get list of iSCSI hosts: %s", + iscsi_err_to_str(err)); return err; - } else if (!num_found) + } else if (!num_found) { log_error("No iSCSI hosts."); + return ISCSI_ERR_NO_OBJS_FOUND; + } return 0; } 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.c 2011-02-24 19:54:10.000000000 -0600 @@ -40,6 +40,7 @@ #include "iface.h" #include "sysdeps.h" #include "fw_context.h" +#include "iscsi_err.h" #define IDBM_HIDE 0 /* Hide parameter when print. */ #define IDBM_SHOW 1 /* Show parameter when print. */ @@ -179,7 +180,7 @@ idbm_recinfo_discovery(discovery_rec_t * u.sendtargets.conn_timeo.active_timeout, IDBM_SHOW, num, 1); __recinfo_int(DISC_ST_MAX_RECV_DLEN, ri, r, - u.sendtargets.iscsi.MaxRecvDataSegmentLength, + u.sendtargets.conn_conf.MaxRecvDataSegmentLength, IDBM_SHOW, num, 1); break; case DISCOVERY_TYPE_ISNS: @@ -426,6 +427,31 @@ void idbm_print(int type, void *rec, int } static void +idbm_setup_session_defaults(struct iscsi_session_operational_config *conf) +{ + conf->InitialR2T = 0; + conf->ImmediateData = 1; + conf->FirstBurstLength = DEF_INI_FIRST_BURST_LEN; + conf->MaxBurstLength = DEF_INI_MAX_BURST_LEN; + conf->DefaultTime2Wait = ISCSI_DEF_TIME2WAIT; + conf->DefaultTime2Retain = 0; + conf->MaxConnections = 1; + conf->MaxOutstandingR2T = 1; + conf->ERL = 0; + conf->FastAbort = 1; +} + +static void idbm_setup_conn_defaults(struct iscsi_conn_operational_config *conf) +{ + conf->MaxXmitDataSegmentLength = 0; + conf->MaxRecvDataSegmentLength = DEF_INI_MAX_RECV_SEG_LEN; + conf->HeaderDigest = CONFIG_DIGEST_NEVER; + conf->DataDigest = CONFIG_DIGEST_NEVER; + conf->IFMarker = 0; + conf->OFMarker = 0; +} + +static void idbm_discovery_setup_defaults(discovery_rec_t *rec, discovery_type_e type) { memset(rec, 0, sizeof(discovery_rec_t)); @@ -443,7 +469,10 @@ idbm_discovery_setup_defaults(discovery_ rec->u.sendtargets.conn_timeo.login_timeout=15; rec->u.sendtargets.conn_timeo.auth_timeout = 45; rec->u.sendtargets.conn_timeo.active_timeout=30; - rec->u.sendtargets.iscsi.MaxRecvDataSegmentLength = + idbm_setup_session_defaults(&rec->u.sendtargets.session_conf); + idbm_setup_conn_defaults(&rec->u.sendtargets.conn_conf); + /* override def setting */ + rec->u.sendtargets.conn_conf.MaxRecvDataSegmentLength = DEF_INI_DISC_MAX_RECV_SEG_LEN; break; case DISCOVERY_TYPE_SLP: @@ -515,7 +544,7 @@ setup_passwd_len: } } - return 1; + return ISCSI_ERR_INVAL; updated: strlcpy((char*)info[i].value, value, VALUE_MAXVAL); @@ -556,12 +585,12 @@ int idbm_verify_param(recinfo_t *info, c else { log_error("Cannot modify %s. It is used to look up " "the record and cannot be changed.", name); - return EINVAL; + return ISCSI_ERR_INVAL; } } log_error("Cannot modify %s. Invalid param name.", name); - return EINVAL; + return ISCSI_ERR_INVAL; } void idbm_recinfo_config(recinfo_t *info, FILE *f) @@ -627,7 +656,7 @@ void idbm_recinfo_config(recinfo_t *info } *(value+i) = 0; - (void)idbm_rec_update_param(info, name, value, line_number); + idbm_rec_update_param(info, name, value, line_number); } while (line); } @@ -781,19 +810,19 @@ get_params_from_disc_link(char *link, ch (*target) = link; *address = strchr(*target, ','); if (!(*address)) - return EINVAL; + return ISCSI_ERR_INVAL; *(*address)++ = '\0'; *port = strchr(*address, ','); if (!(*port)) - return EINVAL; + return ISCSI_ERR_INVAL; *(*port)++ = '\0'; *tpgt = strchr(*port, ','); if (!(*tpgt)) - return EINVAL; + return ISCSI_ERR_INVAL; *(*tpgt)++ = '\0'; *ifaceid = strchr(*tpgt, ','); if (!(*ifaceid)) - return EINVAL; + return ISCSI_ERR_INVAL; *(*ifaceid)++ = '\0'; return 0; } @@ -809,8 +838,9 @@ int idbm_lock(void) if (access(LOCK_DIR, F_OK) != 0) { if (mkdir(LOCK_DIR, 0660) != 0) { - log_error("Could not open %s. Exiting\n", LOCK_DIR); - return errno; + log_error("Could not open %s: %s\n", LOCK_DIR, + strerror(errno)); + return ISCSI_ERR_IDBM; } } @@ -827,7 +857,7 @@ int idbm_lock(void) log_error("Maybe you are not root?"); log_error("Could not lock discovery DB: %s: %s", LOCK_WRITE_FILE, strerror(errno)); - return errno; + return ISCSI_ERR_IDBM; } else if (i == 0) log_debug(2, "Waiting for discovery DB lock"); @@ -880,7 +910,7 @@ static int __idbm_rec_read(node_rec_t *o info = idbm_recinfo_alloc(MAX_KEYS); if (!info) - return ENOMEM; + return ISCSI_ERR_NOMEM; rc = idbm_lock(); if (rc) @@ -888,8 +918,9 @@ static int __idbm_rec_read(node_rec_t *o f = fopen(conf, "r"); if (!f) { - log_debug(5, "Could not open %s err %d\n", conf, errno); - rc = errno; + log_debug(5, "Could not open %s err %s\n", conf, + strerror(errno)); + rc = ISCSI_ERR_IDBM; goto unlock; } @@ -916,7 +947,7 @@ idbm_rec_read(node_rec_t *out_rec, char portal = calloc(1, PATH_MAX); if (!portal) - return ENOMEM; + return ISCSI_ERR_IDBM; /* try old style portal as config */ snprintf(portal, PATH_MAX, "%s/%s/%s,%d", NODE_CONFIG_DIR, @@ -929,14 +960,14 @@ idbm_rec_read(node_rec_t *out_rec, char targetname, ip, port, tpgt, iface->name); log_debug(5, "rec read looking for config file %s.", portal); if (!strlen(iface->name)) { - rc = EINVAL; + rc = ISCSI_ERR_INVAL; goto free_portal; } if (stat(portal, &statb)) { - log_debug(5, "Could not stat %s err %d.", portal, errno); + log_debug(5, "Could not stat %s: %s.", portal, strerror(errno)); free(portal); - return errno; + return ISCSI_ERR_IDBM; } read: @@ -1078,17 +1109,12 @@ static int __idbm_print_all_by_drec(void if (info_level >= 1) { printf("DiscoveryAddress: %s,%d\n", drec->address, drec->port); - rc = idbm_print_discovered(drec, info_level); - if (rc) - return 0; - else - return ENODEV; - } else { + idbm_print_discovered(drec, info_level); + } else printf("%s:%d via %s\n", drec->address, drec->port, drec->type == DISCOVERY_TYPE_ISNS ? "isns" : "sendtargets"); - return 0; - } + return 0; } static int idbm_print_all_st(int info_level) @@ -1168,11 +1194,23 @@ int idbm_print_all_discovery(int info_le return found; } -/* - * This iterates over the ifaces in use in the nodes dir. - * It does not iterate over the ifaces setup in /etc/iscsi/ifaces. +/** + * idbm_for_each_iface - iterate over bound iface recs + * @found: nr of recs found so far + * @data: data pointer passed to fn + * @fn: iterator function ran over each bound iface rec + * @targetname: rec's target name + * @tpgt: rec's portal group tag + * @ip: rec's ip address + * @port: rec's port + * + * This will run fn over all recs with the {targetname,tpgt,ip,port} + * id. It does not iterate over the ifaces setup in /etc/iscsi/ifaces. + * + * fn should return -1 if it skipped the rec, a ISCSI_ERR error code if + * the operation failed or 0 if fn was run successfully. */ -int idbm_for_each_iface(int *found, void *data, +static int idbm_for_each_iface(int *found, void *data, idbm_iface_op_fn *fn, char *targetname, int tpgt, char *ip, int port) { @@ -1185,7 +1223,7 @@ int idbm_for_each_iface(int *found, void portal = calloc(1, PATH_MAX); if (!portal) - return ENOMEM; + return ISCSI_ERR_NOMEM; if (tpgt >= 0) goto read_iface; @@ -1195,7 +1233,7 @@ int idbm_for_each_iface(int *found, void ip, port); if (stat(portal, &statb)) { log_error("iface iter could not stat %s.", portal); - rc = ENODEV; + rc = ISCSI_ERR_IDBM; goto free_portal; } @@ -1217,11 +1255,13 @@ read_iface: iface_dirfd = opendir(portal); if (!iface_dirfd) { log_error("iface iter could not read dir %s.", portal); - rc = errno; + rc = ISCSI_ERR_IDBM; goto free_portal; } while ((iface_dent = readdir(iface_dirfd))) { + int curr_rc; + if (!strcmp(iface_dent->d_name, ".") || !strcmp(iface_dent->d_name, "..")) continue; @@ -1233,14 +1273,12 @@ read_iface: if (__idbm_rec_read(&rec, portal)) continue; + curr_rc = fn(data, &rec); /* less than zero means it was not a match */ - rc = fn(data, &rec); - if (rc > 0) - break; - else if (rc == 0) + if (curr_rc > 0 && !rc) + rc = curr_rc; + else if (curr_rc == 0) (*found)++; - else - rc = 0; } closedir(iface_dirfd); @@ -1263,17 +1301,18 @@ int idbm_for_each_portal(int *found, voi portal = calloc(1, PATH_MAX); if (!portal) - return ENOMEM; + return ISCSI_ERR_NOMEM; snprintf(portal, PATH_MAX, "%s/%s", NODE_CONFIG_DIR, targetname); portal_dirfd = opendir(portal); if (!portal_dirfd) { - rc = errno; + rc = ISCSI_ERR_IDBM; goto done; } while ((portal_dent = readdir(portal_dirfd))) { char *tmp_port, *tmp_tpgt; + int curr_rc; if (!strcmp(portal_dent->d_name, ".") || !strcmp(portal_dent->d_name, "..")) @@ -1288,11 +1327,12 @@ int idbm_for_each_portal(int *found, voi if (tmp_tpgt) *tmp_tpgt++ = '\0'; - rc = fn(found, data, targetname, + curr_rc = fn(found, data, targetname, tmp_tpgt ? atoi(tmp_tpgt) : -1, portal_dent->d_name, atoi(tmp_port)); - if (rc) - break; + /* less than zero means it was not a match */ + if (curr_rc > 0 && !rc) + rc = curr_rc; } closedir(portal_dirfd); done: @@ -1314,14 +1354,17 @@ int idbm_for_each_node(int *found, void return 0; while ((node_dent = readdir(node_dirfd))) { + int curr_rc; + if (!strcmp(node_dent->d_name, ".") || !strcmp(node_dent->d_name, "..")) continue; log_debug(5, "searching %s\n", node_dent->d_name); - rc = fn(found, data, node_dent->d_name); - if (rc) - break; + curr_rc = fn(found, data, node_dent->d_name); + /* less than zero means it was not a match */ + if (curr_rc > 0 && !rc) + rc = curr_rc; } closedir(node_dirfd); @@ -1376,17 +1419,17 @@ idbm_discovery_read(discovery_rec_t *out FILE *f; if (drec_type > 1) - return EINVAL; + return ISCSI_ERR_INVAL; memset(out_rec, 0, sizeof(discovery_rec_t)); info = idbm_recinfo_alloc(MAX_KEYS); if (!info) - return ENOMEM; + return ISCSI_ERR_NOMEM; portal = malloc(PATH_MAX); if (!portal) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto free_info; } @@ -1402,8 +1445,9 @@ idbm_discovery_read(discovery_rec_t *out f = idbm_open_rec_r(portal, disc_type_to_config_vals[drec_type].config_name); if (!f) { - log_debug(1, "Could not open %s err %d\n", portal, errno); - rc = errno; + log_debug(1, "Could not open %s: %s\n", portal, + strerror(errno)); + rc = ISCSI_ERR_IDBM; goto unlock; } @@ -1474,14 +1518,15 @@ static int idbm_rec_write(node_rec_t *re portal = malloc(PATH_MAX); if (!portal) { log_error("Could not alloc portal\n"); - return ENOMEM; + return ISCSI_ERR_NOMEM; } snprintf(portal, PATH_MAX, "%s", NODE_CONFIG_DIR); if (access(portal, F_OK) != 0) { if (mkdir(portal, 0660) != 0) { - log_error("Could not make %s\n", portal); - rc = errno; + log_error("Could not make %s: %s\n", portal, + strerror(errno)); + rc = ISCSI_ERR_IDBM; goto free_portal; } } @@ -1489,8 +1534,9 @@ static int idbm_rec_write(node_rec_t *re snprintf(portal, PATH_MAX, "%s/%s", NODE_CONFIG_DIR, rec->name); if (access(portal, F_OK) != 0) { if (mkdir(portal, 0660) != 0) { - log_error("Could not make %s\n", portal); - rc = errno; + log_error("Could not make %s: %s\n", portal, + strerror(errno)); + rc = ISCSI_ERR_IDBM; goto free_portal; } } @@ -1531,13 +1577,13 @@ static int idbm_rec_write(node_rec_t *re * Old style portal as a file, but with tpgt. Let's update it. */ if (unlink(portal)) { - log_error("Could not convert %s. err %d\n", portal, - errno); - rc = errno; + log_error("Could not convert %s: %s\n", portal, + strerror(errno)); + rc = ISCSI_ERR_IDBM; goto unlock; } } else { - rc = EINVAL; + rc = ISCSI_ERR_INVAL; goto unlock; } @@ -1546,9 +1592,9 @@ mkdir_portal: rec->name, rec->conn[0].address, rec->conn[0].port, rec->tpgt); if (stat(portal, &statb)) { if (mkdir(portal, 0660) != 0) { - log_error("Could not make dir %s err %d\n", - portal, errno); - rc = errno; + log_error("Could not make dir %s: %s\n", + portal, strerror(errno)); + rc = ISCSI_ERR_IDBM; goto unlock; } } @@ -1559,8 +1605,8 @@ mkdir_portal: open_conf: f = fopen(portal, "w"); if (!f) { - log_error("Could not open %s err %d\n", portal, errno); - rc = errno; + log_error("Could not open %s: %sd\n", portal, strerror(errno)); + rc = ISCSI_ERR_IDBM; goto unlock; } @@ -1581,12 +1627,12 @@ idbm_discovery_write(discovery_rec_t *re int rc = 0; if (rec->type > 1) - return EINVAL; + return ISCSI_ERR_INVAL; portal = malloc(PATH_MAX); if (!portal) { log_error("Could not alloc portal\n"); - return ENOMEM; + return ISCSI_ERR_NOMEM; } rc = idbm_lock(); @@ -1597,8 +1643,9 @@ idbm_discovery_write(discovery_rec_t *re disc_type_to_config_vals[rec->type].config_root); if (access(portal, F_OK) != 0) { if (mkdir(portal, 0660) != 0) { - log_error("Could not make %s\n", portal); - rc = errno; + log_error("Could not make %s: %s\n", portal, + strerror(errno)); + rc = ISCSI_ERR_IDBM; goto unlock; } } @@ -1610,8 +1657,8 @@ idbm_discovery_write(discovery_rec_t *re f = idbm_open_rec_w(portal, disc_type_to_config_vals[rec->type].config_name); if (!f) { - log_error("Could not open %s err %d\n", portal, errno); - rc = errno; + log_error("Could not open %s: %s\n", portal, strerror(errno)); + rc = ISCSI_ERR_IDBM; goto unlock; } @@ -1655,9 +1702,9 @@ static int setup_disc_to_node_link(char case DISCOVERY_TYPE_FW: if (access(FW_CONFIG_DIR, F_OK) != 0) { if (mkdir(FW_CONFIG_DIR, 0660) != 0) { - log_error("Could not make %s\n", - FW_CONFIG_DIR); - rc = errno; + log_error("Could not make %s: %s", + FW_CONFIG_DIR, strerror(errno)); + rc = ISCSI_ERR_IDBM; } } @@ -1669,9 +1716,9 @@ static int setup_disc_to_node_link(char case DISCOVERY_TYPE_STATIC: if (access(STATIC_CONFIG_DIR, F_OK) != 0) { if (mkdir(STATIC_CONFIG_DIR, 0660) != 0) { - log_error("Could not make %s\n", - STATIC_CONFIG_DIR); - rc = errno; + log_error("Could not make %s; %s", + STATIC_CONFIG_DIR, strerror(errno)); + rc = ISCSI_ERR_IDBM; } } @@ -1683,9 +1730,9 @@ static int setup_disc_to_node_link(char case DISCOVERY_TYPE_ISNS: if (access(ISNS_CONFIG_DIR, F_OK) != 0) { if (mkdir(ISNS_CONFIG_DIR, 0660) != 0) { - log_error("Could not make %s\n", - ISNS_CONFIG_DIR); - rc = errno; + log_error("Could not make %s: %s", + ISNS_CONFIG_DIR, strerror(errno)); + rc = ISCSI_ERR_IDBM; } } @@ -1732,7 +1779,7 @@ static int setup_disc_to_node_link(char break; case DISCOVERY_TYPE_SLP: default: - rc = EINVAL; + rc = ISCSI_ERR_INVAL; } return rc; @@ -1773,7 +1820,7 @@ int idbm_add_node(node_rec_t *newrec, di node_portal = calloc(2, PATH_MAX); if (!node_portal) - return ENOMEM; + return ISCSI_ERR_NOMEM; disc_portal = node_portal + PATH_MAX; snprintf(node_portal, PATH_MAX, "%s/%s/%s,%d,%d", NODE_CONFIG_DIR, @@ -1795,9 +1842,10 @@ int idbm_add_node(node_rec_t *newrec, di log_debug(7, "link from %s to %s exists", node_portal, disc_portal); else { - rc = errno; + rc = ISCSI_ERR_IDBM; log_error("Could not make link from disc source %s to " - "node %s", disc_portal, node_portal); + "node %s: %s", disc_portal, node_portal, + strerror(errno)); } } idbm_unlock(); @@ -1812,10 +1860,12 @@ static int idbm_bind_iface_to_nodes(idbm { struct node_rec *rec, *tmp; struct list_head new_recs; + int rc; INIT_LIST_HEAD(&new_recs); - if (disc_node_fn(data, iface, &new_recs)) - return ENODEV; + rc = disc_node_fn(data, iface, &new_recs); + if (rc) + return rc; list_for_each_entry_safe(rec, tmp, &new_recs, list) { list_del_init(&rec->list); @@ -1960,7 +2010,7 @@ int idbm_delete_discovery(discovery_rec_ portal = calloc(1, PATH_MAX); if (!portal) - return ENOMEM; + return ISCSI_ERR_NOMEM; snprintf(portal, PATH_MAX, "%s/%s,%d", disc_type_to_config_vals[drec->type].config_root, @@ -2017,7 +2067,7 @@ static int idbm_remove_disc_to_node_link tmprec = malloc(sizeof(*tmprec)); if (!tmprec) - return ENOMEM; + return ISCSI_ERR_NOMEM; memset(portal, 0, PATH_MAX); snprintf(portal, PATH_MAX, "%s/%s/%s,%d,%d/%s", NODE_CONFIG_DIR, @@ -2045,9 +2095,9 @@ static int idbm_remove_disc_to_node_link if (!stat(portal, &statb)) { if (unlink(portal)) { - log_error("Could not remove link %s err %d\n", - portal, errno); - rc = errno; + log_error("Could not remove link %s: %s\n", + portal, strerror(errno)); + rc = ISCSI_ERR_IDBM; } else log_debug(7, "rmd %s", portal); } else @@ -2073,7 +2123,7 @@ int idbm_delete_node(node_rec_t *rec) portal = calloc(1, PATH_MAX); if (!portal) - return ENOMEM; + return ISCSI_ERR_NOMEM; rc = idbm_remove_disc_to_node_link(rec, portal); if (rc) @@ -2100,15 +2150,15 @@ int idbm_delete_node(node_rec_t *rec) if (!stat(portal, &statb)) goto rm_conf; - log_error("Could not stat %s to delete node err %d\n", - portal, errno); - rc = errno; + log_error("Could not stat %s to delete node: %s\n", + portal, strerror(errno)); + rc = ISCSI_ERR_IDBM; goto unlock; rm_conf: if (unlink(portal)) { - log_error("Could not remove %s err %d\n", portal, errno); - rc = errno; + log_error("Could not remove %s: %s\n", portal, strerror(errno)); + rc = ISCSI_ERR_IDBM; goto unlock; } @@ -2178,7 +2228,7 @@ int idbm_node_set_param(void *data, node info = idbm_recinfo_alloc(MAX_KEYS); if (!info) - return ENOMEM; + return ISCSI_ERR_NOMEM; idbm_recinfo_node(rec, info); @@ -2207,7 +2257,7 @@ int idbm_discovery_set_param(void *data, info = idbm_recinfo_alloc(MAX_KEYS); if (!info) - return ENOMEM; + return ISCSI_ERR_NOMEM; idbm_recinfo_discovery((discovery_rec_t *)rec, info); @@ -2242,7 +2292,7 @@ int idbm_init(idbm_get_config_file_fn *f db = malloc(sizeof(idbm_t)); if (!db) { log_error("out of memory on idbm allocation"); - return ENOMEM; + return ISCSI_ERR_NOMEM; } memset(db, 0, sizeof(idbm_t)); db->get_config_file = fn; @@ -2362,16 +2412,7 @@ void idbm_node_setup_defaults(node_rec_t rec->session.err_timeo.tgt_reset_timeout = DEF_TGT_RESET_TIMEO; rec->session.err_timeo.host_reset_timeout = DEF_HOST_RESET_TIMEO; rec->session.timeo.replacement_timeout = DEF_REPLACEMENT_TIMEO; - rec->session.iscsi.InitialR2T = 0; - rec->session.iscsi.ImmediateData = 1; - rec->session.iscsi.FirstBurstLength = DEF_INI_FIRST_BURST_LEN; - rec->session.iscsi.MaxBurstLength = DEF_INI_MAX_BURST_LEN; - rec->session.iscsi.DefaultTime2Wait = ISCSI_DEF_TIME2WAIT; - rec->session.iscsi.DefaultTime2Retain = 0; - rec->session.iscsi.MaxConnections = 1; - rec->session.iscsi.MaxOutstandingR2T = 1; - rec->session.iscsi.ERL = 0; - rec->session.iscsi.FastAbort = 1; + idbm_setup_session_defaults(&rec->session.iscsi); for (i=0; iconn[i].startup = ISCSI_STARTUP_MANUAL; @@ -2385,13 +2426,7 @@ void idbm_node_setup_defaults(node_rec_t rec->conn[i].timeo.noop_out_interval = DEF_NOOP_OUT_INTERVAL; rec->conn[i].timeo.noop_out_timeout = DEF_NOOP_OUT_TIMEO; - rec->conn[i].iscsi.MaxXmitDataSegmentLength = 0; - rec->conn[i].iscsi.MaxRecvDataSegmentLength = - DEF_INI_MAX_RECV_SEG_LEN; - rec->conn[i].iscsi.HeaderDigest = CONFIG_DIGEST_NEVER; - rec->conn[i].iscsi.DataDigest = CONFIG_DIGEST_NEVER; - rec->conn[i].iscsi.IFMarker = 0; - rec->conn[i].iscsi.OFMarker = 0; + idbm_setup_conn_defaults(&rec->conn[i].iscsi); } iface_setup_defaults(&rec->iface); 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/idbm.h 2011-02-24 19:54:10.000000000 -0600 @@ -93,9 +93,6 @@ struct rec_op_data { node_rec_t *match_rec; idbm_iface_op_fn *fn; }; -extern int idbm_for_each_iface(int *found, void *data, - idbm_iface_op_fn *fn, - char *targetname, int tpgt, char *ip, int port); extern int idbm_for_each_portal(int *found, void *data, idbm_portal_op_fn *fn, char *targetname); extern int idbm_for_each_node(int *found, void *data, 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iface.c 2011-02-24 19:54:10.000000000 -0600 @@ -39,6 +39,7 @@ #include "host.h" #include "fw_context.h" #include "sysdeps.h" +#include "iscsi_err.h" /* * Default ifaces for use with transports that do not bind to hardware @@ -101,13 +102,13 @@ struct iface_rec *iface_alloc(char *ifna struct iface_rec *iface; if (!strlen(ifname) || strlen(ifname) + 1 > ISCSI_MAX_IFACE_LEN) { - *err = EINVAL; + *err = ISCSI_ERR_INVAL; return NULL; } iface = calloc(1, sizeof(*iface)); if (!iface) { - *err = ENOMEM; + *err = ISCSI_ERR_NOMEM; return NULL; } @@ -125,11 +126,11 @@ static int __iface_conf_read(struct ifac iface_conf = calloc(1, PATH_MAX); if (!iface_conf) - return ENOMEM; + return ISCSI_ERR_NOMEM; info = idbm_recinfo_alloc(MAX_KEYS); if (!info) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto free_conf; } @@ -147,7 +148,7 @@ static int __iface_conf_read(struct ifac iface_setup_defaults(iface); rc = 0; } else - rc = errno; + rc = ISCSI_ERR_IDBM; goto free_info; } @@ -213,12 +214,12 @@ int iface_conf_delete(struct iface_rec * if (def_iface) { log_error("iface %s is a special interface and " "cannot be deleted.\n", iface->name); - return EINVAL; + return ISCSI_ERR_INVAL; } iface_conf = calloc(1, PATH_MAX); if (!iface_conf) - return ENOMEM; + return ISCSI_ERR_NOMEM; sprintf(iface_conf, "%s/%s", IFACE_CONFIG_DIR, iface->name); rc = idbm_lock(); @@ -226,7 +227,7 @@ int iface_conf_delete(struct iface_rec * goto free_conf; if (unlink(iface_conf)) - rc = errno; + rc = ISCSI_ERR_IDBM; idbm_unlock(); free_conf: @@ -246,17 +247,17 @@ int iface_conf_write(struct iface_rec *i log_error("iface %s is a special interface and " "is not stored in %s.\n", iface->name, IFACE_CONFIG_DIR); - return EINVAL; + return ISCSI_ERR_INVAL; } iface_conf = calloc(1, PATH_MAX); if (!iface_conf) - return ENOMEM; + return ISCSI_ERR_NOMEM; sprintf(iface_conf, "%s/%s", IFACE_CONFIG_DIR, iface->name); f = fopen(iface_conf, "w"); if (!f) { - rc = errno; + rc = ISCSI_ERR_IDBM; goto free_conf; } @@ -285,12 +286,12 @@ int iface_conf_update(struct db_set_para if (def_iface) { log_error("iface %s is a special interface and " "cannot be modified.\n", iface->name); - return EINVAL; + return ISCSI_ERR_INVAL; } info = idbm_recinfo_alloc(MAX_KEYS); if (!info) - return ENOMEM; + return ISCSI_ERR_NOMEM; idbm_recinfo_iface(iface, info); rc = idbm_verify_param(info, param->name); @@ -298,10 +299,8 @@ int iface_conf_update(struct db_set_para goto free_info; rc = idbm_rec_update_param(info, param->name, param->value, 0); - if (rc) { - rc = EIO; + if (rc) goto free_info; - } rc = iface_conf_write(iface); free_info: @@ -418,7 +417,7 @@ int iface_get_by_net_binding(struct ifac __iface_get_by_net_binding); if (rc == 1) return 0; - return ENODEV; + return ISCSI_ERR_NO_OBJS_FOUND; } static int __iface_setup_host_bindings(void *data, struct host_info *hinfo) @@ -438,7 +437,8 @@ static int __iface_setup_host_bindings(v return 0; } - if (iface_get_by_net_binding(&hinfo->iface, &iface) == ENODEV) { + if (iface_get_by_net_binding(&hinfo->iface, &iface) == + ISCSI_ERR_NO_OBJS_FOUND) { /* Must be a new port */ if (!strlen(hinfo->iface.hwaddress)) { log_error("Invalid offload iSCSI host %u. Missing " @@ -704,7 +704,7 @@ int iface_for_each_iface(void *data, int iface_dent->d_name); iface = iface_alloc(iface_dent->d_name, &err); if (!iface || err) { - if (err == EINVAL) + if (err == ISCSI_ERR_INVAL) log_error("Invalid iface name %s. Must be " "from 1 to %d characters.", iface_dent->d_name, @@ -756,7 +756,7 @@ static int iface_link(void *data, struct iface_copy = calloc(1, sizeof(*iface_copy)); if (!iface_copy) - return ENOMEM; + return ISCSI_ERR_NOMEM; memcpy(iface_copy, iface, sizeof(*iface_copy)); INIT_LIST_HEAD(&iface_copy->list); diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.c 2011-02-24 19:54:10.000000000 -0600 @@ -46,6 +46,7 @@ #include "iscsi_settings.h" #include "iface.h" #include "sysdeps.h" +#include "iscsi_err.h" #define ISCSI_CONN_ERR_REOPEN_DELAY 3 #define ISCSI_INTERNAL_ERR_REOPEN_DELAY 5 @@ -53,31 +54,17 @@ #define PROC_DIR "/proc" static void iscsi_login_timedout(void *data); +static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context, + struct iscsi_conn *conn, unsigned long tmo, + int event); -/* - * calculate parameter's padding - */ -static unsigned int -__padding(unsigned int param) -{ - int pad; - - pad = param & 3; - if (pad) { - pad = 4 - pad; - log_debug(1, "parameter's value %d padded to %d bytes\n", - param, param + pad); - } - return param + pad; -} - -static int iscsi_conn_context_alloc(iscsi_conn_t *conn) +static int iscsi_ev_context_alloc(iscsi_conn_t *conn) { int i; for (i = 0; i < CONTEXT_POOL_MAX; i++) { conn->context_pool[i] = calloc(1, - sizeof(struct iscsi_conn_context) + + sizeof(struct iscsi_ev_context) + ipc->ctldev_bufmax); if (!conn->context_pool[i]) { int j; @@ -91,7 +78,7 @@ static int iscsi_conn_context_alloc(iscs return 0; } -static void iscsi_conn_context_free(iscsi_conn_t *conn) +static void iscsi_ev_context_free(iscsi_conn_t *conn) { int i; @@ -107,10 +94,10 @@ static void iscsi_conn_context_free(iscs } } -struct iscsi_conn_context *iscsi_conn_context_get(iscsi_conn_t *conn, - int ev_size) +static struct iscsi_ev_context * +iscsi_ev_context_get(iscsi_conn_t *conn, int ev_size) { - struct iscsi_conn_context *conn_context; + struct iscsi_ev_context *ev_context; int i; if (ev_size > ipc->ctldev_bufmax) @@ -121,26 +108,26 @@ struct iscsi_conn_context *iscsi_conn_co continue; if (!conn->context_pool[i]->allocated) { - conn_context = conn->context_pool[i]; + ev_context = conn->context_pool[i]; - memset(&conn_context->actor, 0, + memset(&ev_context->actor, 0, sizeof(struct actor)); - conn_context->allocated = 1; + ev_context->allocated = 1; /* some callers abuse this pointer */ - conn_context->data = (void *)conn_context + - sizeof(struct iscsi_conn_context); - log_debug(7, "get conn context %p", - &conn_context->actor); - return conn_context; + ev_context->data = (void *)ev_context + + sizeof(struct iscsi_ev_context); + log_debug(7, "get ev context %p", + &ev_context->actor); + return ev_context; } } return NULL; } -void iscsi_conn_context_put(struct iscsi_conn_context *conn_context) +static void iscsi_ev_context_put(struct iscsi_ev_context *ev_context) { - log_debug(7, "put conn context %p", &conn_context->actor); - conn_context->allocated = 0; + log_debug(7, "put ev context %p", &ev_context->actor); + ev_context->allocated = 0; } static void session_online_devs(int host_no, int sid) @@ -205,11 +192,11 @@ __check_iscsi_status_class(iscsi_session log_error("session %d login rejected: Initiator " "failed authentication with target", session->id); - return CONN_LOGIN_FAILED; + return CONN_LOGIN_AUTH_FAILED; case ISCSI_LOGIN_STATUS_TGT_FORBIDDEN: log_error("conn %d login rejected: initiator " "failed authorization with target", conn->id); - return CONN_LOGIN_FAILED; + return CONN_LOGIN_AUTH_FAILED; case ISCSI_LOGIN_STATUS_TGT_NOT_FOUND: log_error("conn %d login rejected: initiator " "error - target not found (%02x/%02x)", @@ -250,183 +237,6 @@ __check_iscsi_status_class(iscsi_session return CONN_LOGIN_FAILED; } -static void -__setup_authentication(iscsi_session_t *session, - struct iscsi_auth_config *auth_cfg) -{ - /* if we have any incoming credentials, we insist on authenticating - * the target or not logging in at all - */ - if (auth_cfg->username_in[0] - || auth_cfg->password_in_length) { - /* sanity check the config */ - if (auth_cfg->password_length == 0) { - log_debug(1, - "node record has incoming " - "authentication credentials but has no outgoing " - "credentials configured, exiting"); - return; - } - session->bidirectional_auth = 1; - } else { - /* no or 1-way authentication */ - session->bidirectional_auth = 0; - } - - /* copy in whatever credentials we have */ - strlcpy(session->username, auth_cfg->username, - sizeof (session->username)); - session->username[sizeof (session->username) - 1] = '\0'; - if ((session->password_length = auth_cfg->password_length)) - memcpy(session->password, auth_cfg->password, - session->password_length); - - strlcpy(session->username_in, auth_cfg->username_in, - sizeof (session->username_in)); - session->username_in[sizeof (session->username_in) - 1] = '\0'; - if ((session->password_in_length = - auth_cfg->password_in_length)) - memcpy(session->password_in, auth_cfg->password_in, - session->password_in_length); - - if (session->password_length || session->password_in_length) { - /* setup the auth buffers */ - session->auth_buffers[0].address = &session->auth_client_block; - session->auth_buffers[0].length = - sizeof (session->auth_client_block); - session->auth_buffers[1].address = - &session->auth_recv_string_block; - session->auth_buffers[1].length = - sizeof (session->auth_recv_string_block); - - session->auth_buffers[2].address = - &session->auth_send_string_block; - session->auth_buffers[2].length = - sizeof (session->auth_send_string_block); - - session->auth_buffers[3].address = - &session->auth_recv_binary_block; - session->auth_buffers[3].length = - sizeof (session->auth_recv_binary_block); - - session->auth_buffers[4].address = - &session->auth_send_binary_block; - session->auth_buffers[4].length = - sizeof (session->auth_send_binary_block); - - session->num_auth_buffers = 5; - log_debug(6, "authentication setup complete..."); - } else { - session->num_auth_buffers = 0; - log_debug(6, "no authentication configured..."); - } -} - -static int -setup_portal(iscsi_conn_t *conn, conn_rec_t *conn_rec) -{ - char port[NI_MAXSERV]; - - sprintf(port, "%d", conn_rec->port); - if (resolve_address(conn_rec->address, port, &conn->saddr)) { - log_error("cannot resolve host name %s", - conn_rec->address); - return EINVAL; - } - conn->failback_saddr = conn->saddr; - - getnameinfo((struct sockaddr *)&conn->saddr, sizeof(conn->saddr), - conn->host, sizeof(conn->host), NULL, 0, NI_NUMERICHOST); - log_debug(4, "resolved %s to %s", conn_rec->address, conn->host); - return 0; -} - -static void -iscsi_copy_operational_params(iscsi_conn_t *conn) -{ - iscsi_session_t *session = conn->session; - conn_rec_t *conn_rec = &session->nrec.conn[conn->id]; - node_rec_t *rec = &session->nrec; - - conn->hdrdgst_en = conn_rec->iscsi.HeaderDigest; - conn->datadgst_en = conn_rec->iscsi.DataDigest; - - conn->max_recv_dlength = - __padding(conn_rec->iscsi.MaxRecvDataSegmentLength); - if (conn->max_recv_dlength < ISCSI_MIN_MAX_RECV_SEG_LEN || - conn->max_recv_dlength > ISCSI_MAX_MAX_RECV_SEG_LEN) { - log_error("Invalid iscsi.MaxRecvDataSegmentLength. Must be " - "within %u and %u. Setting to %u\n", - ISCSI_MIN_MAX_RECV_SEG_LEN, - ISCSI_MAX_MAX_RECV_SEG_LEN, - DEF_INI_MAX_RECV_SEG_LEN); - conn_rec->iscsi.MaxRecvDataSegmentLength = - DEF_INI_MAX_RECV_SEG_LEN; - conn->max_recv_dlength = DEF_INI_MAX_RECV_SEG_LEN; - } - - /* zero indicates to use the target's value */ - conn->max_xmit_dlength = - __padding(conn_rec->iscsi.MaxXmitDataSegmentLength); - if (conn->max_xmit_dlength == 0) - conn->max_xmit_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN; - if (conn->max_xmit_dlength < ISCSI_MIN_MAX_RECV_SEG_LEN || - conn->max_xmit_dlength > ISCSI_MAX_MAX_RECV_SEG_LEN) { - log_error("Invalid iscsi.MaxXmitDataSegmentLength. Must be " - "within %u and %u. Setting to %u\n", - ISCSI_MIN_MAX_RECV_SEG_LEN, - ISCSI_MAX_MAX_RECV_SEG_LEN, - DEF_INI_MAX_RECV_SEG_LEN); - conn_rec->iscsi.MaxXmitDataSegmentLength = - DEF_INI_MAX_RECV_SEG_LEN; - conn->max_xmit_dlength = DEF_INI_MAX_RECV_SEG_LEN; - } - - /* session's operational parameters */ - session->initial_r2t_en = rec->session.iscsi.InitialR2T; - session->imm_data_en = rec->session.iscsi.ImmediateData; - session->first_burst = __padding(rec->session.iscsi.FirstBurstLength); - /* - * some targets like netapp fail the login if sent bad first_burst - * and max_burst lens, even when immediate data=no and - * initial r2t = Yes, so we always check the user values. - */ - if (session->first_burst < ISCSI_MIN_FIRST_BURST_LEN || - session->first_burst > ISCSI_MAX_FIRST_BURST_LEN) { - log_error("Invalid iscsi.FirstBurstLength of %u. Must be " - "within %u and %u. Setting to %u\n", - session->first_burst, - ISCSI_MIN_FIRST_BURST_LEN, - ISCSI_MAX_FIRST_BURST_LEN, - DEF_INI_FIRST_BURST_LEN); - rec->session.iscsi.FirstBurstLength = DEF_INI_FIRST_BURST_LEN; - session->first_burst = DEF_INI_FIRST_BURST_LEN; - } - - session->max_burst = __padding(rec->session.iscsi.MaxBurstLength); - if (session->max_burst < ISCSI_MIN_MAX_BURST_LEN || - session->max_burst > ISCSI_MAX_MAX_BURST_LEN) { - log_error("Invalid iscsi.MaxBurstLength of %u. Must be " - "within %u and %u. Setting to %u\n", - session->max_burst, ISCSI_MIN_MAX_BURST_LEN, - ISCSI_MAX_MAX_BURST_LEN, DEF_INI_MAX_BURST_LEN); - rec->session.iscsi.MaxBurstLength = DEF_INI_MAX_BURST_LEN; - session->max_burst = DEF_INI_MAX_BURST_LEN; - } - - if (session->first_burst > session->max_burst) { - log_error("Invalid iscsi.FirstBurstLength of %u. Must be " - "less than iscsi.MaxBurstLength. Setting to %u\n", - session->first_burst, session->max_burst); - rec->session.iscsi.FirstBurstLength = session->max_burst; - session->first_burst = session->max_burst; - } - - session->def_time2wait = rec->session.iscsi.DefaultTime2Wait; - session->def_time2retain = rec->session.iscsi.DefaultTime2Retain; - session->erl = rec->session.iscsi.ERL; -} - static int __session_conn_create(iscsi_session_t *session, int cid) { @@ -434,9 +244,9 @@ __session_conn_create(iscsi_session_t *s conn_rec_t *conn_rec = &session->nrec.conn[cid]; int err; - if (iscsi_conn_context_alloc(conn)) { + if (iscsi_ev_context_alloc(conn)) { log_error("cannot allocate context_pool for conn cid %d", cid); - return ENOMEM; + return ISCSI_ERR_NOMEM; } conn->state = STATE_FREE; @@ -486,14 +296,15 @@ __session_conn_create(iscsi_session_t *s conn->noop_out_interval = DEF_NOOP_OUT_INTERVAL; } - iscsi_copy_operational_params(conn); + iscsi_copy_operational_params(conn, &session->nrec.session.iscsi, + &conn_rec->iscsi); /* TCP options */ conn->tcp_window_size = conn_rec->tcp.window_size; /* FIXME: type_of_service */ /* resolve the string address to an IP address */ - err = setup_portal(conn, conn_rec); + err = iscsi_setup_portal(conn, conn_rec->address, conn_rec->port); if (err) return err; return 0; @@ -506,7 +317,7 @@ session_release(iscsi_session_t *session if (session->target_alias) free(session->target_alias); - iscsi_conn_context_free(&session->conn[0]); + iscsi_ev_context_free(&session->conn[0]); free(session); } @@ -524,11 +335,10 @@ __session_create(node_rec_t *rec, struct log_debug(2, "Allocted session %p", session); INIT_LIST_HEAD(&session->list); - /* opened at daemon load time (iscsid.c) */ - session->ctrl_fd = control_fd; session->t = t; session->reopen_qtask.mgmt_ipc_fd = -1; session->id = -1; + session->use_ipc = 1; /* save node record. we might need it for redirection */ memcpy(&session->nrec, rec, sizeof(node_rec_t)); @@ -570,7 +380,7 @@ __session_create(node_rec_t *rec, struct session->isid[5] = 0; /* setup authentication variables for the session*/ - __setup_authentication(session, &rec->session.auth); + iscsi_setup_authentication(session, &rec->session.auth); session->param_mask = ~0ULL; if (!(t->caps & CAP_MULTI_R2T)) @@ -601,18 +411,18 @@ __session_create(node_rec_t *rec, struct static void iscsi_flush_context_pool(struct iscsi_session *session) { - struct iscsi_conn_context *conn_context; + struct iscsi_ev_context *ev_context; struct iscsi_conn *conn = &session->conn[0]; int i; for (i = 0; i < CONTEXT_POOL_MAX; i++) { - conn_context = conn->context_pool[i]; - if (!conn_context) + ev_context = conn->context_pool[i]; + if (!ev_context) continue; - if (conn_context->allocated) { + if (ev_context->allocated) { actor_delete(&(conn->context_pool[i]->actor)); - iscsi_conn_context_put(conn_context); + iscsi_ev_context_put(ev_context); } } } @@ -633,9 +443,9 @@ conn_delete_timers(iscsi_conn_t *conn) actor_delete(&conn->nop_out_timer); } -static mgmt_ipc_err_e +static int session_conn_shutdown(iscsi_conn_t *conn, queue_task_t *qtask, - mgmt_ipc_err_e err) + int err) { iscsi_session_t *session = conn->session; @@ -657,7 +467,7 @@ session_conn_shutdown(iscsi_conn_t *conn conn->id, STOP_CONN_TERM)) { log_error("can't stop connection %d:%d (%d)", session->id, conn->id, errno); - return MGMT_IPC_ERR_INTERNAL; + return ISCSI_ERR_INTERNAL; } } @@ -665,7 +475,7 @@ session_conn_shutdown(iscsi_conn_t *conn if (ipc->destroy_conn(session->t->handle, session->id, conn->id)) { log_error("can not safely destroy connection %d", conn->id); - return MGMT_IPC_ERR_INTERNAL; + return ISCSI_ERR_INTERNAL; } cleanup: @@ -674,7 +484,7 @@ cleanup: if (ipc->destroy_session(session->t->handle, session->id)) { log_error("can not safely destroy session %d", session->id); - return MGMT_IPC_ERR_INTERNAL; + return ISCSI_ERR_INTERNAL; } } @@ -688,7 +498,7 @@ cleanup: mgmt_ipc_write_rsp(qtask, err); conn_delete_timers(conn); __session_destroy(session); - return MGMT_IPC_OK; + return ISCSI_SUCCESS; } static void @@ -709,17 +519,17 @@ queue_delayed_reopen(queue_task_t *qtask static int iscsi_conn_connect(struct iscsi_conn *conn, queue_task_t *qtask) { - struct iscsi_conn_context *conn_context; + struct iscsi_ev_context *ev_context; int rc; - conn_context = iscsi_conn_context_get(conn, 0); - if (!conn_context) { + ev_context = iscsi_ev_context_get(conn, 0); + if (!ev_context) { /* while reopening the recv pool should be full */ log_error("BUG: __session_conn_reopen could not get conn " "context for recv."); return ENOMEM; } - conn_context->data = qtask; + ev_context->data = qtask; rc = conn->session->t->template->ep_connect(conn, 1); if (rc < 0 && errno != EINPROGRESS) { @@ -732,11 +542,11 @@ static int iscsi_conn_connect(struct isc log_error("cannot make a connection to %s:%s (%d,%d)", conn->host, serv, rc, errno); - iscsi_conn_context_put(conn_context); + iscsi_ev_context_put(ev_context); return ENOTCONN; } - iscsi_sched_conn_context(conn_context, conn, 0, EV_CONN_POLL); + iscsi_sched_ev_context(ev_context, conn, 0, EV_CONN_POLL); log_debug(3, "Setting login timer %p timeout %d", &conn->login_timer, conn->login_timeout); actor_timer(&conn->login_timer, conn->login_timeout * 1000, @@ -844,8 +654,16 @@ static int iscsi_retry_initial_login(str return 1; } +static int iscsi_login_is_fatal_err(int err) +{ + if (err == ISCSI_ERR_LOGIN_AUTH_FAILED || + err == ISCSI_ERR_FATAL_LOGIN) + return 1; + return 0; +} + static void iscsi_login_eh(struct iscsi_conn *conn, struct queue_task *qtask, - mgmt_ipc_err_e err) + int err) { struct iscsi_session *session = conn->session; @@ -863,7 +681,7 @@ static void iscsi_login_eh(struct iscsi_ "R_STAGE_NO_CHANGE"); /* timeout during initial connect. * clean connection. write ipc rsp or retry */ - if (err == MGMT_IPC_ERR_FATAL_LOGIN_FAILURE || + if (iscsi_login_is_fatal_err(err) || !iscsi_retry_initial_login(conn)) session_conn_shutdown(conn, qtask, err); else { @@ -879,7 +697,7 @@ static void iscsi_login_eh(struct iscsi_ "R_STAGE_SESSION_REDIRECT"); /* timeout during initial redirect connect * clean connection. write ipc rsp or retry */ - if (err == MGMT_IPC_ERR_FATAL_LOGIN_FAILURE || + if (iscsi_login_is_fatal_err(err) || !iscsi_retry_initial_login(conn)) session_conn_shutdown(conn, qtask, err); else @@ -912,7 +730,7 @@ static void iscsi_login_eh(struct iscsi_ * initial redirected connect. Clean connection * and write rsp or retry. */ - if (err == MGMT_IPC_ERR_FATAL_LOGIN_FAILURE || + if (iscsi_login_is_fatal_err(err) || !iscsi_retry_initial_login(conn)) session_conn_shutdown(conn, qtask, err); else @@ -927,7 +745,7 @@ static void iscsi_login_eh(struct iscsi_ break; case R_STAGE_SESSION_CLEANUP: session_conn_shutdown(conn, qtask, - MGMT_IPC_ERR_PDU_TIMEOUT); + ISCSI_ERR_PDU_TIMEOUT); break; default: break; @@ -951,7 +769,7 @@ __conn_error_handle(iscsi_session_t *ses * just cleanup and return to the user. */ if (conn->logout_qtask) { - session_conn_shutdown(conn, conn->logout_qtask, MGMT_IPC_OK); + session_conn_shutdown(conn, conn->logout_qtask, ISCSI_SUCCESS); return; } @@ -992,7 +810,7 @@ __conn_error_handle(iscsi_session_t *ses qtask = session->sync_qtask; else qtask = &session->reopen_qtask; - iscsi_login_eh(conn, qtask, MGMT_IPC_ERR_TRANS_FAILURE); + iscsi_login_eh(conn, qtask, ISCSI_ERR_TRANS); return; } log_debug(1, "ignoring conn error in login. " @@ -1020,19 +838,19 @@ __conn_error_handle(iscsi_session_t *ses static void session_conn_error(void *data) { - struct iscsi_conn_context *conn_context = data; - enum iscsi_err error = *(enum iscsi_err *)conn_context->data; - iscsi_conn_t *conn = conn_context->conn; + struct iscsi_ev_context *ev_context = data; + enum iscsi_err error = *(enum iscsi_err *)ev_context->data; + iscsi_conn_t *conn = ev_context->conn; iscsi_session_t *session = conn->session; log_warning("Kernel reported iSCSI connection %d:%d error (%d) " "state (%d)", session->id, conn->id, error, conn->state); - iscsi_conn_context_put(conn_context); + iscsi_ev_context_put(ev_context); switch (error) { case ISCSI_ERR_INVALID_HOST: - if (session_conn_shutdown(conn, NULL, MGMT_IPC_OK)) + if (session_conn_shutdown(conn, NULL, ISCSI_SUCCESS)) log_error("BUG: Could not shutdown session."); break; default: @@ -1047,13 +865,13 @@ static void iscsi_login_timedout(void *d switch (conn->state) { case STATE_XPT_WAIT: - iscsi_login_eh(conn, qtask, MGMT_IPC_ERR_TRANS_TIMEOUT); + iscsi_login_eh(conn, qtask, ISCSI_ERR_TRANS_TIMEOUT); break; case STATE_IN_LOGIN: - iscsi_login_eh(conn, qtask, MGMT_IPC_ERR_PDU_TIMEOUT); + iscsi_login_eh(conn, qtask, ISCSI_ERR_PDU_TIMEOUT); break; default: - iscsi_login_eh(conn, qtask, MGMT_IPC_ERR_INTERNAL); + iscsi_login_eh(conn, qtask, ISCSI_ERR_INTERNAL); break; } } @@ -1136,17 +954,6 @@ static void conn_send_nop_out(void *data &conn->nop_out_timer, conn->noop_out_timeout); } -static void -print_param_value(enum iscsi_param param, void *value, int type) -{ - log_debug(3, "set operational parameter %d to:", param); - - if (type == ISCSI_STRING) - log_debug(3, "%s", value ? (char *)value : "NULL"); - else - log_debug(3, "%u", *(uint32_t *)value); -} - void free_initiator(void) { struct iscsi_transport *t; @@ -1170,7 +977,7 @@ static void session_scan_host(struct isc pid = iscsi_sysfs_scan_host(hostno, 1); if (pid == 0) { - mgmt_ipc_write_rsp(qtask, MGMT_IPC_OK); + mgmt_ipc_write_rsp(qtask, ISCSI_SUCCESS); if (session) iscsi_sysfs_for_each_device( @@ -1185,302 +992,33 @@ static void session_scan_host(struct isc free(qtask); } } else - mgmt_ipc_write_rsp(qtask, MGMT_IPC_ERR_INTERNAL); -} - -static int __iscsi_host_set_param(struct iscsi_transport *t, - int host_no, int param, char *value, - int type) -{ - int rc; - - rc = ipc->set_host_param(t->handle, host_no, param, value, type); - /* 2.6.20 and below returns EINVAL */ - if (rc && rc != -ENOSYS && rc != -EINVAL) { - log_error("can't set operational parameter %d for " - "host %d, retcode %d (%d)", param, host_no, - rc, errno); - return rc; - } - return 0; + mgmt_ipc_write_rsp(qtask, ISCSI_ERR_INTERNAL); } -mgmt_ipc_err_e iscsi_host_set_param(int host_no, int param, char *value) -{ - struct iscsi_transport *t; - - t = iscsi_sysfs_get_transport_by_hba(host_no); - if (!t) - return MGMT_IPC_ERR_TRANS_FAILURE; - if (__iscsi_host_set_param(t, host_no, param, value, ISCSI_STRING)) - return MGMT_IPC_ERR; - return MGMT_IPC_OK; -} - -#define MAX_SESSION_PARAMS 32 -#define MAX_HOST_PARAMS 3 - static void setup_full_feature_phase(iscsi_conn_t *conn) { iscsi_session_t *session = conn->session; iscsi_login_context_t *c = &conn->login_context; - int i, rc; - uint32_t one = 1, zero = 0; - struct hostparam { - int param; - int type; - void *value; - int set; - } hosttbl[MAX_HOST_PARAMS] = { - { - .param = ISCSI_HOST_PARAM_NETDEV_NAME, - .value = session->nrec.iface.netdev, - .type = ISCSI_STRING, - .set = 1, - }, { - .param = ISCSI_HOST_PARAM_HWADDRESS, - .value = session->nrec.iface.hwaddress, - .type = ISCSI_STRING, - .set = 1, - }, { - .param = ISCSI_HOST_PARAM_INITIATOR_NAME, - .value = session->initiator_name, - .type = ISCSI_STRING, - .set = 0, - }, - }; - struct connparam { - int param; - int type; - void *value; - int conn_only; - } conntbl[MAX_SESSION_PARAMS] = { - { - .param = ISCSI_PARAM_MAX_RECV_DLENGTH, - .value = &conn->max_recv_dlength, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_MAX_XMIT_DLENGTH, - .value = &conn->max_xmit_dlength, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_HDRDGST_EN, - .value = &conn->hdrdgst_en, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_DATADGST_EN, - .value = &conn->datadgst_en, - .type = ISCSI_INT, - .conn_only = 1, - }, { - .param = ISCSI_PARAM_INITIAL_R2T_EN, - .value = &session->initial_r2t_en, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_MAX_R2T, - .value = &one, /* FIXME: session->max_r2t */ - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_IMM_DATA_EN, - .value = &session->imm_data_en, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_FIRST_BURST, - .value = &session->first_burst, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_MAX_BURST, - .value = &session->max_burst, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_PDU_INORDER_EN, - .value = &session->pdu_inorder_en, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param =ISCSI_PARAM_DATASEQ_INORDER_EN, - .value = &session->dataseq_inorder_en, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_ERL, - .value = &zero, /* FIXME: session->erl */ - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_IFMARKER_EN, - .value = &zero,/* FIXME: session->ifmarker_en */ - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_OFMARKER_EN, - .value = &zero,/* FIXME: session->ofmarker_en */ - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_EXP_STATSN, - .value = &conn->exp_statsn, - .type = ISCSI_INT, - .conn_only = 1, - }, { - .param = ISCSI_PARAM_TARGET_NAME, - .conn_only = 0, - .type = ISCSI_STRING, - .value = session->target_name, - }, { - .param = ISCSI_PARAM_TPGT, - .value = &session->portal_group_tag, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_PERSISTENT_ADDRESS, - .value = session->nrec.conn[conn->id].address, - .type = ISCSI_STRING, - .conn_only = 1, - }, { - .param = ISCSI_PARAM_PERSISTENT_PORT, - .value = &session->nrec.conn[conn->id].port, - .type = ISCSI_INT, - .conn_only = 1, - }, { - .param = ISCSI_PARAM_SESS_RECOVERY_TMO, - .value = &session->replacement_timeout, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_USERNAME, - .value = session->username, - .type = ISCSI_STRING, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_USERNAME_IN, - .value = session->username_in, - .type = ISCSI_STRING, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_PASSWORD, - .value = session->password, - .type = ISCSI_STRING, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_PASSWORD_IN, - .value = session->password_in, - .type = ISCSI_STRING, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_FAST_ABORT, - .value = &session->fast_abort, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_ABORT_TMO, - .value = &session->abort_timeout, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_LU_RESET_TMO, - .value = &session->lu_reset_timeout, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_TGT_RESET_TMO, - .value = &session->tgt_reset_timeout, - .type = ISCSI_INT, - .conn_only = 0, - }, { - .param = ISCSI_PARAM_PING_TMO, - .value = &conn->noop_out_timeout, - .type = ISCSI_INT, - .conn_only = 1, - }, { - .param = ISCSI_PARAM_RECV_TMO, - .value = &conn->noop_out_interval, - .type = ISCSI_INT, - .conn_only = 1, - }, { - .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, - }, - }; + int rc; actor_delete(&conn->login_timer); - /* Entered full-feature phase! */ - for (i = 0; i < MAX_SESSION_PARAMS; i++) { - if (conn->id != 0 && !conntbl[i].conn_only) - continue; - - if (!(session->param_mask & (1ULL << conntbl[i].param))) - continue; - rc = ipc->set_param(session->t->handle, session->id, - conn->id, conntbl[i].param, conntbl[i].value, - conntbl[i].type); - if (rc && rc != -ENOSYS) { - log_error("can't set operational parameter %d for " - "connection %d:%d, retcode %d (%d)", - conntbl[i].param, session->id, conn->id, - rc, errno); - - iscsi_login_eh(conn, c->qtask, - MGMT_IPC_ERR_LOGIN_FAILURE); - return; - } - - if (rc == -ENOSYS) { - switch (conntbl[i].param) { - case ISCSI_PARAM_PING_TMO: - /* - * older kernels may not support nops - * in kernel - */ - conn->userspace_nop = 1; - break; - case ISCSI_PARAM_INITIATOR_NAME: - /* use host level one instead */ - hosttbl[ISCSI_HOST_PARAM_INITIATOR_NAME].set = 1; - break; - } - } - - print_param_value(conntbl[i].param, conntbl[i].value, - conntbl[i].type); + if (iscsi_session_set_params(conn)) { + iscsi_login_eh(conn, c->qtask, ISCSI_ERR_LOGIN); + return; } - for (i = 0; i < MAX_HOST_PARAMS; i++) { - if (!hosttbl[i].set) - continue; - - if (__iscsi_host_set_param(session->t, session->hostno, - hosttbl[i].param, hosttbl[i].value, - hosttbl[i].type)) { - iscsi_login_eh(conn, c->qtask, - MGMT_IPC_ERR_LOGIN_FAILURE); - return; - } - - print_param_value(hosttbl[i].param, hosttbl[i].value, - hosttbl[i].type); + if (iscsi_host_set_params(session)) { + iscsi_login_eh(conn, c->qtask, ISCSI_ERR_LOGIN); + return; } if (ipc->start_conn(session->t->handle, session->id, conn->id, &rc) || rc) { log_error("can't start connection %d:%d retcode %d (%d)", session->id, conn->id, rc, errno); - iscsi_login_eh(conn, c->qtask, MGMT_IPC_ERR_INTERNAL); + iscsi_login_eh(conn, c->qtask, ISCSI_ERR_INTERNAL); return; } @@ -1504,7 +1042,7 @@ setup_full_feature_phase(iscsi_conn_t *c session->sync_qtask = NULL; session_online_devs(session->hostno, session->id); - mgmt_ipc_write_rsp(c->qtask, MGMT_IPC_OK); + mgmt_ipc_write_rsp(c->qtask, ISCSI_SUCCESS); log_warning("connection%d:%d is operational after recovery " "(%d attempts)", session->id, conn->id, session->reopen_cnt); @@ -1527,10 +1065,10 @@ setup_full_feature_phase(iscsi_conn_t *c static void iscsi_logout_timedout(void *data) { - struct iscsi_conn_context *conn_context = data; - struct iscsi_conn *conn = conn_context->conn; + struct iscsi_ev_context *ev_context = data; + struct iscsi_conn *conn = ev_context->conn; - iscsi_conn_context_put(conn_context); + iscsi_ev_context_put(ev_context); /* * assume we were in STATE_IN_LOGOUT or there * was some nasty error @@ -1542,7 +1080,7 @@ static void iscsi_logout_timedout(void * static int iscsi_send_logout(iscsi_conn_t *conn) { struct iscsi_logout hdr; - struct iscsi_conn_context *conn_context; + struct iscsi_ev_context *ev_context; if (conn->state != STATE_LOGGED_IN) return EINVAL; @@ -1558,12 +1096,12 @@ static int iscsi_send_logout(iscsi_conn_ return EIO; conn->state = STATE_IN_LOGOUT; - conn_context = iscsi_conn_context_get(conn, 0); - if (!conn_context) + ev_context = iscsi_ev_context_get(conn, 0); + if (!ev_context) /* unbounded logout */ log_warning("Could not allocate conn context for logout."); else { - iscsi_sched_conn_context(conn_context, conn, + iscsi_sched_ev_context(ev_context, conn, conn->logout_timeout, EV_CONN_LOGOUT_TIMER); log_debug(3, "logout timeout timer %u\n", @@ -1575,16 +1113,16 @@ static int iscsi_send_logout(iscsi_conn_ static void iscsi_stop(void *data) { - struct iscsi_conn_context *conn_context = data; - struct iscsi_conn *conn = conn_context->conn; + struct iscsi_ev_context *ev_context = data; + struct iscsi_conn *conn = ev_context->conn; int rc = 0; - iscsi_conn_context_put(conn_context); + iscsi_ev_context_put(ev_context); if (!iscsi_send_logout(conn)) return; - rc = session_conn_shutdown(conn, conn->logout_qtask, MGMT_IPC_OK); + rc = session_conn_shutdown(conn, conn->logout_qtask, ISCSI_SUCCESS); if (rc) log_error("BUG: Could not shutdown session."); } @@ -1683,6 +1221,7 @@ static void iscsi_recv_login_rsp(struct { struct iscsi_session *session = conn->session; iscsi_login_context_t *c = &conn->login_context; + int err = ISCSI_ERR_FATAL_LOGIN; if (iscsi_login_rsp(session, c)) { log_debug(1, "login_rsp ret (%d)", c->ret); @@ -1703,6 +1242,9 @@ static void iscsi_recv_login_rsp(struct switch (__check_iscsi_status_class(session, conn->id, c->status_class, c->status_detail)) { + case CONN_LOGIN_AUTH_FAILED: + err = ISCSI_ERR_LOGIN_AUTH_FAILED; + goto failed; case CONN_LOGIN_FAILED: goto failed; case CONN_LOGIN_IMM_REDIRECT_RETRY: @@ -1720,8 +1262,7 @@ static void iscsi_recv_login_rsp(struct /* more nego. needed! */ conn->state = STATE_IN_LOGIN; if (iscsi_login_req(session, c)) { - iscsi_login_eh(conn, c->qtask, - MGMT_IPC_ERR_LOGIN_FAILURE); + iscsi_login_eh(conn, c->qtask, ISCSI_ERR_LOGIN); return; } } else @@ -1730,22 +1271,22 @@ static void iscsi_recv_login_rsp(struct return; retry: /* retry if not initial login or initial login has not timed out */ - iscsi_login_eh(conn, c->qtask, MGMT_IPC_ERR_LOGIN_FAILURE); + iscsi_login_eh(conn, c->qtask, ISCSI_ERR_LOGIN); return; failed: /* force failure if initial login */ session->reopen_cnt = session->nrec.session.initial_login_retry_max; - iscsi_login_eh(conn, c->qtask, MGMT_IPC_ERR_FATAL_LOGIN_FAILURE); + iscsi_login_eh(conn, c->qtask, err); return; } static void session_conn_recv_pdu(void *data) { - struct iscsi_conn_context *conn_context = data; - iscsi_conn_t *conn = conn_context->conn; + struct iscsi_ev_context *ev_context = data; + iscsi_conn_t *conn = ev_context->conn; struct iscsi_hdr hdr; - conn->recv_context = conn_context; + conn->recv_context = ev_context; switch (conn->state) { case STATE_IN_LOGIN: @@ -1755,11 +1296,10 @@ static void session_conn_recv_pdu(void * case STATE_IN_LOGOUT: case STATE_LOGOUT_REQUESTED: /* read incoming PDU */ - if (!iscsi_io_recv_pdu(conn, &hdr, ISCSI_DIGEST_NONE, - conn->data, ISCSI_DEF_MAX_RECV_SEG_LEN, - ISCSI_DIGEST_NONE, 0)) { + if (iscsi_io_recv_pdu(conn, &hdr, ISCSI_DIGEST_NONE, + conn->data, ISCSI_DEF_MAX_RECV_SEG_LEN, + ISCSI_DIGEST_NONE, 0) < 0) return; - } switch (hdr.opcode & ISCSI_OPCODE_MASK) { case ISCSI_OP_NOOP_IN: @@ -1777,17 +1317,17 @@ static void session_conn_recv_pdu(void * } break; case STATE_XPT_WAIT: - iscsi_conn_context_put(conn_context); + iscsi_ev_context_put(ev_context); log_debug(1, "ignoring incoming PDU in XPT_WAIT. " "let connection re-establish or fail"); break; case STATE_CLEANUP_WAIT: - iscsi_conn_context_put(conn_context); + iscsi_ev_context_put(ev_context); log_debug(1, "ignoring incoming PDU in XPT_WAIT. " "let connection cleanup"); break; default: - iscsi_conn_context_put(conn_context); + iscsi_ev_context_put(ev_context); log_error("Invalid state. Dropping PDU.\n"); } } @@ -1910,15 +1450,15 @@ retry_create: static void session_conn_poll(void *data) { - struct iscsi_conn_context *conn_context = data; - iscsi_conn_t *conn = conn_context->conn; + struct iscsi_ev_context *ev_context = data; + iscsi_conn_t *conn = ev_context->conn; struct iscsi_session *session = conn->session; - mgmt_ipc_err_e err = MGMT_IPC_OK; - queue_task_t *qtask = conn_context->data; + int err = ISCSI_SUCCESS; + queue_task_t *qtask = ev_context->data; iscsi_login_context_t *c = &conn->login_context; int rc; - iscsi_conn_context_put(conn_context); + iscsi_ev_context_put(ev_context); if (conn->state != STATE_XPT_WAIT) return; @@ -1927,16 +1467,16 @@ static void session_conn_poll(void *data if (rc == 0) { log_debug(4, "poll not connected %d", rc); /* timedout: Poll again. */ - conn_context = iscsi_conn_context_get(conn, 0); - if (!conn_context) { + ev_context = iscsi_ev_context_get(conn, 0); + if (!ev_context) { /* while polling the recv pool should be full */ log_error("BUG: session_conn_poll could not get conn " "context."); - iscsi_login_eh(conn, qtask, MGMT_IPC_ERR_INTERNAL); + iscsi_login_eh(conn, qtask, ISCSI_ERR_INTERNAL); return; } - conn_context->data = qtask; - iscsi_sched_conn_context(conn_context, conn, 0, EV_CONN_POLL); + ev_context->data = qtask; + iscsi_sched_ev_context(ev_context, conn, 0, EV_CONN_POLL); } else if (rc > 0) { /* connected! */ memset(c, 0, sizeof(iscsi_login_context_t)); @@ -1945,7 +1485,7 @@ static void session_conn_poll(void *data if (session->id == -1) { if (conn->id == 0 && session_ipc_create(session)) { log_error("Can't create session."); - err = MGMT_IPC_ERR_INTERNAL; + err = ISCSI_ERR_INTERNAL; goto cleanup; } log_debug(3, "created new iSCSI session sid %d host " @@ -1954,17 +1494,16 @@ static void session_conn_poll(void *data if (ipc->create_conn(session->t->handle, session->id, conn->id, &conn->id)) { log_error("Can't create connection."); - err = MGMT_IPC_ERR_INTERNAL; + err = ISCSI_ERR_INTERNAL; goto cleanup; } log_debug(3, "created new iSCSI connection " "%d:%d", session->id, conn->id); } - iscsi_copy_operational_params(conn); - - if (session->t->template->create_conn) - session->t->template->create_conn(conn); + iscsi_copy_operational_params(conn, + &session->nrec.session.iscsi, + &session->nrec.conn[conn->id].iscsi); /* * TODO: use the iface number or some other value * so this will be persistent @@ -1977,7 +1516,7 @@ static void session_conn_poll(void *data log_error("can't bind conn %d:%d to session %d, " "retcode %d (%d)", session->id, conn->id, session->id, rc, errno); - iscsi_login_eh(conn, qtask, MGMT_IPC_ERR_LOGIN_FAILURE); + iscsi_login_eh(conn, qtask, ISCSI_ERR_LOGIN); return; } log_debug(3, "bound iSCSI connection %d:%d to session %d", @@ -1991,13 +1530,13 @@ static void session_conn_poll(void *data conn->exp_statsn = iscsi_sysfs_get_exp_statsn(session->id); if (iscsi_login_begin(session, c)) { - iscsi_login_eh(conn, qtask, MGMT_IPC_ERR_LOGIN_FAILURE); + iscsi_login_eh(conn, qtask, ISCSI_ERR_LOGIN); return; } conn->state = STATE_IN_LOGIN; if (iscsi_login_req(session, c)) { - iscsi_login_eh(conn, qtask, MGMT_IPC_ERR_LOGIN_FAILURE); + iscsi_login_eh(conn, qtask, ISCSI_ERR_LOGIN); return; } } else { @@ -2011,70 +1550,55 @@ cleanup: session_conn_shutdown(conn, qtask, err); } -void iscsi_sched_conn_context(struct iscsi_conn_context *conn_context, - struct iscsi_conn *conn, unsigned long tmo, - int event) +static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context, + struct iscsi_conn *conn, unsigned long tmo, + int event) { enum iscsi_err error; log_debug(7, "sched conn context %p event %d, tmo %lu", - &conn_context->actor, event, tmo); + &ev_context->actor, event, tmo); - conn_context->conn = conn; + ev_context->conn = conn; switch (event) { case EV_CONN_RECV_PDU: - actor_new(&conn_context->actor, session_conn_recv_pdu, - conn_context); - actor_schedule(&conn_context->actor); + actor_new(&ev_context->actor, session_conn_recv_pdu, + ev_context); + actor_schedule(&ev_context->actor); break; case EV_CONN_ERROR: - error = *(enum iscsi_err *)conn_context->data; + error = *(enum iscsi_err *)ev_context->data; - actor_new(&conn_context->actor, session_conn_error, - conn_context); + actor_new(&ev_context->actor, session_conn_error, + ev_context); /* * We handle invalid host, by killing the session. * It must go at the head of the queue, so we do not * initiate error handling or logout or some other op. */ if (error == ISCSI_ERR_INVALID_HOST) - actor_schedule_head(&conn_context->actor); + actor_schedule_head(&ev_context->actor); else - actor_schedule(&conn_context->actor); + actor_schedule(&ev_context->actor); break; case EV_CONN_POLL: - actor_new(&conn_context->actor, session_conn_poll, - conn_context); - actor_schedule(&conn_context->actor); + actor_new(&ev_context->actor, session_conn_poll, + ev_context); + actor_schedule(&ev_context->actor); break; case EV_CONN_LOGOUT_TIMER: - actor_timer(&conn_context->actor, tmo * 1000, - iscsi_logout_timedout, conn_context); + actor_timer(&ev_context->actor, tmo * 1000, + iscsi_logout_timedout, ev_context); break; case EV_CONN_STOP: - actor_new(&conn_context->actor, iscsi_stop, - conn_context); - actor_schedule(&conn_context->actor); + actor_new(&ev_context->actor, iscsi_stop, + ev_context); + actor_schedule(&ev_context->actor); break; default: log_error("Invalid event type %d.", event); - return; } -} - -iscsi_session_t* -session_find_by_sid(int sid) -{ - struct iscsi_transport *t; - iscsi_session_t *session; - - list_for_each_entry(t, &transports, list) { - list_for_each_entry(session, &t->sessions, list) { - if (session->id == sid) - return session; - } - } - return NULL; + return 0; } static iscsi_session_t* session_find_by_rec(node_rec_t *rec) @@ -2111,65 +1635,20 @@ static int session_is_running(node_rec_t return 0; } -static int iface_set_param(struct iscsi_transport *t, struct iface_rec *iface, - struct iscsi_session *session) -{ - int rc = 0; - - log_debug(3, "setting iface %s, dev %s, set ip %s, hw %s, " - "transport %s.\n", - iface->name, iface->netdev, iface->ipaddress, - iface->hwaddress, iface->transport_name); - - if (!t->template->set_host_ip) - return 0; - - /* if we need to set the ip addr then set all the iface net settings */ - if (!iface_is_bound_by_ipaddr(iface)) { - log_warning("Please set the iface.ipaddress for iface %s, " - "then retry the login command.\n", iface->name); - return EINVAL; - } - - rc = __iscsi_host_set_param(t, session->hostno, - ISCSI_HOST_PARAM_IPADDRESS, - iface->ipaddress, ISCSI_STRING); - if (rc) - return rc; - - if (iface_is_bound_by_netdev(iface)) { - rc = __iscsi_host_set_param(t, session->hostno, - ISCSI_HOST_PARAM_NETDEV_NAME, - iface->netdev, ISCSI_STRING); - if (rc) - return rc; - } - - if (iface_is_bound_by_hwaddr(iface)) { - 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) { iscsi_session_t *session; iscsi_conn_t *conn; struct iscsi_transport *t; + int rc; if (session_is_running(rec)) - return MGMT_IPC_ERR_EXISTS; + return ISCSI_ERR_SESS_EXISTS; t = iscsi_sysfs_get_transport_by_name(rec->iface.transport_name); if (!t) - return MGMT_IPC_ERR_TRANS_NOT_FOUND; - if (set_transport_template(t)) - return MGMT_IPC_ERR_TRANS_NOT_FOUND; + return ISCSI_ERR_TRANS_NOT_FOUND; if ((!(t->caps & CAP_RECOVERY_L0) && rec->session.iscsi.ERL != 0) || @@ -2222,27 +1701,28 @@ session_login_task(node_rec_t *rec, queu session = __session_create(rec, t); if (!session) - return MGMT_IPC_ERR_LOGIN_FAILURE; + return ISCSI_ERR_LOGIN; /* FIXME: login all connections! marked as "automatic" */ /* create leading connection */ - if (__session_conn_create(session, 0)) { + rc = __session_conn_create(session, 0); + if (rc) { __session_destroy(session); - return MGMT_IPC_ERR_LOGIN_FAILURE; + return rc; } conn = &session->conn[0]; qtask->conn = conn; - if (iface_set_param(t, &rec->iface, session)) { + if (iscsi_host_set_net_params(&rec->iface, session)) { __session_destroy(session); - return MGMT_IPC_ERR_LOGIN_FAILURE; + return ISCSI_ERR_LOGIN; } conn->state = STATE_XPT_WAIT; if (iscsi_conn_connect(conn, qtask)) { __session_destroy(session); - return MGMT_IPC_ERR_TRANS_FAILURE; + return ISCSI_ERR_TRANS; } if (gettimeofday(&conn->initial_connect_time, NULL)) @@ -2251,17 +1731,19 @@ session_login_task(node_rec_t *rec, queu "login early. You should manually login."); qtask->rsp.command = MGMT_IPC_SESSION_LOGIN; - qtask->rsp.err = MGMT_IPC_OK; - return MGMT_IPC_OK; + qtask->rsp.err = ISCSI_SUCCESS; + return ISCSI_SUCCESS; } static int sync_conn(iscsi_session_t *session, uint32_t cid) { iscsi_conn_t *conn; + int rc; - if (__session_conn_create(session, cid)) - return ENOMEM; + rc = __session_conn_create(session, cid); + if (rc) + return rc; conn = &session->conn[cid]; /* TODO: must export via sysfs so we can pick this up */ @@ -2269,7 +1751,7 @@ sync_conn(iscsi_session_t *session, uint return 0; } -mgmt_ipc_err_e +int iscsi_sync_session(node_rec_t *rec, queue_task_t *qtask, uint32_t sid) { iscsi_session_t *session; @@ -2278,32 +1760,24 @@ iscsi_sync_session(node_rec_t *rec, queu t = iscsi_sysfs_get_transport_by_name(rec->iface.transport_name); if (!t) - return MGMT_IPC_ERR_TRANS_NOT_FOUND; - if (set_transport_template(t)) - return MGMT_IPC_ERR_TRANS_NOT_FOUND; + return ISCSI_ERR_TRANS_NOT_FOUND; session = __session_create(rec, t); if (!session) - return MGMT_IPC_ERR_LOGIN_FAILURE; + return ISCSI_ERR_LOGIN; session->id = sid; session->hostno = iscsi_sysfs_get_host_no_from_sid(sid, &err); if (err) { log_error("Could not get hostno for session %d\n", sid); - err = MGMT_IPC_ERR_NOT_FOUND; goto destroy_session; } session->r_stage = R_STAGE_SESSION_REOPEN; err = sync_conn(session, 0); - if (err) { - if (err == ENOMEM) - err = MGMT_IPC_ERR_NOMEM; - else - err = MGMT_IPC_ERR_INVAL; + if (err) goto destroy_session; - } session->sync_qtask = qtask; qtask->rsp.command = MGMT_IPC_SESSION_SYNC; @@ -2334,12 +1808,12 @@ session_logout_task(int sid, queue_task_ { iscsi_session_t *session; iscsi_conn_t *conn; - mgmt_ipc_err_e rc = MGMT_IPC_OK; + int rc = ISCSI_SUCCESS; session = session_find_by_sid(sid); if (!session) { log_debug(1, "session sid %d not found.\n", sid); - return MGMT_IPC_ERR_NOT_FOUND; + return ISCSI_ERR_SESS_NOT_FOUND; } conn = &session->conn[0]; /* @@ -2354,7 +1828,7 @@ session_logout_task(int sid, queue_task_ invalid_state: log_error("session in invalid state for logout. " "Try again later\n"); - return MGMT_IPC_ERR_INTERNAL; + return ISCSI_ERR_INTERNAL; } /* FIXME: logout all active connections */ @@ -2370,39 +1844,39 @@ invalid_state: switch (conn->state) { case STATE_LOGGED_IN: if (!session_unbind(session)) - return MGMT_IPC_OK; + return ISCSI_SUCCESS; /* unbind is not supported so just do old logout */ if (!iscsi_send_logout(conn)) - return MGMT_IPC_OK; + return ISCSI_SUCCESS; log_error("Could not send logout pdu. Dropping session\n"); /* fallthrough */ default: - rc = session_conn_shutdown(conn, qtask, MGMT_IPC_OK); + rc = session_conn_shutdown(conn, qtask, ISCSI_SUCCESS); break; } return rc; } -mgmt_ipc_err_e +int iscsi_host_send_targets(queue_task_t *qtask, int host_no, int do_login, struct sockaddr_storage *ss) { struct iscsi_transport *t; t = iscsi_sysfs_get_transport_by_hba(host_no); - if (!t || set_transport_template(t)) { + if (!t) { log_error("Invalid host no %d for sendtargets\n", host_no); - return MGMT_IPC_ERR_TRANS_FAILURE; + return ISCSI_ERR_TRANS_NOT_FOUND; } if (!(t->caps & CAP_SENDTARGETS_OFFLOAD)) - return MGMT_IPC_ERR_TRANS_CAPS; + return ISCSI_ERR_TRANS_CAPS; if (ipc->sendtargets(t->handle, host_no, (struct sockaddr *)ss)) - return MGMT_IPC_ERR; + return ISCSI_ERR; - return MGMT_IPC_OK; + return ISCSI_SUCCESS; } /* @@ -2412,7 +1886,7 @@ iscsi_host_send_targets(queue_task_t *qt * the card will have sessions preset in the FLASH and will log into them * automaotically then send us notification that a session is setup. */ -void iscsi_async_session_creation(uint32_t host_no, uint32_t sid) +static void iscsi_async_session_creation(uint32_t host_no, uint32_t sid) { struct iscsi_transport *transport; @@ -2428,7 +1902,20 @@ void iscsi_async_session_creation(uint32 session_scan_host(NULL, host_no, NULL); } -void iscsi_async_session_destruction(uint32_t host_no, uint32_t sid) +static void iscsi_async_session_destruction(uint32_t host_no, uint32_t sid) { log_debug(3, "session destroyed sid %u host no %d", sid, host_no); } + +static struct iscsi_ipc_ev_clbk ipc_clbk = { + .create_session = iscsi_async_session_creation, + .destroy_session = iscsi_async_session_destruction, + .get_ev_context = iscsi_ev_context_get, + .put_ev_context = iscsi_ev_context_put, + .sched_ev_context = iscsi_sched_ev_context, +}; + +void iscsi_initiator_init(void) +{ + ipc_register_ev_callback(&ipc_clbk); +} 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 1969-12-31 18:00:00.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator_common.c 2011-02-24 19:54:10.000000000 -0600 @@ -0,0 +1,601 @@ +/* + * Common code for setting up discovery and normal sessions. + * + * Copyright (C) 2004 Dmitry Yusupov, Alex Aizman + * Copyright (C) 2006 - 2009 Mike Christie + * Copyright (C) 2006 - 2009 Red Hat, Inc. All rights reserved. + * maintained by open-iscsi@googlegroups.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * See the file COPYING included with this distribution for more details. + */ + +#include +#include +#include +#include + +#include "initiator.h" +#include "transport.h" +#include "iscsid.h" +#include "iscsi_ipc.h" +#include "log.h" +#include "iscsi_sysfs.h" +#include "iscsi_settings.h" +#include "iface.h" +#include "host.h" +#include "sysdeps.h" +#include "iscsi_err.h" + +struct iscsi_session *session_find_by_sid(uint32_t sid) +{ + struct iscsi_transport *t; + struct iscsi_session *session; + + list_for_each_entry(t, &transports, list) { + list_for_each_entry(session, &t->sessions, list) { + if (session->id == sid) + return session; + } + } + return NULL; +} + +/* + * calculate parameter's padding + */ +static unsigned int +__padding(unsigned int param) +{ + int pad; + + pad = param & 3; + if (pad) { + pad = 4 - pad; + log_debug(1, "parameter's value %d padded to %d bytes\n", + param, param + pad); + } + return param + pad; +} + +int iscsi_setup_authentication(struct iscsi_session *session, + struct iscsi_auth_config *auth_cfg) +{ + /* if we have any incoming credentials, we insist on authenticating + * the target or not logging in at all + */ + if (auth_cfg->username_in[0] || auth_cfg->password_in_length) { + /* sanity check the config */ + if (auth_cfg->password_length == 0) { + log_warning("CHAP configuratoin has incoming " + "authentication credentials but has no " + "outgoing credentials configured."); + return EINVAL; + } + session->bidirectional_auth = 1; + } else { + /* no or 1-way authentication */ + session->bidirectional_auth = 0; + } + + /* copy in whatever credentials we have */ + strlcpy(session->username, auth_cfg->username, + sizeof (session->username)); + session->username[sizeof (session->username) - 1] = '\0'; + if ((session->password_length = auth_cfg->password_length)) + memcpy(session->password, auth_cfg->password, + session->password_length); + + strlcpy(session->username_in, auth_cfg->username_in, + sizeof (session->username_in)); + session->username_in[sizeof (session->username_in) - 1] = '\0'; + if ((session->password_in_length = + auth_cfg->password_in_length)) + memcpy(session->password_in, auth_cfg->password_in, + session->password_in_length); + + if (session->password_length || session->password_in_length) { + /* setup the auth buffers */ + session->auth_buffers[0].address = &session->auth_client_block; + session->auth_buffers[0].length = + sizeof (session->auth_client_block); + session->auth_buffers[1].address = + &session->auth_recv_string_block; + session->auth_buffers[1].length = + sizeof (session->auth_recv_string_block); + + session->auth_buffers[2].address = + &session->auth_send_string_block; + session->auth_buffers[2].length = + sizeof (session->auth_send_string_block); + + session->auth_buffers[3].address = + &session->auth_recv_binary_block; + session->auth_buffers[3].length = + sizeof (session->auth_recv_binary_block); + + session->auth_buffers[4].address = + &session->auth_send_binary_block; + session->auth_buffers[4].length = + sizeof (session->auth_send_binary_block); + + session->num_auth_buffers = 5; + log_debug(6, "authentication setup complete..."); + } else { + session->num_auth_buffers = 0; + log_debug(6, "no authentication configured..."); + } + + return 0; +} + +void +iscsi_copy_operational_params(struct iscsi_conn *conn, + struct iscsi_session_operational_config *session_conf, + struct iscsi_conn_operational_config *conn_conf) +{ + struct iscsi_session *session = conn->session; + struct iscsi_transport *t = session->t; + + conn->hdrdgst_en = conn_conf->HeaderDigest; + conn->datadgst_en = conn_conf->DataDigest; + + conn->max_recv_dlength = + __padding(conn_conf->MaxRecvDataSegmentLength); + if (conn->max_recv_dlength < ISCSI_MIN_MAX_RECV_SEG_LEN || + conn->max_recv_dlength > ISCSI_MAX_MAX_RECV_SEG_LEN) { + log_error("Invalid iscsi.MaxRecvDataSegmentLength. Must be " + "within %u and %u. Setting to %u\n", + ISCSI_MIN_MAX_RECV_SEG_LEN, + ISCSI_MAX_MAX_RECV_SEG_LEN, + DEF_INI_MAX_RECV_SEG_LEN); + conn_conf->MaxRecvDataSegmentLength = + DEF_INI_MAX_RECV_SEG_LEN; + conn->max_recv_dlength = DEF_INI_MAX_RECV_SEG_LEN; + } + + /* zero indicates to use the target's value */ + conn->max_xmit_dlength = + __padding(conn_conf->MaxXmitDataSegmentLength); + if (conn->max_xmit_dlength == 0) + conn->max_xmit_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN; + if (conn->max_xmit_dlength < ISCSI_MIN_MAX_RECV_SEG_LEN || + conn->max_xmit_dlength > ISCSI_MAX_MAX_RECV_SEG_LEN) { + log_error("Invalid iscsi.MaxXmitDataSegmentLength. Must be " + "within %u and %u. Setting to %u\n", + ISCSI_MIN_MAX_RECV_SEG_LEN, + ISCSI_MAX_MAX_RECV_SEG_LEN, + DEF_INI_MAX_RECV_SEG_LEN); + conn_conf->MaxXmitDataSegmentLength = + DEF_INI_MAX_RECV_SEG_LEN; + conn->max_xmit_dlength = DEF_INI_MAX_RECV_SEG_LEN; + } + + /* session's operational parameters */ + session->initial_r2t_en = session_conf->InitialR2T; + session->imm_data_en = session_conf->ImmediateData; + session->first_burst = __padding(session_conf->FirstBurstLength); + /* + * some targets like netapp fail the login if sent bad first_burst + * and max_burst lens, even when immediate data=no and + * initial r2t = Yes, so we always check the user values. + */ + if (session->first_burst < ISCSI_MIN_FIRST_BURST_LEN || + session->first_burst > ISCSI_MAX_FIRST_BURST_LEN) { + log_error("Invalid iscsi.FirstBurstLength of %u. Must be " + "within %u and %u. Setting to %u\n", + session->first_burst, + ISCSI_MIN_FIRST_BURST_LEN, + ISCSI_MAX_FIRST_BURST_LEN, + DEF_INI_FIRST_BURST_LEN); + session_conf->FirstBurstLength = DEF_INI_FIRST_BURST_LEN; + session->first_burst = DEF_INI_FIRST_BURST_LEN; + } + + session->max_burst = __padding(session_conf->MaxBurstLength); + if (session->max_burst < ISCSI_MIN_MAX_BURST_LEN || + session->max_burst > ISCSI_MAX_MAX_BURST_LEN) { + log_error("Invalid iscsi.MaxBurstLength of %u. Must be " + "within %u and %u. Setting to %u\n", + session->max_burst, ISCSI_MIN_MAX_BURST_LEN, + ISCSI_MAX_MAX_BURST_LEN, DEF_INI_MAX_BURST_LEN); + session_conf->MaxBurstLength = DEF_INI_MAX_BURST_LEN; + session->max_burst = DEF_INI_MAX_BURST_LEN; + } + + if (session->first_burst > session->max_burst) { + log_error("Invalid iscsi.FirstBurstLength of %u. Must be " + "less than iscsi.MaxBurstLength. Setting to %u\n", + session->first_burst, session->max_burst); + session_conf->FirstBurstLength = session->max_burst; + session->first_burst = session->max_burst; + } + + session->def_time2wait = session_conf->DefaultTime2Wait; + session->def_time2retain = session_conf->DefaultTime2Retain; + session->erl = session_conf->ERL; + + if (session->type == ISCSI_SESSION_TYPE_DISCOVERY) { + /* + * Right now, we only support 8K max for kernel based + * sendtargets discovery, because the recv pdu buffers are + * limited to this size. + */ + if ((t->caps & CAP_TEXT_NEGO) && + conn->max_recv_dlength > ISCSI_DEF_MAX_RECV_SEG_LEN) + conn->max_recv_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN; + + /* We do not support discovery sessions with digests */ + conn->hdrdgst_en = ISCSI_DIGEST_NONE; + conn->datadgst_en = ISCSI_DIGEST_NONE; + } + + if (t->template->create_conn) + t->template->create_conn(conn); +} + +int iscsi_setup_portal(struct iscsi_conn *conn, char *address, int port) +{ + char serv[NI_MAXSERV]; + + sprintf(serv, "%d", port); + if (resolve_address(address, serv, &conn->saddr)) { + log_error("cannot resolve host name %s", address); + return ISCSI_ERR_TRANS; + } + conn->failback_saddr = conn->saddr; + + getnameinfo((struct sockaddr *)&conn->saddr, sizeof(conn->saddr), + conn->host, sizeof(conn->host), NULL, 0, NI_NUMERICHOST); + log_debug(4, "resolved %s to %s", address, conn->host); + return 0; +} + +int host_set_param(struct iscsi_transport *t, + uint32_t host_no, int param, char *value, + int type) +{ + int rc; + + rc = ipc->set_host_param(t->handle, host_no, param, value, type); + /* 2.6.20 and below returns EINVAL */ + if (rc && rc != -ENOSYS && rc != -EINVAL) { + log_error("can't set operational parameter %d for " + "host %d, retcode %d (%d)", param, host_no, + rc, errno); + return rc; + } + return 0; +} + +static void print_param_value(enum iscsi_param param, void *value, int type) +{ + log_debug(3, "set operational parameter %d to:", param); + + if (type == ISCSI_STRING) + log_debug(3, "%s", value ? (char *)value : "NULL"); + else + log_debug(3, "%u", *(uint32_t *)value); +} + +#define MAX_HOST_PARAMS 2 + +int iscsi_host_set_params(struct iscsi_session *session) +{ + struct iscsi_transport *t = session->t; + int i; + struct hostparam { + int param; + int type; + void *value; + } hosttbl[MAX_HOST_PARAMS] = { + { + .param = ISCSI_HOST_PARAM_NETDEV_NAME, + .value = session->nrec.iface.netdev, + .type = ISCSI_STRING, + }, { + .param = ISCSI_HOST_PARAM_HWADDRESS, + .value = session->nrec.iface.hwaddress, + .type = ISCSI_STRING, + }, + }; + + for (i = 0; i < MAX_HOST_PARAMS; i++) { + if (host_set_param(t, session->hostno, + hosttbl[i].param, hosttbl[i].value, + hosttbl[i].type)) { + return EPERM; + } + + print_param_value(hosttbl[i].param, hosttbl[i].value, + hosttbl[i].type); + } + + return 0; +} + +#define MAX_SESSION_PARAMS 32 + +int iscsi_session_set_params(struct iscsi_conn *conn) +{ + struct iscsi_session *session = conn->session; + struct iscsi_transport *t = session->t; + int i, rc; + uint32_t one = 1, zero = 0; + struct connparam { + int param; + int type; + void *value; + int conn_only; + } conntbl[MAX_SESSION_PARAMS] = { + { + .param = ISCSI_PARAM_MAX_RECV_DLENGTH, + .value = &conn->max_recv_dlength, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_MAX_XMIT_DLENGTH, + .value = &conn->max_xmit_dlength, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_HDRDGST_EN, + .value = &conn->hdrdgst_en, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_DATADGST_EN, + .value = &conn->datadgst_en, + .type = ISCSI_INT, + .conn_only = 1, + }, { + .param = ISCSI_PARAM_INITIAL_R2T_EN, + .value = &session->initial_r2t_en, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_MAX_R2T, + .value = &one, /* FIXME: session->max_r2t */ + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_IMM_DATA_EN, + .value = &session->imm_data_en, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_FIRST_BURST, + .value = &session->first_burst, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_MAX_BURST, + .value = &session->max_burst, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_PDU_INORDER_EN, + .value = &session->pdu_inorder_en, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param =ISCSI_PARAM_DATASEQ_INORDER_EN, + .value = &session->dataseq_inorder_en, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_ERL, + .value = &zero, /* FIXME: session->erl */ + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_IFMARKER_EN, + .value = &zero,/* FIXME: session->ifmarker_en */ + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_OFMARKER_EN, + .value = &zero,/* FIXME: session->ofmarker_en */ + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_EXP_STATSN, + .value = &conn->exp_statsn, + .type = ISCSI_INT, + .conn_only = 1, + }, { + .param = ISCSI_PARAM_TARGET_NAME, + .conn_only = 0, + .type = ISCSI_STRING, + .value = session->target_name, + }, { + .param = ISCSI_PARAM_TPGT, + .value = &session->portal_group_tag, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_PERSISTENT_ADDRESS, + .value = session->nrec.conn[conn->id].address, + .type = ISCSI_STRING, + .conn_only = 1, + }, { + .param = ISCSI_PARAM_PERSISTENT_PORT, + .value = &session->nrec.conn[conn->id].port, + .type = ISCSI_INT, + .conn_only = 1, + }, { + .param = ISCSI_PARAM_SESS_RECOVERY_TMO, + .value = &session->replacement_timeout, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_USERNAME, + .value = session->username, + .type = ISCSI_STRING, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_USERNAME_IN, + .value = session->username_in, + .type = ISCSI_STRING, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_PASSWORD, + .value = session->password, + .type = ISCSI_STRING, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_PASSWORD_IN, + .value = session->password_in, + .type = ISCSI_STRING, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_FAST_ABORT, + .value = &session->fast_abort, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_ABORT_TMO, + .value = &session->abort_timeout, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_LU_RESET_TMO, + .value = &session->lu_reset_timeout, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_TGT_RESET_TMO, + .value = &session->tgt_reset_timeout, + .type = ISCSI_INT, + .conn_only = 0, + }, { + .param = ISCSI_PARAM_PING_TMO, + .value = &conn->noop_out_timeout, + .type = ISCSI_INT, + .conn_only = 1, + }, { + .param = ISCSI_PARAM_RECV_TMO, + .value = &conn->noop_out_interval, + .type = ISCSI_INT, + .conn_only = 1, + }, { + .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, + }, + }; + + session->param_mask = ~0ULL; + if (!(t->caps & CAP_MULTI_R2T)) + session->param_mask &= ~ISCSI_MAX_R2T; + if (!(t->caps & CAP_HDRDGST)) + session->param_mask &= ~ISCSI_HDRDGST_EN; + if (!(t->caps & CAP_DATADGST)) + session->param_mask &= ~ISCSI_DATADGST_EN; + if (!(t->caps & CAP_MARKERS)) { + session->param_mask &= ~ISCSI_IFMARKER_EN; + session->param_mask &= ~ISCSI_OFMARKER_EN; + } + + /* Entered full-feature phase! */ + for (i = 0; i < MAX_SESSION_PARAMS; i++) { + if (conn->id != 0 && !conntbl[i].conn_only) + continue; + + if (!(session->param_mask & (1ULL << conntbl[i].param))) + continue; + + rc = ipc->set_param(session->t->handle, session->id, + conn->id, conntbl[i].param, conntbl[i].value, + conntbl[i].type); + if (rc && rc != -ENOSYS) { + log_error("can't set operational parameter %d for " + "connection %d:%d, retcode %d (%d)", + conntbl[i].param, session->id, conn->id, + rc, errno); + return EPERM; + } + + if (rc == -ENOSYS) { + switch (conntbl[i].param) { + case ISCSI_PARAM_PING_TMO: + /* + * older kernels may not support nops + * in kernel + */ + conn->userspace_nop = 1; + break; +#if 0 +TODO handle this + case ISCSI_PARAM_INITIATOR_NAME: + /* use host level one instead */ + hosttbl[ISCSI_HOST_PARAM_INITIATOR_NAME].set = 1; + break; +#endif + } + } + + print_param_value(conntbl[i].param, conntbl[i].value, + conntbl[i].type); + } + + return 0; +} + +int iscsi_host_set_net_params(struct iface_rec *iface, + struct iscsi_session *session) +{ + struct iscsi_transport *t = session->t; + int rc = 0; + + log_debug(3, "setting iface %s, dev %s, set ip %s, hw %s, " + "transport %s.\n", + iface->name, iface->netdev, iface->ipaddress, + iface->hwaddress, iface->transport_name); + + if (!t->template->set_host_ip) + return 0; + + /* if we need to set the ip addr then set all the iface net settings */ + if (!iface_is_bound_by_ipaddr(iface)) { + log_warning("Please set the iface.ipaddress for iface %s, " + "then retry the login command.\n", iface->name); + return EINVAL; + } + + rc = host_set_param(t, session->hostno, + ISCSI_HOST_PARAM_IPADDRESS, + iface->ipaddress, ISCSI_STRING); + if (rc) + return rc; + + if (iface_is_bound_by_netdev(iface)) { + rc = host_set_param(t, session->hostno, + ISCSI_HOST_PARAM_NETDEV_NAME, + iface->netdev, ISCSI_STRING); + if (rc) + return rc; + } + + if (iface_is_bound_by_hwaddr(iface)) { + rc = host_set_param(t, session->hostno, + ISCSI_HOST_PARAM_HWADDRESS, + iface->hwaddress, ISCSI_STRING); + if (rc) + return rc; + } + return 0; +} diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/initiator.h 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/initiator.h 2011-02-24 19:54:10.000000000 -0600 @@ -67,6 +67,7 @@ typedef enum conn_login_status_e { CONN_LOGIN_RETRY = 3, CONN_LOGIN_IMM_RETRY = 4, CONN_LOGIN_IMM_REDIRECT_RETRY = 5, + CONN_LOGIN_AUTH_FAILED = 6, } conn_login_status_e; enum iscsi_login_status { @@ -112,14 +113,14 @@ typedef struct iscsi_login_context { struct iscsi_session; struct iscsi_conn; -struct iscsi_conn_context; +struct iscsi_ev_context; /* daemon's connection structure */ typedef struct iscsi_conn { uint32_t id; struct iscsi_session *session; iscsi_login_context_t login_context; - struct iscsi_conn_context *recv_context; + struct iscsi_ev_context *recv_context; struct queue_task *logout_qtask; char data[ISCSI_DEF_MAX_RECV_SEG_LEN]; char host[NI_MAXHOST]; /* scratch */ @@ -131,7 +132,7 @@ typedef struct iscsi_conn { actor_t nop_out_timer; #define CONTEXT_POOL_MAX 32 - struct iscsi_conn_context *context_pool[CONTEXT_POOL_MAX]; + struct iscsi_ev_context *context_pool[CONTEXT_POOL_MAX]; /* login state machine */ int current_stage; @@ -140,6 +141,11 @@ typedef struct iscsi_conn { conn_login_status_e status; /* tcp/socket settings */ + + /* + * Either a tcp/ip or a netlink socket to do + * IO through. + */ int socket_fd; /* address being used for normal session connection */ struct sockaddr_storage saddr; @@ -173,7 +179,7 @@ typedef struct iscsi_conn { uint32_t max_xmit_dlength; /* the value declared by the target */ } iscsi_conn_t; -struct iscsi_conn_context { +struct iscsi_ev_context { struct actor actor; struct iscsi_conn *conn; int allocated; @@ -201,6 +207,7 @@ typedef struct iscsi_session { uint32_t hostno; char netdev[IFNAMSIZ]; struct iscsi_transport *t; + uint8_t use_ipc; node_rec_t nrec; /* copy of original Node record in database */ unsigned int irrelevant_keys_bitmap; int send_async_text; @@ -242,7 +249,6 @@ typedef struct iscsi_session { uint8_t password_in[AUTH_STR_MAX_LEN]; int password_in_length; iscsi_conn_t conn[ISCSI_CONN_MAX]; - int ctrl_fd; uint64_t param_mask; /* connection reopens during recovery */ @@ -330,20 +336,25 @@ extern int iscsi_io_recv_pdu(iscsi_conn_ /* initiator.c */ extern int session_login_task(node_rec_t *rec, queue_task_t *qtask); extern int session_logout_task(int sid, queue_task_t *qtask); -extern iscsi_session_t *session_find_by_sid(int sid); -extern struct iscsi_conn_context *iscsi_conn_context_get(iscsi_conn_t *conn, - int ev_size); -extern void iscsi_conn_context_put(struct iscsi_conn_context *conn_context); -extern void iscsi_sched_conn_context(struct iscsi_conn_context *context, - struct iscsi_conn *conn, unsigned long tmo, - int event); -extern mgmt_ipc_err_e iscsi_sync_session(node_rec_t *rec, queue_task_t +extern iscsi_session_t *session_find_by_sid(uint32_t sid); +extern int iscsi_sync_session(node_rec_t *rec, queue_task_t *tsk, uint32_t sid); -extern mgmt_ipc_err_e iscsi_host_send_targets(queue_task_t *qtask, +extern int iscsi_host_send_targets(queue_task_t *qtask, int host_no, int do_login, struct sockaddr_storage *ss); -extern mgmt_ipc_err_e iscsi_host_set_param(int host_no, int param, char *value); -extern void iscsi_async_session_creation(uint32_t host_no, uint32_t sid); -extern void iscsi_async_session_destruction(uint32_t host_no, uint32_t sid); + extern void free_initiator(void); +extern void iscsi_initiator_init(void); + +/* initiator code common to discovery and normal sessions */ +extern int iscsi_session_set_params(struct iscsi_conn *conn); +extern int iscsi_host_set_params(struct iscsi_session *session); +extern int iscsi_host_set_net_params(struct iface_rec *iface, + struct iscsi_session *session); +extern void iscsi_copy_operational_params(struct iscsi_conn *conn, + struct iscsi_session_operational_config *session_conf, + struct iscsi_conn_operational_config *conn_conf); +extern int iscsi_setup_authentication(struct iscsi_session *session, + struct iscsi_auth_config *auth_cfg); +extern int iscsi_setup_portal(struct iscsi_conn *conn, char *address, int port); #endif /* INITIATOR_H */ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/io.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/io.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/io.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/io.c 2011-02-24 19:54:10.000000000 -0600 @@ -401,7 +401,6 @@ iscsi_io_connect(iscsi_conn_t *conn) int rc, ret; struct sigaction action; struct sigaction old; - char serv[NI_MAXSERV]; /* set a timeout, since the socket calls may take a long time to * timeout on their own @@ -420,22 +419,21 @@ iscsi_io_connect(iscsi_conn_t *conn) */ rc = iscsi_io_tcp_connect(conn, 0); if (timedout) { + log_error("connect to %s timed out", conn->host); + log_debug(1, "socket %d connect timed out", conn->socket_fd); ret = 0; goto done; } else if (rc < 0) { - getnameinfo((struct sockaddr *) &conn->saddr, - sizeof(conn->saddr), - conn->host, sizeof(conn->host), serv, sizeof(serv), - NI_NUMERICHOST|NI_NUMERICSERV); - log_error("cannot make connection to %s:%s (%d)", - conn->host, serv, errno); + log_error("cannot make connection to %s: %s", + conn->host, strerror(errno)); close(conn->socket_fd); ret = 0; goto done; } else if (log_level > 0) { struct sockaddr_storage ss; char lserv[NI_MAXSERV]; + char serv[NI_MAXSERV]; socklen_t salen = sizeof(ss); if (getsockname(conn->socket_fd, (struct sockaddr *) &ss, @@ -503,7 +501,7 @@ iscsi_io_send_pdu(iscsi_conn_t *conn, st /* set a timeout, since the socket calls may take a long time * to timeout on their own */ - if (!ipc) { + if (!session->use_ipc) { memset(&action, 0, sizeof (struct sigaction)); memset(&old, 0, sizeof (struct sigaction)); action.sa_sigaction = NULL; @@ -566,7 +564,7 @@ iscsi_io_send_pdu(iscsi_conn_t *conn, st else pad_bytes = 0; - if (ipc) + if (session->use_ipc) ipc->send_pdu_begin(session->t->handle, session->id, conn->id, end - header, ntoh24(hdr->dlength) + pad_bytes); @@ -575,8 +573,8 @@ iscsi_io_send_pdu(iscsi_conn_t *conn, st vec[0].iov_base = header; vec[0].iov_len = end - header; - if (!ipc) - rc = writev(session->ctrl_fd, vec, 1); + if (!session->use_ipc) + rc = writev(conn->socket_fd, vec, 1); else rc = ipc->writev(0, vec, 1); if (timedout) { @@ -603,13 +601,13 @@ iscsi_io_send_pdu(iscsi_conn_t *conn, st vec[1].iov_base = (void *) &pad; vec[1].iov_len = pad_bytes; - if (!ipc) - rc = writev(session->ctrl_fd, vec, 2); + if (!session->use_ipc) + rc = writev(conn->socket_fd, vec, 2); else rc = ipc->writev(0, vec, 2); if (timedout) { log_error("socket %d write timed out", - conn->socket_fd); + conn->socket_fd); ret = 0; goto done; } else if ((rc <= 0) && (errno != EAGAIN)) { @@ -627,7 +625,7 @@ iscsi_io_send_pdu(iscsi_conn_t *conn, st } } - if (ipc) { + if (session->use_ipc) { if (ipc->send_pdu_end(session->t->handle, session->id, conn->id, &rc)) { ret = 0; @@ -638,7 +636,7 @@ iscsi_io_send_pdu(iscsi_conn_t *conn, st ret = 1; done: - if (!ipc) { + if (!session->use_ipc) { alarm(0); sigaction(SIGALRM, &old, NULL); timedout = 0; @@ -670,7 +668,7 @@ iscsi_io_recv_pdu(iscsi_conn_t *conn, st /* set a timeout, since the socket calls may take a long * time to timeout on their own */ - if (!ipc) { + if (!session->use_ipc) { memset(&action, 0, sizeof (struct sigaction)); memset(&old, 0, sizeof (struct sigaction)); action.sa_sigaction = NULL; @@ -680,7 +678,10 @@ iscsi_io_recv_pdu(iscsi_conn_t *conn, st timedout = 0; alarm(timeout); } else { - if (ipc->recv_pdu_begin(conn)) { + failed = ipc->recv_pdu_begin(conn); + if (failed == -EAGAIN) + return -EAGAIN; + else if (failed < 0) { failed = 1; goto done; } @@ -688,14 +689,14 @@ iscsi_io_recv_pdu(iscsi_conn_t *conn, st /* read a response header */ do { - if (!ipc) - rlen = read(session->ctrl_fd, header, + if (!session->use_ipc) + rlen = read(conn->socket_fd, header, sizeof (*hdr) - h_bytes); else rlen = ipc->read(header, sizeof (*hdr) - h_bytes); if (timedout) { log_error("socket %d header read timed out", - conn->socket_fd); + conn->socket_fd); failed = 1; goto done; } else if (rlen == 0) { @@ -714,7 +715,7 @@ iscsi_io_recv_pdu(iscsi_conn_t *conn, st } while (h_bytes < sizeof (*hdr)); log_debug(4, "read %d PDU header bytes, opcode 0x%x, dlength %u, " - "data %p, max %u", h_bytes, hdr->opcode, + "data %p, max %u", h_bytes, hdr->opcode & ISCSI_OPCODE_MASK, ntoh24(hdr->dlength), data, max_data_length); /* check for additional headers */ @@ -745,14 +746,14 @@ iscsi_io_recv_pdu(iscsi_conn_t *conn, st /* read the rest into our buffer */ d_bytes = 0; while (d_bytes < dlength) { - if (!ipc) - rlen = read(session->ctrl_fd, data + d_bytes, + if (!session->use_ipc) + rlen = read(conn->socket_fd, data + d_bytes, dlength - d_bytes); else rlen = ipc->read(data + d_bytes, dlength - d_bytes); if (timedout) { log_error("socket %d data read timed out", - conn->socket_fd); + conn->socket_fd); failed = 1; goto done; } else if (rlen == 0) { @@ -772,7 +773,7 @@ iscsi_io_recv_pdu(iscsi_conn_t *conn, st /* handle PDU data padding. * data is padded in case of kernel_io */ pad = dlength % ISCSI_PAD_LEN; - if (pad && !ipc) { + if (pad && !session->use_ipc) { int pad_bytes = pad = ISCSI_PAD_LEN - pad; char bytes[ISCSI_PAD_LEN]; @@ -780,7 +781,7 @@ iscsi_io_recv_pdu(iscsi_conn_t *conn, st rlen = read(conn->socket_fd, &bytes, pad_bytes); if (timedout) { log_error("socket %d pad read timed out", - conn->socket_fd); + conn->socket_fd); failed = 1; goto done; } else if (rlen == 0) { @@ -828,7 +829,7 @@ iscsi_io_recv_pdu(iscsi_conn_t *conn, st } done: - if (!ipc) { + if (!session->use_ipc) { alarm(0); sigaction(SIGALRM, &old, NULL); } else { @@ -840,7 +841,7 @@ done: if (timedout || failed) { timedout = 0; - return 0; + return -EIO; } return h_bytes + ahs_bytes + d_bytes; 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsiadm.c 2011-02-24 19:54:10.000000000 -0600 @@ -48,10 +48,11 @@ #include "session_mgmt.h" #include "iscsid_req.h" #include "isns-proto.h" +#include "iscsi_err.h" -struct iscsi_ipc *ipc = NULL; /* dummy */ static char program_name[] = "iscsiadm"; static char config_file[TARGET_NAME_MAXLEN]; +extern struct iscsi_ipc *ipc; enum iscsiadm_mode { MODE_DISCOVERY, @@ -119,7 +120,7 @@ iscsiadm -m fw [ -l ]\n\ iscsiadm -m host [ -P printlevel ] [ -H hostno ]\n\ iscsiadm -k priority\n"); } - exit(status == 0 ? 0 : -1); + exit(status); } static int @@ -212,7 +213,7 @@ static void kill_iscsid(int priority) req.command = MGMT_IPC_IMMEDIATE_STOP; rc = iscsid_exec_req(&req, &rsp, 0); if (rc) { - iscsid_handle_error(rc); + iscsi_err_print_msg(rc); log_error("Could not stop iscsid. Trying sending iscsid " "SIGTERM or SIGKILL signals manually\n"); } @@ -251,12 +252,12 @@ static int print_ifaces(struct iface_rec break; default: log_error("Invalid info level %d. Try 0 - 1.", info_level); - return EINVAL; + return ISCSI_ERR_INVAL; } if (!num_found) { log_error("No interfaces found."); - err = ENODEV; + err = ISCSI_ERR_NO_OBJS_FOUND; } return err; } @@ -296,11 +297,11 @@ for_each_session(struct node_rec *rec, i err = iscsi_sysfs_for_each_session(rec, &num_found, fn); if (err) - log_error("Could not execute operation on all sessions. Err " - "%d.", err); + log_error("Could not execute operation on all sessions: %s", + iscsi_err_to_str(err)); else if (!num_found) { - log_error("No portal found."); - err = ENODEV; + log_error("No session found."); + err = ISCSI_ERR_NO_OBJS_FOUND; } return err; @@ -313,7 +314,7 @@ static int link_recs(void *data, struct rec_copy = calloc(1, sizeof(*rec_copy)); if (!rec_copy) - return ENOMEM; + return ISCSI_ERR_NOMEM; memcpy(rec_copy, rec, sizeof(*rec_copy)); INIT_LIST_HEAD(&rec_copy->list); list_add_tail(&rec_copy->list, list); @@ -326,7 +327,6 @@ __logout_by_startup(void *data, struct l { char *mode = data; node_rec_t rec; - int rc = 0; memset(&rec, 0, sizeof(node_rec_t)); if (idbm_rec_read(&rec, info->targetname, info->tpgt, @@ -352,28 +352,33 @@ __logout_by_startup(void *data, struct l if (rec.startup == ISCSI_STARTUP_ONBOOT) return -1; - if (!match_startup_mode(&rec, mode)) - rc = iscsi_logout_portal(info, list); - return rc; + if (match_startup_mode(&rec, mode)) + return -1; + + return iscsi_logout_portal(info, list); } static int logout_by_startup(char *mode) { int nr_found; + int rc; if (!mode || !(!strcmp(mode, "automatic") || !strcmp(mode, "all") || !strcmp(mode,"manual"))) { log_error("Invalid logoutall option %s.", mode); - usage(0); - return EINVAL; + usage(ISCSI_ERR_INVAL); + return ISCSI_ERR_INVAL; } - return iscsi_logout_portals(mode, &nr_found, 1, __logout_by_startup); + rc = iscsi_logout_portals(mode, &nr_found, 1, __logout_by_startup); + if (rc == ISCSI_ERR_NO_OBJS_FOUND) + log_error("No matching sessions found"); + return rc; } /* - * TODO: merged this and logout into the common for_each_rec by making + * TODO: merged this and logout into the common for_each_matched_rec by making * the matching more generic */ static int @@ -390,36 +395,45 @@ __login_by_startup(void *data, struct li if (match_startup_mode(rec, mode)) return -1; - iscsi_login_portal(NULL, list, rec); - return 0; + return iscsi_login_portal(NULL, list, rec); } static int login_by_startup(char *mode) { - int nr_found = 0, rc, err; + int nr_found = 0, err, rc; struct list_head rec_list; if (!mode || !(!strcmp(mode, "automatic") || !strcmp(mode, "all") || !strcmp(mode,"manual"))) { log_error("Invalid loginall option %s.", mode); - usage(0); - return EINVAL; + usage(ISCSI_ERR_INVAL); + return ISCSI_ERR_INVAL; } INIT_LIST_HEAD(&rec_list); - rc = idbm_for_each_rec(&nr_found, &rec_list, link_recs); + err = idbm_for_each_rec(&nr_found, &rec_list, link_recs); + if (err && !list_empty(&rec_list)) + /* log msg and try to log into what we found */ + log_error("Could not read all records: %s", + iscsi_err_to_str(err)); + else if (err && list_empty(&rec_list)) { + log_error("Could not read node DB: %s.", + iscsi_err_to_str(err)); + return err; + } else if (list_empty(&rec_list)) { + log_error("No records found"); + return ISCSI_ERR_NO_OBJS_FOUND; + } + rc = err; + err = iscsi_login_portals(mode, &nr_found, 1, &rec_list, __login_by_startup); + if (err) + log_error("Could not log into all portals"); + if (err && !rc) rc = err; - - if (rc) - log_error("Could not log into all portals. Err %d.", rc); - else if (!nr_found) { - log_error("No records found!"); - rc = ENODEV; - } return rc; } @@ -454,7 +468,7 @@ static int iscsi_logout_matched_portal(v return iscsi_logout_portal(info, list); } -static int iface_fn(void *data, node_rec_t *rec) +static int rec_match_fn(void *data, node_rec_t *rec) { struct rec_op_data *op_data = data; @@ -465,7 +479,8 @@ static int iface_fn(void *data, node_rec return op_data->fn(op_data->data, rec); } -static int for_each_rec(struct node_rec *rec, void *data, idbm_iface_op_fn *fn) +static int __for_each_matched_rec(int verbose, struct node_rec *rec, + void *data, idbm_iface_op_fn *fn) { struct rec_op_data op_data; int nr_found = 0, rc; @@ -475,30 +490,51 @@ static int for_each_rec(struct node_rec op_data.match_rec = rec; op_data.fn = fn; - rc = idbm_for_each_rec(&nr_found, &op_data, iface_fn); + rc = idbm_for_each_rec(&nr_found, &op_data, rec_match_fn); if (rc) { - log_error("Could not execute operation on all " - "records. Err %d.", rc); + if (verbose) + log_error("Could not execute operation on all " + "records: %s", iscsi_err_to_str(rc)); } else if (!nr_found) { - log_error("no records found!"); - rc = ENODEV; + if (verbose) + log_error("No records found"); + rc = ISCSI_ERR_NO_OBJS_FOUND; } return rc; } +static int for_each_matched_rec(struct node_rec *rec, void *data, + idbm_iface_op_fn *fn) +{ + return __for_each_matched_rec(1, rec, data, fn); +} + + static int login_portals(struct node_rec *pattern_rec) { struct list_head rec_list; - int err, ret, nr_found; + int nr_found, rc, err; INIT_LIST_HEAD(&rec_list); - ret = for_each_rec(pattern_rec, &rec_list, link_recs); + err = for_each_matched_rec(pattern_rec, &rec_list, link_recs); + if (err == ISCSI_ERR_NO_OBJS_FOUND) + return err; + else if (err && list_empty(&rec_list)) + return err; + + rc = err; + /* if there is an err but some recs then try to login to what we have */ + err = iscsi_login_portals(NULL, &nr_found, 1, &rec_list, iscsi_login_portal); - if (err && !ret) - ret = err; - return ret; + if (err) + log_error("Could not log into all portals"); + + if (err && !rc) + rc = err; + + return rc; } static int print_nodes(int info_level, struct node_rec *rec) @@ -509,17 +545,16 @@ static int print_nodes(int info_level, s switch (info_level) { case 0: case -1: - if (for_each_rec(rec, NULL, idbm_print_node_flat)) - rc = -1; + rc = for_each_matched_rec(rec, NULL, idbm_print_node_flat); break; case 1: memset(&tmp_rec, 0, sizeof(node_rec_t)); - if (for_each_rec(rec, &tmp_rec, idbm_print_node_and_iface_tree)) - rc = -1; + rc = for_each_matched_rec(rec, &tmp_rec, + idbm_print_node_and_iface_tree); break; default: log_error("Invalid info level %d. Try 0 or 1.", info_level); - rc = -1; + rc = ISCSI_ERR_INVAL; } return rc; @@ -586,7 +621,7 @@ session_stats(void *data, struct session rc = iscsid_exec_req(&req, &rsp, 1); if (rc) - return EIO; + return rc; printf("Stats for session [sid: %d, target: %s, portal: " "%s,%d]\n", @@ -665,14 +700,14 @@ static int add_static_rec(int *found, ch rec = calloc(1, sizeof(*rec)); if (!rec) { log_error("Could not allocate memory for node addition"); - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto done; } drec = calloc(1, sizeof(*drec)); if (!drec) { log_error("Could not allocate memory for node addition"); - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto free_rec; } drec->type = DISCOVERY_TYPE_STATIC; @@ -715,10 +750,10 @@ static int add_static_portal(int *found, if (strlen(rec->conn[0].address) && strcmp(rec->conn[0].address, ip)) - return 0; + return -1; if (rec->conn[0].port != -1 && rec->conn[0].port != port) - return 0; + return -1; return add_static_rec(found, targetname, tpgt, ip, port, &rec->iface); @@ -733,7 +768,7 @@ static int add_static_node(int *found, v goto search; if (strcmp(rec->name, targetname)) - return 0; + return -1; if (!strlen(rec->conn[0].address)) goto search; @@ -751,11 +786,8 @@ static int add_static_recs(struct node_r int rc, nr_found = 0; rc = idbm_for_each_node(&nr_found, rec, add_static_node); - if (rc) { - log_error("Error while adding records. DB may be in an " - "inconsistent state. Err %d", rc); - return rc; - } + if (rc) + goto done; /* success */ if (nr_found > 0) return 0; @@ -765,13 +797,12 @@ static int add_static_recs(struct node_r rc = add_static_rec(&nr_found, rec->name, rec->tpgt, rec->conn[0].address, rec->conn[0].port, &rec->iface); - if (rc) - goto done; - return 0; + if (!rc) + return 0; } done: - printf("No records added.\n"); - return ENODEV; + log_error("Error while adding record: %s", iscsi_err_to_str(rc)); + return rc; } /* @@ -799,7 +830,7 @@ static int delete_node(void *data, struc "using it. Logout session then rerun command to " "remove record.", rec->iface.name, rec->name, rec->conn[0].address, rec->conn[0].port); - return EINVAL; + return ISCSI_ERR_SESS_EXISTS; } return idbm_delete_node(rec); @@ -822,18 +853,17 @@ static int delete_stale_rec(void *data, * if we are not from the same discovery source * ignore it */ - return 0; + return -1; if (__iscsi_match_session(rec, new_rec->name, new_rec->conn[0].address, new_rec->conn[0].port, &new_rec->iface)) - return 0; + return -1; } /* if there is a error we can continue on */ - delete_node(NULL, rec); - return 0; + return delete_node(NULL, rec); } static int @@ -918,8 +948,12 @@ do_software_sendtargets(discovery_rec_t rc = idbm_bind_ifaces_to_nodes(discovery_sendtargets, drec, ifaces, &rec_list); if (rc) { - log_error("Could not perform SendTargets discovery."); + log_error("Could not perform SendTargets discovery: %s", + iscsi_err_to_str(rc)); return rc; + } else if (list_empty(&rec_list)) { + log_error("No portals found"); + return ISCSI_ERR_NO_OBJS_FOUND; } rc = exec_disc_op_on_recs(drec, &rec_list, info_level, do_login, op); @@ -986,7 +1020,7 @@ do_sendtargets(discovery_rec_t *drec, st } if (list_empty(ifaces)) - return ENODEV; + return ISCSI_ERR_NO_OBJS_FOUND; sw_st: return do_software_sendtargets(drec, ifaces, info_level, do_login, @@ -1013,8 +1047,12 @@ static int do_isns(discovery_rec_t *drec rc = idbm_bind_ifaces_to_nodes(discovery_isns, drec, ifaces, &rec_list); if (rc) { - log_error("Could not perform iSNS discovery."); + log_error("Could not perform iSNS discovery: %s", + iscsi_err_to_str(rc)); return rc; + } else if (list_empty(&rec_list)) { + log_error("No portals found"); + return ISCSI_ERR_NO_OBJS_FOUND; } rc = exec_disc_op_on_recs(drec, &rec_list, info_level, do_login, op); @@ -1071,7 +1109,7 @@ static int exec_iface_op(int op, int do_ rec = idbm_create_rec(NULL, -1, NULL, -1, iface, 0); if (rec && iscsi_check_for_running_session(rec)) { - rc = EBUSY; + rc = ISCSI_ERR_SESS_EXISTS; goto new_fail; } @@ -1088,19 +1126,19 @@ new_fail: if (!iface) { log_error("Could not delete interface. No interface " "passed in."); - return EINVAL; + return ISCSI_ERR_INVAL; } rec = idbm_create_rec(NULL, -1, NULL, -1, iface, 1); if (!rec) { - rc = EINVAL; + rc = ISCSI_ERR_INVAL; goto delete_fail; } /* logout and delete records using it first */ - rc = for_each_rec(rec, NULL, delete_node); - if (rc) - break; + rc = __for_each_matched_rec(0, rec, NULL, delete_node); + if (rc && rc != ISCSI_ERR_NO_OBJS_FOUND) + goto delete_fail; rc = iface_conf_delete(iface); if (rc) @@ -1109,20 +1147,19 @@ new_fail: printf("%s unbound and deleted.\n", iface->name); break; delete_fail: - log_error("Could not delete iface %s. A session is " - "is using it or it could not be found.", - iface->name); + log_error("Could not delete iface %s: %s", iface->name, + iscsi_err_to_str(rc)); break; case OP_UPDATE: if (!iface || !name || !value) { log_error("Update requires name, value, and iface."); - rc = EINVAL; + rc = ISCSI_ERR_INVAL; break; } rec = idbm_create_rec(NULL, -1, NULL, -1, iface, 1); if (!rec) { - rc = EINVAL; + rc = ISCSI_ERR_INVAL; goto update_fail; } @@ -1136,7 +1173,7 @@ delete_fail: log_error("Can not update " "iface.iscsi_ifacename. Delete it, " "and then create a new one."); - rc = EINVAL; + rc = ISCSI_ERR_INVAL; break; } @@ -1146,7 +1183,7 @@ delete_fail: "from hwaddress to net_ifacename. "); log_error("You must delete the interface and " "create a new one"); - rc = EINVAL; + rc = ISCSI_ERR_INVAL; break; } @@ -1156,7 +1193,7 @@ delete_fail: "from net_ifacename to hwaddress. "); log_error("You must delete the interface and " "create a new one"); - rc = EINVAL; + rc = ISCSI_ERR_INVAL; break; } set_param.name = name; @@ -1167,23 +1204,25 @@ delete_fail: if (rc) goto update_fail; - rc = for_each_rec(rec, &set_param, idbm_node_set_param); - if (rc) - break; + rc = __for_each_matched_rec(0, rec, &set_param, + idbm_node_set_param); + if (rc == ISCSI_ERR_NO_OBJS_FOUND) + rc = 0; + else if (rc) + goto update_fail; printf("%s updated.\n", iface->name); break; update_fail: - log_error("Could not update iface %s. A session is " - "is using it or it could not be found.", - iface->name); + log_error("Could not update iface %s: %s", + iface->name, iscsi_err_to_str(rc)); break; default: if (!iface || (iface && info_level > 0)) { if (op == OP_NOOP || op == OP_SHOW) rc = print_ifaces(iface, info_level); else - rc = EINVAL; + rc = ISCSI_ERR_INVAL; } else { rc = iface_conf_read(iface); if (!rc) @@ -1214,33 +1253,29 @@ static int exec_node_op(int op, int do_l rec->name, rec->conn[0].address, rec->conn[0].port); if (op == OP_NEW) { - if (add_static_recs(rec)) - rc = -1; + rc = add_static_recs(rec); goto out; } if (do_rescan) { - if (for_each_session(rec, rescan_portal)) - rc = -1; + rc = for_each_session(rec, rescan_portal); goto out; } if (do_stats) { - if (for_each_session(rec, session_stats)) - rc = -1; + rc = for_each_session(rec, session_stats); goto out; } if (do_login && do_logout) { - log_error("either login or logout at the time allowed!"); - rc = -1; + log_error("Invalid parameters. Both login and logout passed in"); + rc = ISCSI_ERR_INVAL; goto out; } if ((do_login || do_logout) && op > OP_NOOP) { - log_error("either operation or login/logout " - "at the time allowed!"); - rc = -1; + log_error("Invalid parameters. Login/logout and op passed in"); + rc = ISCSI_ERR_INVAL; goto out; } @@ -1252,30 +1287,29 @@ static int exec_node_op(int op, int do_l } if (do_login) { - if (login_portals(rec)) - rc = -1; + rc = login_portals(rec); goto out; } if (do_logout) { int nr_found; - if (iscsi_logout_portals(rec, &nr_found, 1, - iscsi_logout_matched_portal)) - rc = -1; + rc = iscsi_logout_portals(rec, &nr_found, 1, + iscsi_logout_matched_portal); + if (rc == ISCSI_ERR_NO_OBJS_FOUND) + log_error("No matching sessions found"); goto out; } if (op == OP_NOOP || (!do_login && !do_logout && op == OP_SHOW)) { - if (for_each_rec(rec, &do_show, idbm_print_node_info)) - rc = -1; + rc = for_each_matched_rec(rec, &do_show, idbm_print_node_info); goto out; } if (op == OP_UPDATE) { if (!name || !value) { log_error("update requires name and value"); - rc = -1; + rc = ISCSI_ERR_INVAL; goto out; } @@ -1284,7 +1318,7 @@ static int exec_node_op(int op, int do_l strcmp(name, "iface.transport_name")) { log_error("Cannot modify %s. Use iface mode to update " "this value.", name); - rc = -1; + rc = ISCSI_ERR_INVAL; goto out; } @@ -1304,7 +1338,7 @@ static int exec_node_op(int op, int do_l "transport name while a session " "is using it. Log out the session " "then update record."); - rc = -1; + rc = ISCSI_ERR_SESS_EXISTS; goto out; } } @@ -1312,16 +1346,14 @@ static int exec_node_op(int op, int do_l set_param.name = name; set_param.value = value; - if (for_each_rec(rec, &set_param, idbm_node_set_param)) - rc = -1; + rc = for_each_matched_rec(rec, &set_param, idbm_node_set_param); goto out; } else if (op == OP_DELETE) { - if (for_each_rec(rec, NULL, delete_node)) - rc = -1; + rc = for_each_matched_rec(rec, NULL, delete_node); goto out; } else { log_error("operation is not supported."); - rc = -1; + rc = ISCSI_ERR_INVAL; goto out; } out: @@ -1443,7 +1475,7 @@ static int exec_fw_op(discovery_rec_t *d if (!rec) { log_error("Could not convert firmware info to " "node record.\n"); - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; break; } @@ -1493,9 +1525,9 @@ static void setup_drec_defaults(int type * and will read and add a drec, and perform discovery if needed. * * returns: - * -1 - error + * Greater than 0 - error * 0 - op/discovery completed - * 1 - exec db op + * -1 - exec db op */ static int exec_discover(int disc_type, char *ip, int port, struct list_head *ifaces, int info_level, @@ -1506,15 +1538,16 @@ static int exec_discover(int disc_type, if (ip == NULL) { log_error("Please specify portal as [:]"); - return -1; + return ISCSI_ERR_INVAL; } if (op & OP_NEW && !do_discover) { setup_drec_defaults(disc_type, ip, port, drec); - if (idbm_add_discovery(drec)) { + rc = idbm_add_discovery(drec); + if (rc) { log_error("Could not add new discovery record."); - return -1; + return rc; } else { printf("New discovery record for [%s,%d] added.\n", ip, port); @@ -1527,7 +1560,7 @@ static int exec_discover(int disc_type, if (!do_discover) { log_error("Discovery record [%s,%d] not found.", ip, port); - return -1; + return rc; } /* Just add default rec for user */ @@ -1539,11 +1572,11 @@ static int exec_discover(int disc_type, if (rc) { log_error("Could not add new discovery " "record."); - return -1; + return rc; } } } else if (!do_discover) - return 1; + return -1; rc = 0; switch (disc_type) { @@ -1563,9 +1596,7 @@ static int exec_discover(int disc_type, break; } - if (rc) - return -1; - return 0; + return rc; } static int exec_disc2_op(int disc_type, char *ip, int port, @@ -1587,12 +1618,12 @@ static int exec_disc2_op(int disc_type, rc = exec_discover(disc_type, ip, port, ifaces, info_level, do_login, do_discover, op, &drec); - if (rc == 1) + if (rc < 0) goto do_db_op; goto done; case DISCOVERY_TYPE_SLP: log_error("SLP discovery is not fully implemented yet."); - rc = -1; + rc = ISCSI_ERR_INVAL; goto done; case DISCOVERY_TYPE_ISNS: if (port < 0) @@ -1600,29 +1631,30 @@ static int exec_disc2_op(int disc_type, rc = exec_discover(disc_type, ip, port, ifaces, info_level, do_login, do_discover, op, &drec); - if (rc == 1) + if (rc < 0) goto do_db_op; goto done; case DISCOVERY_TYPE_FW: if (!do_discover) { log_error("Invalid command. Possibly missing " "--discover argument."); - rc = -1; + rc = ISCSI_ERR_INVAL; goto done; } drec.type = DISCOVERY_TYPE_FW; - if (exec_fw_op(&drec, ifaces, info_level, do_login, op)) - rc = -1; + rc = exec_fw_op(&drec, ifaces, info_level, do_login, op); goto done; default: - rc = -1; + rc = ISCSI_ERR_INVAL; if (!ip) { if (op == OP_NOOP || op == OP_SHOW) { if (idbm_print_all_discovery(info_level)) /* successfully found some recs */ rc = 0; + else + rc = ISCSI_ERR_NO_OBJS_FOUND; } else log_error("Invalid operation. Operation not " "supported."); @@ -1640,29 +1672,27 @@ do_db_op: if (op == OP_NOOP || op == OP_SHOW) { if (!idbm_print_discovery_info(&drec, do_show)) { - log_error("No records found!"); - rc = -1; + log_error("No records found"); + rc = ISCSI_ERR_NO_OBJS_FOUND; } } else if (op == OP_DELETE) { - if (idbm_delete_discovery(&drec)) { + rc = idbm_delete_discovery(&drec); + if (rc) log_error("Unable to delete record!"); - rc = -1; - } } else if (op == OP_UPDATE) { struct db_set_param set_param; if (!name || !value) { log_error("Update requires name and value."); - rc = -1; + rc = ISCSI_ERR_INVAL; goto done; } set_param.name = name; set_param.value = value; - if (idbm_discovery_set_param(&set_param, &drec)) - rc = -1; + rc = idbm_discovery_set_param(&set_param, &drec); } else { log_error("Operation is not supported."); - rc = -1; + rc = ISCSI_ERR_INVAL; goto done; } done: @@ -1689,7 +1719,7 @@ static int exec_disc_op(int disc_type, c if (ip == NULL) { log_error("Please specify portal as " "[:]"); - rc = -1; + rc = ISCSI_ERR_INVAL; goto done; } @@ -1697,21 +1727,20 @@ static int exec_disc_op(int disc_type, c strlcpy(drec.address, ip, sizeof(drec.address)); drec.port = port; - if (do_sendtargets(&drec, ifaces, info_level, - do_login, op, 1)) { - rc = -1; + rc = do_sendtargets(&drec, ifaces, info_level, + do_login, op, 1); + if (rc) goto done; - } break; case DISCOVERY_TYPE_SLP: log_error("SLP discovery is not fully implemented yet."); - rc = -1; + rc = ISCSI_ERR_INVAL; break; case DISCOVERY_TYPE_ISNS: if (!ip) { log_error("Please specify portal as " ":[]"); - rc = -1; + rc = ISCSI_ERR_INVAL; goto done; } @@ -1721,15 +1750,13 @@ static int exec_disc_op(int disc_type, c else drec.port = port; - if (do_isns(&drec, ifaces, info_level, do_login, op)) { - rc = -1; + rc = do_isns(&drec, ifaces, info_level, do_login, op); + if (rc) goto done; - } break; case DISCOVERY_TYPE_FW: drec.type = DISCOVERY_TYPE_FW; - if (exec_fw_op(&drec, ifaces, info_level, do_login, op)) - rc = -1; + rc = exec_fw_op(&drec, ifaces, info_level, do_login, op); break; default: if (ip) { @@ -1749,42 +1776,41 @@ static int exec_disc_op(int disc_type, c ip, port)) { log_error("Discovery record [%s,%d] " "not found!", ip, port); - rc = -1; + rc = ISCSI_ERR_INVAL; goto done; } if ((do_discover || do_login) && drec.type == DISCOVERY_TYPE_SENDTARGETS) { - do_sendtargets(&drec, ifaces, info_level, - do_login, op, 0); + rc = do_sendtargets(&drec, ifaces, info_level, + do_login, op, 0); } else if (op == OP_NOOP || op == OP_SHOW) { if (!idbm_print_discovery_info(&drec, do_show)) { - log_error("No records found!"); - rc = -1; + log_error("No records found"); + rc = ISCSI_ERR_NO_OBJS_FOUND; } } else if (op == OP_DELETE) { - if (idbm_delete_discovery(&drec)) { + rc = idbm_delete_discovery(&drec); + if (rc) log_error("Unable to delete record!"); - rc = -1; - } } else if (op == OP_UPDATE || op == OP_NEW) { log_error("Operations new and update for " "discovery mode is not supported. " "Use discoverydb mode."); - rc = -1; + rc = ISCSI_ERR_INVAL; goto done; } else { log_error("Invalid operation."); - rc = -1; + rc = ISCSI_ERR_INVAL; goto done; } } else if (op == OP_NOOP || op == OP_SHOW) { if (!idbm_print_all_discovery(info_level)) - rc = -1; + rc = ISCSI_ERR_NO_OBJS_FOUND; goto done; } else { log_error("Invalid operation."); - rc = -1; + rc = ISCSI_ERR_INVAL; goto done; } /* fall through */ @@ -1837,7 +1863,7 @@ main(int argc, char **argv) log_error("Invalid killiscsid priority %d " "Priority must be greater than or " "equal to zero.", killiscsid); - rc = -1; + rc = ISCSI_ERR_INVAL; goto free_ifaces; } break; @@ -1849,7 +1875,7 @@ main(int argc, char **argv) if (op == OP_NOOP) { log_error("can not recognize operation: '%s'", optarg); - rc = -1; + rc = ISCSI_ERR_INVAL; goto free_ifaces; } break; @@ -1865,7 +1891,7 @@ main(int argc, char **argv) if (errno) { log_error("invalid host no %s. %s.", optarg, strerror(errno)); - rc = -1; + rc = ISCSI_ERR_INVAL; goto free_ifaces; } break; @@ -1874,7 +1900,7 @@ main(int argc, char **argv) if (sid < 0) { log_error("invalid sid '%s'", optarg); - rc = -1; + rc = ISCSI_ERR_INVAL; goto free_ifaces; } break; @@ -1921,15 +1947,14 @@ main(int argc, char **argv) break; case 'I': iface = iface_alloc(optarg, &rc); - if (rc == EINVAL) { + if (rc == ISCSI_ERR_INVAL) { printf("Invalid iface name %s. Must be from " "1 to %d characters.\n", optarg, ISCSI_MAX_IFACE_LEN - 1); - rc = -1; goto free_ifaces; } else if (!iface || rc) { printf("Could not add iface %s.", optarg); - rc = -1; + rc = ISCSI_ERR_INVAL; goto free_ifaces; } @@ -1947,7 +1972,7 @@ main(int argc, char **argv) if (optopt) { log_error("unrecognized character '%c'", optopt); - rc = -1; + rc = ISCSI_ERR_INVAL; goto free_ifaces; } @@ -1957,13 +1982,13 @@ main(int argc, char **argv) } if (mode < 0) - usage(0); + usage(ISCSI_ERR_INVAL); if (mode == MODE_FW) { if ((rc = verify_mode_params(argc, argv, "ml", 0))) { log_error("fw mode: option '-%c' is not " "allowed/supported", rc); - rc = -1; + rc = ISCSI_ERR_INVAL; goto free_ifaces; } @@ -1974,7 +1999,7 @@ main(int argc, char **argv) increase_max_files(); if (idbm_init(get_config_file)) { log_warning("exiting due to idbm configuration error"); - rc = -1; + rc = ISCSI_ERR_IDBM; goto free_ifaces; } @@ -1983,7 +2008,7 @@ main(int argc, char **argv) if ((rc = verify_mode_params(argc, argv, "HdmP", 0))) { log_error("host mode: option '-%c' is not " "allowed/supported", rc); - rc = -1; + rc = ISCSI_ERR_INVAL; goto out; } @@ -1995,7 +2020,7 @@ main(int argc, char **argv) if ((rc = verify_mode_params(argc, argv, "IdnvmPo", 0))) { log_error("iface mode: option '-%c' is not " "allowed/supported", rc); - rc = -1; + rc = ISCSI_ERR_INVAL; goto out; } @@ -2014,7 +2039,7 @@ main(int argc, char **argv) if ((rc = verify_mode_params(argc, argv, "DSIPdmntplov", 0))) { log_error("discovery mode: option '-%c' is not " "allowed/supported", rc); - rc = -1; + rc = ISCSI_ERR_INVAL; goto out; } @@ -2026,7 +2051,7 @@ main(int argc, char **argv) if ((rc = verify_mode_params(argc, argv, "DSIPdmntplov", 0))) { log_error("discovery mode: option '-%c' is not " "allowed/supported", rc); - rc = -1; + rc = ISCSI_ERR_INVAL; goto out; } @@ -2039,7 +2064,7 @@ main(int argc, char **argv) 0))) { log_error("node mode: option '-%c' is not " "allowed/supported", rc); - rc = -1; + rc = ISCSI_ERR_INVAL; goto out; } @@ -2069,7 +2094,7 @@ main(int argc, char **argv) rec = idbm_create_rec(targetname, tpgt, ip, port, iface, 1); if (!rec) { - rc = -1; + rc = ISCSI_ERR_NOMEM; goto out; } @@ -2082,7 +2107,7 @@ main(int argc, char **argv) "PiRdrmusonuSv", 1))) { log_error("session mode: option '-%c' is not " "allowed or supported", rc); - rc = -1; + rc = ISCSI_ERR_INVAL; goto out; } if (sid >= 0) { @@ -2094,7 +2119,7 @@ main(int argc, char **argv) info = calloc(1, sizeof(*info)); if (!info) { - rc = ENOMEM; + rc = ISCSI_ERR_NOMEM; goto out; } @@ -2116,8 +2141,6 @@ main(int argc, char **argv) if (!do_logout && !do_rescan && !do_stats && op == OP_NOOP && info_level > 0) { rc = session_info_print(info_level, info); - if (rc) - rc = -1; goto free_info; } @@ -2127,7 +2150,7 @@ main(int argc, char **argv) info->persistent_port, &info->iface, 1); if (!rec) { - rc = -1; + rc = ISCSI_ERR_NOMEM; goto free_info; } 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid.c 2011-02-24 19:54:29.000000000 -0600 @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include "iscsid.h" #include "mgmt_ipc.h" @@ -48,16 +50,17 @@ #include "sysdeps.h" #include "discoveryd.h" #include "iscsid_req.h" +#include "iscsi_err.h" /* global config info */ struct iscsi_daemon_config daemon_config; struct iscsi_daemon_config *dconfig = &daemon_config; static char program_name[] = "iscsid"; -int control_fd, mgmt_ipc_fd; static pid_t log_pid; static gid_t gid; static int daemonize = 1; +static int mgmt_ipc_fd; static struct option const long_options[] = { {"config", required_argument, NULL, 'c'}, @@ -92,7 +95,7 @@ Open-iSCSI initiator daemon.\n\ -v, --version display version and exit\n\ "); } - exit(status == 0 ? 0 : -1); + exit(status); } static void @@ -196,11 +199,6 @@ static int sync_session(void *data, stru t = iscsi_sysfs_get_transport_by_sid(info->sid); if (!t) return 0; - if (set_transport_template(t)) { - log_error("Could not find userspace transport template for %s", - t->name); - return 0; - } /* * Just rescan the device in case this is the first startup. @@ -213,7 +211,8 @@ static int sync_session(void *data, stru host_no = iscsi_sysfs_get_host_no_from_sid(info->sid, &err); if (err) { log_error("Could not get host no from sid %u. Can not " - "sync session. Error %d", info->sid, err); + "sync session: %s", info->sid, + iscsi_err_to_str(err)); return 0; } iscsi_sysfs_scan_host(host_no, 0); @@ -272,7 +271,7 @@ static int sync_session(void *data, stru retry: rc = iscsid_exec_req(&req, &rsp, 0); - if (rc == MGMT_IPC_ERR_ISCSID_NOTCONN && retries < 30) { + if (rc == ISCSI_ERR_ISCSID_NOTCONN && retries < 30) { retries++; sleep(1); goto retry; @@ -302,7 +301,7 @@ static void iscsid_shutdown(void) static void catch_signal(int signo) { - log_debug(1, "%d caught signal -%d...", signo, getpid()); + log_debug(1, "pid %d caught signal %d", getpid(), signo); switch (signo) { case SIGTERM: iscsid_shutdown(); @@ -318,7 +317,7 @@ static void missing_iname_warn(char *ini log_error("Warning: InitiatorName file %s does not exist or does not " "contain a properly formated InitiatorName. If using " "software iscsi (iscsi_tcp or ib_iser) or partial offload " - "(bnx2i or cxgb3i iscsi), you may not be able to log " + "(bnx2i or cxgbi iscsi), you may not be able to log " "into or discover targets. Please create a file %s that " "contains a sting with the format: InitiatorName=" "iqn.yyyy-mm.[:identifier].\n\n" @@ -337,6 +336,7 @@ int main(int argc, char *argv[]) uid_t uid = 0; struct sigaction sa_old; struct sigaction sa_new; + int control_fd; pid_t pid; /* do not allow ctrl-c for now... */ @@ -388,17 +388,17 @@ int main(int argc, char *argv[]) log_pid = log_init(program_name, DEFAULT_AREA_SIZE, daemonize ? log_do_log_daemon : log_do_log_std, NULL); if (log_pid < 0) - exit(1); + exit(ISCSI_ERR); sysfs_init(); if (idbm_init(iscsid_get_config_file)) { log_close(log_pid); - exit(1); + exit(ISCSI_ERR); } if (iscsi_sysfs_check_class_version()) { log_close(log_pid); - exit(1); + exit(ISCSI_ERR); } umask(0177); @@ -410,7 +410,7 @@ int main(int argc, char *argv[]) if ((mgmt_ipc_fd = mgmt_ipc_listen()) < 0) { log_close(log_pid); - exit(1); + exit(ISCSI_ERR); } if (daemonize) { @@ -421,13 +421,13 @@ int main(int argc, char *argv[]) if (fd < 0) { log_error("Unable to create pid file"); log_close(log_pid); - exit(1); + exit(ISCSI_ERR); } pid = fork(); if (pid < 0) { log_error("Starting daemon failed"); log_close(log_pid); - exit(1); + exit(ISCSI_ERR); } else if (pid) { log_error("iSCSI daemon with pid=%d started!", pid); exit(0); @@ -435,14 +435,14 @@ int main(int argc, char *argv[]) if ((control_fd = ipc->ctldev_open()) < 0) { log_close(log_pid); - exit(1); + exit(ISCSI_ERR); } chdir("/"); if (lockf(fd, F_TLOCK, 0) < 0) { log_error("Unable to lock pid file"); log_close(log_pid); - exit(1); + exit(ISCSI_ERR); } ftruncate(fd, 0); sprintf(buf, "%d\n", getpid()); @@ -498,6 +498,7 @@ int main(int argc, char *argv[]) } else reap_inc(); + iscsi_initiator_init(); increase_max_files(); discoveryd_start(daemon_config.initiator_name); @@ -509,7 +510,7 @@ int main(int argc, char *argv[]) if (mlockall(MCL_CURRENT | MCL_FUTURE)) { log_error("failed to mlockall, exiting..."); log_close(log_pid); - exit(1); + exit(ISCSI_ERR); } actor_init(); diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid.h 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid.h 2011-02-24 19:54:10.000000000 -0600 @@ -31,6 +31,5 @@ struct iscsi_daemon_config { char *initiator_alias; }; extern struct iscsi_daemon_config *dconfig; -extern int control_fd; #endif /* ISCSID_H */ diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid_req.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid_req.c 2011-02-24 19:54:10.000000000 -0600 @@ -31,6 +31,7 @@ #include "mgmt_ipc.h" #include "iscsi_util.h" #include "config.h" +#include "iscsi_err.h" static void iscsid_startup(void) { @@ -51,7 +52,7 @@ static void iscsid_startup(void) #define MAXSLEEP 128 -static mgmt_ipc_err_e iscsid_connect(int *fd, int start_iscsid) +static int iscsid_connect(int *fd, int start_iscsid) { int nsec; struct sockaddr_un addr; @@ -59,7 +60,7 @@ static mgmt_ipc_err_e iscsid_connect(int *fd = socket(AF_LOCAL, SOCK_STREAM, 0); if (*fd < 0) { log_error("can not create IPC socket (%d)!", errno); - return MGMT_IPC_ERR_ISCSID_NOTCONN; + return ISCSI_ERR_ISCSID_NOTCONN; } memset(&addr, 0, sizeof(addr)); @@ -72,7 +73,7 @@ static mgmt_ipc_err_e iscsid_connect(int for (nsec = 1; nsec <= MAXSLEEP; nsec <<= 1) { if (connect(*fd, (struct sockaddr *) &addr, sizeof(addr)) == 0) /* Connection established */ - return MGMT_IPC_OK; + return ISCSI_SUCCESS; /* If iscsid isn't there, there's no sense * in retrying. */ @@ -90,10 +91,10 @@ static mgmt_ipc_err_e iscsid_connect(int sleep(nsec); } log_error("can not connect to iSCSI daemon (%d)!", errno); - return MGMT_IPC_ERR_ISCSID_NOTCONN; + return ISCSI_ERR_ISCSID_NOTCONN; } -mgmt_ipc_err_e iscsid_request(int *fd, iscsiadm_req_t *req, int start_iscsid) +int iscsid_request(int *fd, iscsiadm_req_t *req, int start_iscsid) { int err; @@ -105,33 +106,33 @@ mgmt_ipc_err_e iscsid_request(int *fd, i log_error("got write error (%d/%d) on cmd %d, daemon died?", err, errno, req->command); close(*fd); - return MGMT_IPC_ERR_ISCSID_COMM_ERR; + return ISCSI_ERR_ISCSID_COMM_ERR; } - return MGMT_IPC_OK; + return ISCSI_SUCCESS; } -mgmt_ipc_err_e iscsid_response(int fd, iscsiadm_cmd_e cmd, iscsiadm_rsp_t *rsp) +int iscsid_response(int fd, iscsiadm_cmd_e cmd, iscsiadm_rsp_t *rsp) { - mgmt_ipc_err_e iscsi_err; + int iscsi_err; int err; if ((err = recv(fd, rsp, sizeof(*rsp), MSG_WAITALL)) != sizeof(*rsp)) { log_error("got read error (%d/%d), daemon died?", err, errno); - iscsi_err = MGMT_IPC_ERR_ISCSID_COMM_ERR; + iscsi_err = ISCSI_ERR_ISCSID_COMM_ERR; } else iscsi_err = rsp->err; close(fd); if (!iscsi_err && cmd != rsp->command) - iscsi_err = MGMT_IPC_ERR_ISCSID_COMM_ERR; + iscsi_err = ISCSI_ERR_ISCSID_COMM_ERR; return iscsi_err; } -mgmt_ipc_err_e iscsid_exec_req(iscsiadm_req_t *req, iscsiadm_rsp_t *rsp, +int iscsid_exec_req(iscsiadm_req_t *req, iscsiadm_rsp_t *rsp, int start_iscsid) { int fd; - mgmt_ipc_err_e err; + int err; err = iscsid_request(&fd, req, start_iscsid); if (err) @@ -189,31 +190,3 @@ int iscsid_req_by_sid(iscsiadm_cmd_e cmd return err; return iscsid_req_wait(cmd, fd); } - -void iscsid_handle_error(mgmt_ipc_err_e err) -{ - static char *err_msgs[] = { - /* 0 */ "", - /* 1 */ "unknown error", - /* 2 */ "not found", - /* 3 */ "no available memory", - /* 4 */ "encountered connection failure", - /* 5 */ "encountered iSCSI login failure", - /* 6 */ "encountered iSCSI database failure", - /* 7 */ "invalid parameter", - /* 8 */ "connection timed out", - /* 9 */ "internal error", - /* 10 */ "encountered iSCSI logout failure", - /* 11 */ "iSCSI PDU timed out", - /* 12 */ "iSCSI driver not found. Please make sure it is loaded, and retry the operation", - /* 13 */ "daemon access denied", - /* 14 */ "iSCSI driver does not support requested capability.", - /* 15 */ "already exists", - /* 16 */ "Unknown request", - /* 17 */ "encountered iSNS failure", - /* 18 */ "could not communicate to iscsid", - /* 19 */ "encountered non-retryable iSCSI login failure", - /* 20 */ "could not connect to iscsid", - }; - log_error("initiator reported error (%d - %s)", err, err_msgs[err]); -} diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid_req.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsid_req.h 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsid_req.h 2011-02-24 19:54:10.000000000 -0600 @@ -27,7 +27,6 @@ struct node_rec; extern int iscsid_exec_req(struct iscsiadm_req *req, struct iscsiadm_rsp *rsp, int iscsid_start); -extern void iscsid_handle_error(int err); extern int iscsid_req_wait(int cmd, int fd); extern int iscsid_req_by_rec_async(int cmd, struct node_rec *rec, int *fd); extern int iscsid_req_by_rec(int cmd, struct node_rec *rec); diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_err.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_err.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_err.c 1969-12-31 18:00:00.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_err.c 2011-02-24 19:54:10.000000000 -0600 @@ -0,0 +1,72 @@ +/* + * iSCSI error helpers + * + * Copyright (C) 2011 Mike Christie + * Copyright (C) 2011 Red Hat, Inc. All rights reserved. + * maintained by open-iscsi@googlegroups.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * See the file COPYING included with this distribution for more details. + */ +#include "stdlib.h" +#include "iscsi_err.h" +#include "log.h" + +static char *iscsi_err_msgs[] = { + /* 0 */ "", + /* 1 */ "unknown error", + /* 2 */ "session not found", + /* 3 */ "no available memory", + /* 4 */ "encountered connection failure", + /* 5 */ "encountered iSCSI login failure", + /* 6 */ "encountered iSCSI database failure", + /* 7 */ "invalid parameter", + /* 8 */ "connection timed out", + /* 9 */ "internal error", + /* 10 */ "encountered iSCSI logout failure", + /* 11 */ "iSCSI PDU timed out", + /* 12 */ "iSCSI driver not found. Please make sure it is loaded, and retry the operation", + /* 13 */ "daemon access denied", + /* 14 */ "iSCSI driver does not support requested capability.", + /* 15 */ "session exists", + /* 16 */ "Unknown request", + /* 17 */ "iSNS service not supported", + /* 18 */ "could not communicate to iscsid", + /* 19 */ "encountered non-retryable iSCSI login failure", + /* 20 */ "could not connect to iscsid", + /* 21 */ "no objects found", + /* 23 */ "sysfs lookup failure", + /* 23 */ "host not found", + /* 24 */ "iSCSI login failed due to authorization failure", + /* 25 */ "iSNS query failed", + /* 26 */ "iSNS registration failed", +}; + +char *iscsi_err_to_str(int err) +{ + if (err >= ISCSI_MAX_ERR_VAL || err < 0) { + log_error("invalid error code %d", err); + return NULL; + } + + return iscsi_err_msgs[err]; +} + +void iscsi_err_print_msg(int err) +{ + if (err >= ISCSI_MAX_ERR_VAL || err < 0) { + log_error("invalid error code %d", err); + return; + } + log_error("initiator reported error (%d - %s)", err, + iscsi_err_msgs[err]); +} 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_ipc.h 2011-02-24 19:54:10.000000000 -0600 @@ -34,6 +34,26 @@ enum { }; struct iscsi_conn; +struct iscsi_ev_context; + +/* + * When handling async events, the initiator may not be able to + * handle the event in the same context, so this allows the interface + * code to call into the initiator to shedule handling. + */ +struct iscsi_ipc_ev_clbk { + void (*create_session) (uint32_t host_no, uint32_t sid); + void (*destroy_session) (uint32_t host_no, uint32_t sid); + + struct iscsi_ev_context *(*get_ev_context) (struct iscsi_conn *conn, + int ev_size); + void (*put_ev_context) (struct iscsi_ev_context *ev_context); + int (*sched_ev_context) (struct iscsi_ev_context *ev_context, + struct iscsi_conn *conn, + unsigned long tmo, int event); +}; + +extern void ipc_register_ev_callback(struct iscsi_ipc_ev_clbk *ipc_ev_clbk); /** * struct iscsi_ipc - Open-iSCSI Interface for Kernel IPC 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_net_util.c 2011-02-24 19:54:10.000000000 -0600 @@ -41,6 +41,7 @@ struct iscsi_net_driver { static struct iscsi_net_driver net_drivers[] = { #ifdef OFFLOAD_BOOT_SUPPORTED {"cxgb3", "cxgb3i" }, + {"cxgb4", "cxgb4i" }, {"bnx2", "bnx2i" }, {"bnx2x", "bnx2i"}, #endif 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsistart.c 2011-02-24 19:54:10.000000000 -0600 @@ -47,6 +47,7 @@ #include "iface.h" #include "sysdeps.h" #include "iscsid_req.h" +#include "iscsi_err.h" /* global config info */ /* initiator needs initiator name/alias */ @@ -57,10 +58,8 @@ static node_rec_t config_rec; static LIST_HEAD(targets); static char program_name[] = "iscsistart"; -static int mgmt_ipc_fd; /* used by initiator */ -int control_fd; extern struct iscsi_ipc *ipc; static struct option const long_options[] = { @@ -108,7 +107,7 @@ Open-iSCSI initiator.\n\ -v, --version display version and exit\n\ "); } - exit(status == 0 ? 0 : -1); + exit(status); } static int stop_event_loop(void) @@ -121,7 +120,7 @@ static int stop_event_loop(void) req.command = MGMT_IPC_IMMEDIATE_STOP; rc = iscsid_exec_req(&req, &rsp, 0); if (rc) { - iscsid_handle_error(rc); + iscsi_err_print_msg(rc); log_error("Could not stop event_loop\n"); } return rc; @@ -155,12 +154,12 @@ retry: * handle race where iscsid proc is starting up while we are * trying to connect. */ - if (rc == MGMT_IPC_ERR_ISCSID_NOTCONN && retries < 30) { + if (rc == ISCSI_ERR_ISCSID_NOTCONN && retries < 30) { retries++; sleep(1); goto retry; } else if (rc) - iscsid_handle_error(rc); + iscsi_err_print_msg(rc); return rc; } @@ -229,7 +228,7 @@ do { \ if (strlen(str) > max_len) { \ printf("%s: invalid %s %s. Max %s length is %d.\n", \ program_name, param, str, param, max_len); \ - exit(1); \ + exit(ISCSI_ERR_INVAL); \ } \ } while (0); @@ -242,6 +241,7 @@ int main(int argc, char *argv[]) struct boot_context *context, boot_context; struct sigaction sa_old; struct sigaction sa_new; + int control_fd, mgmt_ipc_fd; pid_t pid; idbm_node_setup_defaults(&config_rec); @@ -260,7 +260,7 @@ int main(int argc, char *argv[]) sysfs_init(); if (iscsi_sysfs_check_class_version()) - exit(1); + exit(ISCSI_ERR_SYSFS_LOOKUP); while ((ch = getopt_long(argc, argv, "i:t:g:a:p:d:u:w:U:W:bNfvh", long_options, &longindex)) >= 0) { @@ -316,25 +316,24 @@ int main(int argc, char *argv[]) ret = fw_get_entry(&boot_context); if (ret) { printf("Could not get boot entry.\n"); - exit(1); + exit(ret); } initiatorname = boot_context.initiatorname; ret = fw_get_targets(&targets); if (ret || list_empty(&targets)) { printf("Could not setup fw entries.\n"); - exit(1); + exit(ret); } break; case 'N': - ret = fw_setup_nics(); - exit(ret); + exit(fw_setup_nics()); case 'f': ret = fw_get_targets(&targets); if (ret || list_empty(&targets)) { printf("Could not get list of targets from " "firmware.\n"); - exit(1); + exit(ret); } list_for_each_entry(context, &targets, list) @@ -350,18 +349,18 @@ int main(int argc, char *argv[]) usage(0); break; default: - usage(1); + usage(ISCSI_ERR_INVAL); break; } } if (list_empty(&targets) && check_params(initiatorname)) - exit(1); + exit(ISCSI_ERR_INVAL); pid = fork(); if (pid < 0) { log_error("iscsiboot fork failed"); - exit(1); + exit(ISCSI_ERR_NOMEM); } else if (pid) { int status, rc, rc2; @@ -376,7 +375,7 @@ int main(int argc, char *argv[]) waitpid(pid, &status, WUNTRACED); if (rc || rc2) - exit(-1); + exit(ISCSI_ERR); log_debug(1, "iscsi parent done"); exit(0); @@ -385,12 +384,12 @@ int main(int argc, char *argv[]) mgmt_ipc_fd = mgmt_ipc_listen(); if (mgmt_ipc_fd < 0) { log_error("Could not setup mgmt ipc\n"); - exit(-1); + exit(ISCSI_ERR_NOMEM); } control_fd = ipc->ctldev_open(); if (control_fd < 0) - exit(-1); + exit(ISCSI_ERR_NOMEM); memset(&daemon_config, 0, sizeof (daemon_config)); daemon_config.initiator_name = initiatorname; @@ -420,6 +419,7 @@ int main(int argc, char *argv[]) /* * Start Main Event Loop */ + iscsi_initiator_init(); actor_init(); event_loop(ipc, control_fd, mgmt_ipc_fd); ipc->ctldev_close(); 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_sysfs.c 2011-02-24 19:54:10.000000000 -0600 @@ -36,6 +36,7 @@ #include "iface.h" #include "session_info.h" #include "host.h" +#include "iscsi_err.h" /* * TODO: remove the _DIR defines and search for subsys dirs like @@ -115,6 +116,10 @@ static int read_transports(void) INIT_LIST_HEAD(&t->list); strlcpy(t->name, namelist[i]->d_name, ISCSI_TRANSPORT_NAME_MAXLEN); + if (set_transport_template(t)) { + free(t); + return -1; + } } else log_debug(7, "Updating transport %s", namelist[i]->d_name); @@ -238,7 +243,7 @@ uint32_t iscsi_sysfs_get_host_no_from_si ISCSI_SESSION_SUBSYS, id)) { log_error("Could not lookup devpath for %s. Possible sysfs " "incompatibility.\n", id); - *err = EIO; + *err = ISCSI_ERR_SYSFS_LOOKUP; return 0; } @@ -246,7 +251,7 @@ uint32_t iscsi_sysfs_get_host_no_from_si if (!session_dev) { log_error("Could not get dev for %s. Possible sysfs " "incompatibility.\n", id); - *err = EIO; + *err = ISCSI_ERR_SYSFS_LOOKUP; return 0; } @@ -271,7 +276,7 @@ uint32_t iscsi_sysfs_get_host_no_from_si if (!host_dev) { log_error("Could not get host dev for %s. Possible " "sysfs incompatibility.\n", id); - *err = EIO; + *err = ISCSI_ERR_SYSFS_LOOKUP; return 0; } } @@ -301,7 +306,7 @@ static uint32_t get_host_no_from_netdev( info = calloc(1, sizeof(*info)); if (!info) { - *rc = ENOMEM; + *rc = ISCSI_ERR_NOMEM; return -1; } strcpy(info->iface.netdev, netdev); @@ -311,7 +316,7 @@ static uint32_t get_host_no_from_netdev( if (local_rc == 1) host_no = info->host_no; else - *rc = ENODEV; + *rc = ISCSI_ERR_HOST_NOT_FOUND; free(info); return host_no; } @@ -337,7 +342,7 @@ static uint32_t get_host_no_from_hwaddre info = calloc(1, sizeof(*info)); if (!info) { - *rc = ENOMEM; + *rc = ISCSI_ERR_NOMEM; return -1; } strcpy(info->iface.hwaddress, address); @@ -347,7 +352,7 @@ static uint32_t get_host_no_from_hwaddre if (local_rc == 1) host_no = info->host_no; else - *rc = ENODEV; + *rc = ISCSI_ERR_HOST_NOT_FOUND; free(info); return host_no; } @@ -374,7 +379,7 @@ static uint32_t get_host_no_from_ipaddre info = calloc(1, sizeof(*info)); if (!info) { - *rc = ENOMEM; + *rc = ISCSI_ERR_NOMEM; return -1; } strcpy(info->iface.ipaddress, address); @@ -384,7 +389,7 @@ static uint32_t get_host_no_from_ipaddre if (local_rc == 1) host_no = info->host_no; else - *rc = ENODEV; + *rc = ISCSI_ERR_HOST_NOT_FOUND; free(info); return host_no; } @@ -404,7 +409,7 @@ uint32_t iscsi_sysfs_get_host_no_from_hw strcasecmp(iface->ipaddress, DEFAULT_IPADDRESS)) host_no = get_host_no_from_ipaddress(iface->ipaddress, &tmp_rc); else - tmp_rc = EINVAL; + tmp_rc = ISCSI_ERR_INVAL; *rc = tmp_rc; return host_no; @@ -459,7 +464,7 @@ static int iscsi_sysfs_read_iface(struct * host level because we cannot create different initiator ports * (cannot set isid either). The LLD also exports the iname at the * hba level so apps can see it, but we no longer set the iname for - * each iscsid controlled host since bnx2i cxgb3i can support multiple + * each iscsid controlled host since bnx2i cxgbi can support multiple * initiator names and of course software iscsi can support anything. */ ret = 1; @@ -523,7 +528,10 @@ static int iscsi_sysfs_read_iface(struct iface_str(iface)); } } - return ret; + if (ret) + return ISCSI_ERR_SYSFS_LOOKUP; + else + return 0; } int iscsi_sysfs_get_hostinfo_by_host_no(struct host_info *hinfo) @@ -540,7 +548,7 @@ int iscsi_sysfs_for_each_host(void *data info = malloc(sizeof(*info)); if (!info) - return ENOMEM; + return ISCSI_ERR_NOMEM; n = scandir(ISCSI_HOST_DIR, &namelist, trans_filter, alphasort); @@ -631,7 +639,7 @@ int iscsi_sysfs_get_sid_from_path(char * if (!dev) { log_error("Could not get dev for %s. Possible sysfs " "incompatibility.\n", devpath); - exit(1); + return -1; } if (!strncmp(dev->kernel, "session", 7)) @@ -645,8 +653,7 @@ int iscsi_sysfs_get_sid_from_path(char * } log_error("Unable to find sid in path %s", session); - exit(1); - return 0; + return -1; } int iscsi_sysfs_get_sessioninfo_by_id(struct session_info *info, char *session) @@ -657,21 +664,21 @@ int iscsi_sysfs_get_sessioninfo_by_id(st if (sscanf(session, "session%d", &info->sid) != 1) { log_error("invalid session '%s'", session); - return EINVAL; + return ISCSI_ERR_INVAL; } ret = sysfs_get_str(session, ISCSI_SESSION_SUBSYS, "targetname", info->targetname, sizeof(info->targetname)); if (ret) { log_error("could not read session targetname: %d", ret); - return ret; + return ISCSI_ERR_SYSFS_LOOKUP; } ret = sysfs_get_int(session, ISCSI_SESSION_SUBSYS, "tpgt", &info->tpgt); if (ret) { - log_error("could not read session tpgt: %u", ret); - return ret; + log_error("could not read session tpgt: %d", ret); + return ISCSI_ERR_SYSFS_LOOKUP; } snprintf(id, sizeof(id), ISCSI_CONN_ID, info->sid); @@ -727,8 +734,8 @@ int iscsi_sysfs_get_sessioninfo_by_id(st ret = 0; host_no = iscsi_sysfs_get_host_no_from_sid(info->sid, &ret); if (ret) { - log_error("could not get host_no for session%d err %d.", - info->sid, ret); + log_error("could not get host_no for session%d: %s.", + info->sid, iscsi_err_to_str(ret)); return ret; } @@ -755,7 +762,7 @@ int iscsi_sysfs_for_each_session(void *d info = calloc(1, sizeof(*info)); if (!info) - return ENOMEM; + return ISCSI_ERR_NOMEM; n = scandir(ISCSI_SESSION_DIR, &namelist, trans_filter, alphasort); @@ -797,8 +804,10 @@ int iscsi_sysfs_get_session_state(char * char id[NAME_SIZE]; snprintf(id, sizeof(id), ISCSI_SESSION_ID, sid); - return sysfs_get_str(id, ISCSI_SESSION_SUBSYS, "state", state, - SCSI_MAX_STATE_VALUE); + if (sysfs_get_str(id, ISCSI_SESSION_SUBSYS, "state", state, + SCSI_MAX_STATE_VALUE)) + return ISCSI_ERR_SYSFS_LOOKUP; + return 0; } int iscsi_sysfs_get_host_state(char *state, int host_no) @@ -806,8 +815,10 @@ int iscsi_sysfs_get_host_state(char *sta char id[NAME_SIZE]; snprintf(id, sizeof(id), ISCSI_HOST_ID, host_no); - return sysfs_get_str(id, SCSI_HOST_SUBSYS, "state", state, - SCSI_MAX_STATE_VALUE); + if (sysfs_get_str(id, SCSI_HOST_SUBSYS, "state", state, + SCSI_MAX_STATE_VALUE)) + return ISCSI_ERR_SYSFS_LOOKUP; + return 0; } int iscsi_sysfs_get_device_state(char *state, int host_no, int target, int lun) @@ -818,7 +829,7 @@ int iscsi_sysfs_get_device_state(char *s if (sysfs_get_str(id, SCSI_SUBSYS, "state", state, SCSI_MAX_STATE_VALUE)) { log_debug(3, "Could not read attr state for %s\n", id); - return EIO; + return ISCSI_ERR_SYSFS_LOOKUP; } return 0; @@ -919,7 +930,7 @@ static uint32_t get_target_no_from_sid(u uint32_t host, bus, target = 0; size_t sysfs_len; - *err = ENODEV; + *err = ISCSI_ERR_SESS_NOT_FOUND; snprintf(id, sizeof(id), "session%u", sid); if (!sysfs_lookup_devpath_by_subsys_id(devpath, sizeof(devpath), @@ -970,7 +981,8 @@ struct iscsi_transport *iscsi_sysfs_get_ struct iscsi_transport *t; /* sync up kernel and userspace */ - read_transports(); + if (read_transports()) + return NULL; /* check if the transport is loaded and matches */ list_for_each_entry(t, &transports, list) { @@ -1061,7 +1073,7 @@ int iscsi_sysfs_for_each_device(void *da ISCSI_SESSION_SUBSYS, id)) { log_debug(3, "Could not lookup devpath for %s %s\n", ISCSI_SESSION_SUBSYS, id); - return EIO; + return ISCSI_ERR_SYSFS_LOOKUP; } snprintf(path_full, sizeof(path_full), "%s%s/device/target%d:0:%d", diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_timer.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_timer.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_timer.c 1969-12-31 18:00:00.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_timer.c 2011-02-24 19:54:10.000000000 -0600 @@ -0,0 +1,86 @@ +/* + * iSCSI timer + * + * Copyright (C) 2002 Cisco Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * See the file COPYING included with this distribution for more details. + */ +#include +#include + +void iscsi_timer_clear(struct timeval *timer) +{ + memset(timer, 0, sizeof (*timer)); +} + +/* set timer to now + seconds */ +void iscsi_timer_set(struct timeval *timer, int seconds) +{ + if (timer) { + memset(timer, 0, sizeof (*timer)); + gettimeofday(timer, NULL); + + timer->tv_sec += seconds; + } +} + +int iscsi_timer_expired(struct timeval *timer) +{ + struct timeval now; + + /* no timer, can't have expired */ + if ((timer == NULL) || ((timer->tv_sec == 0) && (timer->tv_usec == 0))) + return 0; + + memset(&now, 0, sizeof (now)); + gettimeofday(&now, NULL); + + if (now.tv_sec > timer->tv_sec) + return 1; + if ((now.tv_sec == timer->tv_sec) && (now.tv_usec >= timer->tv_usec)) + return 1; + return 0; +} + +int iscsi_timer_msecs_until(struct timeval *timer) +{ + struct timeval now; + int msecs; + long partial; + + /* no timer, can't have expired, infinite time til it expires */ + if ((timer == NULL) || ((timer->tv_sec == 0) && (timer->tv_usec == 0))) + return -1; + + memset(&now, 0, sizeof (now)); + gettimeofday(&now, NULL); + + /* already expired? */ + if (now.tv_sec > timer->tv_sec) + return 0; + if ((now.tv_sec == timer->tv_sec) && (now.tv_usec >= timer->tv_usec)) + return 0; + + /* not expired yet, do the math */ + partial = timer->tv_usec - now.tv_usec; + if (partial < 0) { + partial += 1000 * 1000; + msecs = (partial + 500) / 1000; + msecs += (timer->tv_sec - now.tv_sec - 1) * 1000; + } else { + msecs = (partial + 500) / 1000; + msecs += (timer->tv_sec - now.tv_sec) * 1000; + } + + return msecs; +} diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_timer.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_timer.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsi_timer.h 1969-12-31 18:00:00.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/iscsi_timer.h 2011-02-24 19:54:10.000000000 -0600 @@ -0,0 +1,28 @@ +/* + * iSCSI timer + * + * Copyright (C) 2002 Cisco Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * See the file COPYING included with this distribution for more details. + */ +#ifndef ISCSI_TIMER_H +#define ISCSI_TIMER_H + +struct timeval; + +extern void iscsi_timer_clear(struct timeval *timer); +extern void iscsi_timer_set(struct timeval *timer, int seconds); +extern int iscsi_timer_expired(struct timeval *timer); +extern int iscsi_timer_msecs_until(struct timeval *timer); + +#endif diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/login.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/login.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/login.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/login.c 2011-02-24 19:54:10.000000000 -0600 @@ -27,11 +27,14 @@ #include #include #include +#include +#include #include #include "initiator.h" #include "transport.h" #include "log.h" +#include "iscsi_timer.h" /* caller is assumed to be well-behaved and passing NUL terminated strings */ int @@ -1434,11 +1437,15 @@ int iscsi_login_rsp(iscsi_session_t *session, iscsi_login_context_t *c) { iscsi_conn_t *conn = &session->conn[c->cid]; + int err; /* read the target's response into the same buffer */ - if (!iscsi_io_recv_pdu(conn, &c->pdu, ISCSI_DIGEST_NONE, c->data, - c->max_data_length, ISCSI_DIGEST_NONE, - c->timeout)) { + err = iscsi_io_recv_pdu(conn, &c->pdu, ISCSI_DIGEST_NONE, c->data, + c->max_data_length, ISCSI_DIGEST_NONE, + c->timeout); + if (err == -EAGAIN) { + goto done; + } else if (err < 0) { /* * FIXME: caller might want us to distinguish I/O * error and timeout. Might want to switch portals on @@ -1449,6 +1456,7 @@ iscsi_login_rsp(iscsi_session_t *session goto done; } + err = -EIO; c->received_pdu = 1; /* check the PDU response type */ @@ -1490,7 +1498,7 @@ iscsi_login_rsp(iscsi_session_t *session if (c->ret == LOGIN_OK) c->ret = LOGIN_FAILED; } - return 1; + return err; } /** @@ -1514,7 +1522,9 @@ iscsi_login(iscsi_session_t *session, in { iscsi_conn_t *conn = &session->conn[cid]; iscsi_login_context_t *c = &conn->login_context; - int ret; + struct timeval connection_timer; + struct pollfd pfd; + int ret, timeout; /* * assume iscsi_login is only called from discovery, so it is @@ -1532,15 +1542,63 @@ iscsi_login(iscsi_session_t *session, in do { if (iscsi_login_req(session, c)) return c->ret; - ret = iscsi_login_rsp(session, c); - if (status_class) - *status_class = c->status_class; - if (status_detail) - *status_detail = c->status_detail; + /* + * TODO: merge the poll and req/rsp code with the discovery + * poll and text req/rsp. + */ + iscsi_timer_set(&connection_timer, + session->conn[0].active_timeout); + timeout = iscsi_timer_msecs_until(&connection_timer); + + memset(&pfd, 0, sizeof (pfd)); + pfd.fd = conn->socket_fd; + pfd.events = POLLIN | POLLPRI; + +repoll: + pfd.revents = 0; + ret = poll(&pfd, 1, timeout); + log_debug(7, "%s: Poll return %d\n", __FUNCTION__, ret); + if (iscsi_timer_expired(&connection_timer)) { + log_warning("Login response timeout. Waited %d " + "seconds and did not get reponse PDU.\n", + session->conn[0].active_timeout); + c->ret = LOGIN_FAILED; + return c->ret; + } + + if (ret > 0) { + if (pfd.revents & (POLLIN | POLLPRI)) { + ret = iscsi_login_rsp(session, c); + if (ret == -EAGAIN) + goto repoll; + + if (status_class) + *status_class = c->status_class; + if (status_detail) + *status_detail = c->status_detail; + + if (ret) + return c->ret; + } else if (pfd.revents & POLLHUP) { + log_warning("Login POLLHUP"); + c->ret = LOGIN_FAILED; + return c->ret; + } else if (pfd.revents & POLLNVAL) { + log_warning("Login POLLNVAL"); + c->ret = LOGIN_IO_ERROR; + return c->ret; + } else if (pfd.revents & POLLERR) { + log_warning("Login POLLERR"); + c->ret = LOGIN_IO_ERROR; + return c->ret; + } - if (ret) + } else if (ret < 0) { + log_error("Login poll error.\n"); + c->ret = LOGIN_FAILED; return c->ret; + } } while (conn->current_stage != ISCSI_FULL_FEATURE_PHASE); c->ret = LOGIN_OK; 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/Makefile 2011-02-24 19:54:10.000000000 -0600 @@ -37,12 +37,13 @@ PROGRAMS = iscsid iscsiadm iscsistart # libc compat files SYSDEPS_SRCS = $(wildcard ../utils/sysdeps/*.o) # sources shared between iscsid, iscsiadm and iscsistart -ISCSI_LIB_SRCS = iscsi_util.o io.o auth.o login.o log.o md5.o sha1.o iface.o \ - idbm.o sysfs.o host.o session_info.o iscsi_sysfs.o iscsi_net_util.o \ - iscsid_req.o $(SYSDEPS_SRCS) +ISCSI_LIB_SRCS = iscsi_util.o io.o auth.o iscsi_timer.o login.o log.o md5.o \ + sha1.o iface.o idbm.o sysfs.o host.o session_info.o iscsi_sysfs.o \ + iscsi_net_util.o iscsid_req.o transport.o cxgbi.o be2iscsi.o \ + initiator_common.o iscsi_err.o $(IPC_OBJ) $(SYSDEPS_SRCS) # core initiator files -INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o \ - transport.o cxgb3i.o be2iscsi.o +INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o + # fw boot files FW_BOOT_SRCS = $(wildcard ../utils/fwparam_ibft/*.o) @@ -51,14 +52,14 @@ DISCOVERY_SRCS = $(FW_BOOT_SRCS) strings all: $(PROGRAMS) -iscsid: $(ISCSI_LIB_SRCS) $(IPC_OBJ) $(INITIATOR_SRCS) $(DISCOVERY_SRCS) \ +iscsid: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(DISCOVERY_SRCS) \ iscsid.o session_mgmt.o discoveryd.o $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns -lcrypto iscsiadm: $(ISCSI_LIB_SRCS) $(DISCOVERY_SRCS) iscsiadm.o session_mgmt.o $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns -lcrypto -iscsistart: $(IPC_OBJ) $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(FW_BOOT_SRCS) \ +iscsistart: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(FW_BOOT_SRCS) \ iscsistart.o statics.o $(CC) $(CFLAGS) -static $^ -o $@ clean: diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/mgmt_ipc.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/mgmt_ipc.c 2011-02-24 19:54:10.000000000 -0600 @@ -35,6 +35,7 @@ #include "transport.h" #include "sysdeps.h" #include "iscsi_ipc.h" +#include "iscsi_err.h" #define PEERUSER_MAX 64 #define EXTMSG_MAX (64 * 1024) @@ -79,13 +80,13 @@ mgmt_ipc_close(int fd) close(fd); } -static mgmt_ipc_err_e +static int mgmt_ipc_session_login(queue_task_t *qtask) { return session_login_task(&qtask->req.u.session.rec, qtask); } -static mgmt_ipc_err_e +static int mgmt_ipc_session_getstats(queue_task_t *qtask) { int sid = qtask->req.u.session.sid; @@ -93,7 +94,7 @@ mgmt_ipc_session_getstats(queue_task_t * int rc; if (!(session = session_find_by_sid(sid))) - return MGMT_IPC_ERR_NOT_FOUND; + return ISCSI_ERR_SESS_NOT_FOUND; rc = ipc->get_stats(session->t->handle, session->id, session->conn[0].id, @@ -102,33 +103,33 @@ mgmt_ipc_session_getstats(queue_task_t * if (rc) { log_error("get_stats(): IPC error %d " "session [%02d]", rc, sid); - return MGMT_IPC_ERR_INTERNAL; + return ISCSI_ERR_INTERNAL; } - mgmt_ipc_write_rsp(qtask, MGMT_IPC_OK); - return MGMT_IPC_OK; + mgmt_ipc_write_rsp(qtask, ISCSI_SUCCESS); + return ISCSI_SUCCESS; } -static mgmt_ipc_err_e +static int mgmt_ipc_send_targets(queue_task_t *qtask) { iscsiadm_req_t *req = &qtask->req; - mgmt_ipc_err_e err; + int err; err = iscsi_host_send_targets(qtask, req->u.st.host_no, req->u.st.do_login, &req->u.st.ss); mgmt_ipc_write_rsp(qtask, err); - return MGMT_IPC_OK; + return ISCSI_SUCCESS; } -static mgmt_ipc_err_e +static int mgmt_ipc_session_logout(queue_task_t *qtask) { return session_logout_task(qtask->req.u.session.sid, qtask); } -static mgmt_ipc_err_e +static int mgmt_ipc_session_sync(queue_task_t *qtask) { struct ipc_msg_session *session= &qtask->req.u.session; @@ -136,16 +137,16 @@ mgmt_ipc_session_sync(queue_task_t *qtas return iscsi_sync_session(&session->rec, qtask, session->sid); } -static mgmt_ipc_err_e +static int mgmt_ipc_cfg_initiatorname(queue_task_t *qtask) { if (dconfig->initiator_name) strcpy(qtask->rsp.u.config.var, dconfig->initiator_name); - mgmt_ipc_write_rsp(qtask, MGMT_IPC_OK); - return MGMT_IPC_OK; + mgmt_ipc_write_rsp(qtask, ISCSI_SUCCESS); + return ISCSI_SUCCESS; } -static mgmt_ipc_err_e +static int mgmt_ipc_session_info(queue_task_t *qtask) { int sid = qtask->req.u.session.sid; @@ -154,61 +155,50 @@ mgmt_ipc_session_info(queue_task_t *qtas if (!(session = session_find_by_sid(sid))) { log_debug(1, "session with sid %d not found!", sid); - return MGMT_IPC_ERR_NOT_FOUND; + return ISCSI_ERR_SESS_NOT_FOUND; } info = &qtask->rsp.u.session_state; info->conn_state = session->conn[0].state; info->session_state = session->r_stage; - mgmt_ipc_write_rsp(qtask, MGMT_IPC_OK); - return MGMT_IPC_OK; + mgmt_ipc_write_rsp(qtask, ISCSI_SUCCESS); + return ISCSI_SUCCESS; } -static mgmt_ipc_err_e +static int mgmt_ipc_cfg_initiatoralias(queue_task_t *qtask) { strcpy(qtask->rsp.u.config.var, dconfig->initiator_alias); - mgmt_ipc_write_rsp(qtask, MGMT_IPC_OK); - return MGMT_IPC_OK; + mgmt_ipc_write_rsp(qtask, ISCSI_SUCCESS); + return ISCSI_SUCCESS; } -static mgmt_ipc_err_e +static int mgmt_ipc_cfg_filename(queue_task_t *qtask) { strcpy(qtask->rsp.u.config.var, dconfig->config_file); - mgmt_ipc_write_rsp(qtask, MGMT_IPC_OK); - return MGMT_IPC_OK; + mgmt_ipc_write_rsp(qtask, ISCSI_SUCCESS); + return ISCSI_SUCCESS; } -static mgmt_ipc_err_e +static int mgmt_ipc_conn_add(queue_task_t *qtask) { - return MGMT_IPC_ERR; + return ISCSI_ERR; } -static mgmt_ipc_err_e +static int mgmt_ipc_immediate_stop(queue_task_t *qtask) { event_loop_exit(qtask); - return MGMT_IPC_OK; + return ISCSI_SUCCESS; } -static mgmt_ipc_err_e +static int mgmt_ipc_conn_remove(queue_task_t *qtask) { - return MGMT_IPC_ERR; -} - -static mgmt_ipc_err_e -mgmt_ipc_host_set_param(queue_task_t *qtask) -{ - struct ipc_msg_set_host_param *hp = &qtask->req.u.set_host_param; - int err; - - err = iscsi_host_set_param(hp->host_no, hp->param, hp->value); - mgmt_ipc_write_rsp(qtask, err); - return MGMT_IPC_OK; + return ISCSI_ERR; } /* @@ -263,12 +253,11 @@ again: return argc; } -static mgmt_ipc_err_e -mgmt_ipc_notify_common(queue_task_t *qtask, - mgmt_ipc_err_e (*handler)(int, char **)) +static int +mgmt_ipc_notify_common(queue_task_t *qtask, int (*handler)(int, char **)) { char **argv = NULL; - int argc, err = MGMT_IPC_ERR; + int argc, err = ISCSI_ERR; argc = mgmt_ipc_parse_strings(qtask, &argv); if (argc > 0) @@ -277,54 +266,54 @@ mgmt_ipc_notify_common(queue_task_t *qta if (argv) free(argv); mgmt_ipc_write_rsp(qtask, err); - return MGMT_IPC_OK; + return ISCSI_SUCCESS; } /* Replace these dummies as you implement them elsewhere */ -static mgmt_ipc_err_e +static int iscsi_discovery_add_node(int argc, char **argv) { - return MGMT_IPC_OK; + return ISCSI_SUCCESS; } -static mgmt_ipc_err_e +static int iscsi_discovery_del_node(int argc, char **argv) { - return MGMT_IPC_OK; + return ISCSI_SUCCESS; } -static mgmt_ipc_err_e +static int iscsi_discovery_add_portal(int argc, char **argv) { - return MGMT_IPC_OK; + return ISCSI_SUCCESS; } -static mgmt_ipc_err_e +static int iscsi_discovery_del_portal(int argc, char **argv) { - return MGMT_IPC_OK; + return ISCSI_SUCCESS; } -static mgmt_ipc_err_e +static int mgmt_ipc_notify_add_node(queue_task_t *qtask) { return mgmt_ipc_notify_common(qtask, iscsi_discovery_add_node); } -static mgmt_ipc_err_e +static int mgmt_ipc_notify_del_node(queue_task_t *qtask) { return mgmt_ipc_notify_common(qtask, iscsi_discovery_del_node); } -static mgmt_ipc_err_e +static int mgmt_ipc_notify_add_portal(queue_task_t *qtask) { return mgmt_ipc_notify_common(qtask, iscsi_discovery_add_portal); } -static mgmt_ipc_err_e +static int mgmt_ipc_notify_del_portal(queue_task_t *qtask) { return mgmt_ipc_notify_common(qtask, iscsi_discovery_del_portal); @@ -433,7 +422,7 @@ mgmt_ipc_destroy_queue_task(queue_task_t * is for. */ void -mgmt_ipc_write_rsp(queue_task_t *qtask, mgmt_ipc_err_e err) +mgmt_ipc_write_rsp(queue_task_t *qtask, int err) { if (!qtask) return; @@ -510,7 +499,6 @@ static mgmt_ipc_fn_t * mgmt_ipc_function [MGMT_IPC_CONFIG_IALIAS] = mgmt_ipc_cfg_initiatoralias, [MGMT_IPC_CONFIG_FILE] = mgmt_ipc_cfg_filename, [MGMT_IPC_IMMEDIATE_STOP] = mgmt_ipc_immediate_stop, -[MGMT_IPC_SET_HOST_PARAM] = mgmt_ipc_host_set_param, [MGMT_IPC_NOTIFY_ADD_NODE] = mgmt_ipc_notify_add_node, [MGMT_IPC_NOTIFY_DEL_NODE] = mgmt_ipc_notify_del_node, [MGMT_IPC_NOTIFY_ADD_PORTAL] = mgmt_ipc_notify_add_portal, @@ -538,7 +526,7 @@ void mgmt_ipc_handle(int accept_fd) qtask->mgmt_ipc_fd = fd; if (!mgmt_peeruser(fd, user) || strncmp(user, "root", PEERUSER_MAX)) { - err = MGMT_IPC_ERR_ACCESS; + err = ISCSI_ERR_ACCESS; goto err; } @@ -556,12 +544,12 @@ void mgmt_ipc_handle(int accept_fd) /* If the handler returns OK, this means it * already sent the reply. */ err = handler(qtask); - if (err == MGMT_IPC_OK) + if (err == ISCSI_SUCCESS) return; } else { log_error("unknown request: %s(%d) %u", __FUNCTION__, __LINE__, command); - err = MGMT_IPC_ERR_INVALID_REQ; + err = ISCSI_ERR_INVALID_MGMT_REQ; } err: diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.h open-iscsi-2.0-872-rc4-bnx2i.work/usr/mgmt_ipc.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/mgmt_ipc.h 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/mgmt_ipc.h 2011-02-24 19:54:10.000000000 -0600 @@ -26,30 +26,6 @@ #define ISCSIADM_NAMESPACE "ISCSIADM_ABSTRACT_NAMESPACE" #define PEERUSER_MAX 64 -typedef enum mgmt_ipc_err { - MGMT_IPC_OK = 0, - MGMT_IPC_ERR = 1, - MGMT_IPC_ERR_NOT_FOUND = 2, - MGMT_IPC_ERR_NOMEM = 3, - MGMT_IPC_ERR_TRANS_FAILURE = 4, - MGMT_IPC_ERR_LOGIN_FAILURE = 5, - MGMT_IPC_ERR_IDBM_FAILURE = 6, - MGMT_IPC_ERR_INVAL = 7, - MGMT_IPC_ERR_TRANS_TIMEOUT = 8, - MGMT_IPC_ERR_INTERNAL = 9, - MGMT_IPC_ERR_LOGOUT_FAILURE = 10, - MGMT_IPC_ERR_PDU_TIMEOUT = 11, - MGMT_IPC_ERR_TRANS_NOT_FOUND = 12, - MGMT_IPC_ERR_ACCESS = 13, - MGMT_IPC_ERR_TRANS_CAPS = 14, - MGMT_IPC_ERR_EXISTS = 15, - MGMT_IPC_ERR_INVALID_REQ = 16, - MGMT_IPC_ERR_ISNS_UNAVAILABLE = 17, - MGMT_IPC_ERR_ISCSID_COMM_ERR = 18, - MGMT_IPC_ERR_FATAL_LOGIN_FAILURE = 19, - MGMT_IPC_ERR_ISCSID_NOTCONN = 20, -} mgmt_ipc_err_e; - typedef enum iscsiadm_cmd { MGMT_IPC_UNKNOWN = 0, MGMT_IPC_SESSION_LOGIN = 1, @@ -66,11 +42,10 @@ typedef enum iscsiadm_cmd { MGMT_IPC_SESSION_INFO = 13, MGMT_IPC_ISNS_DEV_ATTR_QUERY = 14, MGMT_IPC_SEND_TARGETS = 15, - MGMT_IPC_SET_HOST_PARAM = 16, - MGMT_IPC_NOTIFY_ADD_NODE = 17, - MGMT_IPC_NOTIFY_DEL_NODE = 18, - MGMT_IPC_NOTIFY_ADD_PORTAL = 19, - MGMT_IPC_NOTIFY_DEL_PORTAL = 20, + MGMT_IPC_NOTIFY_ADD_NODE = 16, + MGMT_IPC_NOTIFY_DEL_NODE = 17, + MGMT_IPC_NOTIFY_ADD_PORTAL = 18, + MGMT_IPC_NOTIFY_DEL_PORTAL = 19, __MGMT_IPC_MAX_COMMAND } iscsiadm_cmd_e; @@ -108,7 +83,7 @@ typedef struct iscsiadm_req { /* IPC Response */ typedef struct iscsiadm_rsp { iscsiadm_cmd_e command; - mgmt_ipc_err_e err; + int err; /* ISCSI_ERR value */ union { #define MGMT_IPC_GETSTATS_BUF_MAX (sizeof(struct iscsi_uevent) + \ @@ -132,10 +107,10 @@ typedef struct iscsiadm_rsp { } iscsiadm_rsp_t; struct queue_task; -typedef mgmt_ipc_err_e mgmt_ipc_fn_t(struct queue_task *); +typedef int mgmt_ipc_fn_t(struct queue_task *); struct queue_task; -void mgmt_ipc_write_rsp(struct queue_task *qtask, mgmt_ipc_err_e err); +void mgmt_ipc_write_rsp(struct queue_task *qtask, int err); int mgmt_ipc_listen(void); void mgmt_ipc_close(int fd); void mgmt_ipc_handle(int accept_fd); 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/netlink.c 2011-02-24 19:54:10.000000000 -0600 @@ -33,7 +33,6 @@ #include "types.h" #include "iscsi_if.h" -#include "iscsid.h" #include "log.h" #include "iscsi_ipc.h" #include "initiator.h" @@ -50,6 +49,7 @@ static void *nlm_sendbuf; static void *nlm_recvbuf; static void *pdu_sendbuf; static void *setparam_buf; +static struct iscsi_ipc_ev_clbk *ipc_ev_clbk; static int ctldev_handle(void); @@ -66,7 +66,8 @@ static int ctldev_handle(void); static int kread(char *data, int count) { - log_debug(7, "in %s", __FUNCTION__); + log_debug(7, "in %s %u %u %p %p", __FUNCTION__, recvlen, count, + data, recvbuf); memcpy(data, recvbuf + recvlen, count); recvlen += count; @@ -142,7 +143,8 @@ nlpayload_read(int ctrl_fd, char *data, */ rc = recvmsg(ctrl_fd, &msg, flags); - memcpy(data, NLMSG_DATA(iov.iov_base), count); + if (data) + memcpy(data, NLMSG_DATA(iov.iov_base), count); return rc; } @@ -716,18 +718,34 @@ kstart_conn(uint64_t transport_handle, u static int krecv_pdu_begin(struct iscsi_conn *conn) { + int rc; + log_debug(7, "in %s", __FUNCTION__); if (recvbuf) { log_error("recv's begin state machine bug?"); return -EIO; } + + if (!conn->recv_context) { + rc = ipc->ctldev_handle(); + if (rc == -ENXIO) + /* event for some other conn */ + return -EAGAIN; + else if (rc < 0) + /* fatal handling error or conn error */ + return rc; + /* + * Session create/destroy event for another conn + */ + if (!conn->recv_context) + return -EAGAIN; + } + recvbuf = conn->recv_context->data + sizeof(struct iscsi_uevent); recvlen = 0; - log_debug(3, "recv PDU began, pdu handle 0x%p", - recvbuf); - + log_debug(3, "recv PDU began, pdu handle %p", recvbuf); return 0; } @@ -744,7 +762,7 @@ krecv_pdu_end(struct iscsi_conn *conn) log_debug(3, "recv PDU finished for pdu handle 0x%p", recvbuf); - iscsi_conn_context_put(conn->recv_context); + ipc_ev_clbk->put_ev_context(conn->recv_context); conn->recv_context = NULL; recvbuf = NULL; return 0; @@ -894,7 +912,7 @@ static void drop_data(struct nlmsghdr *n int ev_size; ev_size = nlh->nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr)); - nlpayload_read(ctrl_fd, setparam_buf, ev_size, 0); + nlpayload_read(ctrl_fd, NULL, ev_size, 0); } static int ctldev_handle(void) @@ -905,7 +923,7 @@ static int ctldev_handle(void) iscsi_conn_t *conn = NULL; char nlm_ev[NLMSG_SPACE(sizeof(struct iscsi_uevent))]; struct nlmsghdr *nlh; - struct iscsi_conn_context *conn_context; + struct iscsi_ev_context *ev_context; uint32_t sid = 0, cid = 0; log_debug(7, "in %s", __FUNCTION__); @@ -925,13 +943,15 @@ static int ctldev_handle(void) /* old kernels sent ISCSI_UEVENT_CREATE_SESSION on creation */ case ISCSI_UEVENT_CREATE_SESSION: drop_data(nlh); - iscsi_async_session_creation(ev->r.c_session_ret.host_no, - ev->r.c_session_ret.sid); + if (ipc_ev_clbk->create_session) + ipc_ev_clbk->create_session(ev->r.c_session_ret.host_no, + ev->r.c_session_ret.sid); return 0; case ISCSI_KEVENT_DESTROY_SESSION: drop_data(nlh); - iscsi_async_session_destruction(ev->r.d_session.host_no, - ev->r.d_session.sid); + if (ipc_ev_clbk->destroy_session) + ipc_ev_clbk->destroy_session(ev->r.d_session.host_no, + ev->r.d_session.sid); return 0; case ISCSI_KEVENT_RECV_PDU: sid = ev->r.recv_req.sid; @@ -947,16 +967,30 @@ static int ctldev_handle(void) cid = 0; break; default: - log_error("Unknown kernel event %d. You may want to upgrade " - "your iscsi tools.", ev->type); + if ((ev->type > ISCSI_UEVENT_MAX && ev->type < KEVENT_BASE) || + (ev->type > ISCSI_KEVENT_MAX)) + log_error("Unknown kernel event %d. You may want to " + " upgrade your iscsi tools.", ev->type); + else + /* + * If another app is using the interface we might + * see their + * stuff. Just drop it. + */ + log_debug(7, "Got unknwon event %d. Dropping.", + ev->type); drop_data(nlh); - return -EINVAL; + return 0; } /* verify connection */ session = session_find_by_sid(sid); if (!session) { - log_error("Could not verify connection %d:%d. Dropping " + /* + * this can happen normally when other apps are using the + * nl interface. + */ + log_debug(1, "Could not verify connection %d:%d. Dropping " "event.\n", sid, cid); drop_data(nlh); return -ENXIO; @@ -964,19 +998,20 @@ static int ctldev_handle(void) conn = &session->conn[0]; ev_size = nlh->nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr)); - conn_context = iscsi_conn_context_get(conn, ev_size); - if (!conn_context) { + + ev_context = ipc_ev_clbk->get_ev_context(conn, ev_size); + if (!ev_context) { /* retry later */ log_error("Can not allocate memory for receive context."); return -ENOMEM; } log_debug(6, "message real length is %d bytes, recv_handle %p", - nlh->nlmsg_len, conn_context->data); + nlh->nlmsg_len, ev_context->data); - if ((rc = nlpayload_read(ctrl_fd, conn_context->data, + if ((rc = nlpayload_read(ctrl_fd, ev_context->data, ev_size, 0)) < 0) { - iscsi_conn_context_put(conn_context); + ipc_ev_clbk->put_ev_context(ev_context); log_error("can not read from NL socket, error %d", rc); /* retry later */ return rc; @@ -988,26 +1023,28 @@ static int ctldev_handle(void) */ switch (ev->type) { case ISCSI_KEVENT_RECV_PDU: - iscsi_sched_conn_context(conn_context, conn, 0, - EV_CONN_RECV_PDU); + rc = ipc_ev_clbk->sched_ev_context(ev_context, conn, 0, + EV_CONN_RECV_PDU); break; case ISCSI_KEVENT_CONN_ERROR: - memcpy(conn_context->data, &ev->r.connerror.error, + memcpy(ev_context->data, &ev->r.connerror.error, sizeof(ev->r.connerror.error)); - iscsi_sched_conn_context(conn_context, conn, 0, - EV_CONN_ERROR); + rc = ipc_ev_clbk->sched_ev_context(ev_context, conn, 0, + EV_CONN_ERROR); break; case ISCSI_KEVENT_UNBIND_SESSION: - iscsi_sched_conn_context(conn_context, conn, 0, - EV_CONN_STOP); + rc = ipc_ev_clbk->sched_ev_context(ev_context, conn, 0, + EV_CONN_STOP); break; default: - iscsi_conn_context_put(conn_context); + ipc_ev_clbk->put_ev_context(ev_context); log_error("unknown kernel event %d", ev->type); return -EEXIST; } - return 0; + if (rc) + ipc_ev_clbk->put_ev_context(ev_context); + return rc; } static int @@ -1116,3 +1153,8 @@ struct iscsi_ipc nl_ipc = { .recv_pdu_end = krecv_pdu_end, }; struct iscsi_ipc *ipc = &nl_ipc; + +void ipc_register_ev_callback(struct iscsi_ipc_ev_clbk *ev_clbk) +{ + ipc_ev_clbk = ev_clbk; +} diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_info.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_info.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/session_info.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_info.c 2011-02-24 19:54:10.000000000 -0600 @@ -13,6 +13,7 @@ #include "initiator.h" #include "iface.h" #include "iscsid_req.h" +#include "iscsi_err.h" int session_info_create_list(void *data, struct session_info *info) { @@ -25,7 +26,7 @@ int session_info_create_list(void *data, new = calloc(1, sizeof(*new)); if (!new) - return ENOMEM; + return ISCSI_ERR_NOMEM; memcpy(new, info, sizeof(*new)); INIT_LIST_HEAD(&new->list); @@ -346,13 +347,15 @@ int session_info_print(int info_level, s break; default: log_error("Invalid info level %d. Try 0 - 3.", info_level); - return EINVAL; + return ISCSI_ERR_INVAL; } if (err) { log_error("Can not get list of active sessions (%d)", err); return err; - } else if (!num_found) + } else if (!num_found) { log_error("No active sessions."); + return ISCSI_ERR_NO_OBJS_FOUND; + } return 0; } diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.c open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_mgmt.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/session_mgmt.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/session_mgmt.c 2011-02-24 19:54:10.000000000 -0600 @@ -32,6 +32,7 @@ #include "iscsi_sysfs.h" #include "log.h" #include "iscsid_req.h" +#include "iscsi_err.h" static void log_login_msg(struct node_rec *rec, int rc) { @@ -40,7 +41,7 @@ static void log_login_msg(struct node_re "portal: %s,%d].", rec->iface.name, rec->name, rec->conn[0].address, rec->conn[0].port); - iscsid_handle_error(rc); + iscsi_err_print_msg(rc); } else log_info("Login to [iface: %s, target: %s, portal: " "%s,%d] successful.", rec->iface.name, @@ -82,6 +83,8 @@ static int iscsid_login_reqs_wait(struct rec = curr->data; err = iscsid_req_wait(MGMT_IPC_SESSION_LOGIN, curr->fd); + if (err && !ret) + ret = err; log_login_msg(rec, err); list_del(&curr->list); free(curr); @@ -123,11 +126,7 @@ int iscsi_login_portal(void *data, struc log_login_msg(rec, rc); if (async_req) free(async_req); - /* we raced with another app or instance of iscsiadm */ - if (rc == MGMT_IPC_ERR_EXISTS) - return 0; - - return ENOTCONN; + return rc; } if (async_req) { @@ -191,7 +190,6 @@ int iscsi_login_portals(void *data, int if (!err) (*nr_found)++; } - if (wait) { err = iscsid_login_reqs_wait(&login_list); if (err && !ret) @@ -213,7 +211,7 @@ static void log_logout_msg(struct sessio "portal: %s,%d].", info->sid, info->targetname, info->persistent_address, info->port); - iscsid_handle_error(rc); + iscsi_err_print_msg(rc); } else log_info("Logout of [sid: %d, target: %s, " "portal: %s,%d] successful.", @@ -277,11 +275,7 @@ int iscsi_logout_portal(struct session_i log_logout_msg(info, rc); if (async_req) free(async_req); - - if (rc == MGMT_IPC_ERR_NOT_FOUND) - return 0; - - return EIO; + return rc; } if (async_req) { @@ -325,10 +319,17 @@ int iscsi_logout_portals(void *data, int err = iscsi_sysfs_for_each_session(&link_info, nr_found, session_info_create_list); - if (err || !*nr_found) + if (err && !list_empty(&session_list)) + log_error("Could not read in all sessions: %s", + iscsi_err_to_str(err)); + else if (err && list_empty(&session_list)) { + log_error("Could not read session info."); return err; - + } else if (list_empty(&session_list)) + return ISCSI_ERR_NO_OBJS_FOUND; + ret = err; *nr_found = 0; + list_for_each_entry(curr_info, &session_list, list) { err = logout_fn(data, &logout_list, curr_info); if (err > 0 && !ret) @@ -337,13 +338,22 @@ int iscsi_logout_portals(void *data, int (*nr_found)++; } + if (!*nr_found) { + ret = ISCSI_ERR_NO_OBJS_FOUND; + goto free_list; + } + if (wait) { err = iscsid_logout_reqs_wait(&logout_list); - if (err) + if (err && !ret) ret = err; } else iscsid_reqs_close(&logout_list); + if (ret) + log_error("Could not logout of all requested sessions"); + +free_list: session_info_free_list(&session_list); return ret; } 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/usr/transport.c 2011-02-24 19:54:10.000000000 -0600 @@ -25,7 +25,7 @@ #include "log.h" #include "iscsi_util.h" #include "iscsi_sysfs.h" -#include "cxgb3i.h" +#include "cxgbi.h" #include "be2iscsi.h" struct iscsi_transport_template iscsi_tcp = { @@ -49,7 +49,16 @@ struct iscsi_transport_template cxgb3i = .ep_connect = ktransport_ep_connect, .ep_poll = ktransport_ep_poll, .ep_disconnect = ktransport_ep_disconnect, - .create_conn = cxgb3i_create_conn, + .create_conn = cxgbi_create_conn, +}; + +struct iscsi_transport_template cxgb4i = { + .name = "cxgb4i", + .set_host_ip = 1, + .ep_connect = ktransport_ep_connect, + .ep_poll = ktransport_ep_poll, + .ep_disconnect = ktransport_ep_disconnect, + .create_conn = cxgbi_create_conn, }; struct iscsi_transport_template bnx2i = { @@ -76,6 +85,7 @@ static struct iscsi_transport_template * &iscsi_tcp, &iscsi_iser, &cxgb3i, + &cxgb4i, &bnx2i, &qla4xxx, &be2iscsi, @@ -97,6 +107,7 @@ int set_transport_template(struct iscsi_ } } - log_error("Could not find uspace transport for %s\n", t->name); + log_error("Could not find template for %s. An updated iscsiadm " + "is probably needed.\n", t->name); return ENOSYS; } 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 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fw_entry.c 2011-02-24 19:54:10.000000000 -0600 @@ -34,6 +34,7 @@ #include "fwparam.h" #include "idbm_fields.h" #include "iscsi_net_util.h" +#include "iscsi_err.h" /** * fw_setup_nics - setup nics (ethXs) based on ibft net info @@ -56,7 +57,7 @@ int fw_setup_nics(void) ret = fw_get_targets(&targets); if (ret || list_empty(&targets)) { printf("Could not setup fw entries.\n"); - return ENODEV; + return ISCSI_ERR_NO_OBJS_FOUND; } /* @@ -85,7 +86,10 @@ int fw_setup_nics(void) } fw_free_targets(&targets); - return ret; + if (ret) + return ISCSI_ERR; + else + return 0; } /** diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_ppc.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fwparam_ppc.c --- open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_ppc.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fwparam_ppc.c 2011-02-24 19:54:10.000000000 -0600 @@ -30,6 +30,7 @@ #include "iscsi_obp.h" #include "prom_parse.h" #include "sysdeps.h" +#include "iscsi_err.h" void* yy_scan_string(const char *str); int yyparse(struct ofw_dev *ofwdev); @@ -449,7 +450,7 @@ int fwparam_ppc_boot_info(struct boot_co devtree = find_devtree(filename); if (!devtree) - return EINVAL; + return ISCSI_ERR_INVAL; /* * Always search the device-tree to find the capable nic devices. @@ -459,7 +460,7 @@ int fwparam_ppc_boot_info(struct boot_co goto free_devtree; if (find_file(filename) < 1) - error = ENODEV; + error = ISCSI_ERR_NO_OBJS_FOUND; else { if (debug) printf("%s:\n%s\n\n", filename, bootpath_val); @@ -469,12 +470,12 @@ int fwparam_ppc_boot_info(struct boot_co */ if (!strstr(bootpath_val, "iscsi")) { - error = EINVAL; + error = ISCSI_ERR_INVAL; goto free_devtree; } ofwdevs[0] = calloc(1, sizeof(struct ofw_dev)); if (!ofwdevs[0]) { - error = ENOMEM; + error = ISCSI_ERR_NOMEM; goto free_devtree; } @@ -484,7 +485,7 @@ int fwparam_ppc_boot_info(struct boot_co if (!error) { context = calloc(1, sizeof(*context)); if (!context) - error = ENOMEM; + error = ISCSI_ERR_NOMEM; else fill_context(context, ofwdevs[0]); } @@ -524,7 +525,7 @@ int fwparam_ppc_get_targets(struct list_ devtree = find_devtree(filename); if (!devtree) - return EINVAL; + return ISCSI_ERR_INVAL; /* * Always search the device-tree to find the capable nic devices. @@ -534,7 +535,7 @@ int fwparam_ppc_get_targets(struct list_ goto free_devtree; if (find_file(filename) < 1) - error = ENODEV; + error = ISCSI_ERR_NO_OBJS_FOUND; else { if (debug) printf("%s:\n%s\n\n", filename, bootpath_val); @@ -544,12 +545,12 @@ int fwparam_ppc_get_targets(struct list_ */ if (!strstr(bootpath_val, "iscsi")) { - error = EINVAL; + error = ISCSI_ERR_INVAL; goto free_devtree; } ofwdevs[0] = calloc(1, sizeof(struct ofw_dev)); if (!ofwdevs[0]) { - error = ENOMEM; + error = ISCSI_ERR_NOMEM; goto free_devtree; } @@ -559,7 +560,7 @@ int fwparam_ppc_get_targets(struct list_ if (!error) { context = calloc(1, sizeof(*context)); if (!context) - error = ENOMEM; + error = ISCSI_ERR_NOMEM; else { fill_context(context, ofwdevs[0]); list_add_tail(&context->list, list); diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_sysfs.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fwparam_sysfs.c --- open-iscsi-2.0-872-rc4-bnx2i/utils/fwparam_ibft/fwparam_sysfs.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/fwparam_ibft/fwparam_sysfs.c 2011-02-24 19:54:21.000000000 -0600 @@ -36,6 +36,7 @@ #include "fwparam.h" #include "sysdeps.h" #include "iscsi_net_util.h" +#include "iscsi_err.h" #define ISCSI_BOOT_MAX 255 #define IBFT_SYSFS_ROOT "/sys/firmware/ibft/" @@ -351,7 +352,7 @@ int fwparam_sysfs_boot_info(struct boot_ */ dirfd = opendir(ISCSI_LLD_ROOT); if (!dirfd) - return errno; + return ISCSI_ERR_SYSFS_LOOKUP; while ((dent = readdir(dirfd))) { char lld_root[FILENAMESZ]; @@ -364,12 +365,12 @@ int fwparam_sysfs_boot_info(struct boot_ if (strncmp(dent->d_name, ISCSI_LLD_SUBSYS_PREFIX, 10)) continue; - snprintf(lld_root, FILENAMESZ, ISCSI_LLD_ROOT"%s", + snprintf(lld_root, FILENAMESZ, ISCSI_LLD_ROOT"%s/", dent->d_name); if (!get_boot_info(context, lld_root, dent->d_name)) goto done; } - rc = ENODEV; + rc = ISCSI_ERR_NO_OBJS_FOUND; done: closedir(dirfd); return rc; @@ -401,12 +402,12 @@ static int get_targets(struct list_head rc = fill_tgt_context(subsys, target_list[i], context); if (rc) - break; + goto cleanup; rc = sysfs_get_int(target_list[i], subsys, "nic-assoc", &nic_idx); if (rc) - break; + goto cleanup; for (nic = 0; nic < nic_cnt; nic++) { int id; @@ -420,21 +421,31 @@ static int get_targets(struct list_head if (nic == nic_cnt) { printf("Invalid nic-assoc of %d. Max id %d.\n", nic_idx, nic_cnt); - break; + goto cleanup; } rc = fill_nic_context(subsys, nic_list[nic], context); if (rc) - break; + goto cleanup; fill_initiator_context(subsys, context); list_add_tail(&context->list, list); + continue; +cleanup: + free(context); + context = NULL; } if (rc) { if (context) free(context); - fw_free_targets(list); + /* + * If there are some valid targets return them. Most likely, + * the driver/ibft-implementation reported partial info + * for targets/initiators that were not used for boot. + */ + if (!list_empty(list)) + rc = 0; } deallocate_lists(); @@ -455,7 +466,7 @@ int fwparam_sysfs_get_targets(struct lis */ dirfd = opendir(ISCSI_LLD_ROOT); if (!dirfd) { - rc = errno; + rc = ISCSI_ERR_SYSFS_LOOKUP; goto done; } @@ -463,21 +474,20 @@ int fwparam_sysfs_get_targets(struct lis char lld_root[FILENAMESZ]; memset(&lld_root, 0 , FILENAMESZ); - if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) continue; if (strncmp(dent->d_name, ISCSI_LLD_SUBSYS_PREFIX, 10)) continue; - snprintf(lld_root, FILENAMESZ, ISCSI_LLD_ROOT"%s", + snprintf(lld_root, FILENAMESZ, ISCSI_LLD_ROOT"%s/", dent->d_name); get_targets(list, lld_root, dent->d_name); } closedir(dirfd); done: if (!rc && list_empty(list)) - rc = ENODEV; + rc = ISCSI_ERR_NO_OBJS_FOUND; if (rc) fw_free_targets(list); return rc; diff -Naurp open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/socket.c open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/socket.c --- open-iscsi-2.0-872-rc4-bnx2i/utils/open-isns/socket.c 2010-07-11 04:05:58.000000000 -0500 +++ open-iscsi-2.0-872-rc4-bnx2i.work/utils/open-isns/socket.c 2011-02-24 19:54:10.000000000 -0600 @@ -805,7 +805,7 @@ isns_net_stream_xmit(isns_socket_t *sock void isns_net_stream_hup(isns_socket_t *sock) { - sock->is_poll_mask &= ~POLLIN; + sock->is_poll_mask &= ~(POLLIN|POLLOUT); /* POLLHUP while connecting means we failed */ if (sock->is_state == ISNS_SOCK_CONNECTING) isns_net_stream_error(sock, ECONNREFUSED);