Re: sg driver and the error handler

Douglas Gilbert
2005-05-11T11:59:25Z

Patrick Mansfield wrote:
> Hi Alan -
>
> On Tue, May 10, 2005 at 02:51:44PM -0400, Alan Stern wrote:
>
>>When a command injected through the sg driver encounters any sort of
>>error, the usual retry mechanism and error handler are brought into play.
>>Since sg sets the number of retries to 0 by default, the retry mechanism
>>shouldn't cause any difficulty. But the error handler does. IMO it
>>should never get involved with requests coming through sg -- sg should
>>provide access that is as transparent as possible so that userspace
>>programs will have a clean shot at managing their device.
>
>
> The error handler is mainly a timeout handler, so it has to run to cancel
> the timed out command, we can't complete the timed out command back to the
> upper level until we know the HBA is no longer using it.
>
>
>>Consider a case that just came up. A USB CD drive causes a phase error
>>when it receives a certain READ BUFFER command (buggy firmware on the
>>drive, never mind that now). You would expect the user program to receive
>>from sg a host_status value indicating DID_ERROR or something of the sort.
>>
>>Instead the error handler takes charge and sends out one or two TEST UNIT
>>READY commands. The status information finally received by the user
>>program is the status from the TEST UNIT READY, not from the failed READ
>>BUFFER! How's a program supposed to cope with that sort of obfuscation?
>
>
> :-(

Writing and maintaining a clean SCSI command pass-through in a
block-centric environment has not been easy. It often feels
like a one step forward and two steps back process :-)

In my recent "sense descriptor format" changes I did
unclutter some SG_IO error return paths, mainly for usages
via block device nodes (e.g. /dev/sda).

As ever, handling errors sanely is not easy. It also runs the
risk of tripping up some hardware.

>>Something in the SCSI stack (scsi_io_completion ?) should check for
>>requests coming in via sg and should know to complete the requests
>>immediately. No requeuing and no error handling.

The sg driver does not currently call scsi_io_completion().
In the mid level you can see code like:
if (blk_pc_request(scsi_cmnd->request))
pass-through
else
block-injected [almost always a READ or WRITE]

I think the "_pc_" stands for packet command. Maybe we need more
instances of this.

>>Does this sound like a feasible thing to implement?
>
>
> No per above. I think there are still some cases where sg or SG_IO
> commands are not immediately returned, I think for some certain ASC codes,
> some of those probably should be retried, as should cases like QUEUE FULL.
>
> As you say, what you really want is the correct result going back to the
> user, not the result of the TUR.
>
> So save and restore the result in scsi_eh_tur, and also in scsi_eh_try_stu.
> The request sense one already saves and restores it.
>
> And always set result |= (DRIVER_TIMEOUT << 24) if we are not requeueing
> the IO.
>
> Like (only compile tested) this, against scsi-misc git tree of a few days
> ago. Hopefully, sg or SG_IO programs can handle DRIVER_TIMEOUT :-/ but it
> is certainly better than returning as if no error occurred.

sg3_utils error processing first decodes SCSI status and sense data.
Then if any of the other bits in "result" are set, then it comments
on them.

<snip>
Patch looks fine. Perhaps Alan could try some utility from sg3_utils
in the problem environment once Patrick's patch has been applied.
The sg_dd utility now has a "verbose=<n>" option where <n>=1 should
decode any SCSI status (including DID and DRIVER) errors received.

Doug Gilbert