11.1. /proc/scsi/sg/debug

本附录解释了来自/proc/scsi/sg/debug的输出,通常通过命令 cat /proc/scsi/sg/debug 查看。下面是当命令:sgp_dd if=/dev/sg0 of=/dev/null bs=512 在系统上执行时(略微简化的)输出。该 sgp_dd 命令正在使用命令队列读取磁盘(并且数据被写入到/dev/null它会将其丢弃)。
$ cat /proc/scsi/sg/debug
dev_max(currently)=7 max_active_device=1 (origin 1)
 scsi_dma_free_sectors=416 sg_pool_secs_aval=320 def_reserved_size=32768
 >>> device=sg0 scsi0 chan=0 id=0 lun=0   em=0 sg_tablesize=255 excl=0
   FD(1): timeout=60000ms bufflen=65536 (res)sgat=2 low_dma=0
   cmd_q=1 f_packid=1 k_orphan=0 closed=0
     fin: id=3949312 blen=65536 dur=10ms sgat=2 op=0x28
     act: id=3949440 blen=65536 t_o/elap=60000/10ms sgat=2 op=0x28
     rb>> act: id=3949568 blen=65536 t_o/elap=60000/10ms sgat=2 op=0x28
     act: id=3949696 blen=65536 t_o/elap=60000/0ms sgat=2 op=0x28
上面输出的那些对用户应用程序重要的项将在下面描述。

总的来说,上面的输出显示一切运行良好。四个针对不同 id 的 SCSI READ(10) 命令(SCSI 操作码 0x28)正在进行中。三个命令处于活动状态,而一个命令已完成其状态和数据 read() 操作,并且请求结构正在等待删除。“id” 对应于 sg_io_hdr 结构(或 sg_header 结构)中给出的 pack_id。在 sgp_dd 的情况下,pack_id 值是提供给 SCSI READ(或 WRITE)的块号。您会注意到这 4 个 id 相隔 128。

“>>>” 行显示 sg 设备名,后跟 Linux SCSI 适配器、通道、SCSI ID 和 LUN 号。“em=” 参数指示驱动程序是否模拟 SCSI HBA。ide-scsi 驱动程序会设置 “em=1”。“sg_tablesize” 是适配器驱动程序支持的最大散射/聚集元素数量。“excl=0” 指示当前没有 sg open() 在此设备上使用 O_EXCL 标志。

以 “FD(1)” 开头的接下来两行提供了关于第一个(在本例中是唯一的)打开的文件描述符的数据,该文件描述符位于/dev/sg0。默认超时为 60 秒,但这仅在使用 sg_header 接口时才重要,因为 sg_io_hdr 接口显式地为每个命令设置超时。“bufflen=65536” 是此文件描述符的保留缓冲区大小。“(res)sgat=2” 指示此保留缓冲区需要 2 个散射/聚集元素。“low_dma” 对于 ISA HBA 将设置为 1,指示只有 RAM 的底部 16 MB 可用于其内核缓冲区。“cmd_q=1” 指示允许命令队列。“f_packid=1” 指示 SG_SET_FORCE_PACK_ID 模式已开启。“k_orphan” 值在极少数情况下为 1,即当 SG_IO 在 SCSI 命令 “正在进行中” 时被中断时。“closed” 值在极少数情况下为 1,即当文件描述符在 SCSI 命令 “正在进行中” 时被关闭时。

每个缩进 5 个空格的行表示一个 SCSI 命令。命令的状态可以是

这些状态可以选择以 “rb>>” 为前缀,表示正在使用保留缓冲区;以 “dio>>” 为前缀,表示此命令正在使用直接 IO;或以 “mmap>>” 为前缀,表示此命令正在使用 mmap 映射的 IO。“id” 是来自此命令接口结构的 pack_id。“blen” 是与此命令关联的数据传输使用的缓冲区长度。对于已收到响应的命令,“dur” 显示其持续时间(毫秒)。对于仍在 “正在进行中” 的命令,“t_o/elap=60000/10ms” 表示此命令的超时时间为 60000 毫秒,其中 10 毫秒已经过去。“sgat=2” 参数指示此命令的 “blen” 需要 2 个散射/聚集元素。“op” 值是正在执行的 SCSI 命令的十六进制值。

如果 sg 有大量活动,则 “debug” 输出可能会跨越多行,并且在某些情况下看起来像是损坏的。发生这种情况是因为 procfs 请求固定缓冲区大小的信息,并且如果有更多数据要输出,则稍后返回以获取剩余部分。这种策略的问题是 sg 的内部状态可能已经改变。sg 驱动程序没有使用双缓冲,而是从相同的偏移量继续。虽然 procfs 非常有用,但 ioctl()(例如 SG_GET_REQUEST_TABLE)仍然有其地位。