-
-
Notifications
You must be signed in to change notification settings - Fork 89
Exception-based SCSI error handling #795
Description
This ticket results from #769, which is hard to resolve without improving the SCSI error handling in general.
There is a general issue with how the error handling is organized between controllers and devices, and as we see from this particularly propagating errors is an issue.
Setting of the SCSI error codes is currently done in various places in the Disk class and derived classes. Error codes are set on various call hierarchy levels, either directly or indirectly like in our case, triggered by some function return values. If a function returns an error code one of the callers in the hierarchy is responsible for taking the right action, i.e. setting the SCSI error code and/or returning a flag indicating that there was an error, or at least ensuring that no further code is executed.
By introducing an exception that signals SCSI errors with their Sense Key and ASC we could simplify the error handling in the Disk and drived classes. In case of an error this exception can be caught in the PrimaryDevice::Dispatch() method, and in this method controller->Error() is called with the values propagated by the exception. The caller can be sure that if a method returns there was no error.
This would also simplify code constructs like this, which you find quite a lot:
void PrimaryDevice::TestUnitReady(SASIDEV *controller)
{
if (!CheckReady()) {
controller->Error();
return;
}
controller->Status();
}
would essentially become
void PrimaryDevice::TestUnitReady(SASIDEV *controller)
{
CheckReady();
controller->Status();
}
because CheckReady() throws an exception in case of an error. In some cases it might even be possible to not explicitly request the status phase.
This change is probably done best as part of a PR related to #729, because the fact that SASIDEV * instead of SCSIDEV * is passed to SCSI-related (and not SASI-related) methods also causes various issues.