Move the iSCSI target and initiator source across from dist/iscsi to

external/bsd/iscsi
This commit is contained in:
agc 2009-06-21 21:20:30 +00:00
parent 6a58b20453
commit 2f24582978
62 changed files with 29255 additions and 0 deletions

View File

@ -0,0 +1,42 @@
$NetBSD: COMPATIBILITY,v 1.1 2009/06/21 21:20:30 agc Exp $
The NetBSD iSCSI initiator has been tried with the following initiators:
1. Microsoft iSCSI initiator, versions 1.xx and 2.03
Tested by Alistair Crooks
Seems to work fine - instructions in place at
ftp://ftp.netbsd.org/pub/NetBSD/misc/agc/HOWTO-iSCSI-initiator.pdf
(This is the initiator that is used to test new releases)
Entry added: 26/10/2007
2. Solaris 10 Express 06/04
Tested by Alistair Crooks
Only a small test case was tried
VPD83 functionality was added for this initiator
Entry added: 26/10/2007
3. IBM AIX 5.3 iSCSI initiator
Tested by Andreas
Information in
http://mail-index.netbsd.org/current-users/2007/10/12/0008.html
Entry added: 26/10/2007
4. Linux open-iscsi initiator
Tested by Mark Foster
No issues
http://mark.foster.cc/wiki/index.php/User:Fostermarkd/FreeBSD/iSCSI
Entry added: 24/12/2007
5. NetBSD iSCSI initiator
Tested by Alistair Crooks
Works fine - instructions in
http://mail-index.netbsd.org/netbsd-users/2007/11/10/0002.html
(This initiator receives the most testing with the NetBSD iSCSI target)
Entry added: 24/12/2007
Any information on other initiators tried (either positive or negative)
would be gratefully received.
Alistair Crooks
agc@NetBSD.org
Last updated: 24/12/2007

224
external/bsd/iscsi/dist/doc/FAQ vendored Normal file
View File

@ -0,0 +1,224 @@
iSCSI Frequently Asked Questions
================================
Q1. What is iSCSI?
==================
A1. It's an IETF standard (RFC 3720) for remote access to block-level
storage. It can be thought of as similar to NFS, except that an NFS
server exports files; the iSCSI target exports blocks to the iSCSI
initiators, which are the clients.
Q2. What's the difference between an initiator and a target?
============================================================
A2. The target is the iSCSI server - it serves up blocks to the
clients, which are called initiators. Typically, initiators are part
of the operating system, since the operating system manages block
storage, presenting it to the user as file systems sitting on top of
the storage.
Targets do not generally need to be part of the operating system,
indeed there is some flexibility to be gained by having targets as
part of the user-level daemons that are run. This means that
security credentials need not be buried in the kernel.
Q3. So how do I use it?
=======================
A3. Firstly, you need to set up the iSCSI target. The target is
simply sitting there, waiting for requests for blocks. So we need to
configure the target with an area of storage for it to present to the
initiators.
To set up the target, you need to edit the /etc/iscsi/targets file.
It has a certain layout, to provide a means of (a) mirroring and (b)
combining multiple areas to present one large contiguous area of
storage. This can be multiply-layered.
The basic unit of storage is an extent. This can be either a file
or a device. The offset of the start of the extent to be presented
must be given, and also the length of the extent.
A device is made up of one or more extents, and/or one or more
other devices.
At the highest level, a target is what is presented to the initiator,
and is made up of one or more devices, and/or one or more extents.
The simple example is as follows, consisting of one piece of storage
presented by one target:
# extent file or device start length
extent0 /tmp/iscsi-target0 0 100MB
will produce an extent of storage which is based on one file,
/tmp/iscsi-target0, which starts 0 bytes into the file, and is 100 MB
in length. The file will be created if it does not already exist.
# target storage netmask
target0 extent0 0.0.0.0/0
That extent is then used in target0, and will be presented to an
initiator running on any host.
Extents must be defined before they can be used, and extents cannot
be used more than once.
Devices are used to combine extents or other devices. Device
definitions have the following format:
# devices
device0 RAID1 extent0 extent1
A "RAID1" device behaves in much the same way that RAID1 devices work
in the storage arena - they mirror the original storage. There can be
any number of devices or extents in a RAID1 device, not just 2, but
each device or extent must be of the same size.
A "RAID0" device combines the storage, to produce a larger area of
(virtually) "contiguous" storage.
Devices must be defined before they can be used, and devices may not
be used more than once.
A more detailed example would be as follows:
# Complex file showing 3-way RAID1 (with RAID1 components),
# also using local and (NFS) remote components
# extents
extent0 /iscsi/extents/0 0 100MB
extent1 /imports/remote1/iscsi/extents/0 0 100MB
extent2 /iscsi/extents/1 0 100MB
extent3 /imports/remote1/iscsi/extents/1 0 100MB
extent4 /iscsi/extents/2 0 100MB
extent5 /imports/remote1/iscsi/extents/2 0 100MB
extent6 /iscsi/extents/3 0 100GB
# devices
device0 RAID1 extent0 extent1
device1 RAID1 extent2 extent3
device2 RAID1 extent4 extent5
device3 RAID1 device0 device1 device2
# targets
target0 device3 10.4.0.0/16
# a target can be made from just an extent
target1 extent6 127.0.0.0/8
which will make 7 extents, 3 of them 100 MB in length and remote (via
NFS), and 3 of them 100 MB in length and local, and one of them large
(100 GB) and local. Three separate occurrences of a local and remote
100 MB extent are combined to make three RAID1 devices, and then those
three RAID1 devices are combined into another RAID1 device, and
presented as target0.
The other extent is used to present a simple 100 GB of storage as
target1.
Q4. What about security?
=========================
A4. A good question. RFC 3720 specifies CHAP, SRM and Kerberos as
methods of providing authentication and/or security. In practice,
it's whatever is provided by the initiator you are using which will
determine what authentication or security is used.
If you want any form of security, it's probably best to use ssh port
forwarding for all your traffic if you're worried about security.
CHAP will only provide authentication, the other information will flow
across the network in clear.
Q5. Using the Microsoft initiator, I can't login with CHAP
===========================================================
A5. The 1.06 Microsoft initiator silently enforces a chap password
length of at least 12 characters. If you enter a password which is
less than that, your Discovery login will silently fail.
Since CHAP provides very little authentication anyway, you are advised
not to use it - ssh port forwarding, and the use of tcp wrappers,
will do a much better job of protection.
Q6. What initiators work with the NetBSD iSCSI target?
======================================================
A6. The NetBSD target has been tested at various times with the Microsoft
iSCSI initiator, version 1.06 (which can be downloaded for free from
www.microsoft.com, but needs Windows XP Pro to work), and also with the
NetBSD test harness, which is provided, but not installed, in the same
place as the target.
Q7. What is the difference between Discovery and Normal login?
===============================================================
A7. On direct-attached storage, the kernel verifies what storage is
available, and assigns a device node to it. With iSCSI, storage can
come and go, and our proximity to the devices doesn't matter. So we
need to find a different method of finding out what iSCSI storage is
out there.
This is done by a "Discovery" iSCSI session - the initiator logs in
to the target, finds out what storage is being presented, then logs
back out. This can be seen by the syslog entries:
Feb 5 10:33:44 sys3 iscsi-target: > Discovery login from iqn.1991-05.com.microsoft:inspiron on 10.4.1.5
Feb 5 10:33:44 sys3 iscsi-target: < Discovery logout from iqn.1991-05.com.microsoft:inspiron on 10.4.1.5
The initiator will then perform a "Normal" login session, which will
establish a session between the initiator and target. This is denoted
by the syslog entries:
Feb 5 00:00:28 sys3 iscsi-target: > Discovery login from iqn.1993-03.org.NetBSD.iscsi-initiator:agc on 127.0.0.1
Feb 5 00:00:28 sys3 iscsi-target: < Discovery logout from iqn.1993-03.org.NetBSD.iscsi-initiator:agc on 127.0.0.1
Feb 5 00:00:28 sys3 iscsi-target: > Normal login from iqn.1993-03.org.NetBSD.iscsi-initiator:agc on 127.0.0.1
Feb 5 00:05:32 sys3 iscsi-target: < Normal logout from iqn.1993-03.org.NetBSD.iscsi-initiator:agc on 127.0.0.1
Q8. So what do I do to try it?
==============================
A8. Perform the following steps:
a) define the storage that you want to present in /etc/iscsi/targets
b) start the iSCSI target: /etc/rc.d/iscsi_target forcestart
c) use an initiator to point it at the machine you started it on
Q9. Why does the test harness not work properly?
================================================
A9. Firstly, you should be invoking the test harness as
iscsi-harness -n 3 -h localhost
where the 'n' option is the number of iterations to perform, and the
'h' parameter is the name or address of the machine where the
iscsi-target is running.
If the harness was invoked properly, check any error messages which
the test harness sends:
If one of them looks like:
No matching user configuration entry for `agc' was found
Please add an entry for `agc' to `/etc/iscsi/auths'
(where "agc" is substituted for the name of the user who was running
the test harness), then please do as suggested. The iSCSI test harness
tests, amongst other things, the CHAP authentication process, and so
CHAP credentials for that user are needed.
Alistair Crooks
agc@NetBSD.org
Wed Feb 8 07:21:56 GMT 2006

View File

@ -0,0 +1,245 @@
Encrypted iSCSI Devices on NetBSD
=================================
This document shows how to set up and run an encrypted iSCSI device on
NetBSD. Encryption of devices can be used for maintaining privacy on
devices located remotely, possibly on co-located hardware, for
instance, or on machines which could be stolen, or to which others
could gain access.
To encrypt the iSCSI device, we use the NetBSD iSCSI initiator,
available in NetBSD-current, and the standard cgd device. In all,
setting up an encrypted device in this manner should take less than 15
minutes, even for someone unfamiliar with iSCSI or cgd.
The approach is to layer a vnd on top of the "storage" file presented
by the iSCSI target. This is exactly the same as normal. On top of that
vnd, we layer a cgd device, which ensures that all data is encrypted
on the iSCSI device.
1. Device Initialisation
========================
This first section shows how to initialise the device, a one-time
operation.
Firstly, the initiator is started, pointing at the machine which is
presenting the iSCSI storage (i.e. the machine on which the iSCSI
target is running). In this example, the target is running on the
same machine as the initiator (a laptop called, in a moment of
inspiration, inspiron1300). A 50 MB iSCSI target is being presented
as target1.
# obj/iscsifs -u agc -h inspiron1300.wherever.co.uk /mnt &
[1] 11196
#
# df
Filesystem 1K-blocks Used Avail %Cap Mounted on
/dev/dk0 28101396 20862004 5834324 78% /
kernfs 1 1 0 100% /kern
procfs 4 4 0 100% /proc
ptyfs 1 1 0 100% /dev/pts
/dev/puffs 0 0 0 100% /mnt
#
Looking at the last line, we can see that the initiator is running
via the puffs device.
We now add a vnd device on top of the storage which the target is
presenting:
# vnconfig vnd0 /mnt/inspiron1300.wherever.co.uk/target1/storage
#
We now add a disklabel, which is offset 63 blocks into the iSCSI device.
This is so that the encrypted device which we shall put on top of the vnd
does not clash with the vnd's label. Chapter 14 of the NetBSD guide, on
setting up a cgd device, recommends that the cgd's type be "ccd".
# disklabel -e vnd0
# /dev/rvnd0d:
type: vnd
disk: vnd
label: fictitious
flags:
bytes/sector: 512
sectors/track: 32
tracks/cylinder: 64
sectors/cylinder: 2048
cylinders: 50
total sectors: 102400
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0 # microseconds
track-to-track seek: 0 # microseconds
drivedata: 0
4 partitions:
# size offset fstype [fsize bsize cpg/sgs]
a: 102336 63 ccd 2048 16384 28360 # (Cyl. 0 - 49)
d: 102400 0 unused 0 0 # (Cyl. 0 - 49)
~
=== EdDk.a11098a [confmode] is /tmp/EdDk.a11098a ================(22,11) 95% ==
#
We now set up the cgd device, pointing it at the vnd device.
# priv cgdconfig -s cgd0 /dev/vnd0a aes-cbc 128 < /dev/urandom
#
and then zero the cgd device's storage.
# dd if=/dev/zero of=/dev/rcgd0d bs=32k
dd: /dev/rcgd0d: Invalid argument
1601+0 records in
1600+0 records out
52428800 bytes transferred in 16.633 secs (3152095 bytes/sec)
#
We now unconfigure the cgd device.
# cgdconfig -u cgd0
#
and then write using the disklabel verification method onto the cgd. Sometimes,
this process does not always complete properly, and so it has to be repeated.
# cgdconfig -g -V disklabel -o /etc/cgd/vnd0a aes-cbc 256
cgdconfig: could not calibrate pkcs5_pbkdf2
cgdconfig: Failed to generate defaults for keygen
# cgdconfig -g -V disklabel -o /etc/cgd/vnd0a aes-cbc 256
#
Now we have to add the password to the cgd device
# cgdconfig -V re-enter cgd0 /dev/vnd0a
/dev/vnd0a's passphrase:
re-enter device's passphrase:
#
and disklabel inside the cgd itself:
# disklabel -I -e cgd0
# /dev/rcgd0d:
type: cgd
disk: cgd
label: fictitious
flags:
bytes/sector: 512
sectors/track: 2048
tracks/cylinder: 1
sectors/cylinder: 2048
cylinders: 49
total sectors: 102336
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0 # microseconds
track-to-track seek: 0 # microseconds
drivedata: 0
4 partitions:
# size offset fstype [fsize bsize cpg/sgs]
a: 102336 0 4.2BSD 2048 16384 28360 # (Cyl. 0 - 49*)
d: 102336 0 unused 0 0 # (Cyl. 0 - 49*)
~
~
=== EdDk.a11253a [confmode] is /tmp/EdDk.a11253a =================(22,53) 95% ==
#
Having placed a disklabel inside the cgd, we can now make a filesystem on there:
# newfs /dev/rcgd0a
/dev/rcgd0a: 50.0MB (102336 sectors) block size 8192, fragment size 1024
using 4 cylinder groups of 12.49MB, 1599 blks, 3136 inodes.
super-block backups (for fsck_ffs -b #) at:
32, 25616, 51200, 76784,
#
we can then mount the new file system in the cgd on the /iscsi mount
point:
# df
Filesystem 1K-blocks Used Avail %Cap Mounted on
/dev/dk0 28101396 20910216 5786112 78% /
kernfs 1 1 0 100% /kern
procfs 4 4 0 100% /proc
ptyfs 1 1 0 100% /dev/pts
/dev/puffs 0 0 0 100% /mnt
# mount /dev/cgd0a /iscsi
# df
Filesystem 1K-blocks Used Avail %Cap Mounted on
/dev/dk0 28101396 20910216 5786112 78% /
kernfs 1 1 0 100% /kern
procfs 4 4 0 100% /proc
ptyfs 1 1 0 100% /dev/pts
/dev/puffs 0 0 0 100% /mnt
/dev/cgd0a 49519 1 47043 0% /iscsi
#
The new file system, mounted on /iscsi, can now be used as normal.
2. Unmounting the Encrypted Device
==================================
The device can be freed up using the following commands:
# umount /iscsi
# cgdconfig -u cgd0
# vnconfig -u vnd0
3. Normal Usage
===============
In normal usage, the device can be mounted. Firstly, the initiator
must be configured to connect to the device:
# vnconfig vnd0 /mnt/inspiron1300.wherever.co.uk/target1/storage
# cgdconfig cgd0 /dev/vnd0a
/dev/vnd0a's passphrase:
#
I'm using dk devices on this machine, so I now have to access the cgd
device using the dk that was assigned in the cgdconfig step. If I
wasn't using dk devices, then I'd use the cgd device.
!!!SO PICK ONE OF THE FOLLOWING TWO COMMANDS!!!
# mount /dev/cgd0a /iscsi OR
# mount /dev/dk3 /iscsi
# ls -al /iscsi
total 3
drwxr-xr-x 2 root wheel 512 Jan 1 1970 .
drwxr-xr-x 35 root wheel 1536 Jan 5 08:59 ..
# df
Filesystem 1K-blocks Used Avail %Cap Mounted on
/dev/dk0 28101396 20910100 5786228 78% /
kernfs 1 1 0 100% /kern
procfs 4 4 0 100% /proc
ptyfs 1 1 0 100% /dev/pts
/dev/puffs 0 0 0 100% /mnt
/dev/dk3 49519 1 47043 0% /iscsi
#
4. Conclusion
=============
An iSCSI disk can be in a location over which complete control
cannot be assured. In order to ensure privacy, the cgd device
can be used to encrypt the data on the iSCSI device.
This document has shown how to set up a cgd device on top of the
iSCSI device, and how to mount and unmount on a regular basis.
Alistair Crooks
Sat Jan 5 22:08:32 GMT 2008

View File

@ -0,0 +1,67 @@
The NetBSD iSCSI HOWTO
======================
This document is intended to tell you how to set up an iSCSI target on
a NetBSD host, so that block storage can be presented to the network.
It then goes on to show how to connect to that storage using the
Microsoft iSCSI initiator (version 1.06, running on Windows XP).
1. Configuring the NetBSD iSCSI target
======================================
1.1. Decide what storage will be presented
The iSCSI target serves up block storage to clients on the network.
These clients are called "initiators". Firstly, we must decide how
much storage we are going to serve up, and for this document, we
will serve up 100 MB. It will be in a file called /tmp/iscsi-target0.
So we must first edit /etc/iscsi/targets, so that it contains the
following lines:
# extent file or device start length
extent0 /tmp/iscsi-target0 0 100MB
# target flags storage netmask
target0 rw extent0 0/0
The extent definition tells the file which is used as backing
store. It is persistent, so that the target can serve up the
same storage after reboot. Its length is 100 MB, and there is
no offset into the file for the start of the extent. (An offset
is useful if you need to skip over MBRs, or disklabels).
The extent is mounted read-write by "target0", and is served up
to any host (the 0.0.0.0/0 netmask).
1.2. Start the iscsi-target
Issue the command:
# /etc/rc.d/iscsi_target forcestart
and you should see the messages from the iscsi-target:
Starting iscsi_target.
Reading configuration from `/etc/iscsi/targets'
target0:rw:0/0
extent0:/tmp/iscsi-target0:0:104857600
DISK: 1 logical units (204800 blocks, 512 bytes/block), type iscsi fs
DISK: LU 0: 100 MB disk storage for "target0"
TARGET: TargetName is iqn.1994-04.org.netbsd.iscsi-target
1.3 You're done!
Congratulations - your iSCSI target is now up and running and
serving blocks to initiators.
2. Configuring the Microsoft iSCSI initiator, version 1.06
==========================================================
Please see the relevant documentation on setting up iSCSI initiators.
Alistair Crooks
Sun Jan 6 10:38:19 GMT 2008

64
external/bsd/iscsi/dist/doc/PERFORMANCE vendored Normal file
View File

@ -0,0 +1,64 @@
----------------------
USER LEVEL PERFORMANCE
----------------------
If your system is correctly configured with GbE and a GHz processor,
you should expect user level iSCSI performance similar to the following.
This output was generated by running utest against a target running uramdisk.
##BEGIN DEVICE-SPECIFIC TESTS[0:0]##
read_capacity PASSED
write_read_test PASSED
integrity_test PASSED
SCSI op 0x28: 1000 iters in 0.24 sec --> 244.38 usec
SCSI op 0x2a: 1000 iters in 0.25 sec --> 249.78 usec
SCSI op 0x25: 1000 iters in 0.25 sec --> 250.12 usec
8192 bytes/request: 8 MB written in 0.33 seconds --> 24.35 MB/sec
16384 bytes/request: 8 MB written in 0.30 seconds --> 26.74 MB/sec
32768 bytes/request: 8 MB written in 0.20 seconds --> 39.06 MB/sec
65536 bytes/request: 8 MB written in 0.15 seconds --> 52.95 MB/sec
131072 bytes/request: 8 MB written in 0.12 seconds --> 66.74 MB/sec
262144 bytes/request: 8 MB written in 0.10 seconds --> 77.76 MB/sec
8192 bytes/request: 8 MB read in 0.37 seconds --> 21.34 MB/sec
16384 bytes/request: 8 MB read in 0.19 seconds --> 41.47 MB/sec
32768 bytes/request: 8 MB read in 0.13 seconds --> 62.04 MB/sec
65536 bytes/request: 8 MB read in 0.11 seconds --> 70.99 MB/sec
131072 bytes/request: 8 MB read in 0.10 seconds --> 83.62 MB/sec
262144 bytes/request: 8 MB read in 0.09 seconds --> 92.38 MB/sec
##END DEVICE-SPECIFIC TESTS[0:0]##
------------------------
KERNEL LEVEL PERFORMANCE
------------------------
Kernel level performance (ktest to kramdisk.o) should be similar to the output
shown below. Note that this test does not go through the linux storage stack,
but is rather a kernel level iSCSI test with no attached filesystem or SCSI
midlayer.
This output was generated by installing the module intel_iscsi.o and then
running "ktest <device>" where <device> is one of your iscsi devices (e.g,
/dev/sdb). Although you specify a single device on the command line, all
target devices are tested.
##BEGIN DEVICE-SPECIFIC TESTS[0:0]##
read_capacity PASSED
write_read_test PASSED
integrity_test PASSED
SCSI op 0x28: 1000 iters in 25 jiffies --> 250 usec
SCSI op 0x2a: 1000 iters in 25 jiffies --> 250 usec
SCSI op 0x25: 1000 iters in 25 jiffies --> 250 usec
8192 bytes/request: 8388608 bytes written in 38 jiffies --> ~ 21 MB/second
16384 bytes/request: 8388608 bytes written in 38 jiffies --> ~ 21 MB/second
32768 bytes/request: 8388608 bytes written in 23 jiffies --> ~ 34 MB/second
65536 bytes/request: 8388608 bytes written in 16 jiffies --> ~ 50 MB/second
131072 bytes/request: 8388608 bytes written in 12 jiffies --> ~ 66 MB/second
262144 bytes/request: 8388608 bytes written in 10 jiffies --> ~ 79 MB/second
8192 bytes/request: 8388608 bytes read in 26 jiffies --> ~ 30 MB/second
16384 bytes/request: 8388608 bytes read in 20 jiffies --> ~ 39 MB/second
32768 bytes/request: 8388608 bytes read in 12 jiffies --> ~ 66 MB/second
65536 bytes/request: 8388608 bytes read in 12 jiffies --> ~ 66 MB/second
131072 bytes/request: 8388608 bytes read in 10 jiffies --> ~ 79 MB/second
262144 bytes/request: 8388608 bytes read in 9 jiffies --> ~ 88 MB/second
##END DEVICE-SPECIFIC TESTS[0:0]##

188
external/bsd/iscsi/dist/doc/README vendored Normal file
View File

@ -0,0 +1,188 @@
---------------------------------------
Intel iSCSI v20 Reference Implementation
---------------------------------------
This is a software implementation of iSCSI v20. Included in this distribution
are both host and target mode drivers with built in conformance and performance
tests, and sockets tests that can be used to simulate TCP traffic identical to
that generated between a real iSCSI host and target.
See PERFORMANCE for information regarding the expected performance of this
distribution.
This code has been successfully compiled and tested on Redhat 8.0
(kernel version 2.4.18-14) and Redhat 9.0 (kernel version 2.4.20)
with UP and SMP configurations.
-------------------
Starting the System
-------------------
1a) Modify the array in initiator.c to contain your target ip addresses and port
numbers. If you specify a TargetName there will be no discovery process. For
example, targets 0 and 2 below will first be discovered. Target 1 will not.
ISCSI_PORT is the default port defined in iscsi.h and currently set to 3260.
static INITIATOR_TARGET_T g_target[CONFIG_INITIATOR_NUM_TARGETS] = {
{"192.168.10.10", ISCSI_PORT, "", NULL, 0},
{"192.168.10.11", ISCSI_PORT, "iqn.com.intel.abc123", NULL, 0},
{"192.168.10.12", ISCSI_PORT, "", NULL, 0}};
The initiator currently only connects to one of the discovered targets. If
multiple TargetNames and TargetAddresses are returned, all but 1 are ignored.
1b) Alternately for the kernel mode driver you may specify ip addresses
in a file in the local directory called "./intel_iscsi_targets". This
file will also be looked for in the /etc directory or you may specify
the file name as a module parameter to the insmod command using the
"gfilename" argument, (insmod intel_iscsi.o gfilename="./targets").
The format for the contents of of the file is:
ip=192.168.10.10
ip=192.168.10.11 name=iqn.com.intel.abc123 port=3260
ip=192.168.10.12
The name and port fields are optional. If name is not specified, there
will be a discovery process. If port is not specified, the default port
of 3260 will be used.
1c) For the user mode intiator, if the first entry of the g_target array has ip
address "151.0.1.1", the initiator will prompt the user to enter the number
of targets and their ip addresses.
2) Modify the following constant in initiator.h accordingly:
#define CONFIG_INITIATOR_NUM_TARGETS 3
3) Run "make" to build each of:
intel_iscsi.o - kernel mode iSCSI initiator
kramdisk.o - kernel mode iSCSI target ramdisk
ufsdisk - user mode iSCSI target (disk stored as file in /tmp)
ufsdisk_mmap - same as ufsdisk, but uses mmap
uramdisk - user mode iSCSI ramdisk
utest - user mode iSCSI test suite
ktest - invokes same tests as utest, but from within device driver
usocktest - user mode sockets test that simulates iSCSI traffic
4) Start a user level target (uramdisk, ufsdisk, ufsdisk_mmap) on each target
machine:
Usage: -t <name> iSCSI TargetName (dflt "iqn.com.intel.abc123")
-p <port> Port Number (dflt 3260)
-b <block len> Block Length (dflt 512)
-n <num blocks> Number of Blocks (dflt 204800)
Or start the kernel level target (kramdisk.o):
Usage: insmod kramdisk.o port=<port>
block_len=<block length>
num_blocks=<number of blocks>
With ufsdisk and ufsdisk_mmap you can directly access a device in /dev by
creating a symbolic link in /tmp to point to the appropriate device. For
example:
"ln -s /dev/sdd /tmp/iqn.com.intel.abc123_3260_iscsi_disk_lun_0"
And kramdisk.o only operates in ramdisk mode.
5) Run utest. If you did not successfully connect to each target machine you
specified in initiator.c, then there was a problem. Make sure initiator.h
and initiator.c were correctly edited and all your targets had been started.
6) As root, run "insmod ./intel_iscsi.o." You should see output similar to the
following when either viewing /var/log/messages or running dmesg:
*********************************************
* PARAMETERS NEGOTIATED *
* *
* InitiatorName: Intel *
* InitiatorAlias: Intel *
* SessionType: normal *
* TargetName: iqn.com.intel.abc12 *
*********************************************
*********************************************
* LOGIN SUCCESSFUL *
* *
* CID: 0 *
* ISID: 0 *
* TSID: 1 *
* CmdSN: 0 *
* MaxCmdSN: 0 *
* ExpStatSN: 0 *
*********************************************
Vendor: Intel Model: Intel Labs iSCSI Rev: 2
Type: Direct-Access ANSI SCSI revision: 02
Detected scsi disk sdb at scsi2, channel 0, id 0, lun 0
SCSI device sdb: 204800 512-byte hdwr sectors (105 MB)
sdb: unknown partition table
You can now use the device as you would any other SCSI device. You can also
view driver statistics by viewing the file in /proc/scsi/iscsi. Writing to
the file (e.g. echo reset > /proc/scsi/iscsi/1) will reset all counters.
------------------
Testing the System
------------------
Once your targets and host have been started, you can test the installation
using either a single target, or by creating a RAID volume over multiple
targets.
To test a single target you can either directly read and write the device by
opening, for example, /dev/sdd. Or you can create a filesystem on the device:
fdisk /dev/sdd
mkfs /dev/sdd1
mount -t ext2 /dev/sdd1 /mnt/iscsi_fs
To test a multiple target installation, you can create a RAID volume,
virtualizing multiple targets as one SCSI device. The Linux RAID modules
will either need to be installed or compiled into the kernel. The file
/etc/raidtab must be created to reflect your targets. For example,
raiddev /dev/md0
raid-level 0
nr-raid-disks 5
persistent-superblock 0
chunk-size 64
device /dev/sdd
raid-disk 0
device /dev/sde
raid-disk 1
device /dev/sdf
raid-disk 2
device /dev/sdg
raid-disk 3
device /dev/sdh
raid-disk 4
After initialized the raid device with "mkraid /dev/md0," you can use /dev/md0
as though it were a normal SCSI device. For example,
mkfs /dev/md0
mount -t ext2 /dev/md0 /mnt/iscsi_fs
--------------------
When Things Go Wrong
--------------------
Check the kernel error messages /var/log/messages or run the dmesg command to
see any errors reported from the host driver. The targets will report target
errors to standard output.
If you need more fine grained debugging, modify the Makefile to turn on the
compilation flag CONFIG_ISCSI_DEBUG. Then run "make clean," and then "make."
You can select which type of debugging statements get printed by modifying
iscsiutil.h
-------------------------------------
Interoperability with Cisco Initiator
-------------------------------------
The target is tested to be interoperable with Cisco Initiator release
3.4.1.1

58
external/bsd/iscsi/dist/doc/README_OSD vendored Normal file
View File

@ -0,0 +1,58 @@
-------------------------
Installing the OSD System
-------------------------
1. Build kernel version 2.4 w/ SMP mode disabled and make sure the
directory /usr/src/linux points to this build.
2. Modify initiator.h and initiator.c (as per the README) to point to
your intended target.
3. Run 'make osd' to build all the OSD executables. In particular,
you need uosd, so.o, intel_iscsi.o and osdfs.o.
4. Run 'make all' to build the remaining executables.
5. Select a machine as the target and run "uosd -f" as root on this
machine. This will create files and directories in /tmp.
----------------------
Testing the OSD System
----------------------
6. Run utest to make sure the target is working OK.
7. Do an "insmod ./so.o" to install the Linux SCSI upper layer driver for OSD.
8. Do an "insmod ./intel_iscsi.o" to install the kernel mode iSCSI initiator.
9. Do an "insmod ./osdfs.o" to install the file system.
10. Make the OSD device with "mknod /dev/so0 b 232 0".
11. Do a "mount -t osdfs /dev/so0 /mnt" to mount the filesystem.
12. Go to /mnt and run "echo Hello, World! > foo" to create an object
on the OSD.
13. Do a "cat foo" to read the object. you should see "Hello, world!"
From here you should be able to use /mnt as you would any filesystem.
--------------------
2.4.18 Modifications
--------------------
include/scsi/scsi.h:143
#define TYPE_OSD 0x0e
drivers/scsi/scsi.h:92:
#define MAX_SCSI_DEVICE_CODE 15
drivers/scsi/scsi.h:354:
#define MAX_COMMAND_SIZE 256
drivers/scsi/scsi.c:145:
"OSD ",
drivers/scsi/scsi_dma.c:248:
SDpnt->type == TYPE_DISK || SDpnt->type == TYPE_MOD || SDpnt->type == TYPE_OSD) {
drivers/scsi/scsi_scan.c:644:
case TYPE_OSD:
----------
Hints/Tips
----------
-Field testing on some workstations resulted in compiling errors if highmem support in the kernel as enabled

31
external/bsd/iscsi/dist/doc/license vendored Normal file
View File

@ -0,0 +1,31 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2004, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

101
external/bsd/iscsi/dist/include/compat.h vendored Normal file
View File

@ -0,0 +1,101 @@
#ifndef COMPAT_H_
#define COMPAT_H_
#include "config.h"
#include <sys/types.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_ASM_BYTEORDER_H
#include <asm/byteorder.h>
#endif
#ifdef HAVE_SYS_BYTEORDER_H
# include <sys/byteorder.h>
# if defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
# undef _BIG_ENDIAN
# define _BIG_ENDIAN 4321
# define _BYTE_ORDER _BIG_ENDIAN
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
# undef _LITTLE_ENDIAN
# define _LITTLE_ENDIAN 1234
# define _BYTE_ORDER _LITTLE_ENDIAN
# endif
#endif
#ifdef HAVE_BYTESWAP_H
#include <byteswap.h>
#endif
#ifdef HAVE_MACHINE_ENDIAN_H
#include <machine/endian.h>
#endif
#ifdef HAVE_LIBKERN_OSBYTEORDER_H
#include <libkern/OSByteOrder.h>
#endif
#ifndef HAVE_STRLCPY
size_t strlcpy(char *, const char *, size_t);
#endif
#ifndef __UNCONST
#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
#endif
#ifdef HAVE_HTOBE64
# define ISCSI_HTOBE64(x) htobe64(x)
# define ISCSI_BE64TOH(x) be64toh(x)
#else
# if defined(HAVE_LIBKERN_OSBYTEORDER_H)
# define ISCSI_HTOBE64(x) (x) = OSSwapBigToHostInt64((u_int64_t)(x))
# elif _BYTE_ORDER == _BIG_ENDIAN
# define ISCSI_HTOBE64(x) (x)
# elif defined(HAVE___BSWAP64)
# define ISCSI_HTOBE64(x) (x) = __bswap64((u_int64_t)(x))
# else /* LITTLE_ENDIAN */
# define ISCSI_HTOBE64(x) (((uint64_t)(ISCSI_NTOHL((uint32_t)(((x) << 32) >> 32))) << 32) | (uint32_t)ISCSI_NTOHL(((uint32_t)((x) >> 32))))
# endif /* LITTLE_ENDIAN */
# define ISCSI_BE64TOH(x) ISCSI_HTOBE64(x)
#endif
#ifndef _DIAGASSERT
# ifndef __static_cast
# define __static_cast(x,y) (x)y
# endif
#define _DIAGASSERT(e) (__static_cast(void,0))
#endif
/* Added for busybox, which doesn't define INFTIM */
#ifndef INFTIM
#define INFTIM -1
#endif
#ifndef HAVE_UUID_H
/* Length of a node address (an IEEE 802 address). */
#define _UUID_NODE_LEN 6
/*
* See also:
* http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
* http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
*
* A DCE 1.1 compatible source representation of UUIDs.
*/
typedef struct uuid_t {
uint32_t time_low;
uint16_t time_mid;
uint16_t time_hi_and_version;
uint8_t clock_seq_hi_and_reserved;
uint8_t clock_seq_low;
uint8_t node[_UUID_NODE_LEN];
} uuid_t;
void uuid_create(uuid_t *, uint32_t *);
void uuid_to_string(uuid_t *, char **, uint32_t *);
#endif
#endif /* COMPAT_H_ */

View File

@ -0,0 +1,84 @@
/* $NetBSD: conffile.h,v 1.1 2009/06/21 21:20:30 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CONFFILE_H_
#define CONFFILE_H_ 1
/* split routines */
#include <sys/param.h>
#include <stdio.h>
#include <time.h>
#include "defs.h"
DEFINE_ARRAY(strv_t, char *);
/* this struct describes a configuration file */
typedef struct conffile_t {
FILE *fp; /* in-core file pointer */
char name[MAXPATHLEN]; /* name of file */
int lineno; /* current line number */
int readonly; /* nonzero if file is readonly */
const char *sep; /* set of separators */
const char *comment; /* set of comment characters */
} conffile_t;
/* this struct describes an entry in the configuration file */
typedef struct ent_t {
char buf[BUFSIZ]; /* buffer with entry contents */
strv_t sv; /* split up string dynamic array */
} ent_t;
int conffile_open(conffile_t *, const char *, const char *, const char *, const char *);
int conffile_split(conffile_t *, ent_t *, char *);
int conffile_getent(conffile_t *, ent_t *);
int conffile_get_by_field(conffile_t *, ent_t *, int, char *);
int conffile_putent(conffile_t *, int, char *, char *);
int conffile_get_lineno(conffile_t *);
char *conffile_get_name(conffile_t *);
void conffile_printent(ent_t *);
void conffile_close(conffile_t *);
#ifndef PREFIX
#define PREFIX ""
#endif
#ifndef SYSCONFDIR
#define SYSCONFDIR "/etc"
#endif
#define _PATH_ISCSI_ETC SYSCONFDIR "/iscsi/"
#define _PATH_ISCSI_PASSWD PREFIX _PATH_ISCSI_ETC "auths"
#define _PATH_ISCSI_TARGETS PREFIX _PATH_ISCSI_ETC "targets"
#define _PATH_ISCSI_PID_FILE "/var/run/iscsi-target.pid"
#endif

218
external/bsd/iscsi/dist/include/config.h vendored Normal file
View File

@ -0,0 +1,218 @@
/* ../include/config.h. Generated from config.h.in by configure. */
/* ../include/config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <asm/byteorder.h> header file. */
/* #undef HAVE_ASM_BYTEORDER_H */
/* Define to 1 if you have the `asnprintf' function. */
/* #undef HAVE_ASNPRINTF */
/* Define to 1 if you have the `asprintf' function. */
#define HAVE_ASPRINTF 1
/* Define to 1 if you have the `bcopy' function. */
#define HAVE_BCOPY 1
/* Define to 1 if you have the `bswap64' function. */
#define HAVE_BSWAP64 1
/* Define to 1 if you have the <byteswap.h> header file. */
/* #undef HAVE_BYTESWAP_H */
/* Define to 1 if you have the <ctype.h> header file. */
#define HAVE_CTYPE_H 1
/* Define to 1 if you have the `daemon' function. */
#define HAVE_DAEMON 1
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the `fsync_range' function. */
#define HAVE_FSYNC_RANGE 1
/* Define to 1 if you have the `getaddrinfo' function. */
#define HAVE_GETADDRINFO 1
/* Define to 1 if you have the `getnameinfo' function. */
#define HAVE_GETNAMEINFO 1
/* Define to 1 if you have the `htobe64' function. */
/* #undef HAVE_HTOBE64 */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
/* #undef HAVE_LIBKERN_OSBYTEORDER_H */
/* Define to 1 if you have the `nsl' library (-lnsl). */
/* #undef HAVE_LIBNSL */
/* Define to 1 if you have the `resolv' library (-lresolv). */
#define HAVE_LIBRESOLV 1
/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef HAVE_LIBSOCKET */
/* Define to 1 if the system has the type `long long'. */
#define HAVE_LONG_LONG yes
/* Define to 1 if you have the <machine/endian.h> header file. */
#define HAVE_MACHINE_ENDIAN_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#define HAVE_NETINET_TCP_H 1
/* Define to 1 if you have the `poll' function. */
#define HAVE_POLL 1
/* Define to 1 if you have the <poll.h> header file. */
#define HAVE_POLL_H 1
/* Define to 1 if you have the <pthread.h> header file. */
#define HAVE_PTHREAD_H 1
/* Define to 1 if you have the <pwd.h> header file. */
#define HAVE_PWD_H 1
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1
/* Define to 1 if the system has the type `socklen_t'. */
#define HAVE_SOCKLEN_T yes
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strlcpy' function. */
#define HAVE_STRLCPY 1
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
/* Define to 1 if you have the `syslog' function. */
#define HAVE_SYSLOG 1
/* Define to 1 if you have the <syslog.h> header file. */
#define HAVE_SYSLOG_H 1
/* Define to 1 if you have the <sys/bswap.h> header file. */
#define HAVE_SYS_BSWAP_H 1
/* Define to 1 if you have the <sys/byteorder.h> header file. */
/* #undef HAVE_SYS_BYTEORDER_H */
/* Define to 1 if you have the <sys/mman.h> header file. */
#define HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/uio.h> header file. */
#define HAVE_SYS_UIO_H 1
/* Define to 1 if you have the <sys/vfs.h> header file. */
/* #undef HAVE_SYS_VFS_H */
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if the system has the type `unsigned long long'. */
#define HAVE_UNSIGNED_LONG_LONG yes
/* Define to 1 if you have the <utime.h> header file. */
#define HAVE_UTIME_H 1
/* Define to 1 if you have the `uuid_create' function. */
#define HAVE_UUID_CREATE 1
/* Define to 1 if you have the <uuid.h> header file. */
#define HAVE_UUID_H 1
/* Define to 1 if you have the `uuid_to_string' function. */
#define HAVE_UUID_TO_STRING 1
/* Define to 1 if you have the `vasnprintf' function. */
/* #undef HAVE_VASNPRINTF */
/* Define to 1 if you have the `vasprintf' function. */
#define HAVE_VASPRINTF 1
/* Define to 1 if you have the `vsnprintf' function. */
#define HAVE_VSNPRINTF 1
/* Define to 1 if you have the `__bswap64' function. */
/* #undef HAVE___BSWAP64 */
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "Alistair Crooks <agc@NetBSD.org>"
/* Define to the full name of this package. */
#define PACKAGE_NAME "netbsd-iscsi"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "netbsd-iscsi 20071221"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "netbsd-iscsi"
/* Define to the version of this package. */
#define PACKAGE_VERSION "20071221"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

View File

@ -0,0 +1,217 @@
/* ../include/config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define to 1 if you have the <asm/byteorder.h> header file. */
#undef HAVE_ASM_BYTEORDER_H
/* Define to 1 if you have the `asnprintf' function. */
#undef HAVE_ASNPRINTF
/* Define to 1 if you have the `asprintf' function. */
#undef HAVE_ASPRINTF
/* Define to 1 if you have the `bcopy' function. */
#undef HAVE_BCOPY
/* Define to 1 if you have the `bswap64' function. */
#undef HAVE_BSWAP64
/* Define to 1 if you have the <byteswap.h> header file. */
#undef HAVE_BYTESWAP_H
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
/* Define to 1 if you have the `daemon' function. */
#undef HAVE_DAEMON
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the `fsync_range' function. */
#undef HAVE_FSYNC_RANGE
/* Define to 1 if you have the `getaddrinfo' function. */
#undef HAVE_GETADDRINFO
/* Define to 1 if you have the `getnameinfo' function. */
#undef HAVE_GETNAMEINFO
/* Define to 1 if you have the `htobe64' function. */
#undef HAVE_HTOBE64
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
#undef HAVE_LIBKERN_OSBYTEORDER_H
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define to 1 if you have the `resolv' library (-lresolv). */
#undef HAVE_LIBRESOLV
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define to 1 if the system has the type `long long'. */
#undef HAVE_LONG_LONG
/* Define to 1 if you have the <machine/endian.h> header file. */
#undef HAVE_MACHINE_ENDIAN_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#undef HAVE_NETINET_TCP_H
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
/* Define to 1 if you have the <poll.h> header file. */
#undef HAVE_POLL_H
/* Define to 1 if you have the <pthread.h> header file. */
#undef HAVE_PTHREAD_H
/* Define to 1 if you have the <pwd.h> header file. */
#undef HAVE_PWD_H
/* Define to 1 if you have the <signal.h> header file. */
#undef HAVE_SIGNAL_H
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Define to 1 if the system has the type `socklen_t'. */
#undef HAVE_SOCKLEN_T
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
/* Define to 1 if you have the `strtoll' function. */
#undef HAVE_STRTOLL
/* Define to 1 if you have the `syslog' function. */
#undef HAVE_SYSLOG
/* Define to 1 if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H
/* Define to 1 if you have the <sys/bswap.h> header file. */
#undef HAVE_SYS_BSWAP_H
/* Define to 1 if you have the <sys/byteorder.h> header file. */
#undef HAVE_SYS_BYTEORDER_H
/* Define to 1 if you have the <sys/mman.h> header file. */
#undef HAVE_SYS_MMAN_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/uio.h> header file. */
#undef HAVE_SYS_UIO_H
/* Define to 1 if you have the <sys/vfs.h> header file. */
#undef HAVE_SYS_VFS_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if the system has the type `unsigned long long'. */
#undef HAVE_UNSIGNED_LONG_LONG
/* Define to 1 if you have the <utime.h> header file. */
#undef HAVE_UTIME_H
/* Define to 1 if you have the `uuid_create' function. */
#undef HAVE_UUID_CREATE
/* Define to 1 if you have the <uuid.h> header file. */
#undef HAVE_UUID_H
/* Define to 1 if you have the `uuid_to_string' function. */
#undef HAVE_UUID_TO_STRING
/* Define to 1 if you have the `vasnprintf' function. */
#undef HAVE_VASNPRINTF
/* Define to 1 if you have the `vasprintf' function. */
#undef HAVE_VASPRINTF
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
/* Define to 1 if you have the `__bswap64' function. */
#undef HAVE___BSWAP64
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

94
external/bsd/iscsi/dist/include/defs.h vendored Normal file
View File

@ -0,0 +1,94 @@
/* $NetBSD: defs.h,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* Copyright (c) 1999-2005 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DEFS_H_
#define DEFS_H_
#include "config.h"
#include <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NEWARRAY(type,ptr,size,where,action) do { \
if ((ptr = (type *) calloc(sizeof(type), (unsigned)(size))) == NULL) { \
(void) fprintf(stderr, "%s: can't allocate %lu bytes\n", \
where, (unsigned long)(size * sizeof(type))); \
action; \
} \
} while( /* CONSTCOND */ 0)
#define RENEW(type,ptr,size,where,action) do { \
type *_newptr; \
if ((_newptr = (type *) realloc(ptr, sizeof(type) * (size))) == NULL) { \
(void) fprintf(stderr, "%s: can't realloc %lu bytes\n", \
where, (unsigned long)(size * sizeof(type))); \
action; \
} else { \
ptr = _newptr; \
} \
} while( /* CONSTCOND */ 0)
#define NEW(type, ptr, where, action) NEWARRAY(type, ptr, 1, where, action)
#define FREE(ptr) (void) free(ptr)
#define ALLOC(type, v, size, c, init, incr, where, action) do { \
uint32_t _newsize = size; \
if (size == 0) { \
_newsize = init; \
NEWARRAY(type, v, _newsize, where ": new", action); \
} else if (c == size) { \
_newsize = size + incr; \
RENEW(type, v, _newsize, where ": renew", action); \
} \
size = _newsize; \
} while( /* CONSTCOND */ 0)
/* (void) memset(&v[size], 0x0, sizeof(type) * incr); \*/
#define DEFINE_ARRAY(name, type) \
typedef struct name { \
uint32_t c; \
uint32_t size; \
type *v; \
} name
#ifndef ABS
#define ABS(a) (((a) < 0) ? -(a) : (a))
#endif
#endif /* !DEFS_H_ */

