读懂一个开源项目源码之前,需要先了解该项目的背景知识。背景知识熟悉了,代码只是具体实现手段而已。

源码地址:https://github.com/fujita/tgt

对于tgt来说,背景知识是块设备、scsi、iscsi协议。

众所周知,一条协议一般指的是一个包头,然后把要收发的数据放在包头后面。scsi协议和iscsi协议也如此。

对于tcp/ip协议、http协议,包头能在书中或网上找到,每个字段的含义都非常明确。

1.iscsi协议头一般是跟在tcp包头后面,而iscsi协议的包体就是scsi协议。

2.iscsi协议头和scsi协议头和tcp头部一样,都是二进制格式。但是scsi协议并不是对称的。就是request和response的内容不一样。

3.scsi request报文通常被叫做CDB(主要包含一个opcode表示是读操作还是写操作或者其他)。response叫做status code,如果status code == 0,表示request成功。如果status code == 2,表示后面还要回复一个叫做sense data的response给客户端,指示客户端下一步做什么。

scsi协议只需要看opcode,头部内其他字段都是根据不同的opcode,而代表不同的含义,例如scsi opcode是读操作时:

这只是scsi请求,而scsi响应则是:

若status为2,则还会发一个sense response:

4.iscsi报文比较简单,一个报文叫做一个PDU,一个PDU由iscsi头部和包体组成,头部包含一个字段opcode字段,外加一些可选的key-value,包体就是scsi协议。正真读写的数据则是在scsi协议包体内。

注意,scsi协议头也有opcode,iscsi协议头也有opcode,但是他们不是同一个字段。

scsi的op code,表示本次请求是读/写/获取设备信息等等

iscsi的op code,表示的是本次操作是登录认证/协商会话信息/传输scsi指令等等

总之,关于scsi和iscsi具体协议,版本比较多,opcode也很多,不需要了解所有opcode,因为大部分都用不到。只需要了解几个主要的opcode就行了。

了解完了协议,再来看一下iscsi的架构:

这是一个网络块设备协议,其中有一些架构概念需要了解:

1.scsi和iscsi都是C/S架构

2.scsi设备是插在电脑IO总线上的,内核会给scsi设备分配一个总线ID。

3.这个总线ID下面最多能插16个设备,其中第一个是控制器(虚拟的),所以真实可用的是15个,每一个都会分配一个target ID。

4.每个target就是一个硬盘,一个target又可以做分区,最多分为32个分区,其中第一个是控制器(虚拟的),所以真实可以用的是31个分区,分区被叫做lun(逻辑单元)。

5.客户端叫做initiator,也会有一个initiator ID,用来区分C/S架构里的唯一Client。

这些是scsi协议的背景知识,当然,有scsi协议的时候还没有iscsi协议。所以scsi协议是本机内核与硬盘通信的协议。所以scsi协议是没有认证登录相关协议的,

把scsi协议套上一个iscsi头和tcp/ip头后,这套协议就可以在网络中运行。也不再是内核和硬盘的C/S架构,而是一台客户机和另一台服务器的C/S架构。target、lun这些概念仍然保留,但不再是表示硬盘和分区了。target仅仅代表一个网络地址,lun可以代表一个块设备,这个块设备的后端存储可以是硬盘,也可以是ceph rbd 等。而客户端作为initiator,一般就是请求挂载一个lun。

另外,由于是网络协议,所以iscsi有登录认证相关的协议。

tgtd作为iscsi协议的服务端,首先,它的主线程采用了epoll_wait,来监听3260端口,并把所有连接过来的tcp链接都放到这个epoll内收发数据。tgtd启动后,main函数会堵塞在event_loop函数内。

在进入event_loop之前,各种类型的后端存储都会注册到后端存储表里。当用户使用tgtadm来创建一个lun时,就会根据用户指定的bstype参数来选择该类型的后端存储:aio,rdwr,rbd等,例如rbd引擎的注册:

