All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jscsi.parser.tmf.TaskManagementFunctionRequestParser Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2012, University of Konstanz, Distributed Systems Group 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. * Neither the name of the University of Konstanz 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 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  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.
 */
package org.jscsi.parser.tmf;


import java.util.HashMap;
import java.util.Map;

import org.jscsi.exception.InternetSCSIException;
import org.jscsi.parser.BasicHeaderSegment;
import org.jscsi.parser.Constants;
import org.jscsi.parser.InitiatorMessageParser;
import org.jscsi.parser.ProtocolDataUnit;
import org.jscsi.parser.datasegment.DataSegmentFactory.DataSegmentFormat;
import org.jscsi.utils.Utils;


/**
 * 

TaskManagementFunctionRequestParser

*

* This class parses a Task Management Function Request message defined in the iSCSI Standard (RFC3720). *

*

TotalAHSLength and DataSegmentLength

For this PDU TotalAHSLength and DataSegmentLength MUST be * 0. *

*

LUN

This field is required for functions that address a specific LU (ABORT TASK, CLEAR TASK SET, ABORT TASK * SET, CLEAR ACA, LOGICAL UNIT RESET) and is reserved in all others. *

* * @author Volker Wildi */ public final class TaskManagementFunctionRequestParser extends InitiatorMessageParser { // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- /** * This enumeration defines all valid function codes, which are defined in the iSCSI standard (RFC3720). */ public static enum FunctionCode { /** * This is an artificial function code, which is only used to indicate a not set function code. */ UNSET((byte) 0), /** Aborts the task identified by the Referenced Task Tag field. */ ABORT_TASK((byte) 1), /** Aborts all Tasks issued via this session on the logical unit. */ ABORT_TASK_SET((byte) 2), /** Clears the Auto Contingent Allegiance condition. */ CLEAR_ACA((byte) 3), CLEAR_TASK_SET((byte) 4), LUN_RESET((byte) 5), TARGET_WARM_RESET((byte) 6), TARGET_COLD_RESET((byte) 7), TASK_REASSIGN((byte) 8); private byte value; private static Map mapping; static { FunctionCode.mapping = new HashMap(); for (FunctionCode s : values()) { FunctionCode.mapping.put(s.value, s); } } private FunctionCode (final byte newValue) { value = newValue; } /** * Returns the value of this enumeration. * * @return The value of this enumeration. */ public final byte value () { return value; } /** * Returns the constant defined for the given value. * * @param value The value to search for. * @return The constant defined for the given value. Or null, if this value is not * defined by this enumeration. */ public static final FunctionCode valueOf (final byte value) { return FunctionCode.mapping.get(value); } } // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- /** The function code. */ private FunctionCode functionCode; /** The referenced task tag. */ private int referencedTaskTag; /** The referenced command sequence number. */ private int refCmdSN; /** The expected data sequence number. */ private int expDataSN; // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- /** * Default constructor, creates a new, empty TaskManagementFunctionRequestParser object. * * @param initProtocolDataUnit The reference ProtocolDataUnit instance, which contains this * TaskManagementFunctionRequestParser subclass object. */ public TaskManagementFunctionRequestParser (final ProtocolDataUnit initProtocolDataUnit) { super(initProtocolDataUnit); } // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- /** {@inheritDoc} */ @Override public final String toString () { final StringBuilder sb = new StringBuilder(Constants.LOG_INITIAL_SIZE); // Utils.printField(sb, "Function", functionCode.value(), 1); Utils.printField(sb, "LUN", logicalUnitNumber, 1); Utils.printField(sb, "Referenced Task Tag", referencedTaskTag, 1); sb.append(super.toString()); Utils.printField(sb, "RefCmdSN", refCmdSN, 1); Utils.printField(sb, "ExpDataSN", expDataSN, 1); return sb.toString(); } /** {@inheritDoc} */ @Override public final DataSegmentFormat getDataSegmentFormat () { return DataSegmentFormat.NONE; } /** {@inheritDoc} */ @Override public final void clear () { super.clear(); functionCode = FunctionCode.UNSET; referencedTaskTag = 0x00000000; refCmdSN = 0x00000000; expDataSN = 0x00000000; } // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- /** * For recovery purposes, the iSCSI target and initiator maintain a data acknowledgement reference number - the * first input DataSN number unacknowledged by the initiator. When issuing a new command, this number is set to * 0. If the function is TASK REASSIGN, which establishes a new connection allegiance for a previously * issued Read or Bidirectional command, ExpDataSN will contain an updated data acknowledgement * reference number or the value 0; the latter indicating that the data acknowledgement reference * number is unchanged. The initiator MUST discard any data PDUs from the previous execution that it did not * acknowledge and the target MUST transmit all Data-In PDUs (if any) starting with the data acknowledgement * reference number. The number of retransmitted PDUs may or may not be the same as the original transmission * depending on if there was a change in MaxRecvDataSegmentLength in the reassignment. The target MAY also send no * more Data-In PDUs if all data has been acknowledged. *

* The value of ExpDataSN MUST be 0 or higher than the DataSN of the last * acknowledged Data-In PDU, but not larger than DataSN+1 of the last Data-In PDU sent by the target. * Any other value MUST be ignored by the target. *

* For other functions this field is reserved. *

* * @return The expected data sequence number of this TaskManagementFunctionRequestParser object. */ public final int getExpDataSN () { return expDataSN; } /** * The Task Management functions provide an initiator with a way to explicitly control the execution of one or more * Tasks (SCSI and iSCSI tasks). The Task Management function codes are listed below. For a more detailed * description of SCSI task management, see [SAM2]. *

*

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function CodeDescription
1ABORT TASK - aborts the task identified by the Referenced Task Tag field.
2ABORT TASK SET - aborts all Tasks issued via this session on the logical unit.
3CLEAR ACA - clears the Auto Contingent Allegiance condition.
4CLEAR TASK SET - aborts all Tasks in the appropriate task set as defined by the TST field in the Control mode * page (see [SPC3]).
5LOGICAL UNIT RESET
6TARGET WARM RESET
7TARGET COLD RESET
8TASK REASSIGN - reassigns connection allegiance for the task identified by the Referenced Task Tag field to * this connection, thus resuming the iSCSI exchanges for the task.
*

* For all these functions, the Task Management function response MUST be returned as detailed in Section 10.6 Task * Management Function Response. All these functions apply to the referenced tasks regardless of whether they are * proper SCSI tasks or tagged iSCSI operations. Task management requests must act on all the commands from the same * session having a CmdSN lower than the task management CmdSN. LOGICAL UNIT RESET, TARGET WARM RESET and TARGET * COLD RESET may affect commands from other sessions or commands from the same session with CmdSN equal or * exceeding CmdSN. *

* If the task management request is marked for immediate delivery, it must be considered immediately for execution, * but the operations involved (all or part of them) may be postponed to allow the target to receive all relevant * tasks. According to [SAM2], for all the tasks covered by the Task Management response (i.e., with CmdSN lower * than the task management command CmdSN) but except the Task Management response to a TASK REASSIGN, additional * responses MUST NOT be delivered to the SCSI layer after the Task Management response. The iSCSI initiator MAY * deliver to the SCSI layer all responses received before the Task Management response (i.e., it is a matter of * implementation if the SCSI responses, received before the Task Management response but after the task management * request was issued, are delivered to the SCSI layer by the iSCSI layer in the initiator). The iSCSI target MUST * ensure that no responses for the tasks covered by a task management function are delivered to the iSCSI initiator * after the Task Management response except for a task covered by a TASK REASSIGN. *

* For ABORT TASK SET and CLEAR TASK SET, the issuing initiator MUST continue to respond to all valid target * transfer tags (received via R2T, Text Response, NOP-In, or SCSI Data-In PDUs) related to the affected task set, * even after issuing the task management request. The issuing initiator SHOULD however terminate (i.e., by setting * the F-bit to 1) these response sequences as quickly as possible. The target on its part MUST wait for responses * on all affected target transfer tags before acting on either of these two task management requests. In case all * or part of the response sequence is not received (due to digest errors) for a valid TTT, the target MAY treat it * as a case of within-command error recovery class (see Section 6.1.4.1 Recovery Within-command) if it is * supporting ErrorRecoveryLevel >= 1, or alternatively may drop the connection to complete the requested task set * function. *

* If an ABORT TASK is issued for a task created by an immediate command then RefCmdSN MUST be that of the Task * Management request itself (i.e., CmdSN and RefCmdSN are equal); otherwise RefCmdSN MUST be set to the CmdSN of * the task to be aborted (lower than CmdSN). *

* If the connection is still active (it is not undergoing an implicit or explicit logout), ABORT TASK MUST be * issued on the same connection to which the task to be aborted is allegiant at the time the Task Management * Request is issued. If the connection is implicitly or explicitly logged out (i.e., no other request will be * issued on the failing connection and no other response will be received on the failing connection), then an ABORT * TASK function request may be issued on another connection. This Task Management request will then establish a new * allegiance for the command to be aborted as well as abort it (i.e., the task to be aborted will not have to be * retried or reassigned, and its status, if issued but not acknowledged, will be reissued followed by the Task * Management response). *

* At the target an ABORT TASK function MUST NOT be executed on a Task Management request; such a request MUST * result in Task Management response of "Function rejected". *

* For the LOGICAL UNIT RESET function, the target MUST behave as dictated by the Logical Unit Reset function in * [SAM2]. *

* The implementation of the TARGET WARM RESET function and the TARGET COLD RESET function is OPTIONAL and when * implemented, should act as described below. The TARGET WARM RESET is also subject to SCSI access controls on the * requesting initiator as defined in [SPC3]. When authorization fails at the target, the appropriate response as * described in Section 10.6 Task Management Function Response MUST be returned by the target. The TARGET COLD RESET * function is not subject to SCSI access controls, but its execution privileges may be managed by iSCSI mechanisms * such as login authentication. *

* When executing the TARGET WARM RESET and TARGET COLD RESET functions, the target cancels all pending operations * on all Logical Units known by the issuing initiator. Both functions are equivalent to the Target Reset function * specified by [SAM2]. They can affect many other initiators logged in with the servicing SCSI target port. *

* The target MUST treat the TARGET COLD RESET function additionally as a power on event, thus terminating all of * its TCP connections to all initiators (all sessions are terminated). For this reason, the Service Response * (defined by [SAM2]) for this SCSI task management function may not be reliably delivered to the issuing initiator * port. For the TASK REASSIGN function, the target should reassign the connection allegiance to this new connection * (and thus resume iSCSI exchanges for the task). TASK REASSIGN MUST ONLY be received by the target after the * connection on which the command was previously executing has been successfully logged-out. The Task Management * response MUST be issued before the reassignment becomes effective. For additional usage semantics see Section 6.2 * Retry and Reassign in Recovery. *

* At the target a TASK REASSIGN function request MUST NOT be executed to reassign the connection allegiance of a * Task Management function request, an active text negotiation task, or a Logout task; such a request MUST result * in Task Management response of "Function rejected". *

* TASK REASSIGN MUST be issued as an immediate command. * * @return The function code of this TaskManagementFunctionRequestParser object. */ public final FunctionCode getFunction () { return functionCode; } /** * If an ABORT TASK is issued for a task created by an immediate command then RefCmdSN MUST be that of the Task * Management request itself (i.e., CmdSN and RefCmdSN are equal). *

* For an ABORT TASK of a task created by non-immediate command RefCmdSN MUST be set to the * CmdSN of the task identified by the Referenced Task Tag field. Targets must use this field as * described in section 10.6.1 when the task identified by the Referenced Task Tag field is not with the target. *

* Otherwise, this field is reserved. * * @return The referenced command sequence number of this TaskManagementFunctionRequestParser object. */ public final int getRefCmdSN () { return refCmdSN; } /** * The Initiator Task Tag of the task to be aborted for the ABORT TASK function or reassigned for the TASK REASSIGN * function. For all the other functions this field MUST be set to the reserved value 0xffffffff. * * @return The referenced task tag of this TaskManagementFunctionRequestParser object. */ public final int getReferencedTaskTag () { return referencedTaskTag; } // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- /** {@inheritDoc} */ @Override protected final void deserializeBytes1to3 (final int line) throws InternetSCSIException { functionCode = FunctionCode.valueOf((byte) (line & Constants.SECOND_BYTE_MASK)); Utils.isReserved(line & Constants.LAST_TWO_BYTES_MASK); } /** {@inheritDoc} */ @Override protected final void deserializeBytes20to23 (final int line) throws InternetSCSIException { referencedTaskTag = line; } /** {@inheritDoc} */ @Override protected final void deserializeBytes32to35 (final int line) throws InternetSCSIException { refCmdSN = line; } /** {@inheritDoc} */ @Override protected final void deserializeBytes36to39 (final int line) throws InternetSCSIException { expDataSN = line; } // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- /** {@inheritDoc} */ @Override protected final void checkIntegrity () throws InternetSCSIException { String exceptionMessage; do { BasicHeaderSegment bhs = protocolDataUnit.getBasicHeaderSegment(); if (bhs.getTotalAHSLength() != 0) { exceptionMessage = "TotalAHSLength must be 0!"; break; } if (bhs.getDataSegmentLength() != 0) { exceptionMessage = "DataSegmentLength must be 0!"; break; } if (functionCode != FunctionCode.ABORT_TASK && functionCode != FunctionCode.ABORT_TASK_SET && functionCode != FunctionCode.CLEAR_ACA) { Utils.isReserved(logicalUnitNumber); } // message is checked correctly return; } while (false); throw new InternetSCSIException(exceptionMessage); } // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- /** {@inheritDoc} */ @Override protected final int serializeBytes1to3 () { return functionCode.value() << Constants.TWO_BYTES_SHIFT; } /** {@inheritDoc} */ @Override protected final int serializeBytes20to23 () { return referencedTaskTag; } /** {@inheritDoc} */ @Override protected final int serializeBytes32to35 () { return refCmdSN; } /** {@inheritDoc} */ @Override protected final int serializeBytes36to39 () { return expDataSN; } // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy