View Javadoc

1   /**
2    * Copyright (c) 2012, University of Konstanz, Distributed Systems Group All rights reserved.
3    * 
4    * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
5    * following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of
6    * conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice,
7    * this list of conditions and the following disclaimer in the documentation and/or other materials provided with the
8    * distribution. * Neither the name of the University of Konstanz nor the names of its contributors may be used to
9    * endorse or promote products derived from this software without specific prior written permission.
10   * 
11   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
12   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13   * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
14   * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
15   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
16   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
17   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18   */
19  package org.jscsi.initiator.connection.state;
20  
21  
22  import org.jscsi.exception.InternetSCSIException;
23  import org.jscsi.initiator.connection.Connection;
24  import org.jscsi.initiator.connection.TargetCapacityInformations;
25  import org.jscsi.parser.OperationCode;
26  import org.jscsi.parser.ProtocolDataUnit;
27  import org.jscsi.parser.data.DataInParser;
28  import org.jscsi.parser.scsi.SCSICommandParser.TaskAttributes;
29  import org.jscsi.parser.scsi.SCSIResponseParser;
30  import org.jscsi.parser.scsi.SCSIStatus;
31  
32  
33  /**
34   * <h1>CapacityResponseState</h1>
35   * <p/>
36   * This state handles a Capacity Response to extract the block size and the size of the iSCSI Device.
37   * 
38   * @author Volker Wildi
39   */
40  public final class CapacityResponseState extends AbstractState {
41  
42      // --------------------------------------------------------------------------
43      // --------------------------------------------------------------------------
44  
45      /**
46       * This object contains the informations about the capacity of the connected target.
47       */
48      private final TargetCapacityInformations capacityInformation;
49  
50      // --------------------------------------------------------------------------
51      // --------------------------------------------------------------------------
52  
53      /**
54       * Constructor to create a new, empty <code>CapacityResponseState</code> instance.
55       * 
56       * @param initConnection This is the connection, which is used for the network transmission.
57       * @param initCapacityInformation Store the extracted informations in this instance.
58       */
59      protected CapacityResponseState (final Connection initConnection, final TargetCapacityInformations initCapacityInformation) {
60  
61          super(initConnection);
62          capacityInformation = initCapacityInformation;
63      }
64  
65      // --------------------------------------------------------------------------
66      // --------------------------------------------------------------------------
67  
68      /** {@inheritDoc} */
69      public final void execute () throws InternetSCSIException {
70  
71          final ProtocolDataUnit protocolDataUnit = connection.receive();
72  
73          // first, we extract capacity informations
74          if (!(protocolDataUnit.getBasicHeaderSegment().getParser() instanceof DataInParser)) {
75  
76              // In newer versions of iscsi targets there the target tells the initiator
77              // that the status is cleared using a scsi response. It's defined in the RFC 3720 on page 78 (or
78              // at least mentioned, it's
79              // actually defined in SAM-2 and). This is why we have to ask for capacity informations once again
80              // receiving this
81              // Response to our capacity request.
82              if (protocolDataUnit.getBasicHeaderSegment().getParser() instanceof SCSIResponseParser) {
83                  connection.nextState(new CapacityRequestState(connection, capacityInformation, TaskAttributes.SIMPLE));
84                  super.stateFollowing = true;
85                  return;
86              } else {
87                  throw new InternetSCSIException(protocolDataUnit.getBasicHeaderSegment().getParser().getClass().getSimpleName() + " is not the expected type of PDU.");
88              }
89          }
90  
91          /**
92           * The server responded using the data-in-parser.
93           */
94          final DataInParser parser = (DataInParser) protocolDataUnit.getBasicHeaderSegment().getParser();
95  
96          capacityInformation.deserialize(protocolDataUnit.getDataSegment());
97  
98          if (!parser.isStatusFlag() || parser.getStatus() != SCSIStatus.GOOD) {
99              // receive SCSI Response PDU and check status (no phase
100             // collapse)
101             final ProtocolDataUnit scsiPdu = connection.receive();
102             if (scsiPdu.getBasicHeaderSegment().getOpCode() == OperationCode.SCSI_RESPONSE) {
103                 final SCSIResponseParser scsiParser = (SCSIResponseParser) scsiPdu.getBasicHeaderSegment().getParser();
104                 if (scsiParser.getStatus() == SCSIStatus.GOOD) return;// done
105             }
106             throw new InternetSCSIException("Error: Task did not finish successfully.");
107         }
108 
109     }
110 
111     // --------------------------------------------------------------------------
112     // --------------------------------------------------------------------------
113     // --------------------------------------------------------------------------
114     // --------------------------------------------------------------------------
115 
116 }