SCSI子系统的错误处理

由于 SCSI 底层驱动是由厂商自己实现的,在此就不予讨论。除此之外,SCSI 子系统的出错处理,主要是由 SCSI 中间层完成。在第一次回调过程中,SCSI 底层驱动将 SCSI 命令的处理结果以及获取的 SCSI 状态信息返回给 SCSI 中间层,SCSI 中间层先对 SCSI 底层驱动返回的 SCSI 命令执行的结果进行判断,若无法得到明确的结论,则对 SCSI 底层驱动返回的 SCSI 状态、感测数据等进行判断。对于判断结论为处理成功的 SCSI 命令,SCSI 中间层会直接进行第二次回调;对于判断结论为需要重试的命令,则会被加入块设备请求对列,重新被处理。这个过程可称为 SCSI 中间层对 SCSI 命令执行结果的基本判断方法。

一切看起来似乎是这么简单,但是实际上并非如此,有些错误是没有明确的判断依据的,如感测数据错误或 TIMEOUT 错误。为了解决这个问题,LINUX 内核中 SCSI 子系统引入了一个专门进行错误处理的线程,对于无法判断错误原因的 SCSI 命令,都会交由该线程进行处理。线程处理过程和两个队列密切相关,一个是错误处理队列eh_work_q),一个是错误处理完成队列 (done_q) 。错误处理队列记录了需要进行错误处理的 SCSI 命令,错误处理完成队列记录了在错误处理过程中被处理完成的 SCSI 命令。清单 5 显示了线程对错误处理队列上记录的命令进行错误处理的过程。

清单 5. 错误处理的过程

scsi_unjam_host{

……

if (!scsi_eh_get_sense(&eh_work_q, &eh_done_q))

//get sense data

if (!scsi_eh_abort_cmds(&eh_work_q, &eh_done_q))

//abort command

scsi_eh_ready_devs(shost, &eh_work_q, &eh_done_q);

//reset

scsi_eh_flush_done_q(&eh_done_q);

//complete error io on done_q

……

}

整个处理过程可归纳为四个阶段:

感测数据查询阶段

通过查询感测数据,为处理 SCSI 命令重新提供判断依据,并按照前述基本判断方法进行判断。如果判断结果为成功或者重试,则可将该命令从错误处理队列移到错误处理完成队列。若判断失败,则命令将会继续保留在 SCSI 错误处理队列中,错误处理进入到 ABORT 阶段。

ABORT阶段

在这个阶段中,错误处理队列上的 SCSI 命令会被主动 ABORT 掉。被 ABORT 的命令,会被加入到错误处理完成队列。若 ABORT 过程结束,错误处理队列上还存在未能被处理的命令,则需进入 START STOP UNIT 阶段进行处理。

START STOP UNIT阶段

在这个阶段,START STOP UNIT[6] 命令会被发送到与错误处理队列上的命令相关的 SCSI DEVICE 上,去试图恢复 SCSI DEVICE,如果在 START STOP UNIT 阶段结束后,依旧有命令在错误处理队列上,则需要进入 RESET 阶段进行处理。

RESET阶段

RESET 阶段的处理过程分三个层次:DEVICE RESET,BUS RESET 和 HOST RESET 。首先对与错误队列上的命令相关的 SCSI DEVICE,进行 RESET 操作,如果 DEVICE RESET 后,SCSI 设备能处于正常状态,则和该设备相关的错误处理队列上的错误命令,会被加入到错误处理完成队列中。若通过 DEVICE RESET 不能处理所有的错误命令,则需进入到 BUS RESET 阶段,BUS RESET 会对与错误处理队列上的命令相关的 BUS,进行 RESET 操作。若 BUS RESET 还不能成功处理所有错误处理队列上的 SCSI 命令,则会进入到 HOST RESET 阶段,HOST RESET 会对与错误处理队列上的命令相关的 HOST 进行 RESET 操作。当然,很有可能 HOST RESET 也不能成功处理所有错误命令,则只能认为错误处理队列上错误命令相关的 SCSI 设备不能被使用了。这些不能被使用的设备会被标记为不能使用状态,同时相关的错误命令都会被加入到错误处理完成队列中。

对于被加入到错误处理完成队列上的请求,若是在设备状态正确,命令重试次数小于允许次数的情况下,这些命令将被重新加入到块访问请求队列中,进行重新处理;否则,直接进行第二次回调处理,完成 SCSI 子系统对块访问请求的处理。这样,SCSI 子系统就完成了 SCSI 命令错误处理的整个过程。

结束语

本文浅析了 SCSI 子系统中的 IO 处理机制,希望对大家理解 SCSI 子系统和块设备驱动能有所帮助。


相关内容