Linux Scsi子系统框架介绍( 二 )

  • channel和id对scsi而言没有实质意义 , 因此linuxscsi子系统创造了一个target的概念 , 如下图:
  •  
    Linux Scsi子系统框架介绍

    文章插图
     
    • 上面的图用不同的颜色画出了三个target , target的名字是host编号 , channel编号和id编号组合命名 , 因此上面三个target的名字分别是(k:0:0)(k:0:1) (k:0:...) 。以此类推 , 这张图后面还可以框出更多的target 。注意channel编号和id编号是底层驱动自行管理的 , 而host编号(也就是前k)则是linux scsi子系统自行管理(参看static DEFINE_IDA(host_index_ida)(drivers/scsi/host.c)
    • 引入target概念后 , 每个device内部可以看成被分为被多个target , 每个target下面接着多个lun 。硬件拓扑图可以画成下面的样子:

    Linux Scsi子系统框架介绍

    文章插图
     
    其中channel(0)_id(0)到channel(m)_id(n)就是target(k:0:0)到target(k:m:n) 。
    4. lun
    • 每个target下面挂接着多个lun 。
    • lun是能够接收scsi命令的主体 。例如可以是一个物理硬盘 , 一个光驱;对ufs而言是ufs固件虚拟出来的rpmb , boot0 , boot1;也有一些lun不是物理实体但是能接收scsi命令 , 也被看作为lun , 例如report luns可以响应scsi report luns command返回设备lun总数等信息 。因此软件上每个lun在linux的通用块设备层都有独享的一个request queue 。注意下 , 有时候一个硬盘通过GPT或者MBR分为多个逻辑分区;它们是一个lun里面 , 共用一个request queue 。关于逻辑分区 , 不在linux scsi子系统中处理 , 这里不深究 。
    • 注意每个lun都从host对应的物理总线通路发送和接收数据 。这个也涉及到通用块设备层的配置 , 后面会讲
    二、Linux scsi子系统软件模型接下来会基于linux设备驱动模型描述scsi子系统的框图 。看到这里的小伙伴接下来需要有linux设备驱动模型的基础知识背景了 。
    由于linux scsi子系统代码庞大 , 直接说代码 , 会把人绕进去 , 这里会通过linux设备驱动模型中的bus , class , device框图来描述linux scsi子系统框架 , 后面会结合框架 , 指出子系统中的关键代码和位置 。
    1.图示说明 
    Linux Scsi子系统框架介绍

    文章插图
     
    后面的图中会使用到上面的各种颜色和图形 , 这里描述了这些信息的含义 。这些信息都是linux软件层面的含义 。
    2.主要bus和class图示中有三个主要的bus和class , 分别是左边的”scsi” , 右边的”scsi_host” , 和下边的”scsi_device”
    它们三个构成了scsi的主体范围 。也就是下面三个很粗的双向箭头包裹的区域 。
    Linux Scsi子系统框架介绍

    文章插图
     
    简单介绍:
    ”scsi” bus:所有host , target , lun都有对应的structdevice放在这上面;通用的scsi的磁盘驱动”sd” , 光盘驱动”sr” , 磁带驱动”osst”等驱动也在这个bus上面 , 这些驱动通过struct device被激活 。
    “scsi_host” class: host有对应的device寄存在这上面 , 通过host的structdevice的attr(group,type)获取到控制器的属性 。例如可以通过这上面的scan触发系统做对整个host做scan动作 。
    “scsi_device” class:所有lun的对应的structdevice寄存在这上面 。操作它们的驱动是sg.c 。
     
    下面详细说明
    3. Host,target,lun设备建模(1) host(0-k)
    • Scsi子系统内部针对每个host控制器在linux子系统内部创建两个structdevice结构体:sdhost_dev和shost_gendev 。
     
    Linux Scsi子系统框架介绍

    文章插图
     
    • sdhost_dev寄存”scsi_host” class上面 , 并通过attr显示一些host相关的属性 。
     
    Linux Scsi子系统框架介绍

    文章插图
     
    • shost_gendev则挂在“scsi”bus上面 。“scsi” bus的match函数(scsi_bus_match)不允许shost_gendev有driver对应 。所以目前只有一些attribute可以在用户空间使用 。
     
    Linux Scsi子系统框架介绍


    推荐阅读