summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--Changelog89
-rw-r--r--Makefile1
-rw-r--r--README75
-rw-r--r--TODO13
-rw-r--r--doc/iscsiadm.8115
-rw-r--r--doc/iscsid.823
-rw-r--r--etc/iscsid.conf4
-rw-r--r--etc/systemd/iscsi-init.service8
-rw-r--r--etc/systemd/iscsi.service8
-rw-r--r--etc/systemd/iscsid.service1
-rw-r--r--etc/systemd/iscsiuio.service1
-rw-r--r--include/iscsi_if.h4
-rw-r--r--iscsiuio/src/uip/ipv6.c2
-rw-r--r--iscsiuio/src/uip/uip.c43
-rw-r--r--iscsiuio/src/unix/iscsid_ipc.c3
-rw-r--r--iscsiuio/src/unix/libs/bnx2x.c7
-rw-r--r--iscsiuio/src/unix/libs/qedi.c7
-rw-r--r--iscsiuio/src/unix/nic_nl.c2
-rw-r--r--iscsiuio/src/unix/nic_utils.c20
-rw-r--r--libopeniscsiusr/Makefile3
-rw-r--r--libopeniscsiusr/context.c6
-rw-r--r--libopeniscsiusr/idbm.c2
-rw-r--r--libopeniscsiusr/node.c9
-rw-r--r--libopeniscsiusr/session.c2
-rw-r--r--libopeniscsiusr/version.h2
-rw-r--r--test/harness/util.py4
-rw-r--r--usr/auth.c56
-rw-r--r--usr/discovery.c2
-rw-r--r--usr/event_poll.c2
-rw-r--r--usr/idbm.c45
-rw-r--r--usr/idbm.h1
-rw-r--r--usr/iface.c3
-rw-r--r--usr/initiator.c11
-rw-r--r--usr/io.c2
-rw-r--r--usr/iscsi_net_util.c6
-rw-r--r--usr/iscsi_sysfs.c20
-rw-r--r--usr/iscsi_sysfs.h1
-rw-r--r--usr/iscsi_util.c7
-rw-r--r--usr/iscsiadm.c165
-rw-r--r--usr/iscsid.c28
-rw-r--r--usr/iscsid_req.c2
-rw-r--r--usr/iscsistart.c6
-rw-r--r--usr/log.c8
-rw-r--r--usr/mgmt_ipc.c6
-rw-r--r--usr/netlink.c2
-rw-r--r--usr/statics.c3
-rw-r--r--usr/sysfs.c12
-rw-r--r--usr/version.h2
-rw-r--r--utils/Makefile2
-rw-r--r--utils/fwparam_ibft/fwparam_ibft.c1
-rw-r--r--utils/fwparam_ibft/fwparam_ppc.c57
-rw-r--r--utils/fwparam_ibft/fwparam_sysfs.c5
-rw-r--r--utils/iscsi-iname.c23
54 files changed, 646 insertions, 291 deletions
diff --git a/.gitignore b/.gitignore
index 2483d0f..21415f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,11 @@
*.o
cscope.files
cscope.out
+cscope.in.out
+cscope.po.out
+GPATH
+GRTAGS
+GTAGS
TAGS
tags
*.swp
diff --git a/Changelog b/Changelog
index 9af7bf1..78ed73e 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,92 @@
+open-iscsi-2.1.2 - open-iscsi-2.1.3
+
+Chris Leech (4):
+ iscsiadm buffer overflow regression when discovering many targets at once
+ check for header length underflow during checksum calculation
+ check for u8 overflow when processing TCP options
+ check for TCP urgent pointer past end of frame
+
+Gulam Mohamed (1):
+ iscsid: Poll timeout value to 1 minute for iscsid
+
+Khem Raj (1):
+ libopeniscsiusr: Compare with max int instead of max long
+
+Lee Duncan (4):
+ Add ability to attempt target logins asynchronously
+ Implement login "no_wait" for iscsiadm NODE mode
+ Updated iscsiadm man page.
+ iscsiadm: fix host stats mode coredump
+
+Wenchao Hao (15):
+ Fix memory leak in sysfs_get_str
+ iscsiadm: Optimize the the verification of mode paramters
+ Update .gitignore for cscope and gtags data base
+ iscsi_sysfs: Fix NULL pointer deference in iscsi_sysfs_read_iface
+ iscsi-iname: Verify open() return value before calling read()
+ iscsiuio: Fix invalid parameter when call fstat()
+ open-iscsi: Fix invalid pointer deference in find_initiator()
+ open-iscsi: Fix NULL pointer dereference in mgmt_ipc_read_req()
+ iscsi_net_util: Fix NULL pointer dereference in find_vlan_dev()
+ open-iscsi: Clean user_param list when process exit
+ fwparam_ppc: Fix NULL pointer dereference in find_devtree()
+ sysfs: Verify parameter of sysfs_device_get()
+ fwparam_ppc: Fix illegal memory access in fwparam_ppc.c
+ iscsiuio: Remove unused macro IFNAMSIZ defined in iscsid_ipc.c
+ fwparam_ppc: Fix memory leak in fwparam_ppc.c
+
+Yoshifumi Kinoshita (1):
+ iscsid: fix logging level when starting and shutting down daemon
+
+gulams (1):
+ iscsid: Check Invalid Session id for stop connection
+
+sonukumar159842@gmail.com (1):
+ TODO: Update to todo list.
+
+open-iscsi-2.1.0 - open-iscsi-2.1.2
+
+Christian Glombek (1):
+ Add iscsi-init.service
+
+David Disseldorp (2):
+ use openssl for random data generation
+ drop unused get_random_bytes()
+
+Lee Duncan (10):
+ Fix iscsi.service so it handles restarts better
+ Fix issue where "iscsi-iname -p" core dumps.
+ Add Wants=remote-fs-pre.target for sequencing.
+ Change include of <sys/poll.h> to <poll.h>
+ Fix type mismatch under musl.
+ More changes for musl.
+ Ignore iface.example in iface match checks
+ Fix issue with zero-length arrays at end of struct
+ Fix a compiler complaint about writing one byte
+ Fix compiler complaint about string copy in iscsiuio
+
+Luis.wu (1):
+ Update iscsi-iname.c
+
+Rafael David Tinoco (1):
+ Misspelled socket name might cause confusion to inexperienced user.
+
+Wu Bo (2):
+ iscsi-iname: fix iscsi-iname -p access NULL pointer without given IQN prefix
+ log:modify iSCSI shared memory permissions for logs
+
+fredvx (1):
+ Fix SIGPIPE loop in signal handler
+
+gulams (1):
+ Proper disconnect of TCP connection
+
+wubo009 (3):
+ iscsi: Add break to while loop
+ iscsi: fix fd leak
+ iscsi/libopeniscsiusr:add libopeniscsiuser_node.h to HEADERS
+
+
open-iscsi-2.1.0 - open-iscsi-2.1.1
# output from "git shortlog --no-merges 2.1.0..HEAD"
diff --git a/Makefile b/Makefile
index 7b445a5..7f52cc8 100644
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,7 @@ ETCFILES = etc/iscsid.conf
IFACEFILES = etc/iface.example
RULESFILES = utils/50-iscsi-firmware-login.rules
SYSTEMDFILES = etc/systemd/iscsi.service \
+ etc/systemd/iscsi-init.service \
etc/systemd/iscsid.service etc/systemd/iscsid.socket \
etc/systemd/iscsiuio.service etc/systemd/iscsiuio.socket
diff --git a/README b/README
index 2499d9a..508c9d7 100644
--- a/README
+++ b/README
@@ -218,7 +218,7 @@ The output will be similar to the following.
iscsiadm -m discoverydb [ -hV ] [ -d debug_level ] [-P printlevel] [ -t type -p ip:port -I ifaceN ... [ -Dl ] ] | [ [ -p ip:port -t type] [ -o operation ] [ -n name ] [ -v value ] [ -lD ] ]
iscsiadm -m discovery [ -hV ] [ -d debug_level ] [-P printlevel] [ -t type -p ip:port -I ifaceN ... [ -l ] ] | [ [ -p ip:port ] [ -l | -D ] ]
-iscsiadm -m node [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -L all,manual,automatic ] [ -U all,manual,automatic ] [ -S ] [ [ -T targetname -p ip:port -I ifaceN ] [ -l | -u | -R | -s] ] [ [ -o operation ] [ -n name ] [ -v value ] ]
+iscsiadm -m node [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -L all,manual,automatic ] [ -W ] [ -U all,manual,automatic ] [ -S ] [ [ -T targetname -p ip:port -I ifaceN ] [ -l | -u | -R | -s] ] [ [ -o operation ] [ -n name ] [ -v value ] ]
iscsiadm -m session [ -hV ] [ -d debug_level ] [ -P printlevel] [ -r sessionid | sysfsdir [ -R | -u | -s ] [ -o operation ] [ -n name ] [ -v value ] ]
iscsiadm -m iface [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -I ifacename | -H hostno|MAC ] [ [ -o operation ] [ -n name ] [ -v value ] ] [ -C ping [ -a ip ] [ -b packetsize ] [ -c count ] [ -i interval ] ]
iscsiadm -m fw [ -d debug_level ] [ -l ]
@@ -380,7 +380,7 @@ Mode "node"
-m node --targetname=[name] --portal=[ip:port] \
--interface=iscsi_ifacename] \
- [--login|--logout|--rescan|--stats]
+ [--login|--logout|--rescan|--stats] [-W]
-m node --targetname=[name] --portal=[ip:port]
--interface=[driver,HWaddress] \
--op=[op] [--name=[name] --value=[value]]
@@ -407,6 +407,13 @@ Mode "node"
--stats prints the iSCSI stats for the session.
+ --login normally sends a login request to the specified
+ target and normally waits for the results. If
+ -W/--no_wait is supplied return success if we are
+ able to send the login request, and do not wait
+ for the response. The user will have to poll for
+ success
+
Print level can be 0 to 1.
-m node --logoutall=[all|manual|automatic]
@@ -414,11 +421,16 @@ Mode "node"
with a node startup value manual or automatic.
Nodes marked as ONBOOT are skipped.
- -m node --loginall=[all|manual|automatic]
+ -m node --loginall=[all|manual|automatic] [-W]
Login "all" the running sessions or just the ones
with a node startup value manual or automatic.
Nodes marked as ONBOOT are skipped.
+ If -W is supplied then do not wait for the login
+ response for the target, returning success if we
+ are able to just send the request. The client
+ will have to poll for success.
+
Mode "session"
--------------
@@ -915,8 +927,8 @@ Passing in none of them will result in all node records being operated on.
iscsiadm -m node -l
- iSCSI login to all portals on a node/target through each interface set
- in the db:
- iscsiadm -m node -T iqn.2005-03.com.max -l
+ in the db, but do not wait for the login response:
+ iscsiadm -m node -T iqn.2005-03.com.max -l -W
- iSCSI login to a specific portal through each interface set in the db:
iscsiadm -m node -T iqn.2005-03.com.max -p 192.168.0.4:3260 -l
@@ -1131,11 +1143,11 @@ copied into e.g. /usr/local/share/man8.
==================
There are three steps needed to set up a system to use iSCSI storage:
-7.1. iSCSI startup using the init script or manual startup.
+7.1. iSCSI startup using the systemd units or manual startup.
7.2. Discover targets.
7.3. Automate target logins for future system reboots.
-The init scripts will start the iSCSI daemon and log into any
+The systemd startup units will start the iSCSI daemon and log into any
portals that are set up for automatic login (discussed in 7.2)
or discovered through the discover daemon iscsid.conf params
(discussed in 7.1.2).
@@ -1151,12 +1163,11 @@ Red Hat or Fedora:
-----------------
To start open-iscsi in Red Hat/Fedora you can do:
- service open-iscsi start
+ systemctl start open-iscsi
To get open-iscsi to automatically start at run time you may have to
run:
- chkconfig --level <levels> open-iscsi on
-Where <levels> are the run levels.
+ systemctl enable open-iscsi
And, to automatically mount a file system during startup
you must have the partition entry in /etc/fstab marked with the "_netdev"
@@ -1166,12 +1177,10 @@ option. For example this would mount an iscsi disk sdb:
SUSE or Debian:
---------------
-Otherwise, if there is an initd script for your distro in etc/initd that
-gets installed with "make install"
-
- /etc/init.d/open-iscsi start
-
-will usually get you started.
+The open-iscsi service is socket activated, so there is no need to
+enable the open-iscsi service. Likewise, the iscsi.service login
+service is enabled automatically, so setting 'startup' to "automatic'
+will enable automatic login to open-iscsi targets.
7.1.2 Manual Startup
@@ -1184,12 +1193,12 @@ If there is no initd script, you must start the tools by hand. First load the
iscsi modules:
modprobe -q iscsi_tcp
-After that, start iSCSI daemon process:
- ./iscsid
+After that, start iSCSI as a daemon process:
+ iscsid
-or alternatively, start it with debug enabled and with output
-redirected to the current console:
- ./iscsid -d 8 -f &
+or alternatively, start it with debug enabled, in a seperate window,
+which will force it into "foreground" mode:
+ iscsid -d 8
7.1.2.2 Logging into Targets
@@ -1198,7 +1207,7 @@ redirected to the current console:
Use the configuration utility, iscsiadm, to add/remove/update Discovery
records, iSCSI Node records or monitor active iSCSI sessions (see above or the
iscsiadm man files and see section 7.2 below for how to discover targets):
- ./iscsiadm -m node
+ iscsiadm -m node
will print out the nodes that have been discovered as:
@@ -1210,7 +1219,7 @@ The format is:
If you are using the iface argument or want to see the driver
info, use the following:
- ./iscsiadm -m node -P 1
+ iscsiadm -m node -P 1
Example output:
Target: iqn.1992-08.com.netapp:sn.33615311
@@ -1234,14 +1243,22 @@ Default here is iscsi_tcp/tcp to be used over whichever NIC the
network layer decides is best.
To login, take the ip, port and targetname from above and run:
- ./iscsiadm -m node -T targetname -p ip:port -l
+ iscsiadm -m node -T targetname -p ip:port -l
In this example we would run:
- ./iscsiadm -m node -T iqn.1992-08.com.netapp:sn.33615311 \
+ iscsiadm -m node -T iqn.1992-08.com.netapp:sn.33615311 \
-p 10.15.84.19:3260 -l
Note: drop the portal group tag from the "iscsiadm -m node" output.
+If you wish, for example to login to all targets represented in the node
+database, but not wait for the login responses:
+
+ iscsiadm -m node -l -W
+
+after which you can use "session" mode to detect when the logins complete:
+
+ iscsiadm -m session
7.2. Discover Targets
=====================
@@ -1318,8 +1335,8 @@ all sessions add the following to the /etc/iscsi/iscsid.conf:
Setting this in iscsid.conf will not affect existing nodes. It will only
affect nodes that are discovered after setting the value.
-To login to all automated nodes, simply restart the iscsi service, e.g. with:
- /etc/init.d/open-iscsi restart
+To login to all automated nodes, simply restart the iscsi login service, e.g. with:
+ systemctl restart iscsi
On your next startup the nodes will be logged into automatically.
@@ -1375,7 +1392,7 @@ SendTargets
-n discovery.sendtargets.discoveryd_poll_inval -v 30
To have the new settings take effect, restart iscsid by restarting the
-iscsi service.
+iscsi services.
Note:
When iscsiadm is run with the -o new argument, it will use the
@@ -1404,7 +1421,7 @@ iSNS
-n discovery.isns.discoveryd_poll_inval -v 30
To have the new settings take effect, restart iscsid by restarting the
-iscsi service.
+iscsi services.
Note:
When iscsiadm is run with the -o new argument, it will use the
diff --git a/TODO b/TODO
index 7328180..a3d1d91 100644
--- a/TODO
+++ b/TODO
@@ -377,3 +377,16 @@ I am working on this one. Hopefully it should be done soon.
it gets out of sync with the kernel version, and that's not good.
---------------------------------------------------------------------------
+
+13. Node database
+
+Current implementation of node data is not scalable. It handles database using
+some bunch of files and directories. It has not locking and can not handle
+thousands of targets.
+
+---------------------------------------------------------------------------
+
+14. Migration of duplicate functionality out of iscsid/iscsiadm into libopeniscsi
+and add better error handling .
+
+---------------------------------------------------------------------------
diff --git a/doc/iscsiadm.8 b/doc/iscsiadm.8
index bf23dd2..3729a72 100644
--- a/doc/iscsiadm.8
+++ b/doc/iscsiadm.8
@@ -1,4 +1,4 @@
-.TH ISCSIADM 8 "Sep 2006" "" "Linux Administrator's Manual"
+.TH ISCSIADM 8 "Nov 2020" "" "Linux Administrator's Manual"
.SH NAME
iscsiadm \- open-iscsi administration utility
.SH SYNOPSIS
@@ -9,8 +9,9 @@ iscsiadm \- open-iscsi administration utility
.IR debug_level ]
.RB [ \-P
.IR printlevel ]
-[\
-.BI \-I\ iface\ \-t\ type\ \-p\ ip:port
+.RB [ \-I
+.I iface
+.BI \-t\ type\ \-p\ ip:port
.RB [ \-lD ]
] | [
.RB [ \-p
@@ -33,8 +34,8 @@ iscsiadm \- open-iscsi administration utility
.IR debug_level ]
.RB [ \-P
.IR printlevel ]
-[\
-.BI \-I\ iface\ \-t\ type\ \-p\ ip:port
+.RB [ \-I
+.IB iface\ \-t\ type\ \-p\ ip:port
.RB [ \-l ]
] | [
.RB [ \-p
@@ -51,13 +52,14 @@ iscsiadm \- open-iscsi administration utility
.IR printlevel ]
.RB [ \-L
.IR all,manual,automatic,onboot ]
+.RB [ \-W ]
.RB [ \-U
.IR all,manual,automatic,onboot ]
.RB [ \-S ]
[
.RB [ \-T
-.IB targetname\ \-p\ ip:port\ \-I\ iface
-]
+.IB targetname\ \-p\ ip:port\ \-I
+.IR iface ]
.RB [ \-l | \-u | \-R | \-s ]
]
[
@@ -78,8 +80,7 @@ iscsiadm \- open-iscsi administration utility
.IR debug_level ]
.RB [ \-P
.IR printlevel ]
-[
-.B \-r
+.RB [ \-r
.IR sessionid | sysfsdir
.RB [ \-R ]
.RB [ \-u | \-s | \-o
@@ -93,11 +94,10 @@ iscsiadm \- open-iscsi administration utility
.IR debug_level ]
.RB [ \-P
.IR printlevel ]
-[
-.BI \-I\ ifacename
-|
-.BI \-H\ hostno|MAC
-]
+.RB [ \-I
+.IR ifacename\ |
+.B \-H
+.IR hostno|MAC ]
[
.RB [ \-o
.IR operation ]
@@ -131,20 +131,20 @@ iscsiadm \- open-iscsi administration utility
.RB [ \-H
.IR hostno|MAC ]
[
-.RB [\ \-C
-.IR chap
+.RB [ \-C
+.I chap
.RB [ \-x
.IR chap_tbl_idx ]
] |
-.RB [\ \-C
-.IR flashnode
+.RB [ \-C
+.I flashnode
.RB [ \-A
.IR portal_type ]
.RB [ \-x
.IR flashnode_idx ]
] |
-.RB [\ \-C
-.IR stats \ ]
+.RB [ \-C
+.IR stats ]
]
[
.RB [ \-o
@@ -157,7 +157,7 @@ iscsiadm \- open-iscsi administration utility
.PP
.B iscsiadm
.B \-k priority
-.SH "DESCRIPTION"
+.SH DESCRIPTION
The iscsiadm utility is a command-line tool allowing discovery and login
to iSCSI targets, as well as access and management of the open-iscsi
database.
@@ -238,22 +238,33 @@ layer's interface name (iface.net_ifacename), and it must have the
driver/transport_name
.IP
The available drivers/iscsi_transports are tcp (software iSCSI over TCP/IP),
-iser (software iSCSI over InfiniBand), or qla4xxx (Qlogic 4XXXX HBAs). The
-hwaddress is the MAC address or for software iSCSI it may be the special
-value "default" which directs the initiator to not bind the session to a
+\fIiser\fR (software iSCSI over InfiniBand),
+\fIqla4xxx\fR (Qlogic 4XXXX and 82XXX HBAs),
+\fIcxgb3i\fR and \fIcxgb4i\fR (Chelsio T3 and T4 adapters),
+\fIbnx2i\fR (QLogic Netextreme II adapters),
+\fIbe2iscsi\fR (Emulex 10G adapter),
+\fIqedi\fR (QLogic QEDI 25/40/100Gb adapter), and
+\fIocs\fR (Emulex One Connect storage).
+Some of these are considered experimental, as they are not fully tested.
+.IP
+The hwaddress is the MAC address or for software iSCSI it may be the special
+value \fIdefault\fR which directs the initiator to not bind the session to a
specific hardware resource and instead allow the network or InfiniBand layer
to decide what to do. There is no need to create an iface config with the default
behavior. If you do not specify an iface, then the default behavior is used.
.IP
-As mentioned above there is a special iface name default. There are three
-others -- cxgb3i, bnx2i and iser, which does not bind the session to a
-specific card, but will bind the session to the cxgb3i, bnx2i or iser transport. These
-are experimental and the use is not supported as a stable interface yet.
+As mentioned above there is a special iface name \fIdefault\fR. There are
+others which do not bind the session to a specific card, but instead bind
+the session to the transport:
+\fIiser\fR,
+\fIcxgb3i\fR,
+\fIcxgb4i\fR, and
+\fIbnx2i\fR.
.IP
In discovery mode multiple interfaces can be specified by passing in multiple
\-I/\-\-interface instances. For example:
.IP
-"iscsiadm \-m discoverydb \-t st \-p ip:port \-I iface0 \-I iface2 \-\-discover"
+\fBsh#\fR iscsiadm \-m discoverydb \-t st \-p ip:port \-I iface0 \-I iface2 \-\-discover
.IP
Will direct iscsiadm to setup the node db to create records which will create
sessions through the two intefaces passed in.
@@ -265,7 +276,7 @@ This option is valid for discovery, node and iface mode.
\fB\-k\fR, \fB\-\-killiscsid=\fI[priority]\fR
Currently priority must be zero. This will immediately stop all iscsid
operations and shutdown iscsid. It does not logout any sessions. Running
-this command is the same as doing "killall iscsid". Neither should
+this command is the same as doing \fIkillall iscsid\fR. Neither should
normally be used, because if iscsid is doing error recovery or if there
is an error while iscsid is not running, the system may not be able to recover.
This command and iscsid's SIGTERM handling are experimental.
@@ -292,7 +303,13 @@ in or all running session, except ones marked onboot, if all is passed in.
This option is only valid for node mode (it is valid but not functional
for session mode).
.TP
-\fB\-m, \-\-mode \fIop\fR
+\fB\-W\fR, \fB\-\-\-no_wait\fR
+In node mode, do not wait for a response from the targets.
+This means that success will be returned if the command is able to
+send the login requests, whether or not they succeed. In this case, it will
+be up to the caller to poll for success (i.e. session creation).
+.TP
+\fB\-m\fR, \fB\-\-mode \fIop\fR
specify the mode. \fIop\fR
must be one of \fIdiscovery\fR, \fIdiscoverydb\fR, \fInode\fR, \fIfw\fR,
\fIhost\fR \fIiface\fR or \fIsession\fR.
@@ -483,7 +500,7 @@ resource.
.IP
Performing fw discovery will print the portals, like with other discovery
methods. To see other settings like CHAP values and initiator settings,
-like you would in node mode, run "iscsiadm \-m fw".
+like you would in node mode, run \fIiscsiadm \-m fw\fR.
.IP
fw support in open-iscsi is experimental. The settings and iscsiadm
syntax and output format may change.
@@ -611,26 +628,50 @@ ISCSI_ERR_ISNS_QUERY - iSNS query failure.
.B
26
ISCSI_ERR_ISNS_REG_FAILED - iSNS registration/deregistration failed.
+.TP
+.B
+27
+ISCSI_ERR_OP_NOT_SUPP - operation not support
+.TP
+.B
+28
+ISCSI_ERR_BUSY - device or resource in use
+.TP
+.B
+29
+ISCSI_ERR_AGAIN - operation failed, but retrying later may succeed
+.TP
+.B
+30
+ISCSI_ERR_UNKNOWN_DISCOVERY_TYPE - unknown discovery type
+.TP
+.B
+31
+ISCSI_ERR_CHILD_TERMINATED - child process terminated
+.TP
+.B
+32
+ISCSI_ERR_SESSION_NOT_CONNECTED - session likely not connected
.SH EXAMPLES
Discover targets at a given IP address:
.IP
-iscsiadm \-\-mode discoverydb \-\-type sendtargets \-\-portal 192.168.1.10 \-\-discover
+\fBsh#\fR iscsiadm \-\-mode discoverydb \-\-type sendtargets \-\-portal 192.168.1.10 \-\-discover
.PP
Login, must use a node record id found by the discovery:
.IP
-iscsiadm \-\-mode node \-\-targetname iqn.2001-05.com.doe:test \-\-portal 192.168.1.1:3260 \-\-login
+\fBsh#\fR iscsiadm \-\-mode node \-\-targetname iqn.2001-05.com.doe:test \-\-portal 192.168.1.1:3260 \-\-login
.PP
Logout:
.IP
-iscsiadm \-\-mode node \-\-targetname iqn.2001-05.com.doe:test \-\-portal 192.168.1.1:3260 \-\-logout
+\fBsh#\fR iscsiadm \-\-mode node \-\-targetname iqn.2001-05.com.doe:test \-\-portal 192.168.1.1:3260 \-\-logout
.PP
List node records:
.IP
-iscsiadm \-\-mode node
+\fBsh#\fR iscsiadm \-\-mode node
.PP
Display all data for a given node record:
.IP
-iscsiadm \-\-mode node \-\-targetname iqn.2001-05.com.doe:test \-\-portal 192.168.1.1:3260
+\fBsh#\fR iscsiadm \-\-mode node \-\-targetname iqn.2001-05.com.doe:test \-\-portal 192.168.1.1:3260
.SH FILES
.TP
/etc/iscsi/iscsid.conf
diff --git a/doc/iscsid.8 b/doc/iscsid.8
index 6f9218f..db996b4 100644
--- a/doc/iscsid.8
+++ b/doc/iscsid.8
@@ -24,23 +24,28 @@ Read initiator name from \fIiname\-file\fR rather than the default
.BI [-f|--foreground]
run
.B iscsid
-in the foreground.
+in the foreground. Implies
+.BR --no-pid-file .
.TP
-.BI [-d|--debug=]\fIdebug_level\fP
+.BI [-d|--debug=] debug_level
print debugging information. Valid values for debug_level are 0 to 8.
.TP
-.BI [-u|--uid=]\fIuid\fP
-run under user ID \fIuid\fR (default is the current user ID)
+.BI [-u|--uid=] uid
+run under user ID \fIuid\fR (default is the current user ID).
.TP
-.BI [-g|--gid=]\fIgid\fP
+.BI [-g|--gid=] gid
run under user group ID \fIgid\fR (default is the current user group ID).
.TP
-.BI [-n|--no-pid-file]\fP
-do not write a process ID file.
+.BI [-n|--no-pid-file]
+do not write a process ID file. Conflicts with the
+.BI --pid=
+option.
.TP
-.BI [-p|--pid=]\fIpid\-file\fP
+.BI [-p|--pid=] pid\-file
write process ID to \fIpid\-file\fR rather than the default
-\fI/run/iscsid.pid\fR
+\fI/run/iscsid.pid\fR. Conflicts with the
+.BI --no-pid-file
+option.
.TP
.BI [-h|--help]
display this help and exit
diff --git a/etc/iscsid.conf b/etc/iscsid.conf
index 58f6040..f21ed3d 100644
--- a/etc/iscsid.conf
+++ b/etc/iscsid.conf
@@ -19,8 +19,8 @@
# the time then leave this attribute commented out.
#
# Default for Fedora and RHEL. (uncomment to activate).
-# iscsid.startup = /bin/systemctl start iscsid.socket iscsiuio.soccket
-#
+# iscsid.startup = /bin/systemctl start iscsid.socket iscsiuio.socket
+#
# Default if you are not using systemd (uncomment to activate)
# iscsid.startup = /usr/bin/service start iscsid
diff --git a/etc/systemd/iscsi-init.service b/etc/systemd/iscsi-init.service
new file mode 100644
index 0000000..e058ff0
--- /dev/null
+++ b/etc/systemd/iscsi-init.service
@@ -0,0 +1,8 @@
+[Unit]
+Description=One time configuration for iscsi.service
+ConditionPathExists=!/etc/iscsi/initiatorname.iscsi
+
+[Service]
+Type=oneshot
+RemainAfterExit=no
+ExecStart=/usr/bin/sh -c 'echo "InitiatorName=`/usr/sbin/iscsi-iname`" > /etc/iscsi/initiatorname.iscsi'
diff --git a/etc/systemd/iscsi.service b/etc/systemd/iscsi.service
index e475888..2f2bf81 100644
--- a/etc/systemd/iscsi.service
+++ b/etc/systemd/iscsi.service
@@ -2,16 +2,16 @@
Description=Login and scanning of iSCSI devices
Documentation=man:iscsiadm(8) man:iscsid(8)
Before=remote-fs.target
-After=network.target network-online.target iscsid.service
-Requires=iscsid.service
-ConditionPathExists=/etc/iscsi/initiatorname.iscsi
+After=network.target network-online.target
+After=iscsid.service iscsi-init.service
+Requires=iscsid.socket iscsi-init.service
[Service]
Type=oneshot
ExecStart=/sbin/iscsiadm -m node --loginall=automatic
ExecStop=/sbin/iscsiadm -m node --logoutall=automatic
ExecStop=/sbin/iscsiadm -m node --logoutall=manual
-SuccessExitStatus=21
+SuccessExitStatus=21 15
RemainAfterExit=true
[Install]
diff --git a/etc/systemd/iscsid.service b/etc/systemd/iscsid.service
index 4fef168..648ceea 100644
--- a/etc/systemd/iscsid.service
+++ b/etc/systemd/iscsid.service
@@ -4,6 +4,7 @@ Documentation=man:iscsid(8) man:iscsiuio(8) man:iscsiadm(8)
DefaultDependencies=no
After=network.target iscsiuio.service
Before=remote-fs-pre.target
+Wants=remote-fs-pre.target
[Service]
Type=notify
diff --git a/etc/systemd/iscsiuio.service b/etc/systemd/iscsiuio.service
index e4d9fd0..923e019 100644
--- a/etc/systemd/iscsiuio.service
+++ b/etc/systemd/iscsiuio.service
@@ -7,6 +7,7 @@ Requires=iscsid.service
BindTo=iscsid.service
After=network.target
Before=remote-fs-pre.target iscsid.service
+Wants=remote-fs-pre.target
[Service]
Type=notify
diff --git a/include/iscsi_if.h b/include/iscsi_if.h
index 2d46214..5a1c614 100644
--- a/include/iscsi_if.h
+++ b/include/iscsi_if.h
@@ -841,7 +841,7 @@ struct iscsi_stats {
* up to ISCSI_STATS_CUSTOM_MAX
*/
uint32_t custom_length;
- struct iscsi_stats_custom custom[0]
+ struct iscsi_stats_custom custom[]
__attribute__ ((aligned (sizeof(uint64_t))));
};
@@ -972,7 +972,7 @@ struct iscsi_offload_host_stats {
* up to ISCSI_HOST_STATS_CUSTOM_MAX
*/
uint32_t custom_length;
- struct iscsi_host_stats_custom custom[0]
+ struct iscsi_host_stats_custom custom[]
__attribute__ ((aligned (sizeof(uint64_t))));
};
diff --git a/iscsiuio/src/uip/ipv6.c b/iscsiuio/src/uip/ipv6.c
index 05efa73..11cb4e9 100644
--- a/iscsiuio/src/uip/ipv6.c
+++ b/iscsiuio/src/uip/ipv6.c
@@ -519,7 +519,7 @@ static void ipv6_insert_protocol_chksum(struct ipv6_hdr *ipv6)
* SRC IP, DST IP, Protocol Data Length, and Next Header.
*/
sum = 0;
- ptr = (u16_t *)&ipv6->ipv6_src;
+ ptr = (u16_t *)&ipv6->ipv6_src.addr16[0];
for (i = 0; i < sizeof(struct ipv6_addr); i++) {
sum += HOST_TO_NET16(*ptr);
diff --git a/iscsiuio/src/uip/uip.c b/iscsiuio/src/uip/uip.c
index e2ce2cc..e0a7221 100644
--- a/iscsiuio/src/uip/uip.c
+++ b/iscsiuio/src/uip/uip.c
@@ -316,7 +316,13 @@ static u16_t upper_layer_chksum_ipv4(struct uip_stack *ustack, u8_t proto)
tcp_ipv4_hdr = (struct uip_tcp_ipv4_hdr *)ustack->network_layer;
upper_layer_len = (((u16_t) (tcp_ipv4_hdr->len[0]) << 8) +
- tcp_ipv4_hdr->len[1]) - UIP_IPv4_H_LEN;
+ tcp_ipv4_hdr->len[1]);
+ /* check for underflow from an invalid length field */
+ if (upper_layer_len < UIP_IPv4_H_LEN) {
+ /* return 0 as an invalid checksum */
+ return 0;
+ }
+ upper_layer_len -= UIP_IPv4_H_LEN;
/* First sum pseudoheader. */
/* IP protocol and length fields. This addition cannot carry. */
@@ -1789,16 +1795,18 @@ found_listen:
} else {
/* All other options have a length field, so
that we easily can skip past them. */
- if (ustack->
- uip_buf[uip_ip_tcph_len + UIP_LLH_LEN + 1 +
- c] == 0) {
+ if (ustack->uip_buf[uip_ip_tcph_len + UIP_LLH_LEN + 1 + c] == 0) {
/* If the length field is zero, the
options are malformed
and we don't process them further. */
break;
}
- c += ustack->uip_buf[uip_ip_tcph_len +
- UIP_LLH_LEN + 1 + c];
+ if ((ustack->uip_buf[uip_ip_tcph_len + UIP_LLH_LEN + 1 + c]) > (256 - c)) {
+ /* u8 overflow, actually there should
+ * never be more than 40 bytes of options */
+ break;
+ }
+ c += ustack->uip_buf[uip_ip_tcph_len + UIP_LLH_LEN + 1 + c];
}
}
}
@@ -2004,6 +2012,14 @@ found:
further. */
break;
}
+ if ((ustack->uip_buf[uip_ip_tcph_len
+ + UIP_LLH_LEN + 1 +
+ c]) > (256 - c)) {
+ /* u8 overflow, actually there should
+ * never be more than 40 bytes of
+ * options */
+ break;
+ }
c += ustack->
uip_buf[uip_ip_tcph_len +
UIP_LLH_LEN + 1 +
@@ -2079,11 +2095,16 @@ tcp_send_finack:
} else {
uip_urglen = 0;
#else /* UIP_URGDATA > 0 */
- ustack->uip_appdata =
- ((char *)ustack->uip_appdata) +
- ((tcp_hdr->urgp[0] << 8) | tcp_hdr->urgp[1]);
- ustack->uip_len -=
- (tcp_hdr->urgp[0] << 8) | tcp_hdr->urgp[1];
+ tmp16 = (tcp_hdr->urgp[0] << 8) | tcp_hdr->urgp[1];
+ if (tmp16 <= ustack->uip_len) {
+ ustack->uip_appdata = ((char *)ustack->uip_appdata) + tmp16;
+ ustack->uip_len -= tmp16;
+ } else {
+ /* invalid urgent pointer length greater than frame */
+ /* we're discarding urgent data anyway, throw it all out */
+ ustack->uip_appdata = ((char *)ustack->uip_appdata) + ustack->uip_len;
+ ustack->uip_len = 0;
+ }
#endif /* UIP_URGDATA > 0 */
}
diff --git a/iscsiuio/src/unix/iscsid_ipc.c b/iscsiuio/src/unix/iscsid_ipc.c
index 2acac48..ea03d37 100644
--- a/iscsiuio/src/unix/iscsid_ipc.c
+++ b/iscsiuio/src/unix/iscsid_ipc.c
@@ -54,9 +54,6 @@
#define PFX "iscsi_ipc "
-/* TODO fix me */
-#define IFNAMSIZ 15
-
#include "nic.h"
#include "nic_utils.h"
#include "nic_vlan.h"
diff --git a/iscsiuio/src/unix/libs/bnx2x.c b/iscsiuio/src/unix/libs/bnx2x.c
index c5e7b71..0e326d4 100644
--- a/iscsiuio/src/unix/libs/bnx2x.c
+++ b/iscsiuio/src/unix/libs/bnx2x.c
@@ -751,6 +751,13 @@ static int bnx2x_open(nic_t *nic)
count++;
}
}
+ if (nic->fd == INVALID_FD) {
+ LOG_ERR(PFX "%s: Could not open device: %s, [%s]",
+ nic->log_name, nic->uio_device_name,
+ strerror(errno));
+ rc = errno;
+ goto open_error;
+ }
if (fstat(nic->fd, &uio_stat) < 0) {
LOG_ERR(PFX "%s: Could not fstat device", nic->log_name);
rc = -ENODEV;
diff --git a/iscsiuio/src/unix/libs/qedi.c b/iscsiuio/src/unix/libs/qedi.c
index 3414cb5..1af8d1b 100644
--- a/iscsiuio/src/unix/libs/qedi.c
+++ b/iscsiuio/src/unix/libs/qedi.c
@@ -517,6 +517,13 @@ static int qedi_open(nic_t *nic)
count++;
}
}
+ if (nic->fd == INVALID_FD) {
+ LOG_ERR(PFX "%s: Could not open device: %s, [%s]",
+ nic->log_name, nic->uio_device_name,
+ strerror(errno));
+ rc = errno;
+ goto open_error;
+ }
if (fstat(nic->fd, &uio_stat) < 0) {
LOG_ERR(PFX "%s: Could not fstat device", nic->log_name);
rc = -ENODEV;
diff --git a/iscsiuio/src/unix/nic_nl.c b/iscsiuio/src/unix/nic_nl.c
index f830656..dee462e 100644
--- a/iscsiuio/src/unix/nic_nl.c
+++ b/iscsiuio/src/unix/nic_nl.c
@@ -50,7 +50,7 @@
#include <linux/netlink.h>
#include <iscsi_if.h>
#include <sys/ioctl.h>
-#include <sys/poll.h>
+#include <poll.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/socket.h>
diff --git a/iscsiuio/src/unix/nic_utils.c b/iscsiuio/src/unix/nic_utils.c
index ec3b915..ec4535d 100644
--- a/iscsiuio/src/unix/nic_utils.c
+++ b/iscsiuio/src/unix/nic_utils.c
@@ -603,7 +603,10 @@ static int from_uio_find_associated_host(nic_t *nic, int uio_minor,
search_filters[path_iterator], alphasort);
switch (count) {
- case 1:
+ case 1: {
+ char *parsed_src;
+ size_t parsed_size;
+
parsed_name = (*extract_name[path_iterator]) (files);
if (!parsed_name) {
LOG_WARN(PFX "Couldn't find delimiter in: %s",
@@ -612,15 +615,22 @@ static int from_uio_find_associated_host(nic_t *nic, int uio_minor,
break;
}
- strncpy(name,
- parsed_name +
- extract_name_offset[path_iterator], name_size);
+ parsed_src = parsed_name + extract_name_offset[path_iterator];
+ parsed_size = strlen(parsed_src);
+ if (parsed_size >= name_size) {
+ LOG_WARN(PFX "uio device name too long: %s (max %d)",
+ parsed_src, (int)name_size - 1);
+ rc = -EINVAL;
+ } else {
+ strncpy(name, parsed_src, name_size);
+ rc = 0;
+ }
free(files[0]);
free(files);
- rc = 0;
break;
+ }
case 0:
rc = -EINVAL;
diff --git a/libopeniscsiusr/Makefile b/libopeniscsiusr/Makefile
index a045a45..06b09f5 100644
--- a/libopeniscsiusr/Makefile
+++ b/libopeniscsiusr/Makefile
@@ -37,7 +37,8 @@ PKGFILE = libopeniscsiusr.pc
HEADERS = libopeniscsiusr/libopeniscsiusr.h \
libopeniscsiusr/libopeniscsiusr_common.h \
libopeniscsiusr/libopeniscsiusr_session.h \
- libopeniscsiusr/libopeniscsiusr_iface.h
+ libopeniscsiusr/libopeniscsiusr_iface.h \
+ libopeniscsiusr/libopeniscsiusr_node.h
TESTS = tests/test_context tests/test_session tests/test_iface tests/test_node
EXTRA_MAN_FILES = libopeniscsiusr.h.3
diff --git a/libopeniscsiusr/context.c b/libopeniscsiusr/context.c
index fe92155..c5e869f 100644
--- a/libopeniscsiusr/context.c
+++ b/libopeniscsiusr/context.c
@@ -55,8 +55,12 @@ struct iscsi_context *iscsi_context_new(void)
void iscsi_context_free(struct iscsi_context *ctx)
{
- if (ctx != NULL)
+ if (ctx == NULL)
+ return;
+
+ if (ctx->db)
_idbm_free(ctx->db);
+
free(ctx);
}
diff --git a/libopeniscsiusr/idbm.c b/libopeniscsiusr/idbm.c
index 190d61c..0910c63 100644
--- a/libopeniscsiusr/idbm.c
+++ b/libopeniscsiusr/idbm.c
@@ -260,7 +260,7 @@ do {\
_recs[_n].type = TYPE_INT_LIST; \
_strncpy(_recs[_n].name, _key, NAME_MAXVAL); \
for (unsigned int _i = 0; _i < ARRAY_LEN(_org->_name); _i++) { \
- if (_org->_name[_i] != ~0UL) { \
+ if (_org->_name[_i] != UINT_MAX) { \
for (unsigned int _j = 0; _j < ARRAY_LEN(_tbl); _j++) { \
if (_tbl[_j].value == _org->_name[_i]) { \
strcat(_recs[_n].value, _tbl[_j].name); \
diff --git a/libopeniscsiusr/node.c b/libopeniscsiusr/node.c
index 6bec201..0bf357b 100644
--- a/libopeniscsiusr/node.c
+++ b/libopeniscsiusr/node.c
@@ -109,6 +109,15 @@ int iscsi_nodes_get(struct iscsi_context *ctx, struct iscsi_node ***nodes,
_good(_scandir(ctx, NODE_CONFIG_DIR, &namelist, &n), rc, out);
_debug(ctx, "Got %d target from %s nodes folder", n, NODE_CONFIG_DIR);
+ /*
+ * If continue with n == 0, calloc() might return a memory which failed
+ * to be freed in iscsi_nodes_free()
+ *
+ * So here just goto out to exit if n == 0
+ */
+ if (n == 0)
+ goto out;
+
*node_count = n & UINT32_MAX;
*nodes = (struct iscsi_node **) calloc(*node_count,
sizeof(struct iscsi_node *));
diff --git a/libopeniscsiusr/session.c b/libopeniscsiusr/session.c
index 98601dc..7ace4d6 100644
--- a/libopeniscsiusr/session.c
+++ b/libopeniscsiusr/session.c
@@ -256,6 +256,8 @@ int iscsi_sessions_get(struct iscsi_context *ctx,
*session_count = 0;
_good(_iscsi_sids_get(ctx, &sids, session_count), rc ,out);
+ if (!*session_count)
+ goto out;
*sessions = calloc (*session_count, sizeof(struct iscsi_session *));
_alloc_null_check(ctx, *sessions, rc, out);
diff --git a/libopeniscsiusr/version.h b/libopeniscsiusr/version.h
index 9be3905..62ecf81 100644
--- a/libopeniscsiusr/version.h
+++ b/libopeniscsiusr/version.h
@@ -25,6 +25,6 @@
* This may not be the same value as the kernel versions because
* some other maintainer could merge a patch without going through us
*/
-#define ISCSI_VERSION_STR "2.1.1"
+#define ISCSI_VERSION_STR "2.1.3"
#endif /* End of __ISCSI_OPEN_USR_VERSION_H__ */
diff --git a/test/harness/util.py b/test/harness/util.py
index f6c2a32..d2a7b63 100644
--- a/test/harness/util.py
+++ b/test/harness/util.py
@@ -152,7 +152,7 @@ def new_parseArgs(self, argv):
# now validate stuff
if self.version_request:
- print('%s Version %s, harnes version %s' % \
+ print('%s Version %s, harness version %s' % \
(prog_name, parent_version, lib_version))
sys.exit(0)
Global.verbosity = self.verbosity
@@ -176,7 +176,7 @@ def new_parseArgs(self, argv):
Global.partition = '%s-part1' % Global.device
else:
print('Error: must start with "/dev" or "/dev/disk/by-{id,path}": %s' % \
- Global.device, file=sys.sttderr)
+ Global.device, file=sys.stderr)
sys.exit(1)
if self.subtest_list:
if not user_spec_to_list(self.subtest_list):
diff --git a/usr/auth.c b/usr/auth.c
index a222c53..2f7506f 100644
--- a/usr/auth.c
+++ b/usr/auth.c
@@ -43,11 +43,11 @@ static const char acl_authmethod_set_chap_alg_list[] = "CHAP";
static const char acl_reject_option_name[] = "Reject";
#include <openssl/evp.h>
+#include <openssl/rand.h>
static int auth_hash_init(EVP_MD_CTX **context, int chap_alg);
static void auth_hash_update(EVP_MD_CTX *context, unsigned char *md, unsigned int);
static unsigned int auth_hash_final(unsigned char *, EVP_MD_CTX *context);
-void get_random_bytes(unsigned char *data, unsigned int length);
size_t strlcpy(char *, const char *, size_t);
size_t strlcat(char *, const char *, size_t);
@@ -217,42 +217,6 @@ static unsigned int auth_hash_final(unsigned char *hash, EVP_MD_CTX *context) {
return md_len;
}
-void
-get_random_bytes(unsigned char *data, unsigned int length)
-{
-
- long r;
- unsigned n;
- int fd, r_size = sizeof(r);
-
- fd = open("/dev/urandom", O_RDONLY);
- while (length > 0) {
-
- if (fd == -1 || read(fd, &r, r_size) != r_size)
- r = rand();
- r = r ^ (r >> 8);
- r = r ^ (r >> 4);
- n = r & 0x7;
-
- if (fd == -1 || read(fd, &r, r_size) != r_size)
- r = rand();
- r = r ^ (r >> 8);
- r = r ^ (r >> 5);
- n = (n << 3) | (r & 0x7);
-
- if (fd == -1 || read(fd, &r, r_size) != r_size)
- r = rand();
- r = r ^ (r >> 8);
- r = r ^ (r >> 5);
- n = (n << 2) | (r & 0x3);
-
- *data++ = n;
- length--;
- }
- if (fd)
- close(fd);
-}
-
static const char acl_none_option_name[] = "None";
static int
@@ -1008,6 +972,7 @@ acl_rmt_auth(struct iscsi_acl *client)
enum auth_dbg_status dbg_status;
const char *chap_rsp_key_val;
const char *chap_username_key_val;
+ int ssl_ret = 0;
switch (client->rmt_state) {
case AUTH_RMT_STATE_SEND_ALG:
@@ -1023,7 +988,13 @@ acl_rmt_auth(struct iscsi_acl *client)
client->rmt_state = AUTH_RMT_STATE_DONE;
break;
}
- get_random_bytes(id_data, 1);
+
+ ssl_ret = RAND_bytes(id_data, sizeof(id_data));
+ if (ssl_ret != 1) {
+ client->rmt_state = AUTH_RMT_STATE_ERROR;
+ client->dbg_status = AUTH_DBG_STATUS_AUTH_FAIL;
+ break;
+ }
client->send_chap_identifier = id_data[0];
snprintf(client->scratch_key_value, AUTH_STR_MAX_LEN, "%lu",
(unsigned long)client->send_chap_identifier);
@@ -1032,8 +1003,13 @@ acl_rmt_auth(struct iscsi_acl *client)
client->scratch_key_value);
client->send_chap_challenge.length = client->chap_challenge_len;
- get_random_bytes(client->send_chap_challenge.large_binary,
- client->send_chap_challenge.length);
+ ssl_ret = RAND_bytes(client->send_chap_challenge.large_binary,
+ client->send_chap_challenge.length);
+ if (ssl_ret != 1) {
+ client->rmt_state = AUTH_RMT_STATE_ERROR;
+ client->dbg_status = AUTH_DBG_STATUS_AUTH_FAIL;
+ break;
+ }
acl_set_key_value(&client->send_key_block,
AUTH_KEY_TYPE_CHAP_CHALLENGE, "");
diff --git a/usr/discovery.c b/usr/discovery.c
index 9ce122e..7dec696 100644
--- a/usr/discovery.c
+++ b/usr/discovery.c
@@ -25,7 +25,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/poll.h>
+#include <poll.h>
#include <sys/time.h>
#include <sys/param.h>
#include <sys/socket.h>
diff --git a/usr/event_poll.c b/usr/event_poll.c
index 4cf4ce2..ffd12a3 100644
--- a/usr/event_poll.c
+++ b/usr/event_poll.c
@@ -23,7 +23,7 @@
*/
#include <stdlib.h>
#include <errno.h>
-#include <sys/poll.h>
+#include <poll.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/signalfd.h>
diff --git a/usr/idbm.c b/usr/idbm.c
index b77c4e7..b94b617 100644
--- a/usr/idbm.c
+++ b/usr/idbm.c
@@ -169,6 +169,7 @@ static struct idbm *db;
#define __recinfo_int_list(_key,_info,_rec,_name,_show,_tbl,_n,_mod) do { \
_info[_n].type = TYPE_INT_LIST; \
strlcpy(_info[_n].name, _key, NAME_MAXVAL); \
+ _info[_n].value[0] = '\0'; \
for (unsigned long _i = 0; _i < ARRAY_LEN(_rec->_name); _i++) { \
if (_rec->_name[_i] != (unsigned)~0) { \
for (unsigned long _j = 0; _j < ARRAY_LEN(_tbl); _j++) { \
@@ -1013,8 +1014,8 @@ int idbm_rec_update_param(recinfo_t *info, char *name, char *value,
int i;
int passwd_done = 0;
char passwd_len[8];
- char *tmp_value, *token;
- bool *found;
+ char *tmp_value, *token, *tmp;
+ bool *found = NULL;
int *tmp_data;
setup_passwd_len:
@@ -1078,12 +1079,25 @@ setup_passwd_len:
if (!info[i].data)
continue;
tbl = (void *)info[i].opts[0];
- /* strsep is destructive, make a copy to work with */
+ /*
+ * strsep is destructive, make a copy to work with
+ * tmp_value would be modified in strsep() too, so
+ * here make a copy of tmp_value to tmp
+ */
tmp_value = strdup(value);
+ if (!tmp_value)
+ return ISCSI_ERR_NOMEM;
+ tmp = tmp_value;
+
k = 0;
tmp_data = malloc(info[i].data_len);
+ if (!tmp_data)
+ goto free_tmp;
memset(tmp_data, ~0, info[i].data_len);
+
found = calloc(info[i].numopts, sizeof(bool));
+ if (!found)
+ goto free_tmp_data;
next_token: while ((token = strsep(&tmp_value, ", \n"))) {
if (!strlen(token))
@@ -1112,7 +1126,7 @@ next_token: while ((token = strsep(&tmp_value, ", \n"))) {
" for '%s'", token, info[i].name);
}
memcpy(info[i].data, tmp_data, info[i].data_len);
- free(tmp_value);
+ free(tmp);
free(tmp_data);
tmp_value = NULL;
tmp_data = NULL;
@@ -1134,8 +1148,17 @@ next_token: while ((token = strsep(&tmp_value, ", \n"))) {
return ISCSI_ERR_INVAL;
+free_tmp_data:
+ free(tmp_data);
+
+free_tmp:
+ free(tmp);
+ return ISCSI_ERR_NOMEM;
+
updated:
strlcpy((char*)info[i].value, value, VALUE_MAXVAL);
+ if (found)
+ free(found);
#define check_password_param(_param) \
if (!passwd_done && !strcmp(#_param, name)) { \
@@ -2902,6 +2925,20 @@ free_param:
return NULL;
}
+void idbm_free_user_param(struct user_param *param)
+{
+ if (!param)
+ return;
+
+ if (param->name)
+ free(param->name);
+
+ if (param->value)
+ free(param->value);
+
+ free(param);
+}
+
int idbm_node_set_rec_from_param(struct list_head *params, node_rec_t *rec,
int verify)
{
diff --git a/usr/idbm.h b/usr/idbm.h
index 46cd82a..7496f1d 100644
--- a/usr/idbm.h
+++ b/usr/idbm.h
@@ -153,6 +153,7 @@ extern int idbm_node_set_rec_from_param(struct list_head *params,
extern int idbm_node_set_param(void *data, node_rec_t *rec);
extern int idbm_discovery_set_param(void *data, discovery_rec_t *rec);
struct user_param *idbm_alloc_user_param(char *name, char *value);
+void idbm_free_user_param(struct user_param *param);
extern void idbm_node_setup_defaults(node_rec_t *rec);
extern struct node_rec *idbm_find_rec_in_list(struct list_head *rec_list,
char *targetname, char *addr,
diff --git a/usr/iface.c b/usr/iface.c
index e6b3bfc..21d52b3 100644
--- a/usr/iface.c
+++ b/usr/iface.c
@@ -905,6 +905,9 @@ int iface_for_each_iface(void *data, int skip_def, int *nr_found,
!strcmp(iface_dent->d_name, ".."))
continue;
+ if (!strcmp(iface_dent->d_name, "iface.example"))
+ continue;
+
log_debug(5, "iface_for_each_iface found %s",
iface_dent->d_name);
iface = iface_alloc(iface_dent->d_name, &err);
diff --git a/usr/initiator.c b/usr/initiator.c
index a07f9aa..684647c 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -692,6 +692,7 @@ static void iscsi_login_eh(struct iscsi_conn *conn, struct queue_task *qtask,
int err)
{
struct iscsi_session *session = conn->session;
+ int stop_flag = 0;
log_debug(3, "iscsi_login_eh");
/*
@@ -711,11 +712,11 @@ static void iscsi_login_eh(struct iscsi_conn *conn, struct queue_task *qtask,
!iscsi_retry_initial_login(conn))
session_conn_shutdown(conn, qtask, err);
else {
- session->reopen_cnt++;
- session->t->template->ep_disconnect(conn);
- if (iscsi_conn_connect(conn, qtask))
- queue_delayed_reopen(qtask,
- ISCSI_CONN_ERR_REOPEN_DELAY);
+ stop_flag = (session->id < INVALID_SESSION_ID) ? STOP_CONN_TERM : 0;
+ log_debug(6, "connection %p socket_fd: %d, "
+ "session id: %d stop_flag: %d\n",
+ conn, conn->socket_fd, session->id, stop_flag);
+ session_conn_reopen(conn, qtask, stop_flag);
}
break;
case R_STAGE_SESSION_REDIRECT:
diff --git a/usr/io.c b/usr/io.c
index 210a10a..a46c9f8 100644
--- a/usr/io.c
+++ b/usr/io.c
@@ -24,7 +24,7 @@
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
-#include <sys/poll.h>
+#include <poll.h>
#include <sys/ioctl.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
diff --git a/usr/iscsi_net_util.c b/usr/iscsi_net_util.c
index c38456f..10e6fa6 100644
--- a/usr/iscsi_net_util.c
+++ b/usr/iscsi_net_util.c
@@ -206,6 +206,12 @@ static char *find_vlan_dev(char *netdev, int vlan_id) {
}
ifni = if_nameindex();
+ if (!ifni) {
+ log_error("Failed to find netdev:%s", strerror(errno));
+ close(sockfd);
+ return NULL;
+ }
+
for (i = 0; ifni[i].if_index && ifni[i].if_name; i++) {
strlcpy(vlan_hwaddr.ifr_name, ifni[i].if_name, IFNAMSIZ);
ioctl(sockfd, SIOCGIFHWADDR, &vlan_hwaddr);
diff --git a/usr/iscsi_sysfs.c b/usr/iscsi_sysfs.c
index 435c576..abefde2 100644
--- a/usr/iscsi_sysfs.c
+++ b/usr/iscsi_sysfs.c
@@ -372,17 +372,29 @@ uint32_t iscsi_sysfs_get_host_no_from_hwaddress(char *hwaddress, int *rc)
info = calloc(1, sizeof(*info));
if (!info) {
+ log_debug(4, "No memory for host info");
*rc = ISCSI_ERR_NOMEM;
return -1;
}
- strcpy(info->iface.hwaddress, hwaddress);
+ /* make sure there is room for the MAC address plus NULL terminator */
+ if (strlen(hwaddress) > (ISCSI_HWADDRESS_BUF_SIZE - 1)) {
+ log_debug(4, "HW Address \"%s\" too long (%d max)",
+ hwaddress, ISCSI_HWADDRESS_BUF_SIZE-1);
+ *rc = ISCSI_ERR_INVAL;
+ goto dun;
+ }
+ strncpy(info->iface.hwaddress, hwaddress, ISCSI_HWADDRESS_BUF_SIZE-1);
local_rc = iscsi_sysfs_for_each_host(info, &nr_found,
__get_host_no_from_hwaddress);
if (local_rc == 1)
host_no = info->host_no;
- else
+ else {
+ log_debug(4, "Host not found from HW Address \"%s\"",
+ hwaddress);
*rc = ISCSI_ERR_HOST_NOT_FOUND;
+ }
+dun:
free(info);
return host_no;
}
@@ -844,7 +856,7 @@ static int iscsi_sysfs_read_iface(struct iface_rec *iface, int host_no,
}
}
- if (session && t->template->use_boot_info)
+ if (session && t && t->template->use_boot_info)
iscsi_sysfs_read_boot(iface, session);
if (!iface_kern_id)
@@ -1426,7 +1438,7 @@ int iscsi_sysfs_for_each_session(void *data, int *nr_found,
if (!info)
return ISCSI_ERR_NOMEM;
- info->iscsid_req_tmo = -1;
+ info->iscsid_req_tmo = ISCSID_RESP_POLL_TIMEOUT;
n = scandir(ISCSI_SESSION_DIR, &namelist, trans_filter,
alphasort);
if (n <= 0)
diff --git a/usr/iscsi_sysfs.h b/usr/iscsi_sysfs.h
index 1d0377f..9575c65 100644
--- a/usr/iscsi_sysfs.h
+++ b/usr/iscsi_sysfs.h
@@ -34,6 +34,7 @@ struct iscsi_auth_config;
struct flashnode_rec;
#define SCSI_MAX_STATE_VALUE 32
+#define ISCSID_RESP_POLL_TIMEOUT 60000
extern void free_transports(void);
extern char *iscsi_sysfs_get_iscsi_kernel_version(void);
diff --git a/usr/iscsi_util.c b/usr/iscsi_util.c
index fd8fc0c..db1dc37 100644
--- a/usr/iscsi_util.c
+++ b/usr/iscsi_util.c
@@ -152,7 +152,9 @@ int increase_max_files(void)
log_debug(1, "Could not get file limit (err %d)", errno);
return errno;
}
- log_debug(1, "Max file limits %lu %lu", rl.rlim_cur, rl.rlim_max);
+ log_debug(1, "Max file limits %lu %lu",
+ (long unsigned)rl.rlim_cur,
+ (long unsigned)rl.rlim_max);
if (rl.rlim_cur < ISCSI_MAX_FILES)
rl.rlim_cur = ISCSI_MAX_FILES;
@@ -162,7 +164,8 @@ int increase_max_files(void)
err = setrlimit(RLIMIT_NOFILE, &rl);
if (err) {
log_debug(1, "Could not set file limit to %lu/%lu (err %d)",
- rl.rlim_cur, rl.rlim_max, errno);
+ (long unsigned)rl.rlim_cur,
+ (long unsigned)rl.rlim_max, errno);
return errno;
}
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index e9778c3..4249af8 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -101,6 +101,22 @@ enum _print_node_tree_mode {
_PRINT_MODE_NODE,
};
+struct verify_mode_t {
+ char *mode;
+ char *allowed;
+ int skip_m;
+};
+
+static const struct verify_mode_t mode_paras[] = {
+ [MODE_DISCOVERY] = {"discovery", "DSIPdmntplov", 0},
+ [MODE_DISCOVERYDB] = {"discovery", "DSIPdmntplov", 0},
+ [MODE_NODE] = {"node", "RsPIdmlSonvupTULW", 0},
+ [MODE_SESSION] = {"session", "PiRdrmusonuSv", 1},
+ [MODE_HOST] = {"host", "CHdmPotnvxA", 0},
+ [MODE_IFACE] = {"iface", "HIdnvmPoCabci", 0},
+ [MODE_FW] = {"fw", "dml", 0},
+};
+
static struct option const long_options[] =
{
{"mode", required_argument, NULL, 'm'},
@@ -133,9 +149,10 @@ static struct option const long_options[] =
{"interval", required_argument, NULL, 'i'},
{"index", required_argument, NULL, 'x'},
{"portal_type", optional_argument, NULL, 'A'},
+ {"no_wait", no_argument, NULL, 'W'},
{NULL, 0, NULL, 0},
};
-static char *short_options = "RlDVhm:a:b:c:C:p:P:T:H:i:I:U:k:L:d:r:n:v:o:sSt:ux:A:";
+static char *short_options = "RlDVhm:a:b:c:C:p:P:T:H:i:I:U:k:L:d:r:n:v:o:sSt:ux:A:W";
static void usage(int status)
{
@@ -144,15 +161,15 @@ static void usage(int status)
program_name);
else {
printf("\
-iscsiadm -m discoverydb [ -hV ] [ -d debug_level ] [-P printlevel] [ -t type -p ip:port -I ifaceN ... [ -Dl ] ] | [ [ -p ip:port -t type] \
-[ -o operation ] [ -n name ] [ -v value ] [ -lD ] ] \n\
-iscsiadm -m discovery [ -hV ] [ -d debug_level ] [-P printlevel] [ -t type -p ip:port -I ifaceN ... [ -l ] ] | [ [ -p ip:port ] [ -l | -D ] ] \n\
-iscsiadm -m node [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -L all,manual,automatic ] [ -U all,manual,automatic ] [ -S ] [ [ -T targetname -p ip:port -I ifaceN ] [ -l | -u | -R | -s] ] \
-[ [ -o operation ] [ -n name ] [ -v value ] ]\n\
-iscsiadm -m session [ -hV ] [ -d debug_level ] [ -P printlevel] [ -r sessionid | sysfsdir [ -R | -u | -s ] [ -o operation ] [ -n name ] [ -v value ] ]\n\
-iscsiadm -m iface [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -I ifacename | -H hostno|MAC ] [ [ -o operation ] [ -n name ] [ -v value ] ] [ -C ping [ -a ip ] [ -b packetsize ] [ -c count ] [ -i interval ] ]\n\
-iscsiadm -m fw [ -d debug_level ] [ -l ]\n\
-iscsiadm -m host [ -P printlevel ] [ -H hostno|MAC ] [ [ -C chap [ -x chap_tbl_idx ] ] | [ -C flashnode [ -A portal_type ] [ -x flashnode_idx ] ] | [ -C stats ] ] [ [ -o operation ] [ -n name ] [ -v value ] ] \n\
+iscsiadm -m discoverydb [-hV] [-d debug_level] [-P printlevel] [-t type -p ip:port -I ifaceN ... [-Dl]] | [[-p ip:port -t type] \
+[-o operation] [-n name] [-v value] [-lD]] \n\
+iscsiadm -m discovery [-hV] [-d debug_level] [-P printlevel] [-t type -p ip:port -I ifaceN ... [-l]] | [[-p ip:port] [-l | -D]] \n\
+iscsiadm -m node [-hV] [-d debug_level] [-P printlevel] [-L all,manual,automatic,onboot] [-W] [-U all,manual,automatic,onboot] [-S] [[-T targetname -p ip:port -I ifaceN] [-l | -u | -R | -s]] \
+[[-o operation ] [-n name] [-v value]]\n\
+iscsiadm -m session [-hV] [-d debug_level] [-P printlevel] [-r sessionid | sysfsdir [-R | -u | -s] [-o operation] [-n name] [-v value]]\n\
+iscsiadm -m iface [-hV] [-d debug_level] [-P printlevel] [-I ifacename | -H hostno|MAC] [[-o operation ] [-n name] [-v value]] [-C ping [-a ip] [-b packetsize] [-c count] [-i interval]]\n\
+iscsiadm -m fw [-d debug_level] [-l]\n\
+iscsiadm -m host [-P printlevel] [-H hostno|MAC] [[-C chap [-x chap_tbl_idx]] | [-C flashnode [-A portal_type] [-x flashnode_idx]] | [-C stats]] [[-o operation] [-n name] [-v value]] \n\
iscsiadm -k priority\n");
}
exit(status);
@@ -452,6 +469,8 @@ __do_leading_login(void *data, struct list_head *list, struct node_rec *rec)
struct iface_rec *pattern_iface = data;
int nr_found;
+ log_debug(1, "doing leading login using iface: %s", pattern_iface->name);
+
/* Skip any records that do not match the pattern iface */
if (!iface_match(pattern_iface, &rec->iface))
return -1;
@@ -471,7 +490,7 @@ __do_leading_login(void *data, struct list_head *list, struct node_rec *rec)
}
static int
-login_by_startup(char *mode)
+login_by_startup(char *mode, bool wait)
{
int nr_found = 0, err, rc;
struct startup_data startup;
@@ -512,7 +531,7 @@ login_by_startup(char *mode)
if (!list_empty(&startup.all_logins)) {
log_debug(1, "Logging into normal (non-leading-login) portals");
/* Login all regular (non-leading-login) portals first */
- err = iscsi_login_portals(NULL, &nr_found, 1,
+ err = iscsi_login_portals(NULL, &nr_found, wait,
&startup.all_logins, iscsi_login_portal);
if (err)
log_error("Could not log into all portals");
@@ -657,7 +676,7 @@ static int for_each_matched_rec(struct node_rec *rec, void *data,
}
-static int login_portals(struct node_rec *pattern_rec)
+static int login_portals(struct node_rec *pattern_rec, bool wait)
{
LIST_HEAD(rec_list);
int nr_found, rc, err;
@@ -671,7 +690,7 @@ static int login_portals(struct node_rec *pattern_rec)
rc = err;
/* if there is an err but some recs then try to login to what we have */
- err = iscsi_login_portals(pattern_rec, &nr_found, 1, &rec_list,
+ err = iscsi_login_portals(pattern_rec, &nr_found, wait ? 1 : 0, &rec_list,
iscsi_login_portal);
if (err)
log_error("Could not log into all portals");
@@ -1328,10 +1347,21 @@ sw_discovery:
static int
-verify_mode_params(int argc, char **argv, char *allowed, int skip_m)
+verify_mode_params(int argc, char **argv, enum iscsiadm_mode mode)
{
int ch, longindex;
- int ret = 0;
+ int ret = ISCSI_SUCCESS;
+ char *allowed;
+ int skip_m;
+ int tmp = optind;
+
+ if (mode > MODE_FW || mode < MODE_DISCOVERY) {
+ log_error("mode %d is not yet supported", mode);
+ return ISCSI_ERR_INVAL;
+ }
+
+ allowed = mode_paras[mode].allowed;
+ skip_m = mode_paras[mode].skip_m;
optind = 0;
@@ -1340,10 +1370,14 @@ verify_mode_params(int argc, char **argv, char *allowed, int skip_m)
if (!strchr(allowed, ch)) {
if (ch == 'm' && skip_m)
continue;
- ret = ch;
+ log_error("%s mode: option '-%c' is not "
+ "allowed/supported",
+ mode_paras[mode].mode, ch);
+ ret = ISCSI_ERR_INVAL;
break;
}
}
+ optind = tmp;
return ret;
}
@@ -2806,7 +2840,7 @@ static int verify_node_params(struct list_head *params, struct node_rec *rec)
/* TODO cleanup arguments */
static int exec_node_op(struct iscsi_context *ctx, int op, int do_login,
int do_logout, int do_show, int do_rescan, int do_stats,
- int info_level, struct node_rec *rec,
+ bool wait, int info_level, struct node_rec *rec,
struct list_head *params)
{
int rc = 0;
@@ -2853,7 +2887,7 @@ static int exec_node_op(struct iscsi_context *ctx, int op, int do_login,
}
if (do_login) {
- rc = login_portals(rec);
+ rc = login_portals(rec, wait);
goto out;
}
@@ -3559,6 +3593,7 @@ main(int argc, char **argv)
struct iscsi_session **ses = NULL;
uint32_t se_count = 0;
struct iscsi_session *se = NULL;
+ bool wait = true;
ctx = iscsi_context_new();
if (ctx == NULL) {
@@ -3592,7 +3627,7 @@ main(int argc, char **argv)
"Priority must be greater than or "
"equal to zero.", killiscsid);
rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
+ goto out;
}
break;
case 't':
@@ -3604,7 +3639,7 @@ main(int argc, char **argv)
log_error("can not recognize operation: '%s'",
optarg);
rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
+ goto out;
}
break;
case 'n':
@@ -3616,7 +3651,7 @@ main(int argc, char **argv)
case 'H':
host_no = parse_host_info(optarg, &rc);
if (rc)
- goto free_ifaces;
+ goto out;
break;
case 'r':
sid = iscsi_sysfs_get_sid_from_path(optarg);
@@ -3624,7 +3659,7 @@ main(int argc, char **argv)
log_error("invalid sid '%s'",
optarg);
rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
+ goto out;
}
break;
case 'R':
@@ -3673,6 +3708,9 @@ main(int argc, char **argv)
break;
case 'm':
mode = str_to_mode(optarg);
+ rc = verify_mode_params(argc, argv, mode);
+ if (ISCSI_SUCCESS != rc)
+ goto out;
break;
case 'C':
sub_mode = str_to_submode(optarg);
@@ -3701,11 +3739,11 @@ main(int argc, char **argv)
printf("Invalid iface name %s. Must be from "
"1 to %d characters.\n",
optarg, ISCSI_MAX_IFACE_LEN - 1);
- goto free_ifaces;
+ goto out;
} else if (!iface || rc) {
printf("Could not add iface %s.", optarg);
rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
+ goto out;
}
list_add_tail(&iface->list, &ifaces);
@@ -3722,12 +3760,15 @@ main(int argc, char **argv)
log_error("Invalid index %s. %s.",
optarg, strerror(errno));
rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
+ goto out;
}
break;
case 'A':
portal_type = str_to_portal_type(optarg);
break;
+ case 'W':
+ wait = false;
+ break;
case 'h':
usage(0);
}
@@ -3737,7 +3778,7 @@ main(int argc, char **argv)
if (!param) {
log_error("Cannot allocate memory for params.");
rc = ISCSI_ERR_NOMEM;
- goto free_ifaces;
+ goto out;
}
list_add_tail(&param->list, &params);
name = NULL;
@@ -3748,44 +3789,31 @@ main(int argc, char **argv)
if (optopt) {
log_error("unrecognized character '%c'", optopt);
rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
+ goto out;
}
if (killiscsid >= 0) {
kill_iscsid(killiscsid, timeout);
- goto free_ifaces;
+ goto out;
}
if (mode < 0)
usage(ISCSI_ERR_INVAL);
if (mode == MODE_FW) {
- if ((rc = verify_mode_params(argc, argv, "dml", 0))) {
- log_error("fw mode: option '-%c' is not "
- "allowed/supported", rc);
- rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
- }
-
rc = exec_fw_op(NULL, NULL, info_level, do_login, op);
- goto free_ifaces;
+ goto out;
}
increase_max_files();
if (idbm_init(get_config_file)) {
log_warning("exiting due to idbm configuration error");
rc = ISCSI_ERR_IDBM;
- goto free_ifaces;
+ goto out;
}
switch (mode) {
case MODE_HOST:
- if ((rc = verify_mode_params(argc, argv, "CHdmPotnvxA", 0))) {
- log_error("host mode: option '-%c' is not "
- "allowed/supported", rc);
- rc = ISCSI_ERR_INVAL;
- goto out;
- }
if (sub_mode != -1) {
switch (sub_mode) {
case MODE_CHAP:
@@ -3851,13 +3879,6 @@ main(int argc, char **argv)
case MODE_IFACE:
iscsi_default_iface_setup(ctx);
- if ((rc = verify_mode_params(argc, argv, "HIdnvmPoCabci", 0))) {
- log_error("iface mode: option '-%c' is not "
- "allowed/supported", rc);
- rc = ISCSI_ERR_INVAL;
- goto out;
- }
-
if (!list_empty(&ifaces)) {
iface = list_entry(ifaces.next, struct iface_rec,
list);
@@ -3876,40 +3897,18 @@ main(int argc, char **argv)
break;
case MODE_DISCOVERYDB:
- if ((rc = verify_mode_params(argc, argv, "DSIPdmntplov", 0))) {
- log_error("discovery mode: option '-%c' is not "
- "allowed/supported", rc);
- rc = ISCSI_ERR_INVAL;
- goto out;
- }
-
rc = exec_disc2_op(type, ip, port, &ifaces, info_level,
do_login, do_discover, op, &params,
do_show);
break;
case MODE_DISCOVERY:
- if ((rc = verify_mode_params(argc, argv, "DSIPdmntplov", 0))) {
- log_error("discovery mode: option '-%c' is not "
- "allowed/supported", rc);
- rc = ISCSI_ERR_INVAL;
- goto out;
- }
-
rc = exec_disc_op(type, ip, port, &ifaces, info_level,
do_login, do_discover, op, &params,
do_show);
break;
case MODE_NODE:
- if ((rc = verify_mode_params(argc, argv, "RsPIdmlSonvupTUL",
- 0))) {
- log_error("node mode: option '-%c' is not "
- "allowed/supported", rc);
- rc = ISCSI_ERR_INVAL;
- goto out;
- }
-
if (do_login_all) {
- rc = login_by_startup(group_session_mgmt_mode);
+ rc = login_by_startup(group_session_mgmt_mode, wait);
goto out;
}
@@ -3939,17 +3938,10 @@ main(int argc, char **argv)
}
rc = exec_node_op(ctx, op, do_login, do_logout, do_show,
- do_rescan, do_stats, info_level, rec,
+ do_rescan, do_stats, wait, info_level, rec,
&params);
break;
case MODE_SESSION:
- if ((rc = verify_mode_params(argc, argv,
- "PiRdrmusonuSv", 1))) {
- log_error("session mode: option '-%c' is not "
- "allowed or supported", rc);
- rc = ISCSI_ERR_INVAL;
- goto out;
- }
if (sid >= 0) {
char session[64];
struct session_info *info;
@@ -4025,7 +4017,7 @@ main(int argc, char **argv)
/* drop down to node ops */
rc = exec_node_op(ctx, op, do_login, do_logout, do_show,
- do_rescan, do_stats, info_level,
+ do_rescan, do_stats, wait, info_level,
rec, &params);
free_info:
free(info);
@@ -4040,7 +4032,7 @@ free_info:
if (do_logout || do_rescan || do_stats) {
rc = exec_node_op(ctx, op, do_login, do_logout,
do_show, do_rescan, do_stats,
- info_level, NULL, &params);
+ wait, info_level, NULL, &params);
goto out;
}
@@ -4078,11 +4070,14 @@ out:
free(rec);
iscsi_sessions_free(ses, se_count);
idbm_terminate();
-free_ifaces:
list_for_each_entry_safe(iface, tmp, &ifaces, list) {
list_del(&iface->list);
free(iface);
}
+ list_for_each_entry(param, &params, list) {
+ list_del(&param->list);
+ idbm_free_user_param(param);
+ }
free_transports();
sysfs_cleanup();
return rc;
diff --git a/usr/iscsid.c b/usr/iscsid.c
index a7b8bd6..dc54fec 100644
--- a/usr/iscsid.c
+++ b/usr/iscsid.c
@@ -63,7 +63,7 @@ struct iscsi_daemon_config *dconfig = &daemon_config;
static char program_name[] = "iscsid";
static pid_t log_pid;
static gid_t gid;
-static int daemonize = 1;
+static bool daemonize = true;
static int mgmt_ipc_fd;
static int sessions_to_recover = 0;
@@ -301,7 +301,7 @@ static void iscsid_shutdown(void)
while ((pid = waitpid(0, NULL, 0) > 0))
log_debug(7, "cleaned up pid %d", pid);
- log_warning("iscsid shutting down.");
+ log_info("iscsid shutting down.");
if (daemonize && log_pid >= 0) {
log_debug(1, "daemon stopping");
log_close(log_pid);
@@ -310,7 +310,12 @@ static void iscsid_shutdown(void)
static void catch_signal(int signo)
{
- log_debug(1, "pid %d caught signal %d", getpid(), signo);
+ /*
+ * Do not try to call log_debug() if there is a PIPE error
+ * because we can get caught in a PIPE error loop.
+ */
+ if (signo != SIGPIPE)
+ log_debug(1, "pid %d caught signal %d", getpid(), signo);
/* In foreground mode, treat SIGINT like SIGTERM */
if (!daemonize && signo == SIGINT)
@@ -376,6 +381,8 @@ int main(int argc, char *argv[])
struct sigaction sa_new;
int control_fd;
pid_t pid;
+ bool pid_file_specified = false;
+ bool no_pid_file_specified = false;
while ((ch = getopt_long(argc, argv, "c:i:fd:nu:g:p:vh", long_options,
&longindex)) >= 0) {
@@ -387,7 +394,7 @@ int main(int argc, char *argv[])
initiatorname_file = optarg;
break;
case 'f':
- daemonize = 0;
+ daemonize = false;
break;
case 'd':
log_level = atoi(optarg);
@@ -400,9 +407,11 @@ int main(int argc, char *argv[])
break;
case 'n':
pid_file = NULL;
+ no_pid_file_specified = true;
break;
case 'p':
pid_file = optarg;
+ pid_file_specified = true;
break;
case 'v':
printf("%s version %s\n", program_name,
@@ -417,6 +426,17 @@ int main(int argc, char *argv[])
}
}
+ if (pid_file_specified) {
+ if (no_pid_file_specified) {
+ fprintf(stderr, "error: Conflicting PID-file options requested\n");
+ usage(1);
+ }
+ if (!daemonize) {
+ fprintf(stderr, "error: PID file specified but unused in foreground mode\n");
+ usage(1);
+ }
+ }
+
/* initialize logger */
log_pid = log_init(program_name, DEFAULT_AREA_SIZE,
daemonize ? log_do_log_daemon : log_do_log_std, NULL);
diff --git a/usr/iscsid_req.c b/usr/iscsid_req.c
index 3bbf5b9..a3aba6d 100644
--- a/usr/iscsid_req.c
+++ b/usr/iscsid_req.c
@@ -156,7 +156,7 @@ int iscsid_response(int fd, iscsiadm_cmd_e cmd, iscsiadm_rsp_t *rsp,
if (!err) {
if (poll_wait)
continue;
- return ISCSI_ERR_ISCSID_NOTCONN;
+ return ISCSI_ERR_SESSION_NOT_CONNECTED;
} else if (err < 0) {
if (errno == EINTR)
continue;
diff --git a/usr/iscsistart.c b/usr/iscsistart.c
index 00a9c78..73991b3 100644
--- a/usr/iscsistart.c
+++ b/usr/iscsistart.c
@@ -30,7 +30,6 @@
#include <time.h>
#include <sys/mman.h>
#include <sys/utsname.h>
-#include <sys/signal.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -348,6 +347,7 @@ int main(int argc, char *argv[])
struct boot_context *context, boot_context;
struct sigaction sa_old;
struct sigaction sa_new;
+ struct user_param *param;
int control_fd, mgmt_ipc_fd, err;
pid_t pid;
@@ -542,6 +542,10 @@ int main(int argc, char *argv[])
mgmt_ipc_close(mgmt_ipc_fd);
free_initiator();
sysfs_cleanup();
+ list_for_each_entry(param, &user_params, list) {
+ list_del(&param->list);
+ idbm_free_user_param(param);
+ }
log_debug(1, "iscsi child done");
return 0;
diff --git a/usr/log.c b/usr/log.c
index 6e16e7c..29cf39f 100644
--- a/usr/log.c
+++ b/usr/log.c
@@ -73,7 +73,7 @@ static int logarea_init (int size)
logdbg(stderr,"enter logarea_init\n");
if ((shmid = shmget(IPC_PRIVATE, sizeof(struct logarea),
- 0644 | IPC_CREAT | IPC_EXCL)) == -1) {
+ 0600 | IPC_CREAT | IPC_EXCL)) == -1) {
syslog(LOG_ERR, "shmget logarea failed %d", errno);
return 1;
}
@@ -93,7 +93,7 @@ static int logarea_init (int size)
size = DEFAULT_AREA_SIZE;
if ((shmid = shmget(IPC_PRIVATE, size,
- 0644 | IPC_CREAT | IPC_EXCL)) == -1) {
+ 0600 | IPC_CREAT | IPC_EXCL)) == -1) {
syslog(LOG_ERR, "shmget msg failed %d", errno);
free_logarea();
return 1;
@@ -114,7 +114,7 @@ static int logarea_init (int size)
la->tail = la->start;
if ((shmid = shmget(IPC_PRIVATE, MAX_MSG_SIZE + sizeof(struct logmsg),
- 0644 | IPC_CREAT | IPC_EXCL)) == -1) {
+ 0600 | IPC_CREAT | IPC_EXCL)) == -1) {
syslog(LOG_ERR, "shmget logmsg failed %d", errno);
free_logarea();
return 1;
@@ -448,7 +448,7 @@ int log_init(char *program_name, int size,
syslog(LOG_ERR, "starting logger failed");
exit(1);
} else if (pid) {
- syslog(LOG_WARNING,
+ syslog(LOG_INFO,
"iSCSI logger with pid=%d started!", pid);
return pid;
}
diff --git a/usr/mgmt_ipc.c b/usr/mgmt_ipc.c
index 51267c1..054378e 100644
--- a/usr/mgmt_ipc.c
+++ b/usr/mgmt_ipc.c
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <pwd.h>
#include <sys/un.h>
+#include <string.h>
#include "iscsid.h"
#include "idbm.h"
@@ -452,8 +453,11 @@ mgmt_ipc_read_req(queue_task_t *qtask)
/* Remember the allocated pointer in the
* qtask - it will be freed by write_rsp.
* Note: we allocate one byte in excess
- * so we can append a NUL byte. */
+ * so we can append a NULL byte. */
qtask->payload = malloc(req->payload_len + 1);
+ if (!qtask->payload)
+ return -ENOMEM;
+
rc = mgmt_ipc_read_data(qtask->mgmt_ipc_fd,
qtask->payload,
req->payload_len);
diff --git a/usr/netlink.c b/usr/netlink.c
index d42ca4f..22cad83 100644
--- a/usr/netlink.c
+++ b/usr/netlink.c
@@ -30,7 +30,7 @@
#include <asm/types.h>
#include <sys/socket.h>
#include <sys/types.h>
-#include <sys/poll.h>
+#include <poll.h>
#include <linux/netlink.h>
#include "types.h"
diff --git a/usr/statics.c b/usr/statics.c
index 59fb044..f59729b 100644
--- a/usr/statics.c
+++ b/usr/statics.c
@@ -1,6 +1,6 @@
#include <unistd.h>
#include <pwd.h>
-#include <sys/errno.h>
+#include <errno.h>
#include <sys/types.h>
static struct passwd root_pw = {
@@ -17,4 +17,3 @@ getpwuid(uid_t uid)
return 0;
}
}
-
diff --git a/usr/sysfs.c b/usr/sysfs.c
index 2488160..7f26572 100644
--- a/usr/sysfs.c
+++ b/usr/sysfs.c
@@ -168,9 +168,11 @@ struct sysfs_device *sysfs_device_get(const char *devpath)
int len;
char *pos;
+ if (!devpath)
+ return NULL;
+
/* we handle only these devpathes */
- if (devpath != NULL &&
- strncmp(devpath, "/devices/", 9) != 0 &&
+ if (strncmp(devpath, "/devices/", 9) != 0 &&
strncmp(devpath, "/subsystem/", 11) != 0 &&
strncmp(devpath, "/module/", 8) != 0 &&
strncmp(devpath, "/bus/", 5) != 0 &&
@@ -574,8 +576,12 @@ int sysfs_get_str(char *id, char *subsys, char *param, char *value,
value[0] = '\0';
sysfs_value = sysfs_get_value(id, subsys, param);
- if (!sysfs_value || !strlen(sysfs_value))
+ if (!sysfs_value)
return EIO;
+ if (!strlen(sysfs_value)) {
+ free(sysfs_value);
+ return EIO;
+ }
len = strlen(sysfs_value);
if (len && (sysfs_value[len - 1] == '\n'))
diff --git a/usr/version.h b/usr/version.h
index 4fa9179..a832419 100644
--- a/usr/version.h
+++ b/usr/version.h
@@ -6,7 +6,7 @@
* This may not be the same value as the kernel versions because
* some other maintainer could merge a patch without going through us
*/
-#define ISCSI_VERSION_STR "2.1.1"
+#define ISCSI_VERSION_STR "2.1.3"
#define ISCSI_VERSION_FILE "/sys/module/scsi_transport_iscsi/version"
#endif
diff --git a/utils/Makefile b/utils/Makefile
index f65f1e7..aed3bb0 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -1,7 +1,7 @@
# This Makefile will work only with GNU make.
CFLAGS ?= -O2 -fno-inline -g
-CFLAGS += -Wall -Wstrict-prototypes
+CFLAGS += -Wall -Wextra -Wstrict-prototypes
PROGRAMS = iscsi-iname
all: $(PROGRAMS)
diff --git a/utils/fwparam_ibft/fwparam_ibft.c b/utils/fwparam_ibft/fwparam_ibft.c
index 52edac1..e68e503 100644
--- a/utils/fwparam_ibft/fwparam_ibft.c
+++ b/utils/fwparam_ibft/fwparam_ibft.c
@@ -463,6 +463,7 @@ fwparam_ibft(struct boot_context *context, const char *filepath)
if (stat(filename, &buf)!=0) {
fprintf(stderr, "Could not stat file %s: %s (%d)\n",
filename, strerror(errno), errno);
+ close(fd);
return -1;
}
/* And if not zero use that size */
diff --git a/utils/fwparam_ibft/fwparam_ppc.c b/utils/fwparam_ibft/fwparam_ppc.c
index 429d45c..da9d76e 100644
--- a/utils/fwparam_ibft/fwparam_ppc.c
+++ b/utils/fwparam_ibft/fwparam_ppc.c
@@ -76,6 +76,9 @@ static char *find_devtree(const char *filename)
* /chosen.
*/
+ if (!devtree)
+ return NULL;
+
chop_at = strstr(devtree, "/chosen");
if (!chop_at)
chop_at = strstr(devtree, "/aliases");
@@ -289,15 +292,17 @@ static int find_file(const char *filename)
fprintf(stderr, "%s: Could not open %s: %s (%d)\n",
__func__, filename, strerror(errno), errno);
free(bootpath_val);
+ bootpath_val = NULL;
return -1;
}
bytes_read = read(fd, bootpath_val, bootpath_stat.st_size);
close(fd);
- free(bootpath_val);
if (bytes_read != bootpath_stat.st_size) {
- fprintf(stderr, "%s: Could not open %s: %s (%d)\n",
+ fprintf(stderr, "%s: Failed to read %s: %s (%d)\n",
__func__, filename, strerror(EIO), EIO);
+ free(bootpath_val);
+ bootpath_val = NULL;
return -1;
}
@@ -332,9 +337,16 @@ static int find_initiator(const char *fpath, const struct stat *sb, int tflag,
"/aliases/iscsi-disk"))) {
if (dev_count < OFWDEV_MAX) {
- ofwdevs[dev_count++] = dev =
- calloc(sizeof(struct ofw_dev), 1);
+ dev = calloc(sizeof(struct ofw_dev), 1);
+ if (!dev)
+ return -ENOMEM;
+
dev->prop_path = strdup(fpath + devtree_offset);
+ if (!dev->prop_path) {
+ free(dev);
+ return errno;
+ }
+ ofwdevs[dev_count++] = dev;
}
}
return 0;
@@ -371,6 +383,8 @@ static int loop_devs(const char *devtree)
if (!error)
error = locate_mac(devtree, ofwdevs[i]);
+ free(bootpath_val);
+ bootpath_val = NULL;
}
}
return error;
@@ -432,6 +446,7 @@ int fwparam_ppc_boot_info(struct boot_context *context)
char filename[FILENAMESZ];
int error;
char *devtree;
+ int i;
/*
* For powerpc, our operations are fundamentally to locate
@@ -458,9 +473,10 @@ int fwparam_ppc_boot_info(struct boot_context *context)
if (error)
goto free_devtree;
- if (find_file(filename) < 1)
+ if (find_file(filename) < 1) {
error = ISCSI_ERR_NO_OBJS_FOUND;
- else {
+ goto free_devtree;
+ } else {
if (debug)
printf("%s:\n%s\n\n", filename, bootpath_val);
/*
@@ -470,12 +486,12 @@ int fwparam_ppc_boot_info(struct boot_context *context)
if (!strstr(bootpath_val, "iscsi")) {
error = ISCSI_ERR_INVAL;
- goto free_devtree;
+ goto free_bootpath_val;
}
ofwdevs[0] = calloc(1, sizeof(struct ofw_dev));
if (!ofwdevs[0]) {
error = ISCSI_ERR_NOMEM;
- goto free_devtree;
+ goto free_bootpath_val;
}
error = parse_params(bootpath_val, ofwdevs[0]);
@@ -490,8 +506,16 @@ int fwparam_ppc_boot_info(struct boot_context *context)
free(ofwdevs[0]);
}
+free_bootpath_val:
+ free(bootpath_val);
+ bootpath_val = NULL;
+
free_devtree:
free(devtree);
+ for (i = 0; i < dev_count; i++)
+ if (ofwdevs[i])
+ free(ofwdevs[i]);
+
return error;
}
@@ -506,6 +530,7 @@ int fwparam_ppc_get_targets(struct list_head *list)
struct boot_context *context;
int error;
char *devtree;
+ int i;
/*
* For powerpc, our operations are fundamentally to locate
@@ -532,9 +557,10 @@ int fwparam_ppc_get_targets(struct list_head *list)
if (error)
goto free_devtree;
- if (find_file(filename) < 1)
+ if (find_file(filename) < 1) {
error = ISCSI_ERR_NO_OBJS_FOUND;
- else {
+ goto free_devtree;
+ } else {
if (debug)
printf("%s:\n%s\n\n", filename, bootpath_val);
/*
@@ -544,12 +570,12 @@ int fwparam_ppc_get_targets(struct list_head *list)
if (!strstr(bootpath_val, "iscsi")) {
error = ISCSI_ERR_INVAL;
- goto free_devtree;
+ goto free_bootpath_val;
}
ofwdevs[0] = calloc(1, sizeof(struct ofw_dev));
if (!ofwdevs[0]) {
error = ISCSI_ERR_NOMEM;
- goto free_devtree;
+ goto free_bootpath_val;
}
error = parse_params(bootpath_val, ofwdevs[0]);
@@ -566,8 +592,15 @@ int fwparam_ppc_get_targets(struct list_head *list)
}
free(ofwdevs[0]);
}
+free_bootpath_val:
+ free(bootpath_val);
+ bootpath_val = NULL;
free_devtree:
free(devtree);
+ for (i = 0; i < dev_count; i++)
+ if (ofwdevs[i])
+ free(ofwdevs[i]);
+
return error;
}
diff --git a/utils/fwparam_ibft/fwparam_sysfs.c b/utils/fwparam_ibft/fwparam_sysfs.c
index a0cd1c7..87fd6d4 100644
--- a/utils/fwparam_ibft/fwparam_sysfs.c
+++ b/utils/fwparam_ibft/fwparam_sysfs.c
@@ -115,8 +115,11 @@ static int get_iface_from_device(char *id, struct boot_context *context)
break;
}
- if (sscanf(dent->d_name, "net:%s", context->iface) != 1)
+ if (sscanf(dent->d_name, "net:%s", context->iface) != 1) {
rc = EINVAL;
+ break;
+ }
+
rc = 0;
break;
} else {
diff --git a/utils/iscsi-iname.c b/utils/iscsi-iname.c
index da850dc..834352e 100644
--- a/utils/iscsi-iname.c
+++ b/utils/iscsi-iname.c
@@ -40,6 +40,13 @@
* a seperator and 12 characters (6 random bytes in hex representation) */
#define PREFIX_MAX_LEN 210
+static void usage(void)
+{
+ fprintf(stderr, "Usage: iscsi-iname [-h | --help | -p <prefix>]\n");
+ fprintf(stderr, "where <prefix> has max length of %d\n",
+ PREFIX_MAX_LEN);
+}
+
int
main(int argc, char *argv[])
{
@@ -68,15 +75,17 @@ main(int argc, char *argv[])
"on every invocation.\n");
exit(0);
} else if ( strcmp(prefix, "-p") == 0 ) {
+ if (argc != 3) {
+ usage();
+ exit(1);
+ }
prefix = argv[2];
if (strnlen(prefix, PREFIX_MAX_LEN + 1) > PREFIX_MAX_LEN) {
- printf("Error: Prefix cannot exceed %d "
- "characters.\n", PREFIX_MAX_LEN);
+ usage();
exit(1);
}
} else {
- printf("\nUsage: iscsi-iname [-h | --help | "
- "-p <prefix>]\n");
+ usage();
exit(0);
}
} else {
@@ -87,7 +96,8 @@ main(int argc, char *argv[])
* uniqueness properties
*/
- if ((fd = open(RANDOM_NUM_GENERATOR, O_RDONLY))) {
+ fd = open(RANDOM_NUM_GENERATOR, O_RDONLY);
+ if (fd != -1) {
e = read(fd, &entropy, 16);
if (e >= 1)
MD5Update(&context, (md5byte *)entropy, e);
@@ -132,7 +142,8 @@ main(int argc, char *argv[])
* good as any other).
*/
- if ((fd = open(RANDOM_NUM_GENERATOR, O_RDONLY))) {
+ fd = open(RANDOM_NUM_GENERATOR, O_RDONLY);
+ if (fd != -1) {
if (read(fd, entropy, 1) == 1)
bytes = &digest[(entropy[0] % (sizeof(digest) - 6))];
close(fd);