View File

@ -0,0 +1,52 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _DEVICE_H
#define _DEVICE_H
#include "iscsi.h"
#include "target.h"
/*
* Interface from target to device:
*
* device_init() initializes the device
* device_command() sends a SCSI command to one of the logical units in the device.
* device_shutdown() shuts down the device.
*/
int device_init(globals_t *, targv_t *, disc_target_t *);
int device_command(target_session_t *, target_cmd_t *);
int device_shutdown(target_session_t *);
void device_set_var(const char *, char *);
#endif /* _DEVICE_H */

157
external/bsd/iscsi/dist/include/driver.h vendored Normal file
View File

@ -0,0 +1,157 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Intel iSCSI Driver
*/
#ifndef _DRIVER_H_
#define _DRIVER_H_
#include "iscsi.h"
#include "iscsiutil.h"
#include "initiator.h"
/*
* Driver configuration
*/
#define CONFIG_DRIVER_MAX_LUNS 1024
/*
* Internal
*/
static int driver_init(void);
static int driver_shutdown(void);
typedef struct iscsi_driver_stats_t {
unsigned num_tx, num_tx_queued;
unsigned num_rx, num_rx_queued;
unsigned avg_tx, avg_rx;
unsigned tx_queued, tx, tx_error, tx_overflow;
unsigned rx_queued, rx, rx_error, rx_overflow;
unsigned aborts_success, aborts_failed;
unsigned device_resets, bus_resets, host_resets;
iscsi_spin_t lock;
} iscsi_driver_stats_t;
/*
* Kernel Interface
*/
int iscsi_proc_info (char *, char **, off_t, int, int, int);
int iscsi_detect(Scsi_Host_Template *);
int iscsi_release(struct Scsi_Host *);
int iscsi_ioctl(Scsi_Device *dev, int cmd, void *arg);
int iscsi_command(Scsi_Cmnd *SCpnt);
int iscsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int iscsi_bios_param(Disk *, kdev_t, int *);
int iscsi_abort_handler (Scsi_Cmnd *SCpnt);
int iscsi_device_reset_handler (Scsi_Cmnd *);
int iscsi_bus_reset_handler (Scsi_Cmnd *);
int iscsi_host_reset_handler(Scsi_Cmnd *);
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,0)
int iscsi_revoke (Scsi_Device *ptr);
void iscsi_select_queue_depths(struct Scsi_Host *, Scsi_Device *);
#endif
#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
extern struct proc_dir_entry iscsi_proc_dir;
#endif
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
#define ISCSI { \
name: "Intel iSCSI Driver", \
proc_dir: NULL, \
proc_info: iscsi_proc_info, \
detect: iscsi_detect, \
bios_param: iscsi_bios_param, \
release: iscsi_release, \
revoke: NULL, \
ioctl: iscsi_ioctl, \
command: iscsi_command, \
queuecommand: iscsi_queuecommand, \
select_queue_depths: iscsi_select_queue_depths, \
eh_strategy_handler: NULL, \
eh_abort_handler: iscsi_abort_handler, \
eh_device_reset_handler: iscsi_device_reset_handler, \
eh_bus_reset_handler: iscsi_bus_reset_handler, \
eh_host_reset_handler: iscsi_host_reset_handler, \
slave_attach: NULL, \
can_queue: CONFIG_INITIATOR_QUEUE_DEPTH, \
this_id: -1, \
sg_tablesize: 128, \
cmd_per_lun: 1, /* linked commands not supported */ \
present: 0, \
unchecked_isa_dma: 0, \
use_clustering: 0, \
use_new_eh_code: 1, \
emulated: 0, \
next: NULL, \
module: NULL, \
info: NULL, \
proc_name: "iscsi" \
}
#elif LINUX_VERSION_CODE >= LinuxVersionCode(2,2,0)
#define ISCSI { \
name: "Intel iSCSI Driver", \
proc_dir: &iscsi_proc_dir, \
proc_info: iscsi_proc_info, \
detect: iscsi_detect, \
bios_param: iscsi_bios_param, \
release: iscsi_release, \
ioctl: iscsi_ioctl, \
command: iscsi_command, \
queuecommand: iscsi_queuecommand, \
eh_strategy_handler: NULL, \
eh_abort_handler: iscsi_abort_handler, \
eh_device_reset_handler: iscsi_device_reset_handler, \
eh_bus_reset_handler: iscsi_bus_reset_handler, \
eh_host_reset_handler: iscsi_host_reset_handler, \
use_new_eh_code: 1, \
can_queue: CONFIG_INITIATOR_QUEUE_DEPTH, \
sg_tablesize: SG_ALL, \
cmd_per_lun: 1, /* linked commands not supported */ \
this_id: -1, \
present: 0, \
unchecked_isa_dma: 0, \
use_clustering: 0, \
slave_attach: NULL, \
next: NULL, \
module: NULL, \
info: NULL, \
emulated: 0 \
}
#endif /* LINUX_VERSION_CODE */
#endif /* _DRIVER_H_ */

View File

@ -0,0 +1,145 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _INITIATOR_H_
#define _INITIATOR_H_
#include "iscsi.h"
#include "parameters.h"
#include "defs.h"
#define CONFIG_INITIATOR_NUM_TARGETS 16
/***********
* Private *
***********/
#define CONFIG_INITIATOR_QUEUE_DEPTH CONFIG_INITIATOR_NUM_TARGETS
#define CONFIG_INITIATOR_MAX_SESSIONS CONFIG_INITIATOR_NUM_TARGETS
enum {
INITIATOR_SESSION_STATE_INITIALIZING = 0x001,
INITIATOR_SESSION_STATE_INITIALIZED = 0x002,
INITIATOR_SESSION_STATE_CONNECTING = 0x004,
INITIATOR_SESSION_STATE_CONNECTED = 0x008,
INITIATOR_SESSION_STATE_LOGGING_IN = 0x010,
INITIATOR_SESSION_STATE_AUTHENTICATED = 0x020,
INITIATOR_SESSION_STATE_LOGGED_IN_NORMAL = 0x040,
INITIATOR_SESSION_STATE_LOGGED_IN_DISCOVERY = 0x080,
INITIATOR_SESSION_STATE_LOGGING_OUT = 0x100,
INITIATOR_SESSION_STATE_LOGGED_OUT = 0x200,
INITIATOR_SESSION_STATE_DESTROYING = 0x400
};
enum {
TARGET_HOSTNAME_SIZE = 1024,
TARGET_IP_SIZE = 16,
TARGET_NAME_SIZE = 256
};
#define INITIATOR_STATE_SHUTDOWN 1
typedef struct {
iscsi_mutex_t mutex;
iscsi_cond_t cond;
} initiator_wait_t;
typedef struct initiator_session_t {
iscsi_socket_t sock;
uint32_t CmdSN;
uint32_t ExpStatSN;
uint32_t MaxCmdSN;
iscsi_queue_t tx_queue;
iscsi_worker_t tx_worker;
iscsi_worker_t rx_worker;
uint64_t isid;
int tsih;
int cid;
uint32_t state;
iscsi_parameter_t *params;
struct initiator_cmd_t *cmds;
iscsi_spin_t cmds_spin;
iscsi_sess_param_t sess_params;
} initiator_session_t;
typedef struct initiator_cmd_t {
void *ptr;
int type;
int (*callback) (void *);
void *callback_arg;
uint64_t isid;
int tx_done;
int status;
struct initiator_cmd_t *next;
struct initiator_cmd_t *hash_next;
uint32_t key;
char targetname[TARGET_HOSTNAME_SIZE];
} initiator_cmd_t;
typedef struct initiator_target_t {
char name[TARGET_HOSTNAME_SIZE];
char ip[TARGET_IP_SIZE];
int port;
char TargetName[TARGET_NAME_SIZE];
initiator_session_t *sess;
int has_session;
char iqnwanted[TARGET_NAME_SIZE];
} initiator_target_t;
DEFINE_ARRAY(strv_t, char *);
enum {
ISCSI_IPv4 = AF_INET,
ISCSI_IPv6 = AF_INET6,
ISCSI_UNSPEC = PF_UNSPEC
};
/**********
* Public *
**********/
int initiator_init(const char *, int, int, const char *, int, int, int);
int initiator_info(char *, int, int);
int initiator_command(initiator_cmd_t *);
int initiator_enqueue(initiator_cmd_t *);
int initiator_abort(initiator_cmd_t *);
int initiator_shutdown(void);
int initiator_discover(char *, uint64_t, int);
void get_target_info(uint64_t, initiator_target_t *);
int ii_initiator_init(const char *, int, int, const char *, char *, int, int, int);
int initiator_get_targets(int, strv_t *);
int initiator_set_target_name(int, char *);
#endif /* _INITIATOR_H_ */

View File

@ -0,0 +1,63 @@
/* $NetBSD: iscsi-md5.h,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* This file is derived from the RSA Data Security, Inc. MD5 Message-Digest
* Algorithm and has been modified by Jason R. Thorpe <thorpej@NetBSD.ORG>
* for portability and formatting.
*/
/*
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
* rights reserved.
*
* License to copy and use this software is granted provided that it
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest
* Algorithm" in all material mentioning or referencing this software
* or this function.
*
* License is also granted to make and use derivative works provided
* that such works are identified as "derived from the RSA Data
* Security, Inc. MD5 Message-Digest Algorithm" in all material
* mentioning or referencing the derived work.
*
* RSA Data Security, Inc. makes no representations concerning either
* the merchantability of this software or the suitability of this
* software for any particular purpose. It is provided "as is"
* without express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this
* documentation and/or software.
*/
#ifndef _SYS_MD5_H_
#define _SYS_MD5_H_
#include <sys/types.h>
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
/* iSCSI_MD5 context. */
typedef struct iSCSI_MD5Context {
uint32_t state[4]; /* state (ABCD) */
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} iSCSI_MD5_CTX;
__BEGIN_DECLS
void iSCSI_MD5Init(iSCSI_MD5_CTX *);
void iSCSI_MD5Update(iSCSI_MD5_CTX *, const uint8_t *, size_t);
void iSCSI_MD5Final(unsigned char[16], iSCSI_MD5_CTX *);
#ifndef _KERNEL
char *iSCSI_MD5End(iSCSI_MD5_CTX *, char *);
char *iSCSI_MD5File(const char *, char *);
char *iSCSI_MD5Data(const uint8_t *, size_t, char *);
#endif /* _KERNEL */
__END_DECLS
#endif /* _SYS_MD5_H_ */

536
external/bsd/iscsi/dist/include/iscsi.h vendored Normal file
View File

@ -0,0 +1,536 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ISCSI_H
#define ISCSI_H
#include "iscsiutil.h"
/*
* iSCSI Version 18
*/
#define ISCSI_VENDOR "NetBSD"
#define ISCSI_PRODUCT "NetBSD iSCSI"
#define ISCSI_VERSION 0
/*
* Parameters
*/
#define ISCSI_IMMEDIATE_DATA_DFLT 1
#define ISCSI_INITIAL_R2T_DFLT 1
#define ISCSI_USE_PHASE_COLLAPSED_READ_DFLT 0
#define ISCSI_HEADER_LEN 48
#define ISCSI_PORT 3260 /* Default port */
#define ISCSI_OPCODE(HEADER) (HEADER[0] & 0x3f)
#define ISCSI_FIRST_BURST (ISCSI_FIRST_BURST_DFLT)
#define ISCSI_DATA_PDU_LENGTH (ISCSI_DATA_PDU_LENGTH_DFLT)
/*
* Opcodes
*/
enum {
ISCSI_NOP_OUT = 0x00,
ISCSI_SCSI_CMD = 0x01,
ISCSI_TASK_CMD = 0x02,
ISCSI_LOGIN_CMD = 0x03,
ISCSI_TEXT_CMD = 0x04,
ISCSI_WRITE_DATA = 0x05,
ISCSI_LOGOUT_CMD = 0x06,
ISCSI_SNACK = 0x10, /* not implemented */
ISCSI_NOP_IN = 0x20,
ISCSI_SCSI_RSP = 0x21,
ISCSI_TASK_RSP = 0x22,
ISCSI_LOGIN_RSP = 0x23,
ISCSI_TEXT_RSP = 0x24,
ISCSI_READ_DATA = 0x25,
ISCSI_LOGOUT_RSP = 0x26,
ISCSI_R2T = 0x31,
ISCSI_ASYNC = 0x32,
ISCSI_REJECT = 0x3f
};
enum {
ISCSI_AHS_EXTENDED_CDB = 0x01,
ISCSI_AHS_BIDI_READ = 0x02
};
/*
* Login Phase
*/
enum {
ISCSI_LOGIN_STATUS_SUCCESS = 0,
ISCSI_LOGIN_STATUS_REDIRECTION = 1,
ISCSI_LOGIN_STATUS_INITIATOR_ERROR = 2,
ISCSI_LOGIN_STATUS_TARGET_ERROR = 3,
ISCSI_LOGIN_STAGE_SECURITY = 0,
ISCSI_LOGIN_STAGE_NEGOTIATE = 1,
ISCSI_LOGIN_STAGE_FULL_FEATURE = 3
};
/* detailed return codes for login phase */
enum {
ISCSI_LOGIN_DETAIL_SUCCESS = 0x0,
ISCSI_LOGIN_DETAIL_INIT_AUTH_FAILURE = 0x01,
ISCSI_LOGIN_DETAIL_VERSION_NOT_SUPPORTED = 0x05,
ISCSI_LOGIN_DETAIL_NOT_LOGGED_IN = 0x0b
};
/*
* Logout Phase
*/
enum {
ISCSI_LOGOUT_CLOSE_SESSION = 0,
ISCSI_LOGOUT_CLOSE_CONNECTION = 1,
ISCSI_LOGOUT_CLOSE_RECOVERY = 2,
ISCSI_LOGOUT_STATUS_SUCCESS = 0,
ISCSI_LOGOUT_STATUS_NO_CID = 1,
ISCSI_LOGOUT_STATUS_NO_RECOVERY = 2,
ISCSI_LOGOUT_STATUS_FAILURE = 3
};
/*
* Task Command
*/
enum {
ISCSI_TASK_CMD_ABORT_TASK = 1,
ISCSI_TASK_CMD_ABORT_TASK_SET = 2,
ISCSI_TASK_CMD_CLEAR_ACA = 3,
ISCSI_TASK_CMD_CLEAR_TASK_SET = 4,
ISCSI_TASK_CMD_LOGICAL_UNIT_RESET = 5,
ISCSI_TASK_CMD_TARGET_WARM_RESET = 6,
ISCSI_TASK_CMD_TARGET_COLD_RESET = 7,
ISCSI_TASK_CMD_TARGET_REASSIGN = 8
};
typedef struct iscsi_task_cmd_t {
int32_t immediate;
uint8_t function;
uint64_t lun;
uint32_t tag;
uint32_t ref_tag;
uint32_t CmdSN;
uint32_t ExpStatSN;
uint32_t RefCmdSN;
uint32_t ExpDataSN;
} iscsi_task_cmd_t;
int iscsi_task_cmd_encap(uint8_t *header, iscsi_task_cmd_t * cmd);
int iscsi_task_cmd_decap(uint8_t *header, iscsi_task_cmd_t * cmd);
/*
* Task Response
*/
enum {
ISCSI_TASK_RSP_FUNCTION_COMPLETE = 0,
ISCSI_TASK_RSP_NO_SUCH_TASK = 1,
ISCSI_TASK_RSP_NO_SUCH_LUN = 2,
ISCSI_TASK_RSP_STILL_ALLEGIANT = 3,
ISCSI_TASK_RSP_NO_FAILOVER = 4,
ISCSI_TASK_RSP_NO_SUPPORT = 5,
ISCSI_TASK_RSP_AUTHORIZED_FAILED = 6,
ISCSI_TASK_RSP_REJECTED = 255,
ISCSI_TASK_QUAL_FUNCTION_EXECUTED = 0,
ISCSI_TASK_QUAL_NOT_AUTHORIZED = 1
};
typedef struct iscsi_task_rsp_t {
uint8_t response;
uint32_t length;
uint32_t tag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
} iscsi_task_rsp_t;
int iscsi_task_rsp_encap(uint8_t *header, iscsi_task_rsp_t * rsp);
int iscsi_task_rsp_decap(uint8_t *header, iscsi_task_rsp_t * rsp);
/*
* NOP-Out
*/
typedef struct iscsi_nop_out_args_t {
int32_t immediate;
uint32_t length;
uint64_t lun;
uint32_t tag;
uint32_t transfer_tag;
uint32_t CmdSN;
uint32_t ExpStatSN;
const uint8_t *data;
} iscsi_nop_out_args_t;
int iscsi_nop_out_encap(uint8_t *header, iscsi_nop_out_args_t * cmd);
int iscsi_nop_out_decap(uint8_t *header, iscsi_nop_out_args_t * cmd);
/*
* NOP-In
*/
typedef struct iscsi_nop_in_args_t {
uint32_t length;
uint64_t lun;
uint32_t tag;
uint32_t transfer_tag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
} iscsi_nop_in_args_t;
int iscsi_nop_in_encap(uint8_t *header, iscsi_nop_in_args_t * cmd);
int iscsi_nop_in_decap(uint8_t *header, iscsi_nop_in_args_t * cmd);
/*
* Text Command
*/
typedef struct iscsi_text_cmd_args_t {
int32_t immediate;
int32_t final;
int32_t cont;
uint32_t length;
uint64_t lun;
uint32_t tag;
uint32_t transfer_tag;
uint32_t CmdSN;
uint32_t ExpStatSN;
char *text;
} iscsi_text_cmd_args_t;
int iscsi_text_cmd_encap(uint8_t *header, iscsi_text_cmd_args_t * cmd);
int iscsi_text_cmd_decap(uint8_t *header, iscsi_text_cmd_args_t * cmd);
/*
* Text Response
*/
typedef struct iscsi_text_rsp_args_t {
int32_t final;
int32_t cont;
uint32_t length;
uint64_t lun;
uint32_t tag;
uint32_t transfer_tag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
} iscsi_text_rsp_args_t;
int iscsi_text_rsp_encap(uint8_t *header, iscsi_text_rsp_args_t * rsp);
int iscsi_text_rsp_decap(uint8_t *header, iscsi_text_rsp_args_t * rsp);
/*
* Login Command
*/
typedef struct iscsi_login_cmd_args_t {
int32_t transit;
int32_t cont;
uint8_t csg;
uint8_t nsg;
int8_t version_max;
int8_t version_min;
uint8_t AHSlength;
uint32_t length;
uint64_t isid;
uint16_t tsih;
uint32_t tag;
uint16_t cid;
uint32_t CmdSN;
uint32_t ExpStatSN;
char *text;
} iscsi_login_cmd_args_t;
int iscsi_login_cmd_encap(uint8_t *header, iscsi_login_cmd_args_t * cmd);
int iscsi_login_cmd_decap(uint8_t *header, iscsi_login_cmd_args_t * cmd);
/*
* Login Response
*/
typedef struct iscsi_login_rsp_args_t {
int32_t transit;
int32_t cont;
uint8_t csg;
uint8_t nsg;
int8_t version_max;
int8_t version_active;
uint8_t AHSlength;
uint32_t length;
uint64_t isid;
uint16_t tsih;
uint32_t tag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint8_t status_class;
uint8_t status_detail;
} iscsi_login_rsp_args_t;
int iscsi_login_rsp_encap(uint8_t *header, iscsi_login_rsp_args_t * rsp);
int iscsi_login_rsp_decap(uint8_t *header, iscsi_login_rsp_args_t * rsp);
/*
* Logout Command
*/
typedef struct iscsi_logout_cmd_args_t {
int32_t immediate;
uint8_t reason;
uint32_t tag;
uint16_t cid;
uint32_t CmdSN;
uint32_t ExpStatSN;
} iscsi_logout_cmd_args_t;
int iscsi_logout_cmd_encap(uint8_t *header, iscsi_logout_cmd_args_t * cmd);
int iscsi_logout_cmd_decap(uint8_t *header, iscsi_logout_cmd_args_t * cmd);
/*
* Logout Response
*/
typedef struct iscsi_logout_rsp_args_t {
uint8_t response;
uint32_t length;
uint32_t tag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint16_t Time2Wait;
uint16_t Time2Retain;
} iscsi_logout_rsp_args_t;
int iscsi_logout_rsp_encap(uint8_t *header, iscsi_logout_rsp_args_t * rsp);
int iscsi_logout_rsp_decap(uint8_t *header, iscsi_logout_rsp_args_t * rsp);
/*
* SCSI Command
*/
typedef struct iscsi_scsi_cmd_args_t {
int32_t immediate;
int32_t final;
int32_t input;
int32_t output;
uint8_t attr;
uint32_t length;
uint64_t lun;
uint32_t tag;
uint32_t trans_len;
uint32_t bidi_trans_len;
uint32_t CmdSN;
uint32_t ExpStatSN;
uint8_t *cdb;
uint8_t *ext_cdb;
uint8_t *ahs;
uint8_t ahs_len;
uint8_t *send_data;
int32_t send_sg_len;
uint8_t *recv_data;
int32_t recv_sg_len;
uint8_t status;
uint32_t bytes_sent;
uint32_t bytes_recv;
} iscsi_scsi_cmd_args_t;
int iscsi_scsi_cmd_encap(uint8_t *header, iscsi_scsi_cmd_args_t * cmd);
int iscsi_scsi_cmd_decap(uint8_t *header, iscsi_scsi_cmd_args_t * cmd);
/*
* SCSI Response
*/
typedef struct iscsi_scsi_rsp_args_t {
int32_t bidi_overflow;
int32_t bidi_underflow;
int32_t overflow;
int32_t underflow;
uint8_t response;
uint8_t status;
uint32_t ahs_len;
uint32_t length;
uint32_t tag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint32_t ExpDataSN;
uint32_t bidi_res_cnt;
uint32_t basic_res_cnt;
} iscsi_scsi_rsp_t;
int iscsi_scsi_rsp_encap(uint8_t *header, iscsi_scsi_rsp_t * rsp);
int iscsi_scsi_rsp_decap(uint8_t *header, iscsi_scsi_rsp_t * rsp);
/*
* Ready To Transfer (R2T)
*/
typedef struct iscsi_r2t_args_t {
uint32_t AHSlength;
uint64_t lun;
uint32_t tag;
uint32_t transfer_tag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint32_t R2TSN;
uint32_t offset;
uint32_t length;
} iscsi_r2t_t;
int iscsi_r2t_encap(uint8_t *header, iscsi_r2t_t * cmd);
int iscsi_r2t_decap(uint8_t *header, iscsi_r2t_t * cmd);
/*
* SCSI Write Data
*/
typedef struct iscsi_write_data_args_t {
int32_t final;
uint32_t length;
uint64_t lun;
uint32_t tag;
uint32_t transfer_tag;
uint32_t ExpStatSN;
uint32_t DataSN;
uint32_t offset;
} iscsi_write_data_t;
int iscsi_write_data_encap(uint8_t *header, iscsi_write_data_t * cmd);
int iscsi_write_data_decap(uint8_t *header, iscsi_write_data_t * cmd);
/*
* SCSI Read Data
*/
typedef struct iscsi_read_data_args_t {
int32_t final;
int32_t ack;
int32_t overflow;
int32_t underflow;
int32_t S_bit;
uint8_t status;
uint32_t length;
uint64_t lun;
uint32_t task_tag;
uint32_t transfer_tag;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint32_t DataSN;
uint32_t offset;
uint32_t res_count;
} iscsi_read_data_t;
int iscsi_read_data_encap(uint8_t *header, iscsi_read_data_t * cmd);
int iscsi_read_data_decap(uint8_t *header, iscsi_read_data_t * cmd);
/*
* Reject
*/
typedef struct iscsi_reject_args_t {
uint8_t reason;
uint32_t length;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint32_t DataSN;
char *header;
} iscsi_reject_t;
int iscsi_reject_encap(uint8_t *header, iscsi_reject_t * cmd);
int iscsi_reject_decap(uint8_t *header, iscsi_reject_t * cmd);
/*
* Async Message
*/
typedef struct iscsi_async_msg_args_t {
uint8_t AHSlength;
uint64_t lun;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint32_t length;
uint8_t AsyncEvent;
uint8_t AsyncVCode;
} iscsi_async_msg_t;
int iscsi_amsg_decap(uint8_t *header, iscsi_async_msg_t * msg);
#ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP
#endif
#endif /* ISCSI_H */

View File

@ -0,0 +1,489 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _ISCSIUTIL_H_
#define _ISCSIUTIL_H_
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif
/*
*
*/
#define ISCSI_HTONLL6(x) (uint64_t) \
( ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x0000ff0000000000uLL) >> 40)) \
| ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x000000ff00000000uLL) >> 24)) \
| ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x00000000ff000000uLL) >> 8)) \
| ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x0000000000ff0000uLL) << 8)) \
| ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x000000000000ff00uLL) << 24)) \
| ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x00000000000000ffuLL) << 40)))
#define ISCSI_NTOHLL6(x) (uint64_t) \
( ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x0000ff0000000000uLL) >> 40)) \
| ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x000000ff00000000uLL) >> 24)) \
| ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x00000000ff000000uLL) >> 8)) \
| ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x0000000000ff0000uLL) << 8)) \
| ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x000000000000ff00uLL) << 24)) \
| ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x00000000000000ffuLL) << 40)))
/*
* Debugging Levels
*/
#define TRACE_NET_DEBUG 0x00000001
#define TRACE_NET_BUFF 0x00000002
#define TRACE_NET_IOV 0x00000004
#define TRACE_NET_ALL (TRACE_NET_DEBUG|TRACE_NET_BUFF|TRACE_NET_IOV)
#define TRACE_ISCSI_DEBUG 0x00000010
#define TRACE_ISCSI_CMD 0x00000020
#define TRACE_ISCSI_ARGS 0x00000040
#define TRACE_ISCSI_PARAM 0x00000080
#define TRACE_ISCSI_ALL (TRACE_ISCSI_DEBUG|TRACE_ISCSI_ARGS|TRACE_ISCSI_PARAM|TRACE_ISCSI_CMD)
#define TRACE_SCSI_DEBUG 0x00000100
#define TRACE_SCSI_CMD 0x00000200
#define TRACE_SCSI_DATA 0x00000400
#define TRACE_SCSI_ARGS 0x00000800
#define TRACE_SCSI_ALL (TRACE_SCSI_DEBUG|TRACE_SCSI_CMD|TRACE_SCSI_DATA|TRACE_SCSI_ARGS)
#define TRACE_DEBUG 0x00001000
#define TRACE_HASH 0x00002000
#define TRACE_SYNC 0x00004000
#define TRACE_QUEUE 0x00008000
#define TRACE_WARN 0x00010000
#define TRACE_MEM 0x00020000
#define TRACE_OSD 0x00040000
#define TRACE_OSDFS 0x00080000
#define TRACE_OSDSO 0x00100000
#define TRACE_ALL 0xffffffff
/*
* Set debugging level here. Turn on debugging in Makefile.
*/
#ifndef EXTERN
#define EXTERN extern
#endif
EXTERN uint32_t iscsi_debug_level;
/*
* Debugging Functions
*/
void set_debug(const char *);
void iscsi_trace(const int, const char *, const int, const char *, ...);
void iscsi_trace_warning(const char *, const int, const char *, ...);
void iscsi_trace_error(const char *, const int, const char *, ...);
void iscsi_print_buffer(const char *, const size_t);
/*
* Byte Order
*/
#ifdef HAVE_ASM_BYTEORDER_H
#include <asm/byteorder.h>
#endif
#ifdef HAVE_SYS_BYTEORDER_H
#include <sys/byteorder.h>
#endif
#ifdef HAVE_BYTESWAP_H
#include <byteswap.h>
#endif
#ifdef HAVE_MACHINE_ENDIAN_H
#include <machine/endian.h>
#endif
#define __BYTE_ORDER _BYTE_ORDER
#define __BIG_ENDIAN _BIG_ENDIAN
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define ISCSI_NTOHLL(a) ISCSI_BE64TOH(a)
#define ISCSI_HTONLL(a) ISCSI_HTOBE64(a)
#define ISCSI_NTOHL(a) ntohl(a)
#define ISCSI_HTONL(a) htonl(a)
#define ISCSI_NTOHS(a) ntohs(a)
#define ISCSI_HTONS(a) htons(a)
#define ISCSI_GETPID getpid()
#ifndef HAVE_SOCKLEN_T
typedef int socklen_t;
#endif
/*
* Sleeping
*/
#define ISCSI_SLEEP(N) sleep(N)
/*
* Memory
*/
void *iscsi_malloc(unsigned);
void iscsi_free(void *);
void *iscsi_malloc_atomic(unsigned);
void iscsi_free_atomic(void *);
/*
* Comparison
*/
#ifndef MIN
#define MIN(A,B) (((A)<(B))?(A):(B))
#endif
#define MIN_3(A,B,C) (((A)<(B))?(((A)<(C))?(A):(C)):(((B)<(C))?(B):(C)))
/* Spin locks */
typedef pthread_mutex_t iscsi_spin_t;
int iscsi_spin_init(iscsi_spin_t * );
int iscsi_spin_lock(iscsi_spin_t * );
int iscsi_spin_unlock(iscsi_spin_t * );
int iscsi_spin_lock_irqsave(iscsi_spin_t * , uint32_t *);
int iscsi_spin_unlock_irqrestore(iscsi_spin_t * , uint32_t *);
int iscsi_spin_destroy(iscsi_spin_t * );
/*
* End of ISCSI spin routines
*/
/*
* Tags
*/
#define ISCSI_SET_TAG(tag) do { \
iscsi_spin_lock(&g_tag_spin); \
*tag = g_tag++; \
iscsi_spin_unlock(&g_tag_spin); \
} while (/* CONSTCOND */ 0)
#define ISCSI_SET_TAG_IN_INTR(tag) do { \
uint32_t flags; \
iscsi_spin_lock_irqsave(&g_tag_spin, &flags); \
*tag = g_tag++; \
iscsi_spin_unlock_irqrestore(&g_tag_spin, &flags); \
} while (/* CONSTCOND */ 0)
/*
* Hashing
*/
typedef struct hash_t {
struct initiator_cmd_t **bucket;
int collisions;
int insertions;
int n;
iscsi_spin_t lock;
} hash_t;
int hash_init(hash_t * , int );
int hash_insert(hash_t * , struct initiator_cmd_t * , uint32_t );
struct initiator_cmd_t *hash_remove(hash_t * , uint32_t );
int hash_destroy(hash_t * );
/*
* Queuing
*/
typedef struct iscsi_queue_t {
int head;
int tail;
int count;
void **elem;
int depth;
iscsi_spin_t lock;
} iscsi_queue_t;
int iscsi_queue_init(iscsi_queue_t * , int );
void iscsi_queue_destroy(iscsi_queue_t * );
int iscsi_queue_insert(iscsi_queue_t * , void *);
void *iscsi_queue_remove(iscsi_queue_t * );
int iscsi_queue_depth(iscsi_queue_t * );
int iscsi_queue_full(iscsi_queue_t * );
/*
* Socket Abstraction
*/
typedef int iscsi_socket_t;
/* Turning off Nagle's Algorithm doesn't always seem to work, */
/* so we combine two messages into one when the second's size */
/* is less than or equal to ISCSI_SOCK_HACK_CROSSOVER. */
#define ISCSI_SOCK_HACK_CROSSOVER 1024
#define ISCSI_SOCK_CONNECT_NONBLOCK 0
#define ISCSI_SOCK_CONNECT_TIMEOUT 1
#define ISCSI_SOCK_MSG_BYTE_ALIGN 4
int iscsi_sock_create(iscsi_socket_t * );
int iscsi_socks_establish(iscsi_socket_t *, int *, int *, int, int);
int iscsi_waitfor_connection(iscsi_socket_t *, int, const char *cf, iscsi_socket_t *);
const char *iscsi_address_family(int);
int iscsi_sock_setsockopt(iscsi_socket_t * , int , int , void *, unsigned );
int iscsi_sock_getsockopt(iscsi_socket_t * , int , int , void *, unsigned *);
int iscsi_sock_bind(iscsi_socket_t , int );
int iscsi_sock_listen(iscsi_socket_t );
int iscsi_sock_connect(iscsi_socket_t , char *, int );
int iscsi_sock_accept(iscsi_socket_t , iscsi_socket_t * );
int iscsi_sock_shutdown(iscsi_socket_t , int );
int iscsi_sock_close(iscsi_socket_t );
int iscsi_sock_msg(iscsi_socket_t , int , unsigned , void *, int );
int iscsi_sock_send_header_and_data(iscsi_socket_t ,
void *, unsigned ,
const void *, unsigned , int );
int iscsi_sock_getsockname(iscsi_socket_t , struct sockaddr * , unsigned *);
int iscsi_sock_getpeername(iscsi_socket_t , struct sockaddr * , unsigned *);
int modify_iov(struct iovec ** , int *, uint32_t , uint32_t );
void cdb2lba(uint32_t *, uint16_t *, uint8_t *);
void lba2cdb(uint8_t *, uint32_t *, uint16_t *);
/*
* Mutexes
*/
typedef pthread_mutex_t iscsi_mutex_t;
int iscsi_mutex_init(iscsi_mutex_t * );
int iscsi_mutex_lock(iscsi_mutex_t * );
int iscsi_mutex_unlock(iscsi_mutex_t * );
int iscsi_mutex_destroy(iscsi_mutex_t * );
#define ISCSI_LOCK(M, ELSE) do { \
if (iscsi_mutex_lock(M) != 0) { \
iscsi_trace_error(__FILE__, __LINE__, "iscsi_mutex_lock() failed\n"); \
ELSE; \
} \
} while (/* CONSTCOND */ 0)
#define ISCSI_UNLOCK(M, ELSE) do { \
if (iscsi_mutex_unlock(M) != 0) { \
iscsi_trace_error(__FILE__, __LINE__, "iscsi_mutex_unlock() failed\n"); \
ELSE; \
} \
} while (/* CONSTCOND */ 0)
#define ISCSI_MUTEX_INIT(M, ELSE) do { \
if (iscsi_mutex_init(M) != 0) { \
iscsi_trace_error(__FILE__, __LINE__, "iscsi_mutex_init() failed\n"); \
ELSE; \
} \
} while (/* CONSTCOND */ 0)
#define ISCSI_MUTEX_DESTROY(M, ELSE) do { \
if (iscsi_mutex_destroy(M) != 0) { \
iscsi_trace_error(__FILE__, __LINE__, "iscsi_mutex_destroy() failed\n"); \
ELSE; \
} \
} while (/* CONSTCOND */ 0)
/*
* Condition Variable
*/
typedef pthread_cond_t iscsi_cond_t;
int iscsi_cond_init(iscsi_cond_t * );
int iscsi_cond_wait(iscsi_cond_t * , iscsi_mutex_t * );
int iscsi_cond_signal(iscsi_cond_t * );
int iscsi_cond_destroy(iscsi_cond_t * );
#define ISCSI_COND_INIT(C, ELSE) do { \
if (iscsi_cond_init(C) != 0) { \
ELSE; \
} \
} while (/* CONSTCOND */ 0)
#define ISCSI_WAIT(C, M, ELSE) do { \
if (iscsi_cond_wait(C, M) != 0) { \
ELSE; \
} \
} while (/* CONSTCOND */ 0)
#define ISCSI_SIGNAL(C, ELSE) do { \
if (iscsi_cond_signal(C) != 0) { \
ELSE; \
} \
} while (/* CONSTCOND */ 0)
#define ISCSI_COND_DESTROY(C, ELSE) do { \
if (iscsi_cond_destroy(C) != 0) { \
ELSE; \
} \
} while (/* CONSTCOND */ 0)
/*
* Threading Routines
*/
typedef struct iscsi_thread_t {
pthread_t pthread;
} iscsi_thread_t;
int iscsi_thread_create(iscsi_thread_t * , void *(*proc) (void *), void *);
#define ISCSI_SET_THREAD(ME) /* for user pthread id set by pthread_create
* in iscsi_thread_create */
#define ISCSI_THREAD_START(NAME)
/*
* Worker Thread
*/
#define ISCSI_WORKER_STATE_STARTED 1
#define ISCSI_WORKER_STATE_ERROR 2
#define ISCSI_WORKER_STATE_EXITING 4
typedef struct {
iscsi_thread_t thread;
iscsi_mutex_t work_mutex;
iscsi_cond_t work_cond;
iscsi_mutex_t exit_mutex;
iscsi_cond_t exit_cond;
int id;
int pid;
volatile uint32_t state;
} iscsi_worker_t;
#define ISCSI_WORKER_EXIT(ME) do { \
iscsi_trace(TRACE_ISCSI_DEBUG ,__FILE__, __LINE__, "exiting\n"); \
(ME)->state |= ISCSI_WORKER_STATE_EXITING; \
return 0; \
} while (/* CONSTCOND */ 0)
/*
* Spin Lock
*/
#define ISCSI_SPIN
/*
* Pre/Post condition checking
*/
#define NO_CLEANUP {}
#define RETURN_GREATER(NAME, V1, V2, CU, RC) \
if ((V1)>(V2)) { \
iscsi_trace_error(__FILE__, __LINE__, "Bad \"%s\": %u > %u.\n", NAME, (unsigned)V1, (unsigned)V2); \
CU; \
return RC; \
}
#define RETURN_NOT_EQUAL(NAME, V1, V2, CU, RC) \
if ((V1)!=(V2)) { \
iscsi_trace_error(__FILE__, __LINE__, "Bad \"%s\": Got %u expected %u.\n", NAME, V1, V2); \
CU; \
return RC; \
}
#define WARN_NOT_EQUAL(NAME, V1, V2) \
if ((V1)!=(V2)) { \
iscsi_trace_warning(__FILE__, __LINE__, "Bad \"%s\": Got %u expected %u.\n", NAME, V1, V2); \
}
#define RETURN_EQUAL(NAME, V1, V2, CU, RC) \
if ((V1)==(V2)) { \
iscsi_trace_error(__FILE__, __LINE__, "Bad \"%s\": %u == %u.\n", NAME, V1, V2); \
CU; \
return RC; \
}
/*
* Misc. Functions
*/
uint32_t iscsi_atoi(char *);
int HexTextToData(const char *, uint32_t , uint8_t *, uint32_t );
int HexDataToText(uint8_t *, uint32_t , char *, uint32_t );
void GenRandomData(uint8_t *, uint32_t );
/* this is the maximum number of iovecs which we can use in iscsi_sock_send_header_and_data */
#ifndef ISCSI_MAX_IOVECS
#define ISCSI_MAX_IOVECS 32
#endif
enum {
/* used in iscsi_sock_msg() */
Receive = 0,
Transmit = 1
};
int allow_netmask(const char *, const char *);
#endif /* _ISCSIUTIL_H_ */

149
external/bsd/iscsi/dist/include/osd.h vendored Normal file
View File

@ -0,0 +1,149 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OSD_H
#define OSD_H
#include "config.h"
#include <sys/types.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include "iscsiutil.h"
#define OSD_VENDOR "NetBSD"
#define OSD_PRODUCT "NetBSD/Intel OSD"
#define OSD_VERSION 0
/*
* OSD Configuration
*/
#define CONFIG_OSD_CAPACITY_DFLT 1024
#define CONFIG_OSD_LUNS_DFLT 1
#define CONFIG_OSD_BASEDIR_DFLT "/tmp/iscsi_osd"
#define CONFIG_OSD_CDB_LEN 128
/*
* OSD Service Actions
*/
#define OSD_CREATE_GROUP 0x880B
#define OSD_REMOVE_GROUP 0x880C
#define OSD_CREATE 0x8802
#define OSD_REMOVE 0x880A
#define OSD_READ 0x8805
#define OSD_WRITE 0x8806
#define OSD_GET_ATTR 0x880E
#define OSD_SET_ATTR 0x880F
/*
* OSD Arguments
*/
typedef struct osd_args_t {
uint8_t opcode;
uint8_t control;
uint8_t security;
uint8_t add_cdb_len;
uint16_t service_action;
uint8_t options_byte;
uint8_t second_options_byte;
uint32_t GroupID;
uint64_t UserID;
uint32_t SessionID;
uint64_t length;
uint64_t offset;
uint32_t set_attributes_list_length;
uint32_t get_attributes_page;
uint32_t get_attributes_list_length;
uint32_t get_attributes_allocation_length;
} osd_args_t;
#define OSD_ENCAP_CDB(ARGS, CDB) \
(CDB)[0] = (ARGS)->opcode; \
(CDB)[1] = (ARGS)->control; \
(CDB)[6] = (ARGS)->security; \
(CDB)[7] = (ARGS)->add_cdb_len; \
*((uint16_t *)((CDB)+8)) = ISCSI_HTONS((ARGS)->service_action); \
(CDB)[10] = (ARGS)->options_byte; \
(CDB)[11] = (ARGS)->second_options_byte; \
*((uint32_t *)((CDB)+12)) = ISCSI_HTONL((ARGS)->GroupID); \
*((uint64_t *)((CDB)+16)) = ISCSI_HTONLL((ARGS)->UserID); \
*((uint32_t *)((CDB)+24)) = ISCSI_HTONL((ARGS)->SessionID); \
*((uint64_t *)((CDB)+28)) = ISCSI_HTONLL((ARGS)->length); \
*((uint64_t *)((CDB)+36)) = ISCSI_HTONLL((ARGS)->offset); \
*((uint32_t *)((CDB)+44)) = ISCSI_HTONL((ARGS)->get_attributes_page); \
*((uint32_t *)((CDB)+48)) = ISCSI_HTONL((ARGS)->get_attributes_list_length); \
*((uint32_t *)((CDB)+52)) = ISCSI_HTONL((ARGS)->get_attributes_allocation_length); \
*((uint32_t *)((CDB)+72)) = ISCSI_HTONL((ARGS)->set_attributes_list_length);
#define OSD_DECAP_CDB(CDB, EXT_CDB, ARGS) \
(ARGS)->opcode = (CDB)[0]; \
(ARGS)->control = (CDB)[1]; \
(ARGS)->security = (CDB)[6]; \
(ARGS)->add_cdb_len = (CDB)[7]; \
(ARGS)->service_action = ISCSI_NTOHS(*((uint16_t *)((CDB)+8))); \
(ARGS)->options_byte = (CDB)[10]; \
(ARGS)->second_options_byte = (CDB)[11]; \
(ARGS)->GroupID = ISCSI_NTOHL(*((uint32_t *)((CDB)+12))); \
(ARGS)->UserID = ISCSI_NTOHLL(*((uint64_t *)((EXT_CDB)-16+16))); \
(ARGS)->SessionID = ISCSI_NTOHL(*((uint32_t *)((EXT_CDB)-16+24))); \
(ARGS)->length = ISCSI_NTOHLL(*((uint64_t *)((EXT_CDB)-16+28))); \
(ARGS)->offset = ISCSI_NTOHLL(*((uint64_t *)((EXT_CDB)-16+36))); \
(ARGS)->get_attributes_page = ISCSI_NTOHL(*((uint32_t *)((EXT_CDB)-16+44))); \
(ARGS)->get_attributes_list_length = ISCSI_NTOHL(*((uint32_t *)((EXT_CDB)-16+48))); \
(ARGS)->get_attributes_allocation_length = ISCSI_NTOHL(*((uint32_t *)((EXT_CDB)-16+52))); \
(ARGS)->set_attributes_list_length = ISCSI_NTOHL(*((uint32_t *)((EXT_CDB)-16+72)));
#define OSD_PRINT_CDB(CDB, EXT_CDB) \
PRINT("opcode = 0x%x\n", CDB[0]); \
PRINT("control = 0x%x\n", CDB[1]); \
PRINT("security = 0x%x\n", CDB[6]); \
PRINT("add_cdb_len = %u\n", CDB[7]); \
PRINT("service_action = 0x%x\n", ISCSI_NTOHS(*(uint16_t*)(CDB+8))); \
PRINT("options byte 1 = 0x%x\n", CDB[10]); \
PRINT("options byte 2 = 0x%x\n", CDB[11]); \
PRINT("group id = 0x%x\n", ISCSI_NTOHL(*(uint32_t*)(CDB+12))); \
PRINT("user id = 0x%llx\n", ISCSI_NTOHLL(*(uint64_t*)(EXT_CDB-16+16))); \
PRINT("session id = 0x%x\n", ISCSI_NTOHL(*(uint32_t*)(EXT_CDB-16+24))); \
PRINT("length = %llu\n", ISCSI_NTOHLL(*(uint64_t*)(EXT_CDB-16+28))); \
PRINT("offset = %llu\n", ISCSI_NTOHLL(*(uint64_t*)(EXT_CDB-16+36))); \
PRINT("get attr page = %u\n", ISCSI_NTOHL(*(uint32_t*)(EXT_CDB-16+44))); \
PRINT("get list len = %u\n", ISCSI_NTOHL(*(uint32_t*)(EXT_CDB-16+48))); \
PRINT("get alloc len = %u\n", ISCSI_NTOHL(*(uint32_t*)(EXT_CDB-16+52))); \
PRINT("set list len = %u\n", ISCSI_NTOHL(*(uint32_t*)(EXT_CDB-16+72)));
#endif /* OSD_H */

View File

@ -0,0 +1,61 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2002, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Transport-independent Methods
*/
#ifndef _OSD_OPS_H_
#define _OSD_OPS_H_
#include "osd.h"
typedef struct osd_ops_mem {
const void *send_data;
uint64_t send_len;
int send_sg;
void *recv_data;
uint64_t recv_len;
int recv_sg;
} OSD_OPS_MEM;
int osd_create_group(void *, int (*)(void *, osd_args_t *, OSD_OPS_MEM *), uint32_t *);
int osd_remove_group(void *, uint32_t , int (*)(void *, osd_args_t *, OSD_OPS_MEM *));
int osd_create(void *, uint32_t , int (*)(void *, osd_args_t *, OSD_OPS_MEM *), uint64_t *);
int osd_remove(void *, uint32_t , uint64_t , int (*)(void *, osd_args_t *, OSD_OPS_MEM *));
int osd_write(void *, uint32_t , uint64_t , uint64_t , uint64_t , const void *, int , int (*)(void *, osd_args_t *, OSD_OPS_MEM *));
int osd_read(void *, uint32_t , uint64_t , uint64_t , uint64_t , void *, int , int (*)(void *, osd_args_t *, OSD_OPS_MEM *));
int osd_set_one_attr(void *, uint32_t , uint64_t , uint32_t , uint32_t , uint32_t , void *, int (*)(void *, osd_args_t *, OSD_OPS_MEM *));
int osd_get_one_attr(void *, uint32_t , uint64_t , uint32_t , uint32_t , uint32_t , int (*)(void *, osd_args_t *, OSD_OPS_MEM *), uint16_t *, void *);
#endif

View File

@ -0,0 +1,170 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _PARAMETERS_H_
#define _PARAMETERS_H_
typedef struct MD5Context MD5Context_t;
#define ISCSI_PARAM_MAX_LEN 256
#define ISCSI_PARAM_KEY_LEN 64
/* Parameter Type */
#define ISCSI_PARAM_TYPE_DECLARATIVE 1
#define ISCSI_PARAM_TYPE_DECLARE_MULTI 2 /* for TargetName and
* TargetAddress */
#define ISCSI_PARAM_TYPE_NUMERICAL 3
#define ISCSI_PARAM_TYPE_NUMERICAL_Z 4 /* zero represents no limit */
#define ISCSI_PARAM_TYPE_BINARY_OR 5
#define ISCSI_PARAM_TYPE_BINARY_AND 6
#define ISCSI_PARAM_TYPE_LIST 7
#define ISCSI_CHAP_DATA_LENGTH 16
#define ISCSI_CHAP_STRING_LENGTH 256
#define ISCSI_PARAM_STATUS_AUTH_FAILED -2
#define ISCSI_PARAM_STATUS_FAILED -1
/* types of authentication which the initiator can select */
enum {
AuthNone,
AuthCHAP,
AuthKerberos,
AuthSRP
};
/* types of digest which the initiator can select */
enum {
DigestNone = 0x0,
DigestHeader = 0x01,
DigestData = 0x02
/* these are bit masks, extend accordingly */
};
typedef struct iscsi_parameter_item_t {
char value[ISCSI_PARAM_MAX_LEN];
struct iscsi_parameter_item_t *next;
} iscsi_parameter_value_t;
/* this struct defines the credentials a user has */
typedef struct iscsi_cred_t {
char *user; /* user's name */
char *auth_type; /* preferred authentication type */
char *shared_secret; /* the shared secret which will be used */
} iscsi_cred_t;
/*
* Structure for storing negotiated parameters that are frequently accessed
* on an active session
*/
typedef struct iscsi_sess_param_t {
uint32_t max_burst_length;
uint32_t first_burst_length;
uint32_t max_data_seg_length;
iscsi_cred_t cred;
uint8_t initial_r2t;
uint8_t immediate_data;
uint8_t header_digest;
uint8_t data_digest;
uint8_t auth_type;
uint8_t mutual_auth;
uint8_t digest_wanted;
} iscsi_sess_param_t;
typedef struct iscsi_parameter_t {
char key[ISCSI_PARAM_KEY_LEN]; /* key */
int type; /* type of parameter */
char valid[ISCSI_PARAM_MAX_LEN]; /* list of valid values */
char dflt[ISCSI_PARAM_MAX_LEN]; /* default value */
iscsi_parameter_value_t *value_l; /* value list */
char offer_rx[ISCSI_PARAM_MAX_LEN]; /* outgoing offer */
char offer_tx[ISCSI_PARAM_MAX_LEN]; /* incoming offer */
char answer_tx[ISCSI_PARAM_MAX_LEN]; /* outgoing answer */
char answer_rx[ISCSI_PARAM_MAX_LEN]; /* incoming answer */
char negotiated[ISCSI_PARAM_MAX_LEN]; /* negotiated value */
int tx_offer; /* sent offer */
int rx_offer; /* received offer */
int tx_answer; /* sent answer */
int rx_answer; /* received answer */
int reset; /* reset value_l */
struct iscsi_parameter_t *next;
} iscsi_parameter_t;
int param_list_add(iscsi_parameter_t ** , int , const char *, const char *, const char *);
int param_list_print(iscsi_parameter_t * );
int param_list_destroy(iscsi_parameter_t * );
int param_text_add(iscsi_parameter_t *, const char *, const char *, char *, int *, int, int );
int param_text_parse(iscsi_parameter_t *, iscsi_cred_t *, char *, int , char *, int *, int, int);
int param_text_print(char *, uint32_t );
int param_num_vals(iscsi_parameter_t * , char *);
int param_val_reset(iscsi_parameter_t * , const char *);
char *param_val(iscsi_parameter_t * , const char *);
char *param_val_which(iscsi_parameter_t * , const char *, int );
char *param_offer(iscsi_parameter_t * , char *);
char *param_answer(iscsi_parameter_t * , char *);
iscsi_parameter_t *param_get(iscsi_parameter_t * , const char *);
int driver_atoi(const char *);
int param_atoi(iscsi_parameter_t * , const char *);
int param_equiv(iscsi_parameter_t * , const char *, const char *);
int param_commit(iscsi_parameter_t * );
void set_session_parameters(iscsi_parameter_t * , iscsi_sess_param_t * );
/*
* Macros
*/
#define PARAM_LIST_DESTROY(LIST, ELSE) \
if (param_list_destroy(LIST)!=0) { \
iscsi_trace_error(__FILE__, __LINE__, "param_list_destroy() failed\n"); \
ELSE; \
}
#define PARAM_LIST_ADD(LIST, TYPE, KEY, DFLT, VALID, ELSE) \
if (param_list_add(LIST, TYPE, KEY, DFLT, VALID)!=0) { \
iscsi_trace_error(__FILE__, __LINE__, "param_list_add() failed\n"); \
ELSE; \
}
#define PARAM_TEXT_ADD(LIST, KEY, VAL, TEXT, LEN, SIZE, OFFER, ELSE ) \
if (param_text_add(LIST, KEY, VAL, TEXT, LEN, SIZE, OFFER)!=0) { \
iscsi_trace_error(__FILE__, __LINE__, "param_text_add() failed\n"); \
ELSE; \
}
#define PARAM_TEXT_PARSE(LIST, CRED, TEXT, LEN, TEXT_OUT, LEN_OUT, SIZE, OFFER, ELSE ) \
if (param_text_parse(LIST, CRED, TEXT, LEN, TEXT_OUT, LEN_OUT, SIZE, OFFER)!=0) { \
iscsi_trace_error(__FILE__, __LINE__, "param_text_parse_offer() failed\n"); \
ELSE; \
}
#endif

