This project is read-only.

iSCSI Initiator

May 28, 2010 at 10:48 AM



I'm trying to connect to an iscsi target. But it's hard to understand how to use your API, because there is no example for the iSCSI interface.

Hopely you can help me. :-)

I tried:

Initiator i = new Initiator();
  TargetAddress[] targetadr = new TargetAddress[1];
  targetadr[0] = new TargetAddress("", 3260, "");
  TargetInfo t = new TargetInfo("MyTarget", targetadr);
  Session session = i.ConnectTo(t);

But there I got an error. LoginStatusCode = InitiatorError = 0x0200.

So I don't know whats the problem.

Thanks for help.

Best regards.

May 28, 2010 at 3:17 PM


I use this regularly...

Initiator i = new Initiator();
i.SetCredentials(username, pass);  // if necessary
TargetInfo[] t = i.GetTargets(ipaddress);  // let the system give you the endpoints
Session s = i.ConnectTo(t[0]);   // you may get more than one back so you may need to determine which one you want first

This works for me.



May 28, 2010 at 4:02 PM

Thanks for help.

That worked for me, too.

But, do you have an example how to control a tape library or a jukebox? I only have READ and WRITE on the session. I've got the LUN of the e.g. jukebox. I think I have to WRITE something to the jukebox (not the jukebox drives) to control it?!

best regards

May 29, 2010 at 8:39 AM
Edited May 29, 2010 at 8:40 AM


DiscUtils doesn't have any support specifically for Jukeboxes.  However, I've just uploaded a change that would allow you to send raw SCSI commands.

You'll need to read the T10 specs to understand the format of the SCSI commands you need to send to control your Jukebox (see  You probably want the "Media Changer Commands (SMC)".