有一个叫做global_target的全局变量,

当用户使用tgtadm创建target时,就会创建一个struct target对象,并把它插入到下面链表中:

当用户创建lun时,也会在target对象中的device_list中插入一个struct scsi_lu对象。

这个树状结构的数据结构(target list),就是tgtd要维护在内存里的数据主体,每个target是一个网络地址,它包含很多东西:

多个lun,每个lun对应一个后端块设备,包含对应的后端设备处理函数集,scsi指令最终会调用这个指令来完成

多个session(每个session是一个initiator)

每个session可以有多个connect(tcp link)

在connect和session里面,还包含了本次通信的请求和回复报文,收发数据缓冲区,scsi请求队列,还有当前会话的登录状态、scsi指令执行的状态等等。

总之,顺着全局target list往下看,能看到服务端的整个全景图。

tgt源码阅读的更多相关文章

  1. cas服务器源码阅读笔记,对标博客

    对标源码阅读博客:http://www.cnblogs.com/jiuzhongguo/category/375405.html 在CAS中很多地方使用了策略模式,那么根据什么方式来确定使用哪种策略呢 ...

  2. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  3. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

  4. 【原】FMDB源码阅读(一)

    [原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...

  5. 【原】AFNetworking源码阅读(六)

    [原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...

  6. 【原】AFNetworking源码阅读(五)

    [原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...

  7. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

  8. 【原】AFNetworking源码阅读(三)

    [原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...

  9. 【原】AFNetworking源码阅读(二)

    [原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...

  10. 【原】AFNetworking源码阅读(一)

    [原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...

随机推荐

  1. ShadowSql之借Dapper打通ORM最后一公里

    ShadowSql专职拼写sql,要想做为ORM就需要借高人之手 我们要借的就是Dapper,Dapper以高性能著称,ShadowSql搭配Dapper就是强强联手 为此本项目内置了一个子项目Dap ...

  2. .NET周刊【3月第5期 2025-03-30】

    国内文章 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp智能体框架开发语音交互 https://www.cnblogs.com/GreenShad ...

  3. 异步编程与Tortoise-ORM框架

    title: 异步编程与Tortoise-ORM框架 date: 2025/04/19 00:13:05 updated: 2025/04/19 00:13:05 author: cmdragon e ...

  4. layui动态渲染select表单、初始化默认值、change事件监听等

    layui动态渲染,初始化默认值 var html = ''; html += '<select name="" lay-search lay-verify="re ...

  5. Nacos简介—3.Nacos的配置简介

    大纲 1.Nacos生产集群Web端口与数据库配置 2.Nacos生产集群的Distro协议核心参数 3.Nacos打通CMDB实现跨机房的就近访问 4.Nacos基于SPI动态扩展机制来获取CMDB ...

  6. Python3正则表达式(一)

    Python3正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. r ...

  7. IDEA问题之“MyBatis插件安装【MyBatisX】”

    一.场景 在SSM框架中带有XML文件的查找很是麻烦,特别是在ID命名有大量重复时 而这个插件就可以,让你直接从Service实现类中直接跳到XML中 还有些其他功能,可以探索探索 一.配置步骤 1. ...

  8. python开发Streamable HTTP MCP应用

    一.概述 使用python开发,最好的框架是fastmcp,github连接:https://github.com/jlowin/fastmcp 2025 年 5 月 9 日,fastmcp发布v2. ...

  9. VS2019 配置libzmq-4.3.1

    1.下载libzmq-4.3.1 https://github.com/zeromq/libzmq/tags 2.解压并查看 3.编译 使用vs2019对其进行编译,点击libzmq.sln进入工程环 ...

  10. VS2019 配置 protobuf3.8.0

    1.下载protobuf3.8.0 https://github.com/protocolbuffers/protobuf/releases/tag/v3.8.0 2.准备工作 解压文件并在同级目录建 ...