tgt源码阅读
读懂一个开源项目源码之前,需要先了解该项目的背景知识。背景知识熟悉了,代码只是具体实现手段而已。
源码地址: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源码阅读的更多相关文章
- cas服务器源码阅读笔记,对标博客
对标源码阅读博客:http://www.cnblogs.com/jiuzhongguo/category/375405.html 在CAS中很多地方使用了策略模式,那么根据什么方式来确定使用哪种策略呢 ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
- 【原】FMDB源码阅读(一)
[原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...
- 【原】AFNetworking源码阅读(六)
[原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...
- 【原】AFNetworking源码阅读(五)
[原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...
- 【原】AFNetworking源码阅读(四)
[原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...
- 【原】AFNetworking源码阅读(三)
[原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...
- 【原】AFNetworking源码阅读(二)
[原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...
- 【原】AFNetworking源码阅读(一)
[原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...
随机推荐
- SpringSecurity5(10-动态权限管理)
授权流程 SpringSecurity 的授权流程如下: 拦截请求,已认证用户访问受保护的 web 资源将被 SecurityFilterChain 中的 FilterSecurityIntercep ...
- 当Kafka化身抽水马桶:论组件并发提升与系统可用性的量子纠缠关系
<当Kafka化身抽水马桶:论组件并发提升与系统可用性的量子纠缠关系> 引言:一场OOM引发的血案 某个月黑风高的夜晚,监控系统突然发出刺耳的警报--我们的数据发现流水线集体扑街.事后复盘 ...
- 客户端“自废武功”背后的深层秘密——CORS跨域是怎么回事?
客户端"自废武功"背后的深层秘密--CORS跨域是怎么回事? 嘿,对于刚入门的开发新手,你是不是曾经遇到过这样的情况:你正在愉快地开发一个 Web 应用,代码写得热火朝天,前后端配 ...
- AI穿上身:苹果手表如何改变你的生活?
楔子:一个普通理工男的科技启示录 我是张三,一个标准的90后理工男.在这个日新月异的科技时代,我习惯用精密的逻辑和近乎机械的效率来审视世界.每天早上6点45分准时起床,每一分钟都被精确地规划,生活就像 ...
- DFS 2025/1/15
DFS & DFS 剪枝优化 Basic 01 先搜节点少的分支 如果搜进来一个大分支而答案不在此分支就会浪费大量时间 02 可行性剪枝 已经白扯了就 return 判断当前是否合法 03 最 ...
- Sql语句:数据操作
数据操作,核心是:增删改查. 其中查与增删改不同,要返回数据集,其他的只要知道是否修改成功即可,所以一般调用时,返回值不同,这点要注意. 一.查询: select sname,sdept,sage f ...
- 新建一个空的 ASP.NET Core Web Application
前言 Visual Studio 2017 下操作 1. 新建项目 2. 新建空的 ASP.NET Core Web Application 确定后,需要一小点的时间等待依赖库载入... 3. 新建完 ...
- 调用dll中form,太古老了,可是
太古老了,可是用的不多.应该考虑商品化项目首选. library Prj_dll; { Important note about DLL memory management: ShareMem mus ...
- 多线程,Join()
一.定义:就是该线程是指的主线程等待子线程的终止.也就是在子线程调用了join()方法,后面的代码,只有等到子线程结束了才能执行 二.不加join: class Thread1 extends Thr ...
- 🎀B站-网页优化插件BewlyBewly
简介 一个开源的B站网页优化浏览器插件,对B站网页进行了调整和优化,页面更具视觉吸引力和用户友好性. 源码 https://github.com/BewlyBewly/BewlyBewly 支持 插件 ...