View File

@ -0,0 +1,153 @@
/* $NetBSD: scsi_cmd_codes.h,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SCSI_CMD_CODES_H_
#define SCSI_CMD_CODES_H_
/* information taken from SPC3, T10/1416-D Revision 23, from www.t10.org */
enum {
TEST_UNIT_READY = 0x00,
READ_6 = 0x08,
WRITE_6 = 0x0a,
INQUIRY = 0x12,
MODE_SELECT_6 = 0x15,
RESERVE_6 = 0x16,
RELEASE_6 = 0x17,
MODE_SENSE_6 = 0x1a,
STOP_START_UNIT = 0x1b,
READ_CAPACITY = 0x25,
READ_10 = 0x28,
WRITE_10 = 0x2a,
WRITE_VERIFY = 0x2e,
VERIFY = 0x2f,
SYNC_CACHE = 0x35,
LOG_SENSE = 0x4d,
MODE_SELECT_10 = 0x55,
RESERVE_10 = 0x56,
RELEASE_10 = 0x57,
MODE_SENSE_10 = 0x5a,
PERSISTENT_RESERVE_IN = 0x5e,
PERSISTENT_RESERVE_OUT = 0x5f,
REPORT_LUNS = 0xa0
};
#define SIX_BYTE_COMMAND(op) ((op) <= 0x1f)
#define TEN_BYTE_COMMAND(op) ((op) > 0x1f && (op) <= 0x5f)
enum {
ISCSI_MODE_SENSE_LEN = 11
};
/* miscellaneous definitions */
enum {
DISK_PERIPHERAL_DEVICE = 0x0,
INQUIRY_EVPD_BIT = 0x01,
INQUIRY_UNIT_SERIAL_NUMBER_VPD = 0x80,
INQUIRY_DEVICE_IDENTIFICATION_VPD = 0x83,
INQUIRY_SUPPORTED_VPD_PAGES = 0x0,
INQUIRY_DEVICE_PIV = 0x1,
INQUIRY_IDENTIFIER_TYPE_T10 = 0x1,
INQUIRY_IDENTIFIER_TYPE_EUI64 = 0x2,
INQUIRY_IDENTIFIER_TYPE_NAA = 0x3,
INQUIRY_DEVICE_ASSOCIATION_LOGICAL_UNIT = 0x0,
INQUIRY_DEVICE_ASSOCIATION_TARGET_PORT = 0x1,
INQUIRY_DEVICE_ASSOCIATION_TARGET_DEVICE = 0x2,
INQUIRY_DEVICE_CODESET_UTF8 = 0x3,
INQUIRY_DEVICE_ISCSI_PROTOCOL = 0x5,
INQUIRY_DEVICE_T10_VENDOR = 0x1,
INQUIRY_DEVICE_IDENTIFIER_SCSI_NAME = 0x8,
EXTENDED_INQUIRY_DATA_VPD = 0x86,
EXTENDED_INQUIRY_REF_TAG_OWNER = 0x08,
EXTENDED_INQUIRY_GUARD_CHECK = 0x04,
EXTENDED_INQUIRY_APPLICATION_CHECK = 0x02,
EXTENDED_INQUIRY_REFERENCE_CHECK = 0x01,
EXTENDED_INQUIRY_GROUP_SUPPORT = 0x10,
EXTENDED_INQUIRY_PRIORITY_SUPPORT = 0x8,
EXTENDED_INQUIRY_QUEUE_HEAD_SUPPORT = 0x4,
EXTENDED_INQUIRY_ORDERED_SUPPORT = 0x2,
EXTENDED_INQUIRY_SIMPLE_SUPPORT = 0x1,
PERSISTENT_RESERVE_IN_SERVICE_ACTION_MASK = 0x1f,
PERSISTENT_RESERVE_IN_READ_KEYS = 0x0,
PERSISTENT_RESERVE_IN_READ_RESERVATION = 0x1,
PERSISTENT_RESERVE_IN_REPORT_CAPABILITIES = 0x2,
PERSISTENT_RESERVE_IN_READ_FULL_STATUS = 0x3,
PERSISTENT_RESERVE_IN_CRH = 0x10,
PERSISTENT_RESERVE_IN_SIP_C = 0x8,
PERSISTENT_RESERVE_IN_ATP_C = 0x4,
PERSISTENT_RESERVE_IN_PTPL_C = 0x1, /* persistence through power loss */
PERSISTENT_RESERVE_IN_TMV = 0x80, /* Type Mask Valid */
PERSISTENT_RESERVE_IN_PTPL_A = 0x01, /* persistence through power loss activated */
PERSISTENT_RESERVE_IN_WR_EX_AR = 0x80,
PERSISTENT_RESERVE_IN_EX_AC_RD = 0x40,
PERSISTENT_RESERVE_IN_WR_AC_RD = 0x20,
PERSISTENT_RESERVE_IN_EX_AC = 0x08,
PERSISTENT_RESERVE_IN_WR_EX = 0x02,
PERSISTENT_RESERVE_IN_EX_AC_AR = 0x01,
WIDE_BUS_16 = 0x20,
WIDE_BUS_32 = 0x40,
SCSI_VERSION_SPC = 0x03,
SCSI_VERSION_SPC2 = 0x04,
SCSI_VERSION_SPC3 = 0x05,
/* used in MODE_SENSE_10 */
DISABLE_BLOCK_DESCRIPTORS = 0x08,
LONG_LBA_ACCEPTED = 0x10,
PAGE_CONTROL_MASK = 0xc0,
PAGE_CONTROL_CURRENT_VALUES = 0x0,
PAGE_CONTROL_CHANGEABLE_VALUES = 0x40,
PAGE_CONTROL_DEFAULT_VALUES = 0x80,
PAGE_CONTROL_SAVAED_VALUES = 0xc0,
PAGE_CODE_MASK = 0x3f,
ASC_LUN_UNSUPPORTED = 0x25,
ASCQ_LUN_UNSUPPORTED = 0x0,
SCSI_SKEY_ILLEGAL_REQUEST = 0x05
};
/* device return codes */
enum {
SCSI_SUCCESS = 0x0,
SCSI_CHECK_CONDITION = 0x02
};
#endif /* !SCSI_CMD_CODES_H_ */

56
external/bsd/iscsi/dist/include/so.h vendored Normal file
View File

@ -0,0 +1,56 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2002, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SO_H
#define _SO_H
#ifndef _SCSI_H
#include "scsi.h"
#endif
#ifndef _GENDISK_H
#include <linux/genhd.h>
#endif
typedef struct scsi_osd {
Scsi_Device *device;
unsigned capacity; /* size in blocks */
unsigned char ready; /* flag ready for FLOPTICAL */
unsigned char write_prot; /* flag write_protect for rmvable dev */
unsigned char sector_bit_size; /* sector_size = 2 to the bit size power */
unsigned char sector_bit_shift; /* power of 2 sectors per FS block */
unsigned has_part_table:1; /* has partition table */
} Scsi_Osd;
#endif

View File

@ -0,0 +1,96 @@
/* $NetBSD: storage.h,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STORAGE_H_
#define STORAGE_H_
#include "defs.h"
enum {
DE_EXTENT,
DE_DEVICE
};
/* a device can be made up of an extent or another device */
typedef struct disc_de_t {
int32_t type; /* device or extent */
uint64_t size; /* size of underlying extent or device */
union {
struct disc_extent_t *xp; /* pointer to extent */
struct disc_device_t *dp; /* pointer to device */
} u;
} disc_de_t;
/* this struct describes an extent of storage */
typedef struct disc_extent_t {
char *extent; /* extent name */
char *dev; /* device associated with it */
uint64_t sacred; /* offset of extent from start of device */
uint64_t len; /* size of extent */
int fd; /* in-core file descriptor */
int used; /* extent has been used in a device */
} disc_extent_t;
DEFINE_ARRAY(extv_t, disc_extent_t);
/* this struct describes a device */
typedef struct disc_device_t {
char *dev; /* device name */
int raid; /* RAID level */
uint64_t off; /* current offset in device */
uint64_t len; /* size of device */
uint32_t size; /* size of device/extent array */
uint32_t c; /* # of entries in device/extents */
disc_de_t *xv; /* device/extent array */
int used; /* device has been used in a device/target */
} disc_device_t;
DEFINE_ARRAY(devv_t, disc_device_t);
enum {
TARGET_READONLY = 0x01
};
/* this struct describes an iscsi target's associated features */
typedef struct disc_target_t {
char *target; /* target name */
disc_de_t de; /* pointer to its device */
uint16_t port; /* port to listen on */
char *mask; /* mask to export it to */
uint32_t flags; /* any flags */
uint16_t tsih; /* target session identifying handle */
char *iqn; /* assigned iqn - can be NULL */
} disc_target_t;
DEFINE_ARRAY(targv_t, disc_target_t);
int read_conf_file(const char *, targv_t *, devv_t *, extv_t *);
void write_pid_file(const char *);
#endif /* !STORAGE_H_ */

121
external/bsd/iscsi/dist/include/target.h vendored Normal file
View File

@ -0,0 +1,121 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _TARGET_H_
#define _TARGET_H_
#include "iscsi.h"
#include "iscsiutil.h"
#include "parameters.h"
#include "storage.h"
/* Default configuration */
#define DEFAULT_TARGET_MAX_SESSIONS 16 /* n+1 */
#define DEFAULT_TARGET_NUM_LUNS 1
#define DEFAULT_TARGET_BLOCK_LEN 512
#define DEFAULT_TARGET_NUM_BLOCKS 204800
#define DEFAULT_TARGET_NAME "iqn.1994-04.org.netbsd.iscsi-target"
#define DEFAULT_TARGET_QUEUE_DEPTH 8
#define DEFAULT_TARGET_TCQ 0
enum {
MAX_TGT_NAME_SIZE = 512,
MAX_INITIATOR_ADDRESS_SIZE = 256,
MAX_CONFIG_FILE_NAME = 512,
ISCSI_IPv4 = AF_INET,
ISCSI_IPv6 = AF_INET6,
ISCSI_UNSPEC = PF_UNSPEC,
MAXSOCK = 8
};
/* global variables, moved from target.c */
typedef struct globals_t {
char targetname[MAX_TGT_NAME_SIZE]; /* name of target */
uint16_t port; /* target port */
iscsi_socket_t sock; /* socket on which it's listening */
int sockc; /* # of live sockets on which it's listening */
iscsi_socket_t sockv[MAXSOCK]; /* sockets on which it's listening */
int famv[MAXSOCK]; /* address families */
int state; /* current state of target */
int listener_pid; /* PID on which it's listening */
volatile int listener_listening; /* whether a listener is listening */
char targetaddress[MAX_TGT_NAME_SIZE]; /* iSCSI TargetAddress set after iscsi_sock_accept() */
targv_t *tv; /* array of target devices */
int address_family; /* global default IP address family */
int max_sessions; /* maximum number of sessions */
char config_file[MAX_CONFIG_FILE_NAME]; /* config file name */
uint32_t last_tsih; /* the last TSIH that was used */
} globals_t;
/* session parameters */
typedef struct target_session_t {
int id;
int d;
iscsi_socket_t sock;
uint16_t cid;
uint32_t StatSN;
uint32_t ExpCmdSN;
uint32_t MaxCmdSN;
uint8_t *buff;
int UsePhaseCollapsedRead;
int IsFullFeature;
int IsLoggedIn;
int LoginStarted;
uint64_t isid;
int tsih;
globals_t *globals;
iscsi_worker_t worker;
iscsi_parameter_t *params;
iscsi_sess_param_t sess_params;
char initiator[MAX_INITIATOR_ADDRESS_SIZE];
int address_family;
int32_t last_tsih;
} target_session_t;
typedef struct target_cmd_t {
iscsi_scsi_cmd_args_t *scsi_cmd;
int (*callback) (void *);
void *callback_arg;
} target_cmd_t;
int target_init(globals_t *, targv_t *, char *);
int target_shutdown(globals_t *);
int target_listen(globals_t *);
int target_transfer_data(target_session_t *, iscsi_scsi_cmd_args_t *, struct iovec *, int);
int find_target_tsih(globals_t *, int);
int find_target_iqn(target_session_t *);
#endif /* _TARGET_H_ */

52
external/bsd/iscsi/dist/include/tests.h vendored Normal file
View File

@ -0,0 +1,52 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SCSI_TEST_H
#define _SCSI_TEST_H
#include "initiator.h"
int test_all(int , int );
int integrity_test(uint32_t , uint32_t , uint32_t , int );
int nop_test(uint32_t , uint32_t , uint32_t );
int latency_test(uint64_t , uint32_t , uint8_t , uint32_t );
int throughput_test(uint32_t , uint32_t , uint32_t , uint32_t , uint32_t , int , int );
int read_or_write(uint64_t , uint32_t , uint32_t , uint32_t , uint32_t , uint8_t *, int , int );
int nop_out(uint64_t , int , int , int , const char *);
int read_capacity(uint64_t , uint32_t , uint32_t *, uint32_t *);
int write_read_test(uint64_t , uint32_t , int );
int scatter_gather_test(uint64_t , uint32_t , uint8_t );
int ii_test_all(void);
#endif

85
external/bsd/iscsi/dist/src/Makefile.in vendored Normal file
View File

@ -0,0 +1,85 @@
#
# Compiler Flags. Warning: -O causes problems w/ pthread
#
SHELL= /bin/sh
srcdir=@srcdir@
VPATH=@srcdir@
prefix=@prefix@
exec_prefix=@exec_prefix@
BINDIR=$(exec_prefix)/bin
LIBDIR=$(exec_prefix)/lib
INCDIR=$(prefix)/include
MANDIR=$(prefix)/man
SYSCONFDIR=@sysconfdir@
CC= @CC@
PTHREAD_FLAGS= -pthread
PTHREAD_LDFLAGS= -pthread
PTHREAD_LIBS= -lpthread
GCC_CFLAGS= -Wall -Wstrict-prototypes -fno-strict-aliasing -fno-common -Wno-trigraphs
COMMON_CFLAGS += -DCONFIG_ISCSI_DEBUG -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
COMMON_CFLAGS += -DHAVE_CONFIG_H
COMMON_CFLAGS += -I${INCDIR}
CFLAGS= @CFLAGS@ ${GCC_CFLAGS} ${COMMON_CFLAGS} -I${INCLUDE} ${PTHREAD_FLAGS}
LIBS= @LIBS@
INSTALL= @INSTALL@
PREFIX= @prefix@
INCLUDE = ../include
#
# Compilation Targets
#
TARGETS = iscsi-target # osd
INITIATORS= iscsifs
all: $(TARGETS)
all-initiator: ${INITIATORS}
#
# User-level Targets
#
COMPATOBJS= strlcpy.o snprintf.o strtoll.o uuid.o
USER_TARGET_OBJS = target.o iscsi.o util.o parameters.o netmask.o conffile.o storage.o md5c.o md5hl.c ${COMPATOBJS}
iscsi-target: iscsi-target.c disk.c $(USER_TARGET_OBJS)
$(CC) $(CFLAGS) iscsi-target.c disk.c $(USER_TARGET_OBJS) ${PTHREAD_LDFLAGS} ${PTHREAD_LIBS} ${LIBS} -o iscsi-target
osd: osd-target.c osd.c $(USER_TARGET_OBJS)
$(CC) $(CFLAGS) osd-target.c osd.c $(USER_TARGET_OBJS) ${PTHREAD_LDFLAGS} ${PTHREAD_LIBS} ${LIBS} -o osd
#
# Test harness (initiators)
#
iscsifs: iscsifs.o iscsi.o util.o initiator.o parameters.o conffile.o virtdir.o md5c.o md5hl.o
$(CC) iscsifs.o iscsi.o util.o initiator.o parameters.o md5c.o md5hl.o conffile.o virtdir.o -o iscsifs ${PTHREAD_LDFLAGS} ${PTHREAD_LIBS} -L${LIBDIR} -Wl,-R${LIBDIR} ${LIBS} -lfuse
#
# Dependencies
#
osd_ops.o: $(INCLUDE)/iscsiutil.h $(INCLUDE)/osd.h $(INCLUDE)/osd_ops.h osd_ops.c
util.o: util.c $(INCLUDE)/iscsiutil.h
parameters.o: parameters.c $(INCLUDE)/parameters.h $(INCLUDE)/iscsiutil.h md5c.o md5hl.o
usocktest.o: usocktest.c $(INCLUDE)/iscsiutil.h
disk.o: disk.c $(INCLUDE)/device.h $(INCLUDE)/iscsiutil.h $(INCLUDE)/iscsi.h
osd.o: osd.c $(INCLUDE)/osd.h $(INCLUDE)/device.h $(INCLUDE)/iscsiutil.h $(INCLUDE)/iscsi.h
iscsi.o: iscsi.c $(INCLUDE)/iscsi.h $(INCLUDE)/iscsiutil.h
iscsi-harness.o: iscsi-harness.c $(INCLUDE)/iscsi.h $(INCLUDE)/iscsiutil.h $(INCLUDE)/osd.h $(INCLUDE)/initiator.h $(INCLUDE)/tests.h $(INCLUDE)/parameters.h $(INCLUDE)/osd_ops.h
utarget.o: utarget.c $(INCLUDE)/iscsi.h $(INCLUDE)/iscsiutil.h $(INCLUDE)/target.h $(INCLUDE)/device.h
tests.o: tests.c $(INCLUDE)/iscsi.h $(INCLUDE)/iscsiutil.h $(INCLUDE)/initiator.h $(INCLUDE)/tests.h
target.o: target.c $(INCLUDE)/iscsi.h $(INCLUDE)/iscsiutil.h $(INCLUDE)/target.h $(INCLUDE)/parameters.h
initiator.o: initiator.c $(INCLUDE)/iscsi.h $(INCLUDE)/iscsiutil.h $(INCLUDE)/initiator.h $(INCLUDE)/parameters.h
#
# Util
#
clean:
rm -f $(INITIATORS) $(TARGETS) *.o *.core

49
external/bsd/iscsi/dist/src/TODO vendored Normal file
View File

@ -0,0 +1,49 @@
To do
=====
add kevent
add HUP support to read sig and targets file
CRC/digests
finish reservations
RAID 1 rebuilding, breaking etc
proper allow_netmask support for IPv6
add ability to add a target in, take one out (if !busy)
proper IPv6 support in harness
Done
====
fix debug to be command-line driven
unsigned char -> uint8_t
make target guess method to use depending on size of file/device
sprintf -> snprintf
strcpy -> strlcpy
autoconf
fix lint
Implement name-based stuff - no more inet_addr stuff
split into separate targets
rc.d scripts
move to globals_t in target.c
configuration
Make it so that target can take an iqn as its address
Manual page for iscsi-target
manual page for targets config file
get rid of hardcoded CHAP stuff
use syslog to log info
use syslog to log errors
fix memory leak of user name
error if no config file
mmap & munmap
get port from cmd line
raid0
add discovery masking
clean up IPv6
add socklen_t awareness
add uuid
Solaris initiator compatibility
fix 64-byte swapping macros
add reservations - RESERVE_6 and RELEASE_6 done
pass addr family in sess structure
add poll configure glue
use poll if we have it
proper IPv6 support in target
VPD 80 handling
bind to cmdline port properly now too

281
external/bsd/iscsi/dist/src/conffile.c vendored Normal file
View File

@ -0,0 +1,281 @@
/* $NetBSD: conffile.c,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "conffile.h"
/* start of split routines */
/* open a file */
int
conffile_open(conffile_t *sp, const char *f, const char *mode, const char *sep, const char *comment)
{
(void) memset(sp, 0x0, sizeof(*sp));
if ((sp->fp = fopen(f, mode)) == NULL) {
(void) fprintf(stderr, "can't open `%s' `%s' (%s)\n", f, mode, strerror(errno));
return 0;
}
(void) strlcpy(sp->name, f, sizeof(sp->name));
sp->sep = sep;
sp->comment = comment;
sp->readonly = (strcmp(mode, "r") == 0);
return 1;
}
/* close a file */
void
conffile_close(conffile_t *sp)
{
(void) fclose(sp->fp);
}
/* read the next line from the file */
static char *
read_line(conffile_t *sp, ent_t *ep)
{
char *from;
if (fgets(ep->buf, sizeof(ep->buf), sp->fp) == NULL) {
return NULL;
}
sp->lineno += 1;
for (from = ep->buf ; *from && isspace((unsigned int)*from) ; from++) {
}
return from;
}
/* return 1 if this line contains no entry */
static int
iscomment(conffile_t *sp, char *from)
{
return (*from == 0x0 || *from == '\n' || strchr(sp->comment, *from) != NULL);
}
/* split the entry up into fields */
int
conffile_split(conffile_t *sp, ent_t *ep, char *from)
{
FILE *fp;
const char *seps;
char *to;
char was;
int sepseen;
int cc;
seps = (sp == NULL) ? " \t" : sp->sep;
fp = (sp == NULL) ? stdin : sp->fp;
for (ep->sv.c = 0 ; *from && *from != '\n' ; ) {
for (to = from, sepseen = 0 ; *to && *to != '\n' && strchr(seps, *to) == NULL ; to++) {
if (*to == '\\') {
if (*(to + 1) == '\n') {
cc = (int)(to - ep->buf);
if (fgets(&ep->buf[cc], (int)(sizeof(ep->buf) - cc), fp) != NULL) {
if (sp != NULL) {
sp->lineno += 1;
}
}
} else {
sepseen = 1;
to++;
}
}
}
ALLOC(char *, ep->sv.v, ep->sv.size, ep->sv.c, 14, 14, "conffile_getent", exit(EXIT_FAILURE));
ep->sv.v[ep->sv.c++] = from;
was = *to;
*to = 0x0;
if (sepseen) {
char *cp;
for (cp = from ; *cp ; cp++) {
if (strchr(seps, *cp) != NULL) {
(void) strcpy(cp - 1, cp);
}
}
}
if (was == 0x0 || was == '\n') {
break;
}
for (from = to + 1 ; *from && *from != '\n' && strchr(seps, *from) != NULL ; from++) {
}
}
return 1;
}
/* get the next entry */
int
conffile_getent(conffile_t *sp, ent_t *ep)
{
char *from;
for (;;) {
if ((from = read_line(sp, ep)) == NULL) {
return 0;
}
if (iscomment(sp, from)) {
continue;
}
return conffile_split(sp, ep, from);
}
}
/* return the line number */
int
conffile_get_lineno(conffile_t *sp)
{
return sp->lineno;
}
/* return the name */
char *
conffile_get_name(conffile_t *sp)
{
return sp->name;
}
/* return the entry based upon the contents of field `f' */
int
conffile_get_by_field(conffile_t *sp, ent_t *ep, int f, char *val)
{
while (conffile_getent(sp, ep)) {
if (ep->sv.c > (uint32_t)f && strcmp(ep->sv.v[f], val) == 0) {
return 1;
}
}
return 0;
}
/* check that we wrote `cc' chars of `buf' to `fp' */
static int
safe_write(FILE *fp, char *buf, unsigned cc)
{
return fwrite(buf, sizeof(char), cc, fp) == cc;
}
#if 0
/* check that we wrote the entry correctly */
static int
safe_write_ent(FILE *fp, conffile_t *sp, ent_t *ep)
{
char buf[BUFSIZ];
int cc;
int i;
for (cc = i = 0 ; i < ep->sv.c ; i++) {
cc += snprintf(&buf[cc], sizeof(buf) - cc, "%s%1.1s", ep->sv.v[i], (i == ep->sv.c - 1) ? "\n" : sp->sep);
}
return safe_write(fp, buf, cc);
}
#endif
/* report an error and clear up */
static int
report_error(FILE *fp, char *name, const char *fmt, ...)
{
va_list vp;
va_start(vp, fmt);
(void) vfprintf(stderr, fmt, vp);
va_end(vp);
if (fp)
(void) fclose(fp);
(void) unlink(name);
return 0;
}
/* put the new entry (in place of ent[f] == val, if val is non-NULL) */
int
conffile_putent(conffile_t *sp, int f, char *val, char *newent)
{
ent_t e;
FILE *fp;
char name[MAXPATHLEN];
char *from;
int fd;
(void) strlcpy(name, "/tmp/split.XXXXXX", sizeof(name));
if ((fd = mkstemp(name)) < 0) {
(void) fprintf(stderr, "can't mkstemp `%s' (%s)\n", name, strerror(errno));
return 0;
}
fp = fdopen(fd, "w");
(void) memset(&e, 0x0, sizeof(e));
for (;;) {
if ((from = read_line(sp, &e)) == NULL) {
break;
}
if (iscomment(sp, from)) {
if (!safe_write(fp, e.buf, strlen(e.buf))) {
return report_error(fp, name, "Short write 1 to `%s' (%s)\n", name, strerror(errno));
}
}
(void) conffile_split(sp, &e, from);
if (val != NULL && (uint32_t)f < e.sv.c && strcmp(val, e.sv.v[f]) == 0) {
/* replace it */
if (!safe_write(fp, newent, strlen(newent))) {
return report_error(fp, name, "Short write 2 to `%s' (%s)\n", name, strerror(errno));
}
} else {
if (!safe_write(fp, e.buf, strlen(e.buf))) {
return report_error(fp, name, "Short write 3 to `%s' (%s)\n", name, strerror(errno));
}
}
}
if (val == NULL && !safe_write(fp, newent, strlen(newent))) {
return report_error(fp, name, "Short write 4 to `%s' (%s)\n", name, strerror(errno));
}
(void) fclose(fp);
if (rename(name, sp->name) < 0) {
return report_error(NULL, name, "can't rename %s to %s (%s)\n", name, sp->name, strerror(errno));
}
return 1;
}
/* print the entry on stdout */
void
conffile_printent(ent_t *ep)
{
uint32_t i;
for (i = 0 ; i < ep->sv.c ; i++) {
printf("(%d `%s') ", i, ep->sv.v[i]);
}
printf("\n");
}