An example of sending a raw SCSI command...

            Initiator initiator = new Initiator();
            using(Session s = initiator.ConnectTo(initiator.GetTargets("")[1]))
                    byte[] received = new byte[252];
                    byte[] cmd = {
                                 0x03,    // OpCode
                                 0,       // Flags
                                 0,0,     // Reserved
                                 252,     // Allocated Length
                                 0,       // Control byte
                    long lun = s.GetLuns()[2].Lun;
                    int numRead = s.RawCommand(lun, cmd, null, 0, 0, received, 0, 252);

                    // Parse received data here...
                catch (ScsiCommandException ce)
May 31, 2010 at 7:13 AM
festive_ken wrote:

You'll need to read the T10 specs to understand the format of the SCSI commands you need to send to control your Jukebox (see  You probably want the "Media Changer Commands (SMC)".

Thanks for the hint, but the access is restricted. :-(
Is there a way to get it?

May 31, 2010 at 10:43 AM

SMC-3 is still in draft, so you can get hold of it by clicking the link and supplying a few details.

The published versions you have to pay for...




Jun 1, 2010 at 1:10 PM

Ok thank you, I got the draft.

But I always get an exception ({"Target indicated SCSI failure"}) if I send another command then the "Request Sense 0x03".

E.g. I wanted to ask an optical jukebox (disk library) for ready status. So I tried 0x00 with all reserved bytes. But only for 0x03 I got an answer ... I think ...

byte[] cmd = {0x00, 0, 0, 0, 0, 0};

Talking to SCSI devices through raw commands is new for me. Maybe you can give me another hint? :-)

Thanks a lot.

Jun 1, 2010 at 10:53 PM

It may be worth trying a Media Changer command - such as INITIALISE ELEMENT STATUS (byte[] cmd = {0x07,0,0,0,0,0})

You've made sure you're actually specifying the Jukebox's LUN? (check the DeviceType in LunInfo)

Wireshark can be really useful to see what's going on - does a pretty good job of decoding iSCSI / SCSI on the wire.




Jun 2, 2010 at 7:59 AM
Edited Jun 2, 2010 at 8:25 AM

Ok, I'm really sure, that I target the jukebox (the robotic, not the drives).

For INITIALIZE ELEMENT STATUS I also got an exception. I extended your method in Connection.cs: public int Send(...) at

throw new ScsiCommandException(resp.Status, "Target indicated SCSI failure. Status = "+resp.Status);

There I always get a CheckCondition status. Is this the parsed answer from the jukebox or only an error code by your interface?

If found this in the specification
If the SCSI target port is not able to communicate with the logical unit that contains the media changer device server and determines that communication is not able to be established, then commands addressed to that logical unit shall be rejected with CHECK CONDITION status, with the sense key set to either HARDWARE ERROR or ABORTED COMMAND, and the additional sense code set to LOGICAL UNIT COMMUNICATION FAILURE.

So maybe, it's a communication error? But I tested the device with another software for optical jukebox administration and there all is fine.


Jun 2, 2010 at 9:14 PM

Using wireshark to capture a network trace would be a good plan.

The responses normally contain a bit more info when you get CHECK CONDITION - that could help you narrow down what's happening.

Jun 3, 2010 at 1:14 PM


OK, I installed WireShark. And it's really strange.

If I send the REQUEST SENSE I see it in WireShark. There the Response is RESPONSE LUN ... and so on.
But if I use INITIALIZE ELEMENT STATUS 0x07, no package showed up in WireShark. So your interface throws an exception, but no package gone out.
The only other packages in WireShark are a lot of "TEST UNIT READY" commands. I think these are from the OS.

So I don't know whats going wrong, but it seems, that other commands then the SENSE command are lost in the DiscUtils interface?

Jun 6, 2010 at 6:03 PM

Can you provide a stack trace?

Jun 7, 2010 at 7:56 AM


ex.Message:    "Target indicated SCSI failure. Status = CheckCondition"


"at DiscUtils.Iscsi.Connection.Send(ScsiCommand cmd, Byte[] outBuffer, Int32 outBufferOffset, Int32 outBufferCount, Byte[] inBuffer, Int32 inBufferOffset, Int32 inBufferMax)
in C:\\...\\Visual Studio 2010\\Projects\\SCSITest\\DiskUtils\\src\\Iscsi\\Connection.cs:line 189\r\n
at DiscUtils.Iscsi.Session.Send(ScsiCommand cmd, Byte[] outBuffer, Int32 outBufferOffset, Int32 outBufferCount, Byte[] inBuffer, Int32 inBufferOffset, Int32 inBufferMax)
in C:\\...\\Visual Studio 2010\\Projects\\SCSITest\\DiskUtils\\src\\Iscsi\\Session.cs:line 460\r\n
at DiscUtils.Iscsi.Session.RawCommand(Int64 lun, Byte[] command, Byte[] outBuffer, Int32 outBufferOffset, Int32 outBufferLength, Byte[] inBuffer, Int32 inBufferOffset, Int32 inBufferLength)
in C:\\...\\Visual Studio 2010\\Projects\\SCSITest\\DiskUtils\\src\\Iscsi\\Session.cs:line 356\r\n
at SCSITest.Program.jukeboxInitializeElement(Session session, Int64 lun)
in C:\\...\\visual studio 2010\\Projects\\SCSITest\\SCSITest\\Program.cs:line 93\r\n
at SCSITest.Program.runDiskUtils()
in C:\\...\\visual studio 2010\\Projects\\SCSITest\\SCSITest\\Program.cs:line 69"

No inner exception.

Jun 7, 2010 at 9:48 PM


Can you grab the latest source (or the binaries from the 0.9 preview release), there's been some changes in this area.

With the new source, you should find a ScsiCommandException is thrown.  Can you post the value of the Status property and the GetSenseData() method on the exception.




Jun 9, 2010 at 8:25 AM


ex.Status    CheckCondition    DiscUtils.Iscsi.ScsiStatus

ex.GetSenseData()    {byte[32]}    byte[]
        [0]    112    byte
        [1]    0    byte
        [2]    6    byte
        [3]    0    byte
        [4]    0    byte
        [5]    0    byte
        [6]    0    byte
        [7]    24    byte
        [8]    0    byte
        [9]    0    byte
        [10]    0    byte
        [11]    0    byte
        [12]    41    byte
        [13]    0    byte
        [14]    0    byte
        [15]    0    byte
        [16]    0    byte
        [17]    0    byte
        [18]    128    byte
        [19]    0    byte
        [20]    0    byte
        [21]    0    byte
        [22]    0    byte
        [23]    0    byte
        [24]    0    byte
        [25]    0    byte
        [26]    0    byte
        [27]    0    byte
        [28]    0    byte
        [29]    0    byte
        [30]    0    byte
        [31]    0    byte


Jun 12, 2010 at 9:41 PM


This means the device received the command, and failed it.  Decoding the sense data (see section 4.5 in SPC-4):

This is a type 70h response, the SENSE KEY is 6h (UNIT ATTENTION*), the ADDTIONAL SENSE CODE is 29h and the ADDITIONAL SENSE CODE QUALIFIER is 0h, which translates as: POWER ON, RESET, OR BUS DEVICE RESET OCCURRED




* From the doc: UNIT ATTENTION: Indicates that a unit attention condition has been established (e.g., the removable medium may have been changed, a logical unit reset occurred). See SAM-4.