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 ...
随机推荐
- Netty源码—10.Netty工具之时间轮
大纲 1.什么是时间轮 2.HashedWheelTimer是什么 3.HashedWheelTimer的使用 4.HashedWheelTimer的运行流程 5.HashedWheelTimer的核 ...
- study PostgreSQL【3-get数据库中all表以及表的字段信息】
get一表的字段相关信息: SELECT col_description(a.attrelid,a.attnum) as comment,pg_type.typname as typename,a.a ...
- 智能简历解析器实战教程:基于Spacy+Flask构建自动化人才筛选系统
一.项目背景与技术选型 在人力资源领域,每天需要处理数百份简历的HR团队面临巨大挑战:人工筛选效率低下.关键信息遗漏风险高.跨文档对比分析困难.本教程将构建一个端到端的智能简历解析系统,通过NLP技术 ...
- 1.4K star!几分钟搞定AI视频创作,这个开源神器让故事可视化如此简单!
嗨,大家好,我是小华同学,关注我们获得"最新.最全.最优质"开源项目和高效工作学习方法 story-flicks 是一个基于AI技术的自动化视频生成工具,能够将文字剧本快速转化为高 ...
- Sentinel——系统规则(系统自适应保护)
目录 系统自适应保护 系统规则 系统自适应保护 Sentinel 系统自适应保护从整体维度对应用入口流量进行控制,结合应用的 Load.总体平均 RT.入口 QPS 和线程数等几个维度的监控指标,让系 ...
- java代码中启动exe程序最简单的方法
使用awt的Desktop类的open方法: public static void startExe(String exePath){ try { if(StringUtils.isNotBlank( ...
- Gin RBAC 权限基础实现
RBAC (基于角色的访问控制) 是一种广泛应用的权限管理模型, 通过 角色 将 用户 和 权限 解耦, 简化权限分配管理. 用户 (User): 系统的使用者 权限 (Permission): 对资 ...
- Flex布局-子项
弹性盒子是一种用于 按行 或 按列的一维布局方法. 元素可以膨胀以填充额外的空间, 也可以 收缩 以适应更小的空间. flex 容器项重点 只是用表格进行排版而已, 横向内容无关联哈, 只是简要回忆一 ...
- Python模块的搜索路径
在Python中,模块搜索路径是指解释器用来查找导入模块的位置列表.了解和掌握Python模块搜索路径对于正确导入模块和管理模块的位置至关重要. Python模块搜索路径的主要来源包括当前目录.Pyt ...
- synchronized 锁是可重入锁吗?如何验证?
摘要:举例证明 synchronized锁 是可重入锁,并描述可重入锁的实现原理. 综述 先给大家一个结论:synchronized锁 是可重入锁! 关于什么是可重入锁,通俗来说,当线程请求一 ...