Coverage Report - org.jscsi.target.connection.stage.fullfeature.FormatUnitStage
 
Classes in this File Line Coverage Branch Coverage Complexity
FormatUnitStage
0%
0/16
0%
0/2
1.5
 
 1  
 package org.jscsi.target.connection.stage.fullfeature;
 2  
 
 3  
 
 4  
 import java.io.IOException;
 5  
 import java.security.DigestException;
 6  
 
 7  
 import org.jscsi.exception.InternetSCSIException;
 8  
 import org.jscsi.parser.BasicHeaderSegment;
 9  
 import org.jscsi.parser.ProtocolDataUnit;
 10  
 import org.jscsi.parser.scsi.SCSICommandParser;
 11  
 import org.jscsi.parser.scsi.SCSIResponseParser;
 12  
 import org.jscsi.parser.scsi.SCSIStatus;
 13  
 import org.jscsi.target.connection.TargetPduFactory;
 14  
 import org.jscsi.target.connection.phase.TargetFullFeaturePhase;
 15  
 import org.jscsi.target.scsi.ScsiResponseDataSegment;
 16  
 import org.jscsi.target.scsi.cdb.FormatUnitCDB;
 17  
 import org.jscsi.target.scsi.sense.AdditionalSenseBytes;
 18  
 import org.jscsi.target.scsi.sense.AdditionalSenseCodeAndQualifier;
 19  
 import org.jscsi.target.scsi.sense.ErrorType;
 20  
 import org.jscsi.target.scsi.sense.FixedFormatSenseData;
 21  
 import org.jscsi.target.scsi.sense.SenseKey;
 22  
 import org.jscsi.target.scsi.sense.information.FourByteInformation;
 23  
 import org.jscsi.target.scsi.sense.senseDataDescriptor.senseKeySpecific.FieldPointerSenseKeySpecificData;
 24  
 import org.jscsi.target.settings.SettingsException;
 25  
 import org.slf4j.Logger;
 26  
 import org.slf4j.LoggerFactory;
 27  
 
 28  
 
 29  
 /**
 30  
  * A stage for processing <code>FORMAT UNIT</code> SCSI commands.
 31  
  * <p>
 32  
  * The <code>FORMAT UNIT</code> command requests that the device server format the medium into application client
 33  
  * accessible logical blocks as specified in the number of logical blocks and logical block length values received in
 34  
  * the last mode parameter block descriptor in a <code>MODE SELECT</code> command (see SPC-4). In addition, the device
 35  
  * server may certify the medium and create control structures for the management of the medium and defects.
 36  
  * <p>
 37  
  * The degree that the medium is altered by this command is vendor specific.
 38  
  * <p>
 39  
  * If a device server receives a <code>FORMAT UNIT</code> command before receiving a MODE SELECT command with a mode
 40  
  * parameter block descriptor, then the device server shall use the number of logical blocks and logical block length at
 41  
  * which the logical unit is currently formatted (i.e., no change is made to the number of logical blocks and the
 42  
  * logical block length of the logical unit during the format operation).
 43  
  * <p>
 44  
  * <code>FORMAT UNIT</code> commands received by the jSCI Target will not lead to any persistent changes of the virtual
 45  
  * logical unit.
 46  
  * 
 47  
  * @author Andreas Ergenzinger
 48  
  */
 49  
 public class FormatUnitStage extends TargetFullFeatureStage {
 50  
 
 51  0
     private static final Logger LOGGER = LoggerFactory.getLogger(ReadStage.class);
 52  
 
 53  
     public FormatUnitStage (TargetFullFeaturePhase targetFullFeaturePhase) {
 54  0
         super(targetFullFeaturePhase);
 55  0
     }
 56  
 
 57  
     @Override
 58  
     public void execute (ProtocolDataUnit pdu) throws IOException , InterruptedException , InternetSCSIException , DigestException , SettingsException {
 59  
 
 60  0
         LOGGER.debug("Initiator has sent FORMAT UNIT command.");
 61  
 
 62  0
         final BasicHeaderSegment bhs = pdu.getBasicHeaderSegment();
 63  0
         final SCSICommandParser parser = (SCSICommandParser) bhs.getParser();
 64  
 
 65  0
         ProtocolDataUnit responsePdu = null;// the response PDU
 66  
 
 67  
         // get command details in CDB
 68  0
         final FormatUnitCDB cdb = new FormatUnitCDB(parser.getCDB());
 69  0
         final FieldPointerSenseKeySpecificData[] illegalFieldPointers = cdb.getIllegalFieldPointers();
 70  
 
 71  0
         if (illegalFieldPointers != null) {
 72  
             // an illegal request has been made
 73  
 
 74  0
             FixedFormatSenseData senseData = new FixedFormatSenseData(false,// valid
 75  
             ErrorType.CURRENT,// error type
 76  
             false,// file mark
 77  
             false,// end of medium
 78  
             false,// incorrect length indicator
 79  
             SenseKey.ILLEGAL_REQUEST,// sense key
 80  
             new FourByteInformation(),// information
 81  
             new FourByteInformation(),// command specific information
 82  
             AdditionalSenseCodeAndQualifier.INVALID_FIELD_IN_CDB,// additional
 83  
                                                                  // sense
 84  
                                                                  // code
 85  
                                                                  // and
 86  
                                                                  // qualifier
 87  
             (byte) 0,// field replaceable unit code
 88  
             illegalFieldPointers[0],// sense key specific data, only
 89  
                                     // report first problem
 90  
             new AdditionalSenseBytes());// additional sense bytes
 91  
 
 92  0
             responsePdu = TargetPduFactory.createSCSIResponsePdu(false,// bidirectionalReadResidualOverflow
 93  
                     false,// bidirectionalReadResidualUnderflow
 94  
                     false,// residualOverflow
 95  
                     false,// residualUnderflow,
 96  
                     SCSIResponseParser.ServiceResponse.COMMAND_COMPLETED_AT_TARGET,// response,
 97  
                     SCSIStatus.CHECK_CONDITION,// status,
 98  
                     bhs.getInitiatorTaskTag(),// initiatorTaskTag,
 99  
                     0,// snackTag
 100  
                     0,// expectedDataSequenceNumber
 101  
                     0,// bidirectionalReadResidualCount
 102  
                     0,// residualCount
 103  
                     new ScsiResponseDataSegment(senseData, parser.getExpectedDataTransferLength()));// data
 104  
                                                                                                     // segment
 105  
 
 106  0
         } else {
 107  
             // PDU is okay
 108  
 
 109  
             // carry out command
 110  
             /*
 111  
              * If we were nice, we would have to get (we would actually have to save it first) the number of blocks and
 112  
              * the block length requested by the initiator in the last MODE SENSE command and then change the logical
 113  
              * block layout accordingly. However, since the target is not required by the SCSI standard to make those
 114  
              * changes ("The degree that the medium is altered by this command is vendor specific."), doing nothing is
 115  
              * okay.
 116  
              */
 117  
 
 118  0
             responsePdu = createScsiResponsePdu(SCSIStatus.GOOD,// status
 119  
                     bhs.getInitiatorTaskTag(),// initiatorTaskTag,
 120  
                     parser.getExpectedDataTransferLength(),// expectedDataTransferLength,
 121  
                     0);// responseDataSize
 122  
         }
 123  
 
 124  
         // send response
 125  0
         connection.sendPdu(responsePdu);
 126  0
     }
 127  
 
 128  
 }