5870
external/bsd/iscsi/dist/src/configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
AC_INIT([netbsd-iscsi],[20080207],[Alistair Crooks <agc@NetBSD.org>])
AC_CONFIG_SRCDIR([iscsi.c])
AC_CONFIG_HEADER(../include/config.h)
dnl Checks for programs.
AC_PROG_INSTALL
AC_PROG_CC
AC_PROG_RANLIB
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(sys/types.h sys/param.h sys/stat.h sys/time.h sys/mman.h sys/uio.h sys/socket.h sys/time.h sys/vfs.h)
AC_CHECK_HEADERS(arpa/inet.h netinet/in.h netinet/tcp.h netdb.h poll.h)
AC_CHECK_HEADERS(asm/byteorder.h sys/bswap.h sys/byteorder.h sys/select.h libkern/OSByteOrder.h byteswap.h machine/endian.h)
AC_CHECK_HEADERS(ctype.h errno.h fcntl.h pthread.h pwd.h signal.h stdint.h stdlib.h syslog.h unistd.h string.h stdarg.h utime.h uuid.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIZE_T
AC_CHECK_TYPES(socklen_t,,,[
#include <sys/socket.h>
#include <arpa/inet.h>
])
AC_CHECK_TYPES([long long, unsigned long long])
AC_DEFINE_UNQUOTED(HAVE_SOCKLEN_T, $ac_cv_type_socklen_t)
AC_DEFINE_UNQUOTED(HAVE_LONG_LONG, $ac_cv_type_long_long)
AC_DEFINE_UNQUOTED(HAVE_UNSIGNED_LONG_LONG, $ac_cv_type_unsigned_long_long)
dnl check for libraries
AC_CHECK_LIB(nsl, gethostbyname)
AC_CHECK_LIB(socket, connect)
AC_CHECK_LIB(resolv, inet_aton)
dnl Check for functionality
AC_CHECK_FUNCS(__bswap64 asprintf asnprintf bswap64 daemon fsync_range getaddrinfo getnameinfo htobe64 memset bcopy poll snprintf strlcpy strtoll syslog uuid_create uuid_to_string vasprintf vasnprintf vsnprintf)
dnl that's it for now...
AC_OUTPUT(Makefile)

1298
external/bsd/iscsi/dist/src/disk.c vendored Normal file

File diff suppressed because it is too large Load Diff

652
external/bsd/iscsi/dist/src/driver.c vendored Normal file
View File

@ -0,0 +1,652 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Intel SCSI device driver for iSCSI
*/
#ifdef __linux__
#include <linux/blk.h>
#include <linux/string.h>
#include <scsi.h>
#include <hosts.h>
#include <sd.h>
#endif
#include "iscsiutil.h"
#include "util.c"
#include "driver.h"
#include "iscsi.h"
#include "iscsi.c"
#include "tests.h"
#include "tests.c"
#include "osd_ops.h"
#include "osd_ops.c"
#include "parameters.h"
#include "parameters.c"
#include "initiator.h"
#include "initiator.c"
/*
* Version-specific include files
*/
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
#include <linux/in.h>
#else
struct proc_dir_entry iscsi_proc_dir = {PROC_SCSI_NOT_PRESENT, 5, "iscsi", S_IFDIR | S_IRUGO | S_IXUGO, 2};
#endif
#ifdef MODULE
Scsi_Host_Template driver_template = ISCSI;
#include "scsi_module.c"
#endif
/*
* Globals
*/
static initiator_cmd_t *g_cmd;
static iscsi_queue_t g_cmd_q;
static struct iovec **g_iov;
static iscsi_queue_t g_iovec_q;
static iscsi_driver_stats_t g_stats;
/*
* Definitions
*/
/*
* Starting with kernel 2.4.10, we define a license string. This source is under BSD License.
* Consult <linux/include/linux/module.h> for details
*/
MODULE_AUTHOR("Intel Corporation, <http://www.intel.com>");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10)
MODULE_LICENSE("Dual BSD/GPL"); /* This source is under BSD License. This is the closest ident that module.h provides */
# endif
/*
* Private
*/
static int driver_init(void) {
int i;
iscsi_trace(TRACE_SCSI_DEBUG, __FILE__, __LINE__, "initializing iSCSI driver\n");
if ((g_cmd=iscsi_malloc_atomic(sizeof(initiator_cmd_t)*CONFIG_INITIATOR_QUEUE_DEPTH))==NULL) {
iscsi_trace_error("iscsi_malloc_atomic() failed\n");
return -1;
}
if ((g_iov=iscsi_malloc_atomic(sizeof(struct iovec*)*CONFIG_INITIATOR_QUEUE_DEPTH))==NULL) {
iscsi_trace_error("iscsi_malloc_atomic() failed\n");
iscsi_free_atomic(g_cmd);
return -1;
}
for (i=0; i<CONFIG_INITIATOR_QUEUE_DEPTH; i++) {
g_iov[i] = NULL;
g_cmd[i].ptr = NULL;
}
#define DI_ERROR { \
for (i=0; i<CONFIG_INITIATOR_QUEUE_DEPTH; i++) { \
if (g_cmd[i].ptr != NULL) iscsi_free_atomic(g_cmd[i].ptr); \
} \
for (i=0; i<CONFIG_INITIATOR_QUEUE_DEPTH; i++) { \
if (g_iov[i] != NULL) iscsi_free_atomic(g_iov[i]); \
} \
iscsi_free_atomic(g_iov); \
iscsi_free_atomic(g_cmd); \
return -1; \
}
for (i=0; i<CONFIG_INITIATOR_QUEUE_DEPTH; i++) {
if ((g_iov[i]=iscsi_malloc_atomic(sizeof(struct iovec)*SG_ALL))==NULL) {
iscsi_trace_error("iscsi_malloc_atomic() failed\n");
DI_ERROR;
}
}
if (iscsi_queue_init(&g_cmd_q, CONFIG_INITIATOR_QUEUE_DEPTH)!=0) {
iscsi_trace_error("iscsi_queue_init() failed\n");
DI_ERROR;
}
if (iscsi_queue_init(&g_iovec_q, CONFIG_INITIATOR_QUEUE_DEPTH)!=0) {
iscsi_trace_error("iscsi_queue_init() failed\n");
DI_ERROR;
}
for (i=0; i<CONFIG_INITIATOR_QUEUE_DEPTH; i++) {
if ((g_cmd[i].ptr = iscsi_malloc_atomic(sizeof(iscsi_scsi_cmd_args_t)))==NULL) {
iscsi_trace_error("iscsi_malloc_atomic() failed\n");
DI_ERROR;
}
g_cmd[i].type = ISCSI_SCSI_CMD;
if (iscsi_queue_insert(&g_cmd_q, &g_cmd[i])!=0) {
iscsi_trace_error("iscsi_queue_insert() failed\n");
DI_ERROR;
}
if (iscsi_queue_insert(&g_iovec_q, g_iov[i])!=0) {
iscsi_trace_error("iscsi_queue_insert() failed\n");
DI_ERROR;
}
}
memset(&g_stats, 0, sizeof(g_stats));
iscsi_spin_init(&g_stats.lock);
if (initiator_init()!=0) {
iscsi_trace_error("initiator_init() failed\n");
DI_ERROR;
}
iscsi_trace(TRACE_SCSI_DEBUG, "iSCSI initialization complete\n");
return 0;
}
static int driver_shutdown(void) {
int i;
iscsi_trace(TRACE_SCSI_DEBUG, "shutting down iSCSI driver\n");
if (initiator_shutdown()!=0) {
iscsi_trace_error("initiator_shutdown() failed\n");
return -1;
}
iscsi_spin_destroy(&g_stats.lock);
iscsi_queue_destroy(&g_iovec_q);
iscsi_queue_destroy(&g_cmd_q);
for (i=0; i<CONFIG_INITIATOR_QUEUE_DEPTH; i++) {
iscsi_free_atomic(g_iov[i]);
iscsi_free_atomic(g_cmd[i].ptr);
}
iscsi_free_atomic(g_cmd);
iscsi_free_atomic(g_iov);
iscsi_trace(TRACE_SCSI_DEBUG, "iSCSI driver shutdown complete\n");
return 0;
}
/*
* Public
*/
int iscsi_detect(Scsi_Host_Template *tptr) {
struct Scsi_Host *ptr;
iscsi_trace(TRACE_SCSI_DEBUG, "detecting iSCSI host\n");
spin_unlock(&io_request_lock);
if (driver_init()!=0) {
iscsi_trace_error("driver_init() failed\n");
spin_lock(&io_request_lock);
return 0; /*No 'SCSI' host detected, return 0 */
}
ptr = scsi_register(tptr, 0);
ptr->max_id = CONFIG_INITIATOR_NUM_TARGETS;
ptr->max_lun = CONFIG_DRIVER_MAX_LUNS;
ptr->max_cmd_len = 255;
iscsi_trace(TRACE_SCSI_DEBUG, "iSCSI host detected\n");
spin_lock(&io_request_lock);
return 1;
}
int iscsi_release(struct Scsi_Host *host) {
iscsi_trace(TRACE_SCSI_DEBUG, "releasing iSCSI host\n");
driver_shutdown();
iscsi_trace(TRACE_SCSI_DEBUG, "iSCSI host released\n");
return 0;
}
int iscsi_bios_param(Disk *disk, kdev_t dev, int *ip) {
ip[0] = 32; /* heads */
ip[1] = 63; /* sectors */
if((ip[2] = disk->capacity >> 11) > 1024) { /* cylinders, test for big disk */
ip[0] = 255; /* heads */
ip[1] = 63; /* sectors */
ip[2] = disk->capacity / (255 * 63); /* cylinders */
}
iscsi_trace(TRACE_SCSI_DEBUG, "%u sectors, H/S/C: %u/%u/%u\n", disk->capacity, ip[0], ip[1], ip[2]);
return 0;
}
int iscsi_command(Scsi_Cmnd *SCpnt) {
iscsi_trace(TRACE_SCSI_DEBUG, "0x%p: op 0x%x, chan %i, target %i, lun %i, bufflen %i, sg %i\n",
SCpnt, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, SCpnt->lun,
SCpnt->request_bufflen, SCpnt->use_sg);
iscsi_trace_error("NOT IMPLEMENTED\n");
return -1;
}
int iscsi_done(void *ptr) {
initiator_cmd_t *cmd = (initiator_cmd_t *) ptr;
iscsi_scsi_cmd_args_t *scsi_cmd = (iscsi_scsi_cmd_args_t *) cmd->ptr;
Scsi_Cmnd *SCpnt = (Scsi_Cmnd *) cmd->callback_arg;
unsigned long flags = 0;
if (SCpnt==0) {
return 0;
}
if (cmd->status==0) {
SCpnt->result = scsi_cmd->status;
} else {
SCpnt->result = -1;
}
iscsi_trace(TRACE_SCSI_DEBUG, "scsi_arg 0x%p SCpnt 0x%p op 0x%x done (result %i)\n",
scsi_cmd, SCpnt, SCpnt->cmnd[0], SCpnt->result);
if ((scsi_cmd->input)&&(scsi_cmd->output)) {
iscsi_trace_error("bidi xfers not implemented\n");
return -1;
} else if (scsi_cmd->input) {
iscsi_spin_lock_irqsave(&g_stats.lock, &flags);
if ((g_stats.rx+SCpnt->request_bufflen)<g_stats.rx) {
g_stats.rx_overflow++;
}
g_stats.rx += SCpnt->request_bufflen;
g_stats.rx_queued -= SCpnt->request_bufflen;
if (g_stats.num_rx_queued) g_stats.num_rx_queued--;
g_stats.num_rx++;
iscsi_spin_unlock_irqrestore(&g_stats.lock, &flags);
} else if (scsi_cmd->output) {
iscsi_spin_lock_irqsave(&g_stats.lock, &flags);
if ((g_stats.tx+SCpnt->request_bufflen)<g_stats.tx) {
g_stats.tx_overflow++;
}
g_stats.tx += SCpnt->request_bufflen;
g_stats.tx_queued -= SCpnt->request_bufflen;
if (g_stats.num_tx_queued) g_stats.num_tx_queued--;
g_stats.num_tx++;
iscsi_spin_unlock_irqrestore(&g_stats.lock, &flags);
}
if (SCpnt->host_scribble) {
unsigned char *hs;
hs = SCpnt->host_scribble;
SCpnt->host_scribble = NULL; /* for abort */
if (iscsi_queue_insert(&g_iovec_q, hs)!=0) {
iscsi_trace_error("iscsi_queue_insert() failed\n");
return -1;
}
}
iscsi_free_atomic(scsi_cmd->ahs);
if (iscsi_queue_insert(&g_cmd_q, cmd)!=0) {
iscsi_trace_error("iscsi_queue_insert() failed\n");
cmd->callback_arg = NULL; /* for abort */
return -1;
}
cmd->callback_arg = NULL; /* for abort */
if (SCpnt->result==0) {
SCpnt->scsi_done(SCpnt);
} else {
iscsi_trace_error("SCSI cmd 0x%x failed at iSCSI level (ignoring)\n", SCpnt->cmnd[0]);
}
return 0;
}
int iscsi_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
initiator_cmd_t *cmd;
iscsi_scsi_cmd_args_t *scsi_cmd;
unsigned char *data;
unsigned length, trans_len;
int input, output;
unsigned long flags =0;
/* Tagged command queuing is handled from within this SCSI driver. */
if ((SCpnt->device->tagged_supported)&&(SCpnt->device->tagged_queue)) {
SCpnt->tag = SCpnt->device->current_tag++;
}
spin_unlock(&io_request_lock);
iscsi_trace(TRACE_SCSI_DEBUG, "SCpnt %p: tid %i lun %i op 0x%x tag %u len %i sg %i buff 0x%p\n",
SCpnt, SCpnt->target, SCpnt->lun, SCpnt->cmnd[0], SCpnt->tag, SCpnt->request_bufflen,
SCpnt->use_sg, SCpnt->buffer);
/* Determine direction of data transfer */
trans_len = length = output = input = 0;
if ((SCpnt->cmnd[0]!=TEST_UNIT_READY)&&(SCpnt->request_bufflen)) {
if (SCpnt->sc_data_direction == SCSI_DATA_WRITE) {
output = 1; input = 0;
length = trans_len = SCpnt->request_bufflen;
iscsi_spin_lock_irqsave(&g_stats.lock, &flags);
g_stats.num_tx_queued++;
g_stats.tx_queued += trans_len;
iscsi_spin_unlock_irqrestore(&g_stats.lock, &flags);
} else if (SCpnt->sc_data_direction == SCSI_DATA_READ) {
length = output = 0; input = 1;
trans_len = SCpnt->request_bufflen;
iscsi_spin_lock_irqsave(&g_stats.lock, &flags);
g_stats.num_rx_queued++;
g_stats.rx_queued += trans_len;
iscsi_spin_unlock_irqrestore(&g_stats.lock, &flags);
}
}
/* Convert scatterlist to iovec */
if (SCpnt->use_sg) {
struct scatterlist *sg = (struct scatterlist *) SCpnt->buffer;
struct iovec *iov;
int i;
iov = iscsi_queue_remove(&g_iovec_q);
if (iov == NULL) {
iscsi_trace_error("iscsi_queue_remove() failed\n");
spin_lock(&io_request_lock);
return -1;
}
for (i=0; i<SCpnt->use_sg; i++) {
iov[i].iov_base = sg[i].address;
iov[i].iov_len = sg[i].length;
}
data = SCpnt->host_scribble = (unsigned char *)iov;
} else {
data = SCpnt->buffer;
SCpnt->host_scribble = NULL;
}
/* Get free cmd structure */
if ((cmd=iscsi_queue_remove(&g_cmd_q))==NULL) {
iscsi_trace_error("iscsi_queue_remove() failed\n");
spin_lock(&io_request_lock);
return -1;
}
scsi_cmd = (iscsi_scsi_cmd_args_t *) cmd->ptr;
memset(scsi_cmd, 0, sizeof(*scsi_cmd));
scsi_cmd->send_data = output?data:0;
scsi_cmd->send_sg_len = output?SCpnt->use_sg:0;
scsi_cmd->recv_data = input?data:NULL;
scsi_cmd->recv_sg_len = input?SCpnt->use_sg:0;
scsi_cmd->input = input;
scsi_cmd->output = output;
scsi_cmd->length = length;
scsi_cmd->lun = SCpnt->lun;
scsi_cmd->lun = scsi_cmd->lun << 32;
scsi_cmd->trans_len = trans_len;
scsi_cmd->cdb = SCpnt->cmnd;
/* AHS for CDBs larget than 16 bytes */
if (SCpnt->cmd_len>16) {
iscsi_trace(TRACE_ISCSI_DEBUG, "creating AHS for extended CDB (%i bytes)\n", SCpnt->cmd_len);
if ((scsi_cmd->ahs=iscsi_malloc_atomic(SCpnt->cmd_len-16))==NULL) {
iscsi_trace_error("iscsi_malloc_atomic() failed\n");
spin_lock(&io_request_lock);
return -1;
}
memset(scsi_cmd->ahs, 0, 4);
*((uint16_t *)scsi_cmd->ahs) = HTONS(SCpnt->cmd_len-15); /* AHS length */
scsi_cmd->ahs[2] = 0x01; /* Type */
memcpy(scsi_cmd->ahs+4, SCpnt->cmnd+16, SCpnt->cmd_len-16); /* Copy in remaining CDB */
scsi_cmd->ahs_len = SCpnt->cmd_len-16;
}
SCpnt->scsi_done = done; /* The midlayer's callback called in iscsi_done */
SCpnt->result = 0x02; /* Default to a check condition */
cmd->callback = iscsi_done; /* This driver's callback called by initiator library */
cmd->callback_arg = SCpnt;
cmd->isid = SCpnt->target;
if (initiator_enqueue(cmd)!=0) {
iscsi_trace_error("initiator_enqueue() failed\n");
if (SCpnt->cmd_len>16) iscsi_free_atomic(scsi_cmd->ahs);
spin_lock(&io_request_lock);
return -1;
}
spin_lock(&io_request_lock);
return 0;
}
int iscsi_proc_info (char *buffer, char **start, off_t offset, int length, int hostno, int writing) {
unsigned char *info = NULL;
uint32_t infolen = 8192;
int len = 0;
iscsi_trace(TRACE_SCSI_DEBUG, "buffer = 0x%p, offset %u, length = %i, hostno %i, writing %i\n",
buffer, (unsigned) offset, length, hostno, writing);
/* writing resets counters */
if (writing) {
iscsi_spin_lock(&g_stats.lock);
g_stats.num_tx = g_stats.num_tx_queued = 0;
g_stats.num_rx = g_stats.num_rx_queued = 0;
g_stats.tx_queued = g_stats.tx = g_stats.tx_overflow = g_stats.tx_error = 0;
g_stats.rx_queued = g_stats.rx = g_stats.rx_overflow = g_stats.rx_error = 0;
g_stats.aborts_success = g_stats.aborts_failed = 0;
g_stats.device_resets = g_stats.bus_resets = g_stats.host_resets = 0;
iscsi_spin_unlock(&g_stats.lock);
return 0;
} else {
if ((info=iscsi_malloc_atomic(infolen))==NULL) {
iscsi_trace_error("iscsi_malloc_atomic() failed\n");
return -1;
}
len += snprintf(info, infolen, "%s\n\n", driver_template.name);
len += snprintf(&info[len], infolen - len, "Write file to reset counters (e.g., \"echo reset > /proc/scsi/iscsi/2\").\n\n");
len += snprintf(&info[len], infolen - len, "--------------------\n");
len += snprintf(&info[len], infolen - len, "Driver Configuration\n");
len += snprintf(&info[len], infolen - len, "--------------------\n\n");
len += snprintf(&info[len], infolen - len, " CONFIG_INITIATOR_NUM_TARGETS: %u\n", CONFIG_INITIATOR_NUM_TARGETS);
len += snprintf(&info[len], infolen - len, " CONFIG_INITIATOR_QUEUE_DEPTH: %u\n\n", CONFIG_INITIATOR_QUEUE_DEPTH);
len += snprintf(&info[len], infolen - len, "---------------\n");
len += snprintf(&info[len], infolen - len, "SCSI Statistics\n");
len += snprintf(&info[len], infolen - len, "---------------\n\n");
len += snprintf(&info[len], infolen - len, " Tx:\n");
len += snprintf(&info[len], infolen - len, " queued: %u\n", g_stats.num_tx_queued);
len += snprintf(&info[len], infolen - len, " completed: %u\n", g_stats.num_tx);
len += snprintf(&info[len], infolen - len, " avg size: %u\n", g_stats.num_tx?(g_stats.tx/g_stats.num_tx):0);
len += snprintf(&info[len], infolen - len, " total bytes: %u MB\n", g_stats.tx/1048576 + g_stats.tx_overflow*4096);
len += snprintf(&info[len], infolen - len, " total overflow: %u\n", g_stats.tx_overflow);
len += snprintf(&info[len], infolen - len, " Rx:\n");
len += snprintf(&info[len], infolen - len, " queued: %u\n", g_stats.num_rx_queued);
len += snprintf(&info[len], infolen - len, " completed: %u\n", g_stats.num_rx);
len += snprintf(&info[len], infolen - len, " avg size: %u\n", g_stats.num_rx?(g_stats.rx/g_stats.num_rx):0);
len += snprintf(&info[len], infolen - len, " total bytes: %u MB\n", g_stats.rx/1048576 + g_stats.rx_overflow*4096);
len += snprintf(&info[len], infolen - len, " total overflow: %u\n", g_stats.rx_overflow);
len += snprintf(&info[len], infolen - len, " Errors:\n");
len += snprintf(&info[len], infolen - len, " aborts: %u\n", g_stats.aborts_success);
/* len += snprintf(&info[len], infolen - len, " failed aborts: %u\n", g_stats.aborts_failed); */
len += snprintf(&info[len], infolen - len, " device resets: %u\n", g_stats.device_resets);
len += snprintf(&info[len], infolen - len, " bus resets: %u\n", g_stats.bus_resets);
len += snprintf(&info[len], infolen - len, " host resets: %u\n", g_stats.host_resets);
len += snprintf(&info[len], infolen - len, " Tx error bytes: %u\n", g_stats.tx_error);
len += snprintf(&info[len], infolen - len, " Rx error bytes: %u\n\n", g_stats.rx_error);
len += snprintf(&info[len], infolen - len, "--------------------\n");
len += snprintf(&info[len], infolen - len, "iSCSI Initiator Info\n");
len += snprintf(&info[len], infolen - len, "--------------------\n\n");
if ((len += initiator_info(&info[len], infolen, len))==-1) {
iscsi_trace_error("initiator_info() failed\n");
if (info != NULL) iscsi_free_atomic(info);
return -1;
}
if (offset>len-1) {
len = 0;
} else if (offset+length>len-1) {
len -= offset;
} else {
len = length;
}
*start = buffer;
memcpy(buffer, info+offset, len);
if (info != NULL) iscsi_free_atomic(info);
return len;
}
}
int iscsi_ioctl (Scsi_Device *dev, int cmd, void *argp) {
int i;
int lun = 0;
/* Run tests for each target */
for (i=0; i<CONFIG_INITIATOR_NUM_TARGETS; i++) {
if (test_all(i, lun)!=0) {
iscsi_trace_error("test_all() failed\n");
return -1;
}
}
return 0;
}
void iscsi_select_queue_depths(struct Scsi_Host *host, Scsi_Device *scsi_devs) {
struct scsi_device *device;
for (device = scsi_devs; device; device = device->next) {
if (device->host != host) {
iscsi_trace_error("got device for different host\n");
continue;
}
if (device->tagged_supported) {
iscsi_trace(TRACE_SCSI_DEBUG, "target %i lun %i supports TCQ\n", device->id, device->lun);
device->tagged_queue = 1;
device->current_tag = 0;
device->queue_depth = CONFIG_INITIATOR_QUEUE_DEPTH;
iscsi_trace(TRACE_SCSI_DEBUG, "device queue depth set to %i\n", device->queue_depth);
} else {
iscsi_trace(TRACE_SCSI_DEBUG, "target %i lun %i does NOT support TCQ\n", device->id, device->lun);
device->queue_depth = 1;
}
}
}
/*
* Error Handling Routines
*/
int iscsi_abort_handler (Scsi_Cmnd *SCpnt) {
iscsi_scsi_cmd_args_t *scsi_cmd;
initiator_session_t *sess;
int i;
unsigned long flags;
spin_unlock_irq(&io_request_lock);
iscsi_trace_error("aborting SCSI cmd 0x%p (op 0x%x, tid %i, lun %i)\n",
SCpnt, SCpnt->cmnd[0], SCpnt->target, SCpnt->lun);
for (i=0; i<CONFIG_INITIATOR_QUEUE_DEPTH; i++) {
/* Find the cmd ptr in g_cmd. We look for the callback_arg that's equal */
/* to SCpnt. iscsi_done() sets callback_arg to NULL when a command */
/* completes. So we know that any non_NULL callback_arg is associated */
/* with an outstanding command. */
if (g_cmd[i].callback_arg == SCpnt) {
/* Abort the command */
if (initiator_abort(&g_cmd[i])!=0) {
iscsi_trace_error("initiator_abort() failed\n");
spin_lock_irq(&io_request_lock);
return FAILED;
}
/* Update counters */
scsi_cmd = (iscsi_scsi_cmd_args_t *) g_cmd[i].ptr;
if ((scsi_cmd->input)&&(scsi_cmd->output)) {
iscsi_trace_error("bidi xfers not implemented\n");
spin_lock_irq(&io_request_lock);
return FAILED;
} else if (scsi_cmd->input) {
iscsi_spin_lock_irqsave(&g_stats.lock,&flags);
g_stats.rx_error += SCpnt->request_bufflen;
g_stats.rx_queued -= SCpnt->request_bufflen;
iscsi_spin_unlock_irqrestore(&g_stats.lock, &flags);
} else if (scsi_cmd->output) {
iscsi_spin_lock_irqsave(&g_stats.lock, &flags);
g_stats.tx_error += SCpnt->request_bufflen;
g_stats.tx_queued -= SCpnt->request_bufflen;
iscsi_spin_unlock_irqrestore(&g_stats.lock, &flags);
}
break;
}
}
/* Destroy session */
if (g_target[SCpnt->target].has_session) {
sess = g_target[SCpnt->target].sess;
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
if (in_interrupt()) {
iscsi_trace_error("aborting within interrupt (killing Tx and Rx threads)\n");
#endif
iscsi_trace_error("killing Tx and Rx threads\n");
kill_proc(sess->rx_worker.pid, SIGKILL, 1);
kill_proc(sess->tx_worker.pid, SIGKILL, 1);
sess->tx_worker.state = 0;
sess->rx_worker.state = 0;
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
} else {
iscsi_trace_error("aborting outside interrupt (gracefully ending Tx and Rx)\n");
}
#endif
iscsi_trace(TRACE_ISCSI_DEBUG, "destroying session\n");
if (session_destroy_i(sess)!=0) {
iscsi_trace_error("session_destroy() failed\n");
g_stats.aborts_failed++;
spin_lock_irq(&io_request_lock);
return FAILED;
}
} else {
iscsi_trace(TRACE_ISCSI_DEBUG, "no session\n");
}
g_stats.aborts_success++;
iscsi_trace_error("successfully aborted SCSI cmd 0x%p (op 0x%x, tid %i, lun %i)\n",
SCpnt, SCpnt->cmnd[0], SCpnt->target, SCpnt->lun);
spin_lock_irq(&io_request_lock);
return SUCCESS;
}
int iscsi_device_reset_handler (Scsi_Cmnd *SCpnt) {
iscsi_trace_error("***********************\n");
iscsi_trace_error("*** DEVICE %i RESET ***\n", SCpnt->target);
iscsi_trace_error("***********************\n");
g_stats.device_resets++;
return SUCCESS;
}
int iscsi_bus_reset_handler (Scsi_Cmnd *SCpnt) {
iscsi_trace_error("********************\n");
iscsi_trace_error("*** BUS %i RESET ***\n", SCpnt->target);
iscsi_trace_error("********************\n");
g_stats.bus_resets++;
return SUCCESS;
}
int iscsi_host_reset_handler(Scsi_Cmnd *SCpnt) {
iscsi_trace_error("*********************\n");
iscsi_trace_error("*** HOST RESET %i ***\n", SCpnt->target);
iscsi_trace_error("*********************\n");
g_stats.host_resets++;
return SUCCESS;
}

3246
external/bsd/iscsi/dist/src/initiator.c vendored Normal file

File diff suppressed because it is too large Load Diff

238
external/bsd/iscsi/dist/src/install-sh vendored Executable file
View File

@ -0,0 +1,238 @@
#! /bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
tranformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

View File

@ -0,0 +1,219 @@
/*
* Copyright © 2007 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#define EXTERN
#include <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#include "scsi_cmd_codes.h"
#include "iscsi.h"
#include "initiator.h"
#include "tests.h"
int
main(int argc, char **argv)
{
struct sigaction act;
struct passwd *pwp;
char hostname[1024];
char lun[1024];
char *host;
char *user;
int address_family;
int port;
int digest_type;
int mutual_auth;
int iterations;
int auth_type;
int i;
/* Check args */
user = NULL;
(void) gethostname(host = hostname, sizeof(hostname));
digest_type = DigestNone;
auth_type = AuthNone;
address_family = ISCSI_UNSPEC;
port = ISCSI_PORT;
mutual_auth = 0;
lun[0] = 0x0;
iterations = 1;
while ((i = getopt(argc, argv, "46a:d:h:n:p:t:u:V")) != -1) {
switch(i) {
case '4':
address_family = ISCSI_IPv4;
break;
case '6':
address_family = ISCSI_IPv6;
break;
case 'a':
if (strcasecmp(optarg, "chap") == 0) {
auth_type = AuthCHAP;
} else if (strcasecmp(optarg, "kerberos") == 0) {
auth_type = AuthKerberos;
} else if (strcasecmp(optarg, "srp") == 0) {
auth_type = AuthSRP;
}
break;
case 'd':
if (strcasecmp(optarg, "header") == 0) {
digest_type = DigestHeader;
} else if (strcasecmp(optarg, "data") == 0) {
digest_type = DigestData;
} else if (strcasecmp(optarg, "both") == 0 || strcasecmp(optarg, "all") == 0) {
digest_type = (DigestHeader | DigestData);
}
break;
case 'h':
host = optarg;
break;
case 'n':
iterations = atoi(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 't':
(void) strlcpy(lun, optarg, sizeof(lun));
break;
case 'u':
user = optarg;
break;
case 'V':
(void) printf("\"%s\" %s\nPlease send all bug reports to %s\n", PACKAGE_NAME, PACKAGE_VERSION, PACKAGE_BUGREPORT);
exit(EXIT_SUCCESS);
/* NOTREACHED */
default:
(void) fprintf(stderr, "%s: unknown option `%c'", *argv, i);
}
}
if (user == NULL) {
if ((pwp = getpwuid(geteuid())) == NULL) {
iscsi_trace_error(__FILE__, __LINE__, "can't find user information\n");
exit(EXIT_FAILURE);
}
user = pwp->pw_name;
}
if (argc == 1) {
(void) fprintf(stderr, "usage: %s [-4] [-6] [-V] [-a auth-type] [-d digest-type] [-h hostname] [-l lun] [-p port] [-t target] [-u user]\n", *argv);
exit(EXIT_FAILURE);
}
/* Ignore sigpipe */
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL);
for (i = 0 ; i < iterations ; i++) {
/* Initialize Initiator */
if (ii_initiator_init(host, port, address_family, user, lun, auth_type, mutual_auth, digest_type) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "initiator_init() failed\n");
return -1;
}
/* Run tests for target */
if (ii_test_all() != 0) {
iscsi_trace_error(__FILE__, __LINE__, "test_all() failed\n");
return -1;
}
/* Shutdown Initiator */
if (initiator_shutdown() == -1) {
iscsi_trace_error(__FILE__, __LINE__, "initiator_shutdown() failed\n");
return -1;
}
}
printf("\n");
printf("************************************\n");
printf("* ALL TESTS COMPLETED SUCCESSFULLY *\n");
printf("************************************\n");
printf("\n");
exit(EXIT_SUCCESS);
}

View File

@ -0,0 +1,124 @@
.\" $NetBSD: iscsi-target.8,v 1.1 2009/06/21 21:20:31 agc Exp $
.\"
.\" Copyright © 2006 Alistair Crooks. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. The name of the author may not be used to endorse or promote
.\" products derived from this software without specific prior written
.\" permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd May 27, 2006
.Dt ISCSI-TARGET 8
.Os
.Sh NAME
.Nm iscsi-target
.Nd service remote iSCSI requests
.Sh SYNOPSIS
.Nm
.Op Fl 46DV
.Op Fl b Ar block length
.Op Fl f Ar configuration file
.Op Fl p Ar port number
.Op Fl s Ar maximum number of sessions
.Op Fl t Ar target name
.Op Fl v Ar verbose arg
.Sh DESCRIPTION
.Nm
is the server for
iSCSI
requests from iSCSI initiators.
.Nm
listens for discovery and login requests on the required port,
and responds to those requests appropriately.
.Pp
Options and operands available for
.Nm iscsi-target :
.Bl -tag -width Ds
.It Fl 4
.Nm
will listen for IPv4 connections,
and respond back using IPv4.
This is the default address family.
.It Fl 6
.Nm
will listen for IPv6 connections,
and respond back using IPv6.
.It Fl b Ar blocksize
Specify the underlying block size for iSCSI storage which will be served.
The possible sizes are: 512, 1024, 2048, and 4096 bytes, with the default
being 512 bytes.
.It Fl D
When this option is specified,
.Nm
will not detach itself from the controlling tty, and will
not become a daemon.
This can be useful for debugging purposes.
.It Fl f Ar configfile
Use the named file as the configuration file.
The default file can be found in
.Ar /etc/iscsi/targets .
See
.Xr targets 5
for more information.
.It Fl p Ar port number
Use the port number provided as the argument as the port
on which to listen for iSCSI service requests from
initiators.
.It Fl s Ar maximum number of sessions
Allow the maximum number of sessions to be initiated when
connecting to the target.
.It Fl t Ar filename
The target name (as it appears to the iSCSI initiator) can be specified
using this flag.
.It Fl V
.Nm
will print the utility name and version number,
and the address for bug reports, and then exit.
.It Fl v Ar argument
The amount of information shown can be varied by using this command.
Possible values of
.Ar argument
are
.Ar net
to show network-related information,
.Ar iscsi
to show iSCSI protocol-related information,
.Ar scsi
to show SCSI protocol information, and
.Ar all
to show information from all of the above arguments.
.El
.Sh FILES
.Bl -tag -width /var/run/iscsi-target.pid -compact
.It Pa /etc/iscsi/targets
the list of exported storage
.It Pa /var/run/iscsi-target.pid
the PID of the currently running
.Nm
.El
.Sh SEE ALSO
.Xr targets 5
.Sh HISTORY
The
.Nm
utility first appeared in
.Nx 4.0 .

View File

@ -0,0 +1,166 @@
/* $NetBSD: iscsi-target.c,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#define EXTERN
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <unistd.h>
#include "iscsi.h"
#include "iscsiutil.h"
#include "target.h"
#include "device.h"
#include "conffile.h"
#include "storage.h"
static int g_main_pid;
static globals_t g;
int
main(int argc, char **argv)
{
targv_t tv;
devv_t dv;
extv_t ev;
char TargetName[1024];
int detach_me_harder;
int i;
(void) memset(&g, 0x0, sizeof(g));
(void) memset(&tv, 0x0, sizeof(tv));
(void) memset(&dv, 0x0, sizeof(dv));
(void) memset(&ev, 0x0, sizeof(ev));
/* set defaults */
(void) strlcpy(TargetName, DEFAULT_TARGET_NAME, sizeof(TargetName));
detach_me_harder = 1;
g.port = ISCSI_PORT;
g.address_family = ISCSI_UNSPEC;
g.max_sessions = DEFAULT_TARGET_MAX_SESSIONS;
(void) strlcpy(g.config_file, _PATH_ISCSI_TARGETS, sizeof(g.config_file));
while ((i = getopt(argc, argv, "46b:Df:p:s:t:Vv:")) != -1) {
switch (i) {
case '4':
g.address_family = ISCSI_IPv4;
break;
case '6':
g.address_family = ISCSI_IPv6;
break;
case 'b':
device_set_var("blocklen", optarg);
break;
case 'D':
detach_me_harder = 0;
break;
case 'f':
(void) strlcpy(g.config_file, optarg, sizeof(g.config_file));
break;
case 'p':
g.port = (uint16_t) atoi(optarg);
break;
case 's':
if ((g.max_sessions = atoi(optarg)) <= 0) {
g.max_sessions = DEFAULT_TARGET_MAX_SESSIONS;
}
break;
case 't':
(void) strlcpy(TargetName, optarg, sizeof(TargetName));
break;
case 'V':
(void) printf("\"%s\" %s\nPlease send all bug reports to %s\n", PACKAGE_NAME, PACKAGE_VERSION, PACKAGE_BUGREPORT);
exit(EXIT_SUCCESS);
/* NOTREACHED */
case 'v':
if (strcmp(optarg, "net") == 0) {
set_debug("net");
} else if (strcmp(optarg, "iscsi") == 0) {
set_debug("iscsi");
} else if (strcmp(optarg, "scsi") == 0) {
set_debug("scsi");
} else if (strcmp(optarg, "all") == 0) {
set_debug("all");
}
break;
}
}
if (!read_conf_file(g.config_file, &tv, &dv, &ev)) {
(void) fprintf(stderr, "Error: can't open `%s'\n", g.config_file);
return EXIT_FAILURE;
}
(void) signal(SIGPIPE, SIG_IGN);
g_main_pid = ISCSI_GETPID;
if (tv.c == 0) {
(void) fprintf(stderr, "No targets to initialise\n");
return EXIT_FAILURE;
}
/* Initialize target */
if (target_init(&g, &tv, TargetName) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "target_init() failed\n");
exit(EXIT_FAILURE);
}
#ifdef HAVE_DAEMON
/* if we are supposed to be a daemon, detach from controlling tty */
if (detach_me_harder && daemon(0, 0) < 0) {
iscsi_trace_error(__FILE__, __LINE__, "daemon() failed\n");
exit(EXIT_FAILURE);
}
#endif
/* write pid to a file */
write_pid_file(_PATH_ISCSI_PID_FILE);
/* Wait for connections */
if (target_listen(&g) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "target_listen() failed\n");
}
return EXIT_SUCCESS;
}

1378
external/bsd/iscsi/dist/src/iscsi.c vendored Normal file

File diff suppressed because it is too large Load Diff

368
external/bsd/iscsi/dist/src/md5c.c vendored Normal file
View File

@ -0,0 +1,368 @@
/* $NetBSD: md5c.c,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* This file is derived from the RSA Data Security, Inc. MD5 Message-Digest
* Algorithm and has been modifed by Jason R. Thorpe <thorpej@NetBSD.ORG>
* for portability and formatting.
*/
/*
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
* rights reserved.
*
* License to copy and use this software is granted provided that it
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest
* Algorithm" in all material mentioning or referencing this software
* or this function.
*
* License is also granted to make and use derivative works provided
* that such works are identified as "derived from the RSA Data
* Security, Inc. MD5 Message-Digest Algorithm" in all material
* mentioning or referencing the derived work.
*
* RSA Data Security, Inc. makes no representations concerning either
* the merchantability of this software or the suitability of this
* software for any particular purpose. It is provided "as is"
* without express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this
* documentation and/or software.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if defined(_KERNEL) || defined(_STANDALONE)
#include <lib/libkern/libkern.h>
#include <sys/param.h>
#include <sys/md5.h>
#define _DIAGASSERT(x) (void)0
#else
/* #include "namespace.h" */
#include <assert.h>
#include <string.h>
#include "iscsi-md5.h"
#endif /* _KERNEL || _STANDALONE */
#if defined(HAVE_MEMSET)
#define ZEROIZE(d, l) memset((d), 0, (l))
#else
# if defined(HAVE_BZERO)
#define ZEROIZE(d, l) bzero((d), (l))
# else
#error You need either memset or bzero
# endif
#endif
typedef unsigned char *POINTER;
typedef uint16_t UINT2;
typedef uint32_t UINT4;
/*
* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
#if 0
#if !defined(_KERNEL) && !defined(_STANDALONE) && defined(__weak_alias)
__weak_alias(iSCSI_MD5Init,_MD5Init)
__weak_alias(iSCSI_MD5Update,_MD5Update)
__weak_alias(iSCSI_MD5Final,_MD5Final)
#endif
#endif
#ifndef _DIAGASSERT
#define _DIAGASSERT(cond) assert(cond)
#endif
static void iSCSI_MD5Transform(UINT4 [4], const unsigned char [64]);
static void Encode(unsigned char *, UINT4 *, unsigned int);
static void Decode(UINT4 *, const unsigned char *, unsigned int);
/*
* Encodes input (UINT4) into output (unsigned char). Assumes len is
* a multiple of 4.
*/
static void
Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/*
* Decodes input (unsigned char) into output (UINT4). Assumes len is
* a multiple of 4.
*/
static void
Decode (output, input, len)
UINT4 *output;
const unsigned char *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
static const unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/*
* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/*
* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
* Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/*
* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void
iSCSI_MD5Init(iSCSI_MD5_CTX *context)
{
_DIAGASSERT(context != 0);
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants. */
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/*
* MD5 block update operation. Continues an MD5 message-digest
* operation, processing another message block, and updating the
* context.
*/
void
iSCSI_MD5Update(iSCSI_MD5_CTX *context, const uint8_t *input, size_t inputLen)
{
unsigned int i, idx, partLen;
_DIAGASSERT(context != 0);
_DIAGASSERT(input != 0);
/* Compute number of bytes mod 64 */
idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - idx;
/* Transform as many times as possible. */
if (inputLen >= partLen) {
/* LINTED const castaway ok */
memcpy((POINTER)&context->buffer[idx],
input, partLen);
iSCSI_MD5Transform(context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
iSCSI_MD5Transform(context->state, &input[i]);
idx = 0;
} else
i = 0;
/* Buffer remaining input */
/* LINTED const castaway ok */
memcpy((POINTER)&context->buffer[idx], &input[i],
inputLen - i);
}
/*
* MD5 finalization. Ends an MD5 message-digest operation, writing the
* message digest and zeroing the context.
*/
void
iSCSI_MD5Final(unsigned char digest[16], iSCSI_MD5_CTX *context)
{
unsigned char bits[8];
unsigned int idx;
size_t padLen;
_DIAGASSERT(digest != 0);
_DIAGASSERT(context != 0);
/* Save number of bits */
Encode(bits, context->count, 8);
/* Pad out to 56 mod 64. */
idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (idx < 56) ? (56 - idx) : (120 - idx);
iSCSI_MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
iSCSI_MD5Update(context, bits, 8);
/* Store state in digest */
Encode(digest, context->state, 16);
/* Zeroize sensitive information. */
ZEROIZE((POINTER)(void *)context, sizeof(*context));
}
/*
* MD5 basic transformation. Transforms state based on block.
*/
static void
iSCSI_MD5Transform(state, block)
UINT4 state[4];
const unsigned char block[64];
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode(x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information. */
ZEROIZE((POINTER)(void *)x, sizeof (x));
}

122
external/bsd/iscsi/dist/src/md5hl.c vendored Normal file
View File

@ -0,0 +1,122 @@
/* $NetBSD: md5hl.c,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* Written by Jason R. Thorpe <thorpej@netbsd.org>, April 29, 1997.
* Public domain.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define MDALGORITHM iSCSI_MD5
/* #include "namespace.h" */
#include "iscsi-md5.h"
#ifndef _DIAGASSERT
#define _DIAGASSERT(cond) assert(cond)
#endif
/* $NetBSD: md5hl.c,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
* from FreeBSD Id: mdXhl.c,v 1.8 1996/10/25 06:48:12 bde Exp
*/
/*
* Modifed April 29, 1997 by Jason R. Thorpe <thorpej@netbsd.org>
*/
#include <assert.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#define CONCAT(x,y) __CONCAT(x,y)
#define MDNAME(x) CONCAT(MDALGORITHM,x)
char *
MDNAME(End)(MDNAME(_CTX) *ctx, char *buf)
{
int i;
unsigned char digest[16];
static const char hex[]="0123456789abcdef";
_DIAGASSERT(ctx != 0);
if (buf == NULL)
buf = malloc(33);
if (buf == NULL)
return (NULL);
MDNAME(Final)(digest, ctx);
for (i = 0; i < 16; i++) {
buf[i+i] = hex[(uint32_t)digest[i] >> 4];
buf[i+i+1] = hex[digest[i] & 0x0f];
}
buf[i+i] = '\0';
return (buf);
}
char *
MDNAME(File)(filename, buf)
const char *filename;
char *buf;
{
unsigned char buffer[BUFSIZ];
MDNAME(_CTX) ctx;
int f, j;
size_t i;
_DIAGASSERT(filename != 0);
/* buf may be NULL */
MDNAME(Init)(&ctx);
f = open(filename, O_RDONLY, 0666);
if (f < 0)
return NULL;
while ((i = read(f, buffer, sizeof(buffer))) > 0)
MDNAME(Update)(&ctx, buffer, (size_t)i);
j = errno;
close(f);
errno = j;
#if 0
if (i < 0)
return NULL;
#endif
return (MDNAME(End)(&ctx, buf));
}
char *
MDNAME(Data)(const uint8_t *data, size_t len, char *buf)
{
MDNAME(_CTX) ctx;
_DIAGASSERT(data != 0);
MDNAME(Init)(&ctx);
MDNAME(Update)(&ctx, data, len);
return (MDNAME(End)(&ctx, buf));
}

172
external/bsd/iscsi/dist/src/netmask.c vendored Normal file
View File

@ -0,0 +1,172 @@
/* $NetBSD: netmask.c,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include "iscsiutil.h"
enum {
NETMASK_BUFFER_SIZE = 256
};
/* this struct is used to define a magic netmask value */
typedef struct magic_t {
const char *magic; /* string to match */
const char *xform; /* string to transform it into */
} magic_t;
static magic_t magics[] = {
{ "any", "0/0" },
{ "all", "0/0" },
{ "none", "0/32" },
{ NULL, NULL },
};
#ifndef ISCSI_HTONL
#define ISCSI_HTONL(x) htonl(x)
#endif
/* return 1 if address is in netmask's range */
int
allow_netmask(const char *netmaskarg, const char *addr)
{
struct in_addr a;
struct in_addr m;
const char *netmask;
magic_t *mp;
char maskaddr[NETMASK_BUFFER_SIZE];
char *cp;
int slash;
int i;
/* firstly check for any magic values in the netmask */
netmask = netmaskarg;
for (mp = magics ; mp->magic ; mp++) {
if (strcmp(netmask, mp->magic) == 0) {
netmask = mp->xform;
break;
}
}
/* find out if slash notation has been used */
(void) memset(&a, 0x0, sizeof(a));
if ((cp = strchr(netmask, '/')) == NULL) {
(void) strlcpy(maskaddr, netmask, sizeof(maskaddr));
slash = 32;
} else {
(void) strlcpy(maskaddr, netmask, MIN(sizeof(maskaddr), (size_t)(cp - netmask) + 1));
slash = atoi(cp + 1);
}
/* if we have a wildcard "slash" netmask, then we allow it */
if (slash == 0) {
return 1;
}
/* canonicalise IPv4 address to dotted quad */
for (i = 0, cp = maskaddr ; *cp ; cp++) {
if (*cp == '.') {
i += 1;
}
}
for ( ; i < 3 ; i++) {
(void) snprintf(cp, sizeof(maskaddr) - (int)(cp - maskaddr), ".0");
cp += 2;
}
/* translate netmask to in_addr */
if (!inet_aton(maskaddr, &m)) {
(void) fprintf(stderr, "allow_netmask: can't interpret mask `%s' as an IPv4 address\n", maskaddr);
return 0;
}
/* translate address to in_addr */
if (!inet_aton(addr, &a)) {
(void) fprintf(stderr, "allow_netmask: can't interpret address `%s' as an IPv4 address\n", addr);
return 0;
}
#ifdef ALLOW_NETMASK_DEBUG
printf("addr %s %08x, mask %s %08x, slash %d\n", addr, (ISCSI_HTONL(a.s_addr) >> (32 - slash)), maskaddr, (ISCSI_HTONL(m.s_addr) >> (32 - slash)), slash);
#endif
/* and return 1 if address is in netmask */
return (ISCSI_HTONL(a.s_addr) >> (32 - slash)) == (ISCSI_HTONL(m.s_addr) >> (32 - slash));
}
#ifdef ALLOW_NETMASK_DEBUG
int
main(int argc, char **argv)
{
int i;
for (i = 1 ; i < argc ; i+= 2) {
if (allow_netmask(argv[i], argv[i + 1])) {
printf("mask %s matches addr %s\n\n", argv[i], argv[i + 1]);
} else {
printf("No match for mask %s from addr %s\n\n", argv[i], argv[i + 1]);
}
}
exit(EXIT_SUCCESS);
}
#endif
#if 0
[11:33:02] agc@sys3 ...local/src/netmask 248 > ./n 10.4/16 10.4.0.29 10.4/16 10.5.0.29 10.4/0 10.4.0.19 10.4 10.4.0.19 10.4.3/8 10.4.3.7 10.4.3/24 10.4.3.7
mask 10.4/16 matches addr 10.4.0.29
No match for mask 10.4/16 from addr 10.5.0.29
mask 10.4/0 matches addr 10.4.0.19
No match for mask 10.4 from addr 10.4.0.19
mask 10.4.3/8 matches addr 10.4.3.7
mask 10.4.3/24 matches addr 10.4.3.7
[14:44:52] agc@sys3 ...local/src/netmask 249 >
#endif

181
external/bsd/iscsi/dist/src/osd-target.c vendored Normal file
View File

@ -0,0 +1,181 @@
/* $NetBSD: osd-target.c,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright © 2006 \
The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: osd-target.c,v 1.1 2009/06/21 21:20:31 agc Exp $");
#endif
#include "config.h"
#define EXTERN
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <unistd.h>
#include "iscsi.h"
#include "iscsiutil.h"
#include "target.h"
#include "device.h"
#include "conffile.h"
#include "storage.h"
/*
* Globals
*/
static int g_main_pid;
static globals_t g;
/*
* Control-C handler
*/
/* ARGSUSED0 */
static void
handler(int s)
{
if (ISCSI_GETPID != g_main_pid)
return;
if (target_shutdown(&g) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "target_shutdown() failed\n");
return;
}
return;
}
int
main(int argc, char **argv)
{
const char *cf;
targv_t tv;
devv_t dv;
extv_t ev;
char TargetName[1024];
int detach_me_harder;
int i;
(void) memset(&g, 0x0, sizeof(g));
(void) memset(&tv, 0x0, sizeof(tv));
(void) memset(&dv, 0x0, sizeof(dv));
(void) memset(&ev, 0x0, sizeof(ev));
/* set defaults */
(void) strlcpy(TargetName, DEFAULT_TARGET_NAME, sizeof(TargetName));
g.port = ISCSI_PORT;
detach_me_harder = 1;
cf = _PATH_OSD_TARGETS;
while ((i = getopt(argc, argv, "Dd:p:t:v:")) != -1) {
switch (i) {
case 'D':
detach_me_harder = 0;
break;
case 'd':
device_set_var("directory", optarg);
break;
case 'f':
cf = optarg;
break;
case 'p':
g.port = (uint16_t) atoi(optarg);
break;
case 't':
(void) strlcpy(TargetName, optarg, sizeof(TargetName));
break;
case 'v':
if (strcmp(optarg, "net") == 0) {
set_debug("net");
} else if (strcmp(optarg, "iscsi") == 0) {
set_debug("iscsi");
} else if (strcmp(optarg, "scsi") == 0) {
set_debug("scsi");
} else if (strcmp(optarg, "osd") == 0) {
set_debug("osd");
} else if (strcmp(optarg, "all") == 0) {
set_debug("all");
}
break;
}
}
if (!read_conf_file(cf, &tv, &dv, &ev)) {
(void) fprintf(stderr, "Error: can't open `%s'\n", cf);
return EXIT_FAILURE;
}
(void) signal(SIGPIPE, SIG_IGN);
(void) signal(SIGINT, handler);
g_main_pid = ISCSI_GETPID;
if (tv.c == 0) {
(void) fprintf(stderr, "No targets to initialise\n");
return EXIT_FAILURE;
}
/* Initialize target */
for (i = optind ; i < argc ; i++) {
if (target_init(&g, &tv, TargetName, i) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "target_init() failed\n");
exit(EXIT_FAILURE);
}
}
#ifdef HAVE_DAEMON
/* if we are supposed to be a daemon, detach from controlling tty */
if (detach_me_harder && daemon(0, 0) < 0) {
iscsi_trace_error(__FILE__, __LINE__, "daemon() failed\n");
exit(EXIT_FAILURE);
}
#endif
/* write pid to a file */
write_pid_file(_PATH_OSD_PID_FILE);
/* Wait for connections */
if (target_listen(&g) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "target_listen() failed\n");
}
return EXIT_SUCCESS;
}

662
external/bsd/iscsi/dist/src/osd.c vendored Normal file
View File

@ -0,0 +1,662 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <sys/types.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <unistd.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <unistd.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#include "scsi_cmd_codes.h"
#include "iscsi.h"
#include "iscsiutil.h"
#include "device.h"
#include "osd.h"
/*
* Globals
*/
static int osd_luns = CONFIG_OSD_LUNS_DFLT;
static uint64_t osd_capacity = CONFIG_OSD_CAPACITY_DFLT * 1048576;
static char base_dir[64] = CONFIG_OSD_BASEDIR_DFLT;
#ifndef __KERNEL__
void
device_set_var(const char *var, char *arg)
{
if (strcmp(var, "capacity") == 0) {
osd_capacity = strtoll(arg, (char **) NULL, 10) * 1048576;
} else if (strcmp(var, "luns") == 0) {
osd_luns = atoi(arg);
} else if (strcmp(var, "directory") == 0) {
(void) strlcpy(base_dir, arg, sizeof(base_dir));
} else {
(void) fprintf(stderr, "Unrecognised variable: `%s'\n", var);
}
}
#endif
int
device_init(globals_t *gp, char *dev)
{
struct stat st;
char FileName[1024];
int i;
if (stat(base_dir, &st) < 0) {
/* Create directory for OSD */
if (mkdir(base_dir, 0755) != 0) {
if (errno != EEXIST) {
iscsi_trace_error(__FILE__, __LINE__, "error creating directory \"%s\" for OSD: errno %d\n", base_dir, errno);
return -1;
}
}
/* Create directory for LU */
for (i = 0; i < osd_luns; i++) {
sprintf(FileName, "%s/lun_%d", base_dir, i);
if (mkdir(FileName, 0755) != 0) {
if (errno != EEXIST) {
iscsi_trace_error(__FILE__, __LINE__, "error creating \"%s\" for LU %d: errno %d\n", FileName, i, errno);
return -1;
}
}
}
}
/* Display LU info */
return 0;
}
int
osd_read_callback(void *arg)
{
struct iovec *sg = (struct iovec *) arg;
int i = 0;
while (sg[i].iov_base != NULL) {
iscsi_free_atomic(sg[i].iov_base);
i++;
}
return 0;
}
int
device_command(target_session_t * sess, target_cmd_t * cmd)
{
iscsi_scsi_cmd_args_t *args = cmd->scsi_cmd;
uint8_t *data;
char FileName[1024];
uint8_t *write_data = NULL;
uint8_t *read_data = NULL;
uint8_t *set_list = NULL;
uint8_t *get_list = NULL;
struct iovec sg[3];
int sg_len = 0;
int rc;
osd_args_t osd_args;
uint32_t GroupID = 0;
uint64_t UserID = 0;
char string[1024];
uint8_t *get_data = NULL;
uint32_t page = 0;
uint32_t index = 0;
int attr_len = 0;
iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "SCSI op 0x%x (lun %llu)\n", args->cdb[0], args->lun);
if (args->lun >= osd_luns) {
iscsi_trace(TRACE_SCSI_DEBUG, __FILE__, __LINE__, "invalid lun: %llu\n", args->lun);
args->status = 0x01;
return 0;
}
args->status = 1;
switch (args->cdb[0]) {
case TEST_UNIT_READY:
iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "TEST_UNIT_READY(lun %llu)\n", args->lun);
args->status = 0;
args->length = 0;
break;
case INQUIRY:
iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "INQUIRY(lun %llu)\n", args->lun);
data = args->send_data;
memset(data, 0, args->cdb[4]); /* Clear allocated buffer */
data[0] = 0x0e; /* Peripheral Device Type */
/* data[1] |= 0x80; // Removable Bit */
data[2] |= 0x02;/* ANSI-approved version */
/* data[3] |= 0x80; // AENC */
/* data[3] |= 0x40; // TrmIOP */
/* data[3] |= 0x20; // NormACA */
data[4] = args->cdb[4] - 4; /* Additional length */
/*
* data[7] |= 0x80; // Relative
* addressing
*/
data[7] |= 0x40;/* WBus32 */
data[7] |= 0x20;/* WBus16 */
/* data[7] |= 0x10; // Sync */
/* data[7] |= 0x08; // Linked Commands */
/* data[7] |= 0x04; // TransDis */
/*
* data[7] |= 0x02; // Tagged Command
* Queueing
*/
/* data[7] |= 0x01; // SftRe */
(void) memset(data + 8, 0x0, 32);
strlcpy(data + 8, OSD_VENDOR, 8); /* Vendor */
strlcpy(data + 16, OSD_PRODUCT, 16); /* Product ID */
(void) snprintf(data + 32, 8, "%d", OSD_VERSION); /* Product Revision */
args->input = 1;
args->length = args->cdb[4] + 1;
args->status = 0;
break;
case 0x7F:
OSD_DECAP_CDB(args->cdb, args->ext_cdb, &osd_args);
/* OSD_PRINT_CDB(args->cdb, args->ext_cdb); */
GroupID = osd_args.GroupID;
UserID = osd_args.UserID;
/*
* Transfer all data
*/
if (osd_args.set_attributes_list_length) {
if ((set_list = iscsi_malloc_atomic(osd_args.set_attributes_list_length)) == NULL) {
iscsi_trace_error(__FILE__, __LINE__, "iscsi_malloc_atomic() failed\n");
goto done;
}
sg[sg_len].iov_base = set_list;
sg[sg_len].iov_len = osd_args.set_attributes_list_length;
sg_len++;
}
if (osd_args.get_attributes_list_length) {
if ((get_list = iscsi_malloc_atomic(osd_args.get_attributes_list_length)) == NULL) {
iscsi_trace_error(__FILE__, __LINE__, "iscsi_malloc_atomic() failed\n");
goto done;
}
sg[sg_len].iov_base = get_list;
sg[sg_len].iov_len = osd_args.get_attributes_list_length;
sg_len++;
}
if (osd_args.service_action == OSD_WRITE) {
if ((write_data = iscsi_malloc_atomic(osd_args.length)) == NULL) {
iscsi_trace_error(__FILE__, __LINE__, "iscsi_malloc_atomic() failed\n");
goto done;
}
sg[sg_len].iov_base = write_data;
sg[sg_len].iov_len = osd_args.length;
sg_len++;
}
if (sg_len) {
if (target_transfer_data(sess, args, sg, sg_len) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "target_transfer_data() failed\n");
goto done;
}
}
/*
* Set any attributes
*/
if (osd_args.set_attributes_list_length) {
uint32_t page, attr;
uint16_t len;
int i;
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "OSD_SET_ATTR(lun %llu, GroupID 0x%x, UserID 0x%llx)\n", args->lun, osd_args.GroupID, osd_args.UserID);
for (i = 0; i < osd_args.set_attributes_list_length;) {
page = ISCSI_NTOHL(*((uint32_t *) (&(set_list[i]))));
i += 4;
attr = ISCSI_NTOHL(*((uint32_t *) (&(set_list[i]))));
i += 4;
len = ISCSI_NTOHS(*((uint16_t *) (&(set_list[i]))));
i += 2;
sprintf(FileName, "%s/lun_%llu/0x%x/0x%llx.0x%x.%u",
base_dir, args->lun, osd_args.GroupID, osd_args.UserID, page, attr);
if ((rc = open(FileName, O_WRONLY | O_CREAT, 0644)) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "error opening \"%s\": errno %d\n", FileName, errno);
goto done;
}
if (write(rc, set_list + i, len) != len) {
iscsi_trace_error(__FILE__, __LINE__, "write() failed\n");
}
close(rc);
i += len;
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "SET(0x%x,%u,%u>\n", page, attr, len);
}
}
args->send_sg_len = 0;
sg_len = 0;
switch (osd_args.service_action) {
case OSD_CREATE_GROUP:
do {
GroupID = rand() % 1048576 * 1024 + 1;
sprintf(FileName, "%s/lun_%llu/0x%x", base_dir, args->lun, GroupID);
rc = mkdir(FileName, 0755);
} while (rc == -1 && errno == EEXIST);
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "OSD_CREATE_GROUP(lun %llu) --> 0x%x\n", args->lun, GroupID);
args->status = 0;
break;
case OSD_REMOVE_GROUP:
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "OSD_REMOVE_GROUP(lun %llu, 0x%x)\n", args->lun, osd_args.GroupID);
sprintf(FileName, "%s/lun_%llu/0x%x", base_dir, args->lun, osd_args.GroupID);
if ((rc = rmdir(FileName)) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "rmdir(\"%s\") failed: errno %d\n", FileName, errno);
goto done;
}
args->status = 0;
break;
case OSD_CREATE:
UserID = rand() % 1048576 * 1024 + 1;
create_user_again:
sprintf(FileName, "%s/lun_%llu/0x%x/0x%llx",
base_dir, args->lun, osd_args.GroupID, UserID);
rc = open(FileName, O_CREAT | O_EXCL | O_RDWR, 0644);
if ((rc == -1) && (errno == EEXIST)) {
UserID = rand() % 1048576 * 1024 + 1;
goto create_user_again;
}
close(rc);
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "OSD_CREATE(lun %llu, GroupID 0x%x) --> 0x%llx\n", args->lun, osd_args.GroupID, UserID);
args->status = 0;
break;
case OSD_REMOVE:
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "OSD_REMOVE(lun %llu, 0x%llx)\n", args->lun, osd_args.UserID);
sprintf(FileName, "%s/lun_%llu/0x%x/0x%llx",
base_dir, args->lun, osd_args.GroupID, osd_args.UserID);
if ((rc = unlink(FileName)) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "unlink(\"%s\") failed: errno %d\n", FileName, errno);
goto done;
}
sprintf(string, "rm -f %s/lun_%llu/0x%x/0x%llx.*", base_dir, args->lun, osd_args.GroupID, osd_args.UserID);
if (system(string) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "\"%s\" failed\n", string);
return -1;
}
args->status = 0;
break;
case OSD_WRITE:
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "OSD_WRITE(lun %llu, GroupID 0x%x, UserID 0x%llx, length %llu, offset %llu)\n",
args->lun, osd_args.GroupID, osd_args.UserID, osd_args.length, osd_args.offset);
sprintf(FileName, "%s/lun_%llu/0x%x/0x%llx",
base_dir, args->lun, osd_args.GroupID, osd_args.UserID);
if ((rc = open(FileName, O_WRONLY, 0644)) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "error opening \"%s\": errno %d\n", FileName, errno);
goto write_done;
}
if (lseek(rc, osd_args.offset, SEEK_SET) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "error seeking \"%s\": errno %d\n", FileName, errno);
goto write_done;
}
if (write(rc, write_data, osd_args.length) != osd_args.length) {
iscsi_trace_error(__FILE__, __LINE__, "write() failed\n");
goto write_done;
}
close(rc);
args->status = 0;
write_done:
break;
case OSD_READ:
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "OSD_READ(lun %llu, GroupID 0x%x, UserID 0x%llx, length %llu, offset %llu)\n",
args->lun, osd_args.GroupID, osd_args.UserID, osd_args.length, osd_args.offset);
sprintf(FileName, "%s/lun_%llu/0x%x/0x%llx",
base_dir, args->lun, osd_args.GroupID, osd_args.UserID);
if ((rc = open(FileName, O_RDONLY, 0644)) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "error opening \"%s\": errno %d\n", FileName, errno);
goto read_done;
}
if ((read_data = iscsi_malloc_atomic(osd_args.length)) == NULL) {
iscsi_trace_error(__FILE__, __LINE__, "iscsi_malloc_atomic() failed\n");
goto read_done;
}
if (lseek(rc, osd_args.offset, SEEK_SET) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "error seeking \"%s\": errno %d\n", FileName, errno);
goto read_done;
}
if (read(rc, read_data, osd_args.length) != osd_args.length) {
iscsi_trace_error(__FILE__, __LINE__, "read() failed\n");
goto read_done;
}
close(rc);
args->status = 0;
read_done:
if (args->status == 0) {
args->input = 1;
sg[0].iov_base = read_data;
sg[0].iov_len = osd_args.length;
sg[1].iov_base = NULL;
sg[1].iov_len = 0;
args->send_data = (void *) sg;
args->send_sg_len = 1;
sg_len++;
cmd->callback = osd_read_callback;
cmd->callback_arg = sg;
} else {
if (read_data)
iscsi_free_atomic(read_data);
args->length = 0; /* Need a better way of
* specifying an error.. */
}
break;
case OSD_GET_ATTR:
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "OSD_GET_ATTR(lun %llu, GroupID 0x%x, UserID 0x%llx)\n",
args->lun, osd_args.GroupID, osd_args.UserID);
args->status = 0;
break;
case OSD_SET_ATTR:
args->status = 0;
break;
}
if (args->status)
goto done;
/*
* Send back requested attributes
*/
if (osd_args.get_attributes_list_length || osd_args.get_attributes_page) {
if ((get_data = iscsi_malloc_atomic(osd_args.get_attributes_allocation_length)) == NULL) {
iscsi_trace_error(__FILE__, __LINE__, "iscsi_malloc_atomic() failed\n");
goto done;
}
}
if (osd_args.get_attributes_list_length) {
int i;
for (i = 0; i < osd_args.get_attributes_list_length;) {
page = ISCSI_NTOHL(*((uint32_t *) (&(get_list[i]))));
i += 4;
index = ISCSI_NTOHL(*((uint32_t *) (&(get_list[i]))));
i += 4;
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "GET(0x%x,%u)\n", page, index);
switch (page) {
case 0x40000001:
switch (index) {
case 0x1:
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(page);
attr_len += 4;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(index);
attr_len += 4;
*((uint16_t *) & get_data[attr_len]) = ISCSI_HTONS(4);
attr_len += 2;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(GroupID);
attr_len += 4;
break;
default:
iscsi_trace_error(__FILE__, __LINE__, "unknown attr index %u\n", index);
goto done;
}
break;
case 0x00000001:
switch (index) {
case 0x1:
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(page);
attr_len += 4;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(index);
attr_len += 4;
*((uint16_t *) & get_data[attr_len]) = ISCSI_HTONS(4);
attr_len += 2;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(GroupID);
attr_len += 4;
break;
case 0x2:
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(page);
attr_len += 4;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(index);
attr_len += 4;
*((uint16_t *) & get_data[attr_len]) = ISCSI_HTONS(8);
attr_len += 2;
*((uint64_t *) & get_data[attr_len]) = ISCSI_HTONLL(UserID);
attr_len += 8;
break;
default:
iscsi_trace_error(__FILE__, __LINE__, "unknown attr index %u\n", index);
goto done;
}
break;
/* Vendor-specific */
case 0x30000000:
switch (index) {
case 0x1:
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(page);
attr_len += 4;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(index);
attr_len += 4;
*((uint16_t *) & get_data[attr_len]) = ISCSI_HTONS(480);
attr_len += 2;
sprintf(FileName, "%s/lun_%llu/0x%x/0x%llx.0x%x.%u",
base_dir, args->lun, osd_args.GroupID, osd_args.UserID, page, index);
if ((rc = open(FileName, O_RDONLY, 0644)) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "error opening \"%s\": errno %d\n", FileName, errno);
}
if (read(rc, get_data + attr_len, 480) != 480) {
iscsi_trace_error(__FILE__, __LINE__, "read() failed\n");
goto done;
}
close(rc);
attr_len += 480;
break;
default:
iscsi_trace_error(__FILE__, __LINE__, "unknown vendor attr index %u\n", index);
goto done;
}
break;
default:
iscsi_trace_error(__FILE__, __LINE__, "unknown page 0x%x\n", page);
goto done;
}
}
}
if (osd_args.get_attributes_page) {
/*
* Right now, if we get a request for an entire page,
* we return only one attribute.
*/
page = osd_args.get_attributes_page;
switch (osd_args.get_attributes_page) {
case 0x40000001:
index = 1;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(page);
attr_len += 4;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(index);
attr_len += 4;
*((uint16_t *) & get_data[attr_len]) = ISCSI_HTONS(4);
attr_len += 2;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(GroupID);
attr_len += 4;
break;
case 0x00000001:
index = 2;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(page);
attr_len += 4;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(index);
attr_len += 4;
*((uint16_t *) & get_data[attr_len]) = ISCSI_HTONS(8);
attr_len += 2;
*((uint64_t *) & get_data[attr_len]) = ISCSI_HTONLL(UserID);
attr_len += 8;
break;
case 0x30000000:
index = 1;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(page);
attr_len += 4;
*((uint32_t *) & get_data[attr_len]) = ISCSI_HTONL(index);
attr_len += 4;
*((uint16_t *) & get_data[attr_len]) = ISCSI_HTONS(480);
attr_len += 2;
sprintf(FileName, "%s/lun_%llu/0x%x/0x%llx.0x%x.%u",
base_dir, args->lun, osd_args.GroupID, osd_args.UserID, page, index);
if ((rc = open(FileName, O_RDONLY, 0644)) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "error opening \"%s\": errno %d\n", FileName, errno);
}
if (read(rc, get_data + attr_len, 480) != 480) {
iscsi_trace_error(__FILE__, __LINE__, "read() failed\n");
goto done;
}
close(rc);
attr_len += 480;
break;
default:
iscsi_trace_error(__FILE__, __LINE__, "page not yet supported\n");
goto done;
}
}
if (attr_len) {
if (attr_len != osd_args.get_attributes_allocation_length) {
iscsi_trace_error(__FILE__, __LINE__, "allocation lengths differ: got %u, expected %u\n",
osd_args.get_attributes_allocation_length, attr_len);
goto done;
}
if (!args->status) {
args->input = 1;
sg[sg_len].iov_base = get_data;
sg[sg_len].iov_len = osd_args.get_attributes_allocation_length;
sg_len++;
sg[sg_len].iov_base = NULL;
sg[sg_len].iov_len = 0;
args->send_data = (void *) sg;
args->send_sg_len++;
cmd->callback = osd_read_callback;
cmd->callback_arg = sg;
} else {
if (get_data)
iscsi_free_atomic(get_data);
}
}
break;
default:
iscsi_trace_error(__FILE__, __LINE__, "UNKNOWN OPCODE 0x%x\n", args->cdb[0]);
args->status = 0x01;
break;
}
done:
iscsi_trace(TRACE_SCSI_DEBUG, __FILE__, __LINE__, "SCSI op 0x%x: done (status 0x%x)\n", args->cdb[0], args->status);
if (set_list) {
iscsi_free_atomic(set_list);
}
if (get_list) {
iscsi_free_atomic(get_list);
}
if (write_data) {
iscsi_free_atomic(write_data);
}
return 0;
}
/* ARGSUSED */
int
device_shutdown(target_session_t *sess)
{
return 0;
}

416
external/bsd/iscsi/dist/src/osd_ops.c vendored Normal file
View File

@ -0,0 +1,416 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2002, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Transport-independent Methods
*/
#include "config.h"
#include "osd.h"
#include "iscsiutil.h"
#include "compat.h"
#include "osd_ops.h"
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
static int
extract_attribute(uint32_t page, uint32_t n, uint16_t len,
uint8_t * data, unsigned length, void *val)
{
int i = 0;
for (i = 0; i < length;) {
if (ISCSI_NTOHL(*(uint32_t *) (data + i)) != page) {
iscsi_trace_error(__FILE__, __LINE__, "page mismatch: got 0x%x, expected 0x%x\n", ISCSI_NTOHL(*(uint32_t *) (data + i)), page);
return -1;
}
i += 4;
if (ISCSI_NTOHL(*(uint32_t *) (data + i)) != n) {
iscsi_trace_error(__FILE__, __LINE__, "index mismatch\n");
return -1;
}
i += 4;
if (ISCSI_NTOHS(*(uint16_t *) (data + i)) != len) {
iscsi_trace_error(__FILE__, __LINE__, "len mismatch\n");
return -1;
}
i += 2;
iscsi_trace(TRACE_DEBUG, __FILE__, __LINE__, "page 0x%x, index %u, len %u\n", page, n, len);
memcpy(val, data + i, len);
i += len;
}
iscsi_trace(TRACE_DEBUG, __FILE__, __LINE__, "parsed %i bytes\n", i);
return i;
}
int
osd_create_group(void *dev,
int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem),
uint32_t * GroupID)
{
osd_args_t args;
#if 0
uint8_t get_list[8];
#endif
uint8_t get_data[14];
OSD_OPS_MEM mem;
mem.recv_data = get_data;
mem.recv_len = 14;
mem.recv_sg = 0;
memset(&args, 0, sizeof(osd_args_t));
args.opcode = 0x7F;
args.service_action = OSD_CREATE_GROUP;
#if 0
args.length = 8;
args.get_attributes_list_length = 8;
*((unsigned long *) get_list) = ISCSI_HTONL(0x40000001);
*((unsigned long *) (get_list + 4)) = ISCSI_HTONL(0x1);
mem.send_data = get_list;
mem.send_len = 8;
mem.send_sg = 0;
#else
args.get_attributes_page = 0x40000001;
mem.send_data = NULL;
mem.send_len = 0;
mem.send_sg = 0;
#endif
args.get_attributes_allocation_length = 14;
if (osd_exec(dev, &args, &mem) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "osd_exec() failed\n");
return -1;
}
if (extract_attribute(0x40000001, 0x1, 4, get_data, 14, GroupID) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "extract_attributes() failed\n");
return -1;
}
*GroupID = ISCSI_NTOHL(*GroupID);
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "osd_create_group() OK --> GroupID 0x%x\n", *GroupID);
return 0;
}
int
osd_create(void *dev, uint32_t GroupID,
int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem),
uint64_t * UserID)
{
osd_args_t args;
#if 0
uint8_t get_list[8];
#endif
uint8_t get_data[18];
OSD_OPS_MEM mem;
mem.recv_data = get_data;
mem.recv_len = 18;
mem.recv_sg = 0;
memset(&args, 0, sizeof(osd_args_t));
args.opcode = 0x7F;
args.service_action = OSD_CREATE;
args.GroupID = GroupID;
#if 0
args.length = 8;
args.get_attributes_list_length = 8;
*((unsigned long *) get_list) = ISCSI_HTONL(0x00000001);
*((unsigned long *) (get_list + 4)) = ISCSI_HTONL(0x2);
mem.send_data = get_list;
mem.send_len = 8;
mem.send_sg = 0;
#else
args.get_attributes_page = 0x000000001;
mem.send_data = NULL;
mem.send_len = 0;
mem.send_sg = 0;
#endif
args.get_attributes_allocation_length = 18;
if (osd_exec(dev, &args, &mem) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "osd_exec() failed\n");
return -1;
}
if (extract_attribute(0x00000001, 0x2, 8, get_data, 18, UserID) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "extract_attributes() failed\n");
return -1;
}
*UserID = ISCSI_NTOHLL(*UserID);
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "osd_create(GroupID 0x%x) OK --> UserID 0x%llx\n", GroupID, *UserID);
return 0;
}
int
osd_remove_group(void *dev, uint32_t GroupID,
int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem))
{
osd_args_t args;
OSD_OPS_MEM mem;
mem.send_data = NULL;
mem.send_len = 0;
mem.send_sg = 0;
mem.recv_data = NULL;
mem.recv_len = 0;
mem.recv_sg = 0;
memset(&args, 0, sizeof(osd_args_t));
args.opcode = 0x7F;
args.service_action = OSD_REMOVE_GROUP;
args.GroupID = GroupID;
if (osd_exec(dev, &args, &mem) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "osd_exec() failed\n");
return -1;
}
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "osd_remove_group(Group ID 0x%x) OK\n", GroupID);
return 0;
}
int
osd_remove(void *dev, uint32_t GroupID, uint64_t UserID,
int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem))
{
osd_args_t args;
OSD_OPS_MEM mem;
mem.send_data = NULL;
mem.send_len = 0;
mem.send_sg = 0;
mem.recv_data = NULL;
mem.recv_len = 0;
mem.recv_sg = 0;
memset(&args, 0, sizeof(osd_args_t));
args.opcode = 0x7F;
args.service_action = OSD_REMOVE;
args.UserID = UserID;
args.GroupID = GroupID;
if (osd_exec(dev, &args, &mem) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "osd_exec() failed\n");
return -1;
}
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "osd_remove(GroupID 0x%x, UserID 0x%llx) OK\n", GroupID, UserID);
return 0;
}
int
osd_write(void *dev,
uint32_t GroupID, uint64_t UserID, uint64_t offset, uint64_t len, const void *send_data, int sg_len,
int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem))
{
osd_args_t args;
OSD_OPS_MEM mem;
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "osd_write(GroupID 0x%x, UserID 0x%llx, Offset %llu, Len %llu)\n", GroupID, UserID, offset, len);
mem.send_data = send_data;
mem.send_len = len;
mem.send_sg = sg_len;
mem.recv_data = NULL;
mem.recv_len = 0;
mem.recv_sg = 0;
memset(&args, 0, sizeof(osd_args_t));
args.opcode = 0x7F;
args.service_action = OSD_WRITE;
args.GroupID = GroupID;
args.UserID = UserID;
args.offset = offset;
args.length = len;
if (osd_exec(dev, &args, &mem) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "osd_exec() failed\n");
return -1;
}
return 0;
}
int
osd_read(void *dev,
uint32_t GroupID, uint64_t UserID, uint64_t offset, uint64_t len, void *recv_data, int sg_len,
int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem))
{
osd_args_t args;
OSD_OPS_MEM mem;
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "osd_read(GroupID 0x%x, UserID 0x%llx, Offset %llu, Len %llu)\n", GroupID, UserID, offset, len);
mem.send_data = NULL;
mem.send_len = 0;
mem.send_sg = 0;
mem.recv_data = recv_data;
mem.recv_len = len;
mem.recv_sg = sg_len;
memset(&args, 0, sizeof(osd_args_t));
args.opcode = 0x7F;
args.service_action = OSD_READ;
args.GroupID = GroupID;
args.UserID = UserID;
args.offset = offset;
args.length = len;
if (osd_exec(dev, &args, &mem) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "osd_exec() failed\n");
return -1;
}
return 0;
}
int
osd_set_one_attr(void *dev,
uint32_t GroupID, uint64_t UserID, uint32_t page, uint32_t n, uint32_t len, void *value,
int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem))
{
osd_args_t args;
OSD_OPS_MEM mem;
uint8_t list[10];
#if 0
struct iovec sg[2];
#else
uint8_t *buffer = NULL;
#endif
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "osd_set_one_attr(GroupID 0x%x, UserID 0x%llx, Page 0x%x, Index %u, Len %u)\n",
GroupID, UserID, page, n, len);
memset(&args, 0, sizeof(osd_args_t));
args.opcode = 0x7F;
args.service_action = OSD_SET_ATTR;
args.GroupID = GroupID;
args.UserID = UserID;
args.length = 10 + len;
args.set_attributes_list_length = 10 + len;
*((uint32_t *) (list + 0)) = ISCSI_HTONL(page);
*((uint32_t *) (list + 4)) = ISCSI_HTONL(n);
*((uint16_t *) (list + 8)) = ISCSI_HTONS(len);
#if 0
sg[0].iov_base = list;
sg[0].iov_len = 10;
sg[1].iov_base = value;
sg[1].iov_len = len;
mem.send_data = sg;
mem.send_len = 10 + len;
mem.send_sg = 2;
#else
if ((buffer = iscsi_malloc_atomic(10 + len)) == NULL) {
iscsi_trace_error(__FILE__, __LINE__, "iscsi_malloc() failed\n");
return -1;
}
memcpy(buffer, list, 10);
memcpy(buffer + 10, value, len);
mem.send_data = buffer;
mem.send_len = 10 + len;
mem.send_sg = 0;
#endif
mem.recv_data = NULL;
mem.recv_len = 0;
mem.recv_sg = 0;
if (osd_exec(dev, &args, &mem) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "osd_exec() failed\n");
return -1;
}
if (buffer)
iscsi_free_atomic(buffer);
return 0;
}
int
osd_get_one_attr(void *dev,
uint32_t GroupID, uint64_t UserID, uint32_t page, uint32_t n, uint32_t alloc_len,
int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem),
uint16_t * len, void *value)
{
osd_args_t args;
OSD_OPS_MEM mem;
uint8_t list_out[8];
#if 0
uint8_t list_in[10];
struct iovec sg[2];
#else
uint8_t *buffer;
#endif
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "osd_get_one_attr(GroupID 0x%x, UserID 0x%llx, Page 0x%x, Index %u, Alloc Len %u)\n",
GroupID, UserID, page, n, alloc_len);
memset(&args, 0, sizeof(osd_args_t));
args.opcode = 0x7F;
args.service_action = OSD_GET_ATTR;
args.GroupID = GroupID;
args.UserID = UserID;
if (n) {
args.length = 8;
*((uint32_t *) (list_out + 0)) = ISCSI_HTONL(page);
*((uint32_t *) (list_out + 4)) = ISCSI_HTONL(n);
args.get_attributes_list_length = 8;
mem.send_data = list_out;
mem.send_len = 8;
mem.send_sg = 0;
} else {
iscsi_trace(TRACE_OSD, __FILE__, __LINE__, "requesting entire page or reference page\n");
mem.send_data = NULL;
mem.send_len = 0;
mem.send_sg = 0;
args.get_attributes_page = page;
}
#if 0
sg[0].iov_base = list_in;
sg[0].iov_len = 10;
sg[1].iov_base = value;
sg[1].iov_len = alloc_len;
mem.recv_data = sg;
mem.recv_len = 10 + alloc_len;
mem.recv_sg = 2;
#else
if ((buffer = iscsi_malloc_atomic(10 + alloc_len)) == NULL) {
iscsi_trace_error(__FILE__, __LINE__, "iscsi_malloc() failed\n");
return -1;
}
mem.recv_data = buffer;
mem.recv_len = 10 + alloc_len;
mem.recv_sg = 0;
#endif
args.get_attributes_allocation_length = 10 + alloc_len;
if (osd_exec(dev, &args, &mem) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "osd_exec() failed\n");
return -1;
}
memcpy(value, buffer + 10, alloc_len);
if (buffer)
iscsi_free_atomic(buffer);
return 0;
}

1076
external/bsd/iscsi/dist/src/osdfs.c vendored Normal file

File diff suppressed because it is too large Load Diff

1291
external/bsd/iscsi/dist/src/parameters.c vendored Normal file

File diff suppressed because it is too large Load Diff

665
external/bsd/iscsi/dist/src/snprintf.c vendored Normal file
View File

@ -0,0 +1,665 @@
/*
* Copyright (c) 1995-2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* From heimdal lib/roken/snprintf.c. */
#include "config.h"
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#if 0
RCSID("$Id: snprintf.c,v 1.1 2009/06/21 21:20:31 agc Exp $");
#endif
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#if 0
#include <roken.h>
#endif
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#undef max
#define max(a,b) ((a) > (b) ? (a) : (b))
enum format_flags {
minus_flag = 1,
plus_flag = 2,
space_flag = 4,
alternate_flag = 8,
zero_flag = 16
};
/*
* Common state
*/
struct state {
unsigned char *str;
unsigned char *s;
unsigned char *theend;
size_t sz;
size_t max_sz;
void (*append_char)(struct state *, unsigned char);
/* XXX - methods */
};
#if TEST_SNPRINTF
#include "snprintf-test.h"
#endif /* TEST_SNPRINTF */
#if !defined(HAVE_VSNPRINTF) || defined(TEST_SNPRINTF)
static int
sn_reserve (struct state *state, size_t n)
{
return state->s + n > state->theend;
}
static void
sn_append_char (struct state *state, unsigned char c)
{
if (!sn_reserve (state, 1))
*state->s++ = c;
}
#endif
static int
as_reserve (struct state *state, size_t n)
{
if (state->s + n > state->theend) {
int off = state->s - state->str;
unsigned char *tmp;
if (state->max_sz && state->sz >= state->max_sz)
return 1;
state->sz = max(state->sz * 2, state->sz + n);
if (state->max_sz)
state->sz = min(state->sz, state->max_sz);
tmp = realloc (state->str, state->sz);
if (tmp == NULL)
return 1;
state->str = tmp;
state->s = state->str + off;
state->theend = state->str + state->sz - 1;
}
return 0;
}
static void
as_append_char (struct state *state, unsigned char c)
{
if(!as_reserve (state, 1))
*state->s++ = c;
}
/* longest integer types */
#ifdef HAVE_LONG_LONG
typedef unsigned long long u_longest;
typedef long long longest;
#else
typedef unsigned long u_longest;
typedef long longest;
#endif
/*
* is # supposed to do anything?
*/
static int
use_alternative (int flags, u_longest num, unsigned base)
{
return flags & alternate_flag && (base == 16 || base == 8) && num != 0;
}
static int
append_number(struct state *state,
u_longest num, unsigned base, char *rep,
int width, int prec, int flags, int minusp)
{
int len = 0;
int i;
u_longest n = num;
/* given precision, ignore zero flag */
if(prec != -1)
flags &= ~zero_flag;
else
prec = 1;
/* zero value with zero precision -> "" */
if(prec == 0 && n == 0)
return 0;
do{
(*state->append_char)(state, rep[n % base]);
++len;
n /= base;
} while(n);
prec -= len;
/* pad with prec zeros */
while(prec-- > 0){
(*state->append_char)(state, '0');
++len;
}
/* add length of alternate prefix (added later) to len */
if(use_alternative(flags, num, base))
len += base / 8;
/* pad with zeros */
if(flags & zero_flag){
width -= len;
if(minusp || (flags & space_flag) || (flags & plus_flag))
width--;
while(width-- > 0){
(*state->append_char)(state, '0');
len++;
}
}
/* add alternate prefix */
if(use_alternative(flags, num, base)){
if(base == 16)
(*state->append_char)(state, rep[10] + 23); /* XXX */
(*state->append_char)(state, '0');
}
/* add sign */
if(minusp){
(*state->append_char)(state, '-');
++len;
} else if(flags & plus_flag) {
(*state->append_char)(state, '+');
++len;
} else if(flags & space_flag) {
(*state->append_char)(state, ' ');
++len;
}
if(flags & minus_flag)
/* swap before padding with spaces */
for(i = 0; i < len / 2; i++){
char c = state->s[-i-1];
state->s[-i-1] = state->s[-len+i];
state->s[-len+i] = c;
}
width -= len;
while(width-- > 0){
(*state->append_char)(state, ' ');
++len;
}
if(!(flags & minus_flag))
/* swap after padding with spaces */
for(i = 0; i < len / 2; i++){
char c = state->s[-i-1];
state->s[-i-1] = state->s[-len+i];
state->s[-len+i] = c;
}
return len;
}
/*
* return length
*/
static int
append_string (struct state *state,
const unsigned char *arg,
int width,
int prec,
int flags)
{
int len = 0;
if(arg == NULL)
arg = (const unsigned char*)"(null)";
if(prec != -1)
width -= prec;
else
width -= strlen((const char *)arg);
if(!(flags & minus_flag))
while(width-- > 0) {
(*state->append_char) (state, ' ');
++len;
}
if (prec != -1) {
while (*arg && prec--) {
(*state->append_char) (state, *arg++);
++len;
}
} else {
while (*arg) {
(*state->append_char) (state, *arg++);
++len;
}
}
if(flags & minus_flag)
while(width-- > 0) {
(*state->append_char) (state, ' ');
++len;
}
return len;
}
static int
append_char(struct state *state,
unsigned char arg,
int width,
int flags)
{
int len = 0;
while(!(flags & minus_flag) && --width > 0) {
(*state->append_char) (state, ' ') ;
++len;
}
(*state->append_char) (state, arg);
++len;
while((flags & minus_flag) && --width > 0) {
(*state->append_char) (state, ' ');
++len;
}
return 0;
}
/*
* This can't be made into a function...
*/
#ifdef HAVE_LONG_LONG
#define PARSE_INT_FORMAT(res, arg, unsig) \
if (long_long_flag) \
res = (unsig long long)va_arg(arg, unsig long long); \
else if (long_flag) \
res = (unsig long)va_arg(arg, unsig long); \
else if (short_flag) \
res = (unsig short)va_arg(arg, unsig int); \
else \
res = (unsig int)va_arg(arg, unsig int)
#else
#define PARSE_INT_FORMAT(res, arg, unsig) \
if (long_flag) \
res = (unsig long)va_arg(arg, unsig long); \
else if (short_flag) \
res = (unsig short)va_arg(arg, unsig int); \
else \
res = (unsig int)va_arg(arg, unsig int)
#endif
/*
* zyxprintf - return length, as snprintf
*/
static int
xyzprintf (struct state *state, const char *char_format, va_list ap)
{
const unsigned char *format = (const unsigned char *)char_format;
unsigned char c;
int len = 0;
while((c = *format++)) {
if (c == '%') {
int flags = 0;
int width = 0;
int prec = -1;
int long_long_flag = 0;
int long_flag = 0;
int short_flag = 0;
/* flags */
while((c = *format++)){
if(c == '-')
flags |= minus_flag;
else if(c == '+')
flags |= plus_flag;
else if(c == ' ')
flags |= space_flag;
else if(c == '#')
flags |= alternate_flag;
else if(c == '0')
flags |= zero_flag;
else
break;
}
if((flags & space_flag) && (flags & plus_flag))
flags ^= space_flag;
if((flags & minus_flag) && (flags & zero_flag))
flags ^= zero_flag;
/* width */
if (isdigit(c))
do {
width = width * 10 + c - '0';
c = *format++;
} while(isdigit(c));
else if(c == '*') {
width = va_arg(ap, int);
c = *format++;
}
/* precision */
if (c == '.') {
prec = 0;
c = *format++;
if (isdigit(c))
do {
prec = prec * 10 + c - '0';
c = *format++;
} while(isdigit(c));
else if (c == '*') {
prec = va_arg(ap, int);
c = *format++;
}
}
/* size */
if (c == 'h') {
short_flag = 1;
c = *format++;
} else if (c == 'l') {
long_flag = 1;
c = *format++;
if (c == 'l') {
long_long_flag = 1;
c = *format++;
}
}
switch (c) {
case 'c' :
append_char(state, va_arg(ap, int), width, flags);
++len;
break;
case 's' :
len += append_string(state,
va_arg(ap, unsigned char*),
width,
prec,
flags);
break;
case 'd' :
case 'i' : {
longest arg;
u_longest num;
int minusp = 0;
PARSE_INT_FORMAT(arg, ap, signed);
if (arg < 0) {
minusp = 1;
num = -arg;
} else
num = arg;
len += append_number (state, num, 10, "0123456789",
width, prec, flags, minusp);
break;
}
case 'u' : {
u_longest arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
len += append_number (state, arg, 10, "0123456789",
width, prec, flags, 0);
break;
}
case 'o' : {
u_longest arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
len += append_number (state, arg, 010, "01234567",
width, prec, flags, 0);
break;
}
case 'x' : {
u_longest arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
len += append_number (state, arg, 0x10, "0123456789abcdef",
width, prec, flags, 0);
break;
}
case 'X' :{
u_longest arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
len += append_number (state, arg, 0x10, "0123456789ABCDEF",
width, prec, flags, 0);
break;
}
case 'p' : {
unsigned long arg = (unsigned long)va_arg(ap, void*);
len += append_number (state, arg, 0x10, "0123456789ABCDEF",
width, prec, flags, 0);
break;
}
case 'n' : {
int *arg = va_arg(ap, int*);
*arg = state->s - state->str;
break;
}
case '\0' :
--format;
/* FALLTHROUGH */
case '%' :
(*state->append_char)(state, c);
++len;
break;
default :
(*state->append_char)(state, '%');
(*state->append_char)(state, c);
len += 2;
break;
}
} else {
(*state->append_char) (state, c);
++len;
}
}
return len;
}
#if !defined(HAVE_SNPRINTF) || defined(TEST_SNPRINTF)
int
snprintf (char *str, size_t sz, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = vsnprintf (str, sz, format, args);
va_end(args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = malloc (sz);
if (tmp == NULL)
abort ();
va_start(args, format);
ret2 = vsprintf (tmp, format, args);
va_end(args);
if (ret != ret2 || strcmp(str, tmp))
abort ();
free (tmp);
}
#endif
return ret;
}
#endif
#if !defined(HAVE_ASPRINTF) || defined(TEST_SNPRINTF)
int
asprintf (char **ret, const char *format, ...)
{
va_list args;
int val;
va_start(args, format);
val = vasprintf (ret, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = malloc (val + 1);
if (tmp == NULL)
abort ();
ret2 = vsprintf (tmp, format, args);
if (val != ret2 || strcmp(*ret, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return val;
}
#endif
#if !defined(HAVE_VASPRINTF) || defined(TEST_SNPRINTF)
int
vasprintf (char **ret, const char *format, va_list args)
{
return vasnprintf (ret, 0, format, args);
}
#endif
#if !defined(HAVE_VASNPRINTF) || defined(TEST_SNPRINTF)
int
vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
{
int st;
struct state state;
state.max_sz = max_sz;
state.sz = 1;
state.str = malloc(state.sz);
if (state.str == NULL) {
*ret = NULL;
return -1;
}
state.s = state.str;
state.theend = state.s + state.sz - 1;
state.append_char = as_append_char;
st = xyzprintf (&state, format, args);
if (st > state.sz) {
free (state.str);
*ret = NULL;
return -1;
} else {
char *tmp;
*state.s = '\0';
tmp = realloc (state.str, st+1);
if (tmp == NULL) {
free (state.str);
*ret = NULL;
return -1;
}
*ret = tmp;
return st;
}
}
#endif
#if !defined(HAVE_VSNPRINTF) || defined(TEST_SNPRINTF)
int
vsnprintf (char *str, size_t sz, const char *format, va_list args)
{
struct state state;
int ret;
unsigned char *ustr = (unsigned char *)str;
state.max_sz = 0;
state.sz = sz;
state.str = ustr;
state.s = ustr;
state.theend = ustr + sz - (sz > 0);
state.append_char = sn_append_char;
ret = xyzprintf (&state, format, args);
if (state.s != NULL)
*state.s = '\0';
return ret;
}
#endif
#if !defined(HAVE_ASNPRINTF) || defined(TEST_SNPRINTF)
int
asnprintf (char **ret, size_t max_sz, const char *format, ...)
{
va_list args;
int val;
va_start(args, format);
val = vasnprintf (ret, max_sz, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = malloc (val + 1);
if (tmp == NULL)
abort ();
ret2 = vsprintf (tmp, format, args);
if (val != ret2 || strcmp(*ret, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return val;
}
#endif

1060
external/bsd/iscsi/dist/src/so.c vendored Normal file

File diff suppressed because it is too large Load Diff

5
external/bsd/iscsi/dist/src/start_osd vendored Normal file
View File

@ -0,0 +1,5 @@
#!/bin/sh
insmod ./so.o
insmod ./intel_iscsi.o
insmod ./osdfs.o
mount -t osdfs /dev/so0 /mnt -o gid=0x2d159c01 -o uid=0x2c8f1801

5
external/bsd/iscsi/dist/src/stop_osd vendored Normal file
View File

@ -0,0 +1,5 @@
#!/bin/sh
umount /mnt
rmmod osdfs
rmmod intel_iscsi
rmmod so

424
external/bsd/iscsi/dist/src/storage.c vendored Normal file
View File

@ -0,0 +1,424 @@
/* $NetBSD: storage.c,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <unistd.h>
#include "iscsi.h"
#include "iscsiutil.h"
#include "target.h"
#include "device.h"
#include "conffile.h"
#include "storage.h"
/* let's use symbolic names for the fields in the config file */
enum {
EXTENT_NAME_COL = 0,
EXTENT_DEVICE_COL = 1,
EXTENT_SACRED_COL = 2,
EXTENT_LENGTH_COL = 3,
DEVICE_NAME_COL = 0,
DEVICE_RAIDLEVEL_COL = 1,
DEVICE_LENGTH_COL = 2,
TARGET_NAME_COL = 0,
TARGET_V1_DEVICE_COL = 1,
TARGET_V1_NETMASK_COL = 2,
TARGET_V2_FLAGS_COL = 1,
TARGET_V2_DEVICE_COL = 2,
TARGET_V2_NETMASK_COL = 3
};
#define DEFAULT_FLAGS "ro"
/* find an extent by name */
static disc_extent_t *
find_extent(extv_t *evp, char *s)
{
size_t i;
for (i = 0 ; i < evp->c ; i++) {
if (strcmp(evp->v[i].extent, s) == 0) {
return &evp->v[i];
}
}
return NULL;
}
/* allocate space for a new extent */
static int
do_extent(conffile_t *cf, extv_t *evp, ent_t *ep)
{
struct stat st;
char *cp;
if (find_extent(evp, ep->sv.v[EXTENT_NAME_COL]) != NULL) {
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Error: attempt to re-define extent `%s'\n", ep->sv.v[EXTENT_NAME_COL]);
return 0;
}
ALLOC(disc_extent_t, evp->v, evp->size, evp->c, 14, 14, "do_extent", exit(EXIT_FAILURE));
evp->v[evp->c].extent = strdup(ep->sv.v[EXTENT_NAME_COL]);
evp->v[evp->c].dev = strdup(ep->sv.v[EXTENT_DEVICE_COL]);
evp->v[evp->c].sacred = strtoll(ep->sv.v[EXTENT_SACRED_COL], NULL, 10);
if (strcasecmp(ep->sv.v[EXTENT_LENGTH_COL], "size") == 0) {
if (stat(ep->sv.v[EXTENT_DEVICE_COL], &st) == 0) {
evp->v[evp->c].len = st.st_size;
}
} else {
evp->v[evp->c].len = strtoll(ep->sv.v[EXTENT_LENGTH_COL], &cp, 10);
if (cp != NULL) {
switch(tolower((unsigned)*cp)) {
case 't':
evp->v[evp->c].len *= (uint64_t)(1024ULL * 1024ULL * 1024ULL * 1024ULL);
break;
case 'g':
evp->v[evp->c].len *= (uint64_t)(1024ULL * 1024ULL * 1024ULL);
break;
case 'm':
evp->v[evp->c].len *= (uint64_t)(1024ULL * 1024ULL);
break;
case 'k':
evp->v[evp->c].len *= (uint64_t)1024ULL;
break;
}
}
}
evp->c += 1;
return 1;
}
/* find a device by name */
static disc_device_t *
find_device(devv_t *devvp, char *s)
{
size_t i;
for (i = 0 ; i < devvp->c ; i++) {
if (strcmp(devvp->v[i].dev, s) == 0) {
return &devvp->v[i];
}
}
return NULL;
}
/* return the size of the sub-device/extent */
static uint64_t
getsize(conffile_t *cf, devv_t *devvp, extv_t *evp, char *s)
{
disc_extent_t *xp;
disc_device_t *dp;
if ((xp = find_extent(evp, s)) != NULL) {
return xp->len;
}
if ((dp = find_device(devvp, s)) != NULL) {
switch (dp->xv[0].type) {
case DE_EXTENT:
return dp->xv[0].u.xp->len;
case DE_DEVICE:
return dp->xv[0].u.dp->len;
}
}
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Warning: sub-device/extent `%s' not found\n", s);
return 0;
}
/* allocate space for a device */
static int
do_device(conffile_t *cf, devv_t *devvp, extv_t *evp, ent_t *ep)
{
if (find_device(devvp, ep->sv.v[DEVICE_NAME_COL]) != NULL) {
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Error: attempt to re-define device `%s'\n", ep->sv.v[DEVICE_NAME_COL]);
return 0;
}
ALLOC(disc_device_t, devvp->v, devvp->size, devvp->c, 14, 14, "do_device", exit(EXIT_FAILURE));
devvp->v[devvp->c].dev = strdup(ep->sv.v[DEVICE_NAME_COL]);
devvp->v[devvp->c].raid = (strncasecmp(ep->sv.v[DEVICE_RAIDLEVEL_COL], "raid", 4) == 0) ? atoi(&ep->sv.v[DEVICE_RAIDLEVEL_COL][4]) : 0;
devvp->v[devvp->c].size = ep->sv.c - 2;
devvp->v[devvp->c].len = getsize(cf, devvp, evp, ep->sv.v[DEVICE_LENGTH_COL]);
NEWARRAY(disc_de_t, devvp->v[devvp->c].xv, ep->sv.c - 2, "do_device", exit(EXIT_FAILURE));
for (devvp->v[devvp->c].c = 0 ; devvp->v[devvp->c].c < devvp->v[devvp->c].size ; devvp->v[devvp->c].c++) {
if ((devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.xp = find_extent(evp, ep->sv.v[devvp->v[devvp->c].c + 2])) != NULL) {
if (devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.xp->used) {
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Error: extent `%s' has already been used\n", ep->sv.v[devvp->v[devvp->c].c + 2]);
return 0;
}
if (devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.xp->len != devvp->v[devvp->c].len && devvp->v[devvp->c].raid != 0) {
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Error: extent `%s' has size %" PRIu64 ", not %" PRIu64"\n", ep->sv.v[devvp->v[devvp->c].c + 2], devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.xp->len, devvp->v[devvp->c].len);
return 0;
}
devvp->v[devvp->c].xv[devvp->v[devvp->c].c].type = DE_EXTENT;
devvp->v[devvp->c].xv[devvp->v[devvp->c].c].size = devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.xp->len;
devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.xp->used = 1;
} else if ((devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.dp = find_device(devvp, ep->sv.v[devvp->v[devvp->c].c + 2])) != NULL) {
if (devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.dp->used) {
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Error: device `%s' has already been used\n", ep->sv.v[devvp->v[devvp->c].c + 2]);
return 0;
}
devvp->v[devvp->c].xv[devvp->v[devvp->c].c].type = DE_DEVICE;
devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.dp->used = 1;
devvp->v[devvp->c].xv[devvp->v[devvp->c].c].size = devvp->v[devvp->c].xv[devvp->v[devvp->c].c].u.dp->len;
} else {
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Error: no extent or device found for `%s'\n", ep->sv.v[devvp->v[devvp->c].c + 2]);
return 0;
}
}
if (devvp->v[devvp->c].raid == 1) {
/* check we have more than 1 device/extent */
if (devvp->v[devvp->c].c < 2) {
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Error: device `%s' is specified as RAID1, but has only %d sub-devices/extents\n", devvp->v[devvp->c].dev, devvp->v[devvp->c].c);
return 0;
}
}
devvp->c += 1;
return 1;
}
/* find a target by name */
static disc_target_t *
find_target(targv_t *tvp, char *s)
{
size_t i;
for (i = 0 ; i < tvp->c ; i++) {
if (strcmp(tvp->v[i].target, s) == 0) {
return &tvp->v[i];
}
}
return NULL;
}
/* allocate space for a new target */
static int
do_target(conffile_t *cf, targv_t *tvp, devv_t *devvp, extv_t *evp, ent_t *ep)
{
disc_extent_t *xp;
disc_device_t *dp;
const char *flags;
char tgt[256];
char *iqn;
int netmaskcol;
int devcol;
if ((iqn = strchr(ep->sv.v[TARGET_NAME_COL], '=')) == NULL) {
(void) strlcpy(tgt, ep->sv.v[TARGET_NAME_COL], sizeof(tgt));
} else {
(void) snprintf(tgt, sizeof(tgt), "%.*s", (int)(iqn - ep->sv.v[TARGET_NAME_COL]), ep->sv.v[TARGET_NAME_COL]);
iqn += 1;
}
if (find_target(tvp, tgt) != NULL) {
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Error: attempt to re-define target `%s'\n", tgt);
return 0;
}
ALLOC(disc_target_t, tvp->v, tvp->size, tvp->c, 14, 14, "do_target", exit(EXIT_FAILURE));
if (ep->sv.c == 3) {
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Warning: old 3 field \"targets\" entry, assuming read-only target\n");
devcol = TARGET_V1_DEVICE_COL;
netmaskcol = TARGET_V1_NETMASK_COL;
flags = DEFAULT_FLAGS;
} else {
devcol = TARGET_V2_DEVICE_COL;
flags = ep->sv.v[TARGET_V2_FLAGS_COL];
netmaskcol = TARGET_V2_NETMASK_COL;
}
if (iqn != NULL) {
tvp->v[tvp->c].iqn = strdup(iqn);
}
if ((dp = find_device(devvp, ep->sv.v[devcol])) != NULL) {
tvp->v[tvp->c].de.type = DE_DEVICE;
tvp->v[tvp->c].de.u.dp = dp;
tvp->v[tvp->c].target = strdup(tgt);
tvp->v[tvp->c].mask = strdup(ep->sv.v[netmaskcol]);
if (strcmp(flags, "readonly") == 0 || strcmp(flags, "ro") == 0 || strcmp(flags, "r") == 0) {
tvp->v[tvp->c].flags |= TARGET_READONLY;
}
tvp->c += 1;
return 1;
}
if ((xp = find_extent(evp, ep->sv.v[devcol])) != NULL) {
tvp->v[tvp->c].de.type = DE_EXTENT;
tvp->v[tvp->c].de.u.xp = xp;
tvp->v[tvp->c].target = strdup(tgt);
tvp->v[tvp->c].mask = strdup(ep->sv.v[netmaskcol]);
if (strcmp(flags, "readonly") == 0 || strcmp(flags, "ro") == 0 || strcmp(flags, "r") == 0) {
tvp->v[tvp->c].flags |= TARGET_READONLY;
}
tvp->c += 1;
return 1;
}
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Error: no device or extent found for `%s'\n", ep->sv.v[devcol]);
return 0;
}
/* print an extent */
static void
pextent(disc_extent_t *ep, int indent)
{
int i;
for (i = 0 ; i < indent ; i++) {
(void) fputc('\t', stdout);
}
printf("%s:%s:%" PRIu64 ":%" PRIu64 "\n", ep->extent, ep->dev, ep->sacred, ep->len);
}
static void pdevice(disc_device_t *, int);
/* print information about an extent or a device */
static void
pu(disc_de_t *dep, int indent)
{
switch(dep->type) {
case DE_EXTENT:
pextent(dep->u.xp, indent);
break;
case DE_DEVICE:
pdevice(dep->u.dp, indent);
break;
}
}
/* print information about a device */
static void
pdevice(disc_device_t *dp, int indent)
{
int i;
size_t j;
for (i = 0 ; i < indent ; i++) {
(void) fputc('\t', stdout);
}
printf("%s:RAID%d\n", dp->dev, dp->raid);
for (j = 0 ; j < dp->c ; j++) {
pu(&dp->xv[j], indent + 1);
}
}
/* print informnation about a target */
static void
ptarget(disc_target_t *tp, int indent)
{
int i;
for (i = 0 ; i < indent ; i++) {
(void) fputc('\t', stdout);
}
printf("%s:%s:%s\n", tp->target, (tp->flags & TARGET_READONLY) ? "ro" : "rw", tp->mask);
pu(&tp->de, indent + 1);
}
/* print all information */
static void
ptargets(targv_t *tvp)
{
size_t i;
for (i = 0 ; i < tvp->c ; i++) {
ptarget(&tvp->v[i], 0);
}
}
/* read a configuration file */
int
read_conf_file(const char *cf, targv_t *tvp, devv_t *dvp, extv_t *evp)
{
conffile_t conf;
ent_t e;
(void) memset(&conf, 0x0, sizeof(conf));
if (!conffile_open(&conf, cf, "r", " \t", "#")) {
(void) fprintf(stderr, "Error: can't open `%s'\n", cf);
return 0;
}
printf("Reading configuration from `%s'\n", cf);
(void) memset(&e, 0x0, sizeof(e));
while (conffile_getent(&conf, &e)) {
if (strncmp(e.sv.v[0], "extent", 6) == 0) {
do_extent(&conf, evp, &e);
} else if (strncmp(e.sv.v[0], "device", 6) == 0) {
do_device(&conf, dvp, evp, &e);
} else if (strncmp(e.sv.v[0], "target", 6) == 0 ||
strncmp(e.sv.v[0], "lun", 3) == 0) {
do_target(&conf, tvp, dvp, evp, &e);
}
e.sv.c = 0;
}
ptargets(tvp);
(void) conffile_close(&conf);
return 1;
}
/* write the pid to the pid file */
void
write_pid_file(const char *f)
{
FILE *fp;
if ((fp = fopen(f, "w")) == NULL) {
(void) fprintf(stderr, "Couldn't create pid file \"%s\": %s", f, strerror(errno));
} else {
fprintf(fp, "%ld\n", (long) getpid());
fclose(fp);
}
}

68
external/bsd/iscsi/dist/src/strlcpy.c vendored Normal file
View File

@ -0,0 +1,68 @@
/* $NetBSD: strlcpy.c,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "compat.h"
#include <sys/types.h>
#include <assert.h>
#include <string.h>
#if !HAVE_STRLCPY
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
#ifdef _LIBC
_strlcpy(dst, src, siz)
#else
strlcpy(dst, src, siz)
#endif
char *dst;
const char *src;
size_t siz;
{
char *d = dst;
const char *s = src;
size_t n = siz;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}
#endif

60
external/bsd/iscsi/dist/src/strtoll.c vendored Normal file
View File

@ -0,0 +1,60 @@
/* $NetBSD: strtoll.c,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "compat.h"
#ifndef HAVE_STRTOLL
static char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
int64_t
strtoll(const char *ptr, const char **endptr, int base)
{
const char *cp;
int64_t ret;
char *dig;
int d;
for (ret = 0, cp = ptr ; *cp && (dig = strchr(digits, *cp)) != NULL && (d = (int)(dig - digits)) < base ; cp++) {
ret = (ret * base) + d;
}
if (endptr != NULL) {
*endptr = cp;
}
return ret;
}
#endif /* HAVE_STRTOLL */

1761
external/bsd/iscsi/dist/src/target.c vendored Normal file

File diff suppressed because it is too large Load Diff

179
external/bsd/iscsi/dist/src/targets.5 vendored Normal file
View File

@ -0,0 +1,179 @@
.\" $NetBSD: targets.5,v 1.1 2009/06/21 21:20:31 agc Exp $
.\"
.\" Copyright © 2006 Alistair Crooks. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. The name of the author may not be used to endorse or promote
.\" products derived from this software without specific prior written
.\" permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd December 18, 2007
.Dt TARGETS 5
.Os
.Sh NAME
.Nm targets
.Nd configuration file for iSCSI targets
.Sh SYNOPSIS
.Nm targets
.Sh DESCRIPTION
The
.Nm
file describes the iSCSI storage which is presented to iSCSI
initiators by the
.Xr iscsi-target 8
service.
A description of the iSCSI protocol can be found in
.%T "Internet Small Computer Systems Interface \\*(tNRFC\\*(sP 3720" .
.Pp
Each line in the file
(other than comment lines that begin with a
.Sq # )
specifies an extent, a device (made up of extents or other devices),
or a target to present to the initiator.
.Pp
Each definition, an extent, a device, and a target, is specified
on a single whitespace delimited line.
.Pp
The
.Ar extent
definition specifies a piece of storage that will be used
as storage, and presented to initiators.
It is the basic definition for an iSCSI target.
Each target must contain at least one extent definition.
The first field in the definition is the extent name, which must
begin with the word
.Dq extent
and be followed by a number.
The next field is the file or
.Nx
device which will be used as persistent storage.
The next field is the offset (in bytes) of the start of the extent.
This field is usually 0.
The fourth field in the definition is the size of the extent.
The basic unit is bytes, and the shorthand
.Ar KB ,
.Ar MB ,
.Ar GB ,
and
.Ar TB
can be used for kilobytes (1024 bytes),
megabytes (1024 kilobytes), gigabytes
(1024 megabytes), and
terabytes (1024 gigabytes) respectively.
It is possible to use the word
.Dq size
to use the full size of the pre-existing regular file
given in the extent name.
.Pp
The
.Ar device
definition specifies a LUN or device, and is made up of extents
and other devices.
It is possible to create hierarchies of devices using the device definition.
The first field in the definition is the device name, which must
begin with the word
.Dq device
and be followed by a number.
The next field is the type of resilience that is to be provided
by the device.
For simple devices,
.Ar RAID0
suffices.
Greater resilience can be gained by using the
.Ar RAID1
resilience field.
Following the resilience field is a list of extents or other devices.
Large devices can be created by using multiple RAID0 extents,
in which case each extent will be concatenated.
Resilient devices can be created by using multiple RAID1 devices
or extents, in which case data will be written to each of the
devices or extents in turn.
If RAID1 resilience is used, all the extents or sub-devices must
be the same size.
Please note that RAID1 recovery is not yet supported by the
.Xr iscsi-target 8
utility.
An extent or sub-device may only be used once.
.Pp
The
.Ar target
definition specifies an iSCSI target, which is presented to the iSCSI
initiator.
Multiple targets can be specified.
The first field in the definition is the target name, which must
begin with either of the words
.Dq target
or
.Dq lun
and be followed by a number.
Optionally, if a target is followed by an
.Dq =
sign and some text,
the text is taken to be that of the iSCSI Qualified Name
of the target.
This IQN is used by the initiator to connect to the appropriate target.
The next field is a selector for whether the storage should be presented
as writable, or merely as read-only storage.
The field of
.Dq rw
denotes read-write storage,
whilst
.Dq ro
denotes read-only storage.
The next field is the device or extent name that will be used as persistent storage
for this target.
The fourth field is a slash-notation netmask which will be used, during the
discovery phase, to control the network addresses to which targets will
be presented.
The magic values
.Dq any
and
.Dq all
will expand to be the same as
.Dq 0/0 .
If an attempt is made to discover a target which is not allowed
by the netmask, a warning will be issued using
.Xr syslog 3
to make administrators aware of this attempt.
The administrator can still use
tcp wrapper functionality, as found in
.Xr hosts_access 5
and
.Xr hosts.deny 5
to allow or deny discovery attempts from initiators as
well as using the inbuilt netmask functionality.
.Sh FILES
.Bl -tag -width /etc/iscsi/targets -compact
.It Pa /etc/iscsi/targets
the list of exported storage
.Nm
.El
.Sh SEE ALSO
.Xr syslog 3 ,
.Xr hosts.deny 5 ,
.Xr hosts_access 5 ,
.Xr iscsi-target 8
.Sh HISTORY
The
.Nm
file first appeared in
.Nx 4.0 .

1229
external/bsd/iscsi/dist/src/tests.c vendored Normal file

File diff suppressed because it is too large Load Diff

378
external/bsd/iscsi/dist/src/usocktest.c vendored Normal file
View File

@ -0,0 +1,378 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#define EXTERN
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <string.h>
#include "iscsiutil.h"
/*
* NOTE: THIS IS A WORK IN PROGRESS.
*
* For now, you must manually enter the host and target send and recv patterns
* (shown in the code below) beginning at line 104. By default, this code will
* simulate the TCP traffic generated by an 8K iSCSI read between host and target.
*/
#define NUM_ITERS_DEFAULT 200
#define VERBOSE_FREQ_DEFAULT 20
#define PORT_DEFAULT 5001
#define HOST_SEND_PATTERN_DEFAULT "48" /* send iSCSI command PDU (SCSI READ) */
#define TARG_RECV_PATTERN_DEFAULT "48"
#define TARG_SEND_PATTERN_DEFAULT "48+8192" /* phase collapsed 8K data + status */
#define HOST_RECV_PATTERN_DEFAULT "48+8192"
/*
* Constants
*/
#define toSeconds(t) (t.tv_sec + (t.tv_usec/1000000.))
#define MAX_PATTERN_LEN 1024
#define MAX_BUFFS MAX_PATTERN_LEN/2
char usage[] = "usage: -t <target IP> I/O target\n"
" -hsp <host send pattern> e.g., 48\n"
" -tsp <targ recv pattern> e.g., 48\n"
" -hsp <targ repl pattern> e.g.. 8240\n"
" -hsp <host recv pattern> e.g., 48+8192\n"
" -n <num iter> number of iterations\n"
" -v <freq> verbose mode\n"
" -p <port> port number\n"
"\nNOTE: The pattern args are not yet implemented.\n"
" You must manually edit usocktest.c to change\n"
" the request pattern which, by default, generates\n"
" TCP traffic identical to an 32 MB iSCSI read\n"
" that uses 8KB data PDUs.\n";
int main(int argc, char *argv[]) {
int i, j, n;
char HostSendPattern[MAX_PATTERN_LEN];
char HostRecvPattern[MAX_PATTERN_LEN];
char TargSendPattern[MAX_PATTERN_LEN];
char TargRecvPattern[MAX_PATTERN_LEN];
int HostSendSize[MAX_BUFFS];
int HostRecvSize[MAX_BUFFS];
int TargSendSize[MAX_BUFFS];
int TargRecvSize[MAX_BUFFS];
unsigned char* HostSendBuff[MAX_BUFFS];
unsigned char* HostRecvBuff[MAX_BUFFS];
unsigned char* TargSendBuff[MAX_BUFFS];
unsigned char* TargRecvBuff[MAX_BUFFS];
int NumHostSendBuffs;
int NumHostRecvBuffs;
int NumTargSendBuffs;
int NumTargRecvBuffs;
char ctrlBufferSend[MAX_PATTERN_LEN];
char ctrlBufferRecv[MAX_PATTERN_LEN];
unsigned ctrlBuffSize = MAX_PATTERN_LEN;
struct timeval t_start, t_stop;
double time;
iscsi_socket_t iscsi_sock, iscsi_sock_new;
int HostSendTotal, HostRecvTotal;
int TargRecvTotal, TargSendTotal;
int IsTarget;
int Port = PORT_DEFAULT;
int NumIters = NUM_ITERS_DEFAULT;
int VerboseFreq = VERBOSE_FREQ_DEFAULT;
char TargetIP[64] = "";
/*
* Parse command line
*/
strcpy(HostSendPattern, HOST_SEND_PATTERN_DEFAULT);
strcpy(HostRecvPattern, HOST_RECV_PATTERN_DEFAULT);
strcpy(TargSendPattern, TARG_SEND_PATTERN_DEFAULT);
strcpy(TargRecvPattern, TARG_RECV_PATTERN_DEFAULT);
for (i=1; i<argc; i++) {
if (!strcmp(argv[i], "-t")) {
i++; strcpy(TargetIP, argv[i]);
} else if (!strcmp(argv[i], "-p")) {
i++; sscanf(argv[i], "%u", &Port);
} else if (!strcmp(argv[i], "-n")) {
i++; sscanf(argv[i], "%u", &NumIters);
} else if (!strcmp(argv[i], "-v")) {
i++; sscanf(argv[i], "%u", &VerboseFreq);
} else {
printf("Unknown option \"%s\"\n", argv[i]);
printf("%s\n", usage);
return -1;
}
}
if (argc == 1) printf("%s\n", usage);
IsTarget = (strlen(TargetIP)>0)?0:1;
/*
* Convert command line string patterns here. For now, you must
* manually enter these below.
*/
NumHostSendBuffs = 1;
HostSendSize[0] = 48;
NumTargRecvBuffs = 1;
TargRecvSize[0] = 48;
NumHostRecvBuffs = 2;
HostRecvSize[0] = 48;
HostRecvSize[1] = 524288;
NumTargSendBuffs = 2;
TargSendSize[0] = 48;
TargSendSize[1] = 524288;
/*
* Create/bind/listen
*/
if (iscsi_sock_create(&iscsi_sock)!=0) {
iscsi_trace_error("iscsi_sock_create() failed\n");
return -1;
}
if (IsTarget) {
if (iscsi_sock_bind(iscsi_sock, Port)!=0) {
iscsi_trace_error("iscsi_sock_bind() failed\n");
return -1;
}
if (iscsi_sock_listen(iscsi_sock)!=0) {
iscsi_trace_error("iscsi_sock_listen() failed\n");
return -1;
}
}
/*
* Accept connection
*/
accept:
if (IsTarget) {
printf("Waiting for TCP connection on port %u\n", Port);
if(iscsi_sock_accept(iscsi_sock, &iscsi_sock_new)!=0) {
iscsi_trace_error("iscsi_sock_accept() failed\n");
return -1;
}
printf("Connection accepted\n");
} else {
printf("Connecting to %s\n", TargetIP);
if(iscsi_sock_connect(iscsi_sock, TargetIP, Port)!=0) {
iscsi_trace_error("iscsi_sock_connect() failed\n");
return -1;
}
printf("Connected\n");
iscsi_sock_new = iscsi_sock;
}
/*
* Host/Target handshake for test parameters
*/
if (!IsTarget) {
iscsi_trace(TRACE_DEBUG, "Sending test parameters\n");
sprintf(ctrlBufferSend, "%s:%s:%s:%s:%i:%i:%i",
HostSendPattern, HostRecvPattern, TargSendPattern, TargRecvPattern,
NumIters, VerboseFreq, Port);
if ((n=iscsi_sock_msg(iscsi_sock_new, 1, ctrlBuffSize, ctrlBufferSend, 0))!=ctrlBuffSize) {
iscsi_trace_error("iscsi_sock_msg() failed\n");
return -1;
}
if ((n=iscsi_sock_msg(iscsi_sock_new, 0, ctrlBuffSize, ctrlBufferRecv, 0))!=ctrlBuffSize) {
iscsi_trace_error("iscsi_sock_msg() failed\n");
return -1;
}
iscsi_trace(TRACE_DEBUG, "Test parameters sent\n");
} else {
char *ptr, *delim;
iscsi_trace(TRACE_DEBUG, "Receiving test parameters\n");
if ((n=iscsi_sock_msg(iscsi_sock_new, 0, ctrlBuffSize, ctrlBufferRecv, 0))!=ctrlBuffSize) {
iscsi_trace_error("iscsi_sock_msg() failed\n");
return -1;
}
ptr = ctrlBufferRecv;
delim = strchr(ptr, ':');
strncpy(HostSendPattern, ptr, delim-ptr+1); HostSendPattern[delim-ptr] = 0x0; ptr = delim+1;
delim = strchr(ptr, ':');
strncpy(HostRecvPattern, ptr, delim-ptr+1); HostRecvPattern[delim-ptr] = 0x0; ptr = delim+1;
delim = strchr(ptr, ':');
strncpy(TargSendPattern, ptr, delim-ptr+1); TargSendPattern[delim-ptr] = 0x0; ptr = delim+1;
delim = strchr(ptr, ':');
strncpy(TargRecvPattern, ptr, delim-ptr+1); TargRecvPattern[delim-ptr] = 0x0; ptr = delim+1;
sscanf(ptr, "%i:%i", &NumIters, &VerboseFreq);
if ((n=iscsi_sock_msg(iscsi_sock_new, 1, ctrlBuffSize, ctrlBufferSend, 0))!=ctrlBuffSize) {
iscsi_trace_error("iscsi_sock_msg() failed\n");
return -1;
}
iscsi_trace(TRACE_DEBUG, "Test parameters received\n");
}
/*
* Check Arguments
*/
HostSendTotal = 0; for (i=0; i<NumHostSendBuffs; i++) HostSendTotal += HostSendSize[i];
TargRecvTotal = 0; for (i=0; i<NumTargRecvBuffs; i++) TargRecvTotal += TargRecvSize[i];
if (HostSendTotal != TargRecvTotal) {
iscsi_trace_error("Host sending size (%i) > Target receiving size (%i)\n",
HostSendTotal, TargRecvTotal);
return -1;
}
HostRecvTotal = 0; for (i=0; i<NumHostRecvBuffs; i++) HostRecvTotal += HostRecvSize[i];
TargSendTotal = 0; for (i=0; i<NumTargSendBuffs; i++) TargSendTotal += TargSendSize[i];
if (HostRecvTotal != TargSendTotal) {
iscsi_trace_error("Host receiving size (%i) > Target sending size (%i)\n",
HostRecvTotal, TargSendTotal);
return -1;
}
iscsi_trace(TRACE_DEBUG, "HostSendPattern: \"%s\"\n", HostSendPattern);
iscsi_trace(TRACE_DEBUG, "HostRecvPattern: \"%s\"\n", HostRecvPattern);
iscsi_trace(TRACE_DEBUG, "TargRecvPattern: \"%s\"\n", TargRecvPattern);
iscsi_trace(TRACE_DEBUG, "TargSendPattern: \"%s\"\n", TargSendPattern);
iscsi_trace(TRACE_DEBUG, "NumIters: %i\n", NumIters);
iscsi_trace(TRACE_DEBUG, "VerboseFreq: %i\n", VerboseFreq);
iscsi_trace(TRACE_DEBUG, "HostSendTotal: %i bytes\n", HostSendTotal);
iscsi_trace(TRACE_DEBUG, "HostRecvTotal: %i bytes\n", HostRecvTotal);
/*
* Allocate buffers
*/
for (i=0; i<NumHostSendBuffs; i++)
if ((HostSendBuff[i]=iscsi_malloc(HostSendSize[i]))==NULL) {
iscsi_trace_error("out of memory\n");
return -1;
}
for (i=0; i<NumHostRecvBuffs; i++)
if ((HostRecvBuff[i]=iscsi_malloc(HostRecvSize[i]))==NULL) {
iscsi_trace_error("out of memory\n");
return -1;
}
for (i=0; i<NumTargSendBuffs; i++)
if ((TargSendBuff[i]=iscsi_malloc(TargSendSize[i]))==NULL) {
iscsi_trace_error("out of memory\n");
return -1;
}
for (i=0; i<NumTargRecvBuffs; i++)
if ((TargRecvBuff[i]=iscsi_malloc(TargRecvSize[i]))==NULL) {
iscsi_trace_error("out of memory\n");
return -1;
}
/*
* Begin I/O
*/
gettimeofday(&t_start, 0);
for (i=0; i<NumIters; i++) {
iscsi_trace(TRACE_DEBUG, "begin iteration %i\n", i);
if (!IsTarget) {
/* Send to target */
for (j=0; j<NumHostSendBuffs; j++) {
if (iscsi_sock_msg(iscsi_sock_new, 1, HostSendSize[j], HostSendBuff[j], 0)!= HostSendSize[j]) {
iscsi_trace_error("iscsi_sock_msg() failed\n");
return -1;
}
iscsi_trace(TRACE_DEBUG, "Tx HostSendBuff[%i] (size %i)\n", j, HostSendSize[j]);
}
/* Recv from target */
for (j=0; j<NumHostRecvBuffs; j++) {
if (iscsi_sock_msg(iscsi_sock_new, 0, HostRecvSize[j], HostRecvBuff[j], 0)!= HostRecvSize[j]) {
iscsi_trace_error("iscsi_sock_msg() failed\n");
return -1;
}
iscsi_trace(TRACE_DEBUG, "Rx HostRecvBuff[%i] (size %i)\n", j, HostRecvSize[j]);
}
} else {
/* Recv from host */
for (j=0; j<NumTargRecvBuffs; j++) {
if (iscsi_sock_msg(iscsi_sock_new, 0, TargRecvSize[j], TargRecvBuff[j], 0)!= TargRecvSize[j]) {
iscsi_trace_error("iscsi_sock_msg() failed\n");
return -1;
}
iscsi_trace(TRACE_DEBUG, "Rx TargRecvBuff[%i] (size %i)\n", j, TargRecvSize[j]);
}
/* Send to host */
for (j=0; j<NumTargSendBuffs; j++) {
if (iscsi_sock_msg(iscsi_sock_new, 1, TargSendSize[j], TargSendBuff[j], 0)!= TargSendSize[j]) {
iscsi_trace_error("iscsi_sock_msg() failed\n");
return -1;
}
iscsi_trace(TRACE_DEBUG, "Tx TargSendBuff[%i] (size %i)\n", j, TargSendSize[j]);
}
}
if ((!IsTarget)&&((i+1)%VerboseFreq==0)) {
printf("Iter %i: %i total bytes sent, %i total bytes recv\n",
i+1, HostSendTotal*(i+1), HostRecvTotal*(i+1));
}
iscsi_trace(TRACE_DEBUG, "end iteration %i\n", i);
}
gettimeofday(&t_stop, 0);
/*
* End I/O
*/
/* Free buffers */
for (i=0; i<NumHostSendBuffs; i++) iscsi_free(HostSendBuff[i]);
for (i=0; i<NumHostRecvBuffs; i++) iscsi_free(HostRecvBuff[i]);
for (i=0; i<NumTargSendBuffs; i++) iscsi_free(TargSendBuff[i]);
for (i=0; i<NumTargRecvBuffs; i++) iscsi_free(TargRecvBuff[i]);
/* Output stats */
if (IsTarget) {
goto accept;
} else {
time = (double) (toSeconds(t_stop) - toSeconds(t_start));
printf("Send Size: %i bytes\n", HostSendTotal);
printf("Recv Size: %i bytes\n", HostRecvTotal);
printf("Num Iters: %i\n", NumIters);
printf("Elapsed Time: %.4f sec\n", time);
printf("Avg RT Latency: %.2f usec\n", (time*1000000/NumIters));
printf("Send Performance: %.2f MB/sec sec\n", ((HostSendTotal*NumIters)/time)/1048576);
printf("Recv Performance: %.2f MB/sec sec\n", ((HostRecvTotal*NumIters)/time)/1048576);
}
return 0;
}

158
external/bsd/iscsi/dist/src/utest.c vendored Normal file
View File

@ -0,0 +1,158 @@
/*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
* using the software you agree to this license. If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Intel License Agreement
*
* Copyright (c) 2000, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* -Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
*
* -The name of Intel Corporation may not be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#define EXTERN
#include <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <unistd.h>
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#include "scsi_cmd_codes.h"
#include "iscsi.h"
#include "initiator.h"
#include "tests.h"
int
mycallback(void *arg)
{
(*((int *) arg))++;
return 0;
}
int
main(int argc, char *argv[])
{
struct sigaction act;
char hostname[1024];
char *host;
int tgtlo = 0;
int tgthi = CONFIG_INITIATOR_NUM_TARGETS;
int target = -1;
int lun = 0;
int i, j;
int iterations;
/* Check args */
iterations = 1;
(void) gethostname(host = hostname, sizeof(hostname));
while ((i = getopt(argc, argv, "h:l:n:t:")) != -1) {
switch(i) {
case 'h':
host = optarg;
break;
case 'l':
lun = atoi(optarg);
break;
case 'n':
iterations = atoi(optarg);
break;
case 't':
target = atoi(optarg);
break;
default:
(void) fprintf(stderr, "%s: unknown option `%c'", *argv, i);
}
}
if (target != -1) {
if (target >= CONFIG_INITIATOR_NUM_TARGETS) {
iscsi_trace_error(__FILE__, __LINE__, "initiator only configured with %d targets\n", CONFIG_INITIATOR_NUM_TARGETS);
exit(EXIT_FAILURE);
}
tgtlo = target;
tgthi = target + 1;
}
if (argc == 1) {
(void) fprintf(stderr, "usage: %s [-h hostname] [-l lun] [-n iterations] [-t target]\n", *argv);
exit(EXIT_FAILURE);
}
for (j = 0; j < iterations; j++) {
printf("<ITERATION %d>\n", j);
/* Ignore sigpipe */
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL);
/* Initialize Initiator */
if (initiator_init(host) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "initiator_init() failed\n");
return -1;
}
/* Run tests for each target */
for (i = tgtlo; i < tgthi; i++) {
if (test_all(i, lun) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "test_all() failed\n");
return -1;
}
}
/* Shutdown Initiator */
if (initiator_shutdown() == -1) {
iscsi_trace_error(__FILE__, __LINE__, "initiator_shutdown() failed\n");
return -1;
}
}
printf("\n");
printf("************************************\n");
printf("* ALL TESTS COMPLETED SUCCESSFULLY *\n");
printf("************************************\n");
printf("\n");
exit(EXIT_SUCCESS);
}

1296
external/bsd/iscsi/dist/src/util.c vendored Normal file

File diff suppressed because it is too large Load Diff

100
external/bsd/iscsi/dist/src/uuid.c vendored Normal file
View File

@ -0,0 +1,100 @@
/* $NetBSD: uuid.c,v 1.1 2009/06/21 21:20:31 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_UUID_H
#include <uuid.h>
#endif
#include "compat.h"
#include "defs.h"
#ifndef HAVE_UUID_CREATE
/* just fill the struct with random values for now */
void
uuid_create(uuid_t *uuid, uint32_t *status)
{
uint64_t ether;
time_t t;
(void) time(&t);
ether = (random() << 32) | random();
uuid->time_low = t;
uuid->time_mid = (uint16_t)(random() & 0xffff);
uuid->time_hi_and_version = (uint16_t)(random() & 0xffff);
uuid->clock_seq_low = random() & 0xff;
uuid->clock_seq_hi_and_reserved = random() & 0xff;
(void) memcpy(&uuid->node, &ether, sizeof(uuid->node));
*status = 0;
}
#endif
#ifndef HAVE_UUID_TO_STRING
/* convert the struct to a printable string */
void
uuid_to_string(uuid_t *uuid, char **str, uint32_t *status)
{
char s[64];
(void) snprintf(s, sizeof(s), "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
uuid->time_low,
uuid->time_mid,
uuid->time_hi_and_version,
uuid->clock_seq_hi_and_reserved,
uuid->clock_seq_low,
uuid->node[0],
uuid->node[1],
uuid->node[2],
uuid->node[3],
uuid->node[4],
uuid->node[5]);
*str = strdup(s);
*status = 0;
}
#endif