tgt是用户态实现的iscsi target,而iet(iscsi enterprise target)是在内核态实现的target,tgt相比于iet来说,因为其用户态实现,方便调试,新加入一些功能等,不过性能相比iet来说要稍差一点。下面就介绍一下tgt的程序框架(略过iscsi协议解析处理部分),以便于整体把握tgt的代码,方便后续的一些修改。

1.整体框架

这里借用tgt官网给出的一张图。

tgt中命令的操作,与initiator端的通信都是通过epoll来实现的,下面分别对这两部分进行说明。

1.1 tgtadm与tgtd的交互

在启动tgtd进程的时候,就会初始化一个unix socket,将该fd加到epoll中,监听EPOLLIN事件,后续每执行一条tgtadm命令,就会使用这个unix socket来和tgtd通信。

如图所示,当在命令行里敲一条tgtadm命令时,通过unix socket发起请求,就会触发epoll 的EPOLLIN事件,tgtd端accept,将连接fd加到epoll中,并注册回调函数mtask_recv_send_handler,返回连接建立的响应给tgtadm端,然后tgtadm命令触发EPOLLIN事件,tgtd端调用mtask_recv_send_handler,根据不同的mode调用不同的处理函数进行处理(这里有sys_mgmt/target_mgmt/portal_mgmt等),处理完后,将事件改为EPOLLIN|EPOLLOUT,然后发送响应给tgtadm端。

1.2 initiator与tgtd的交互

tgtd进程在启动的时候就会创建一个socket,用于监听initiator的请求(具体是iscsi_tcp_init_portal函数中的处理),将该socket加到epoll中,注册回调函数accept_connection。 initiator端的请求到来时,将新连接的fd加到epoll中,并注册回调函数iscsi_tcp_event_handler,然后当收到EPOLLIN事件时,会调用iscsi_rx_handler进行iscsi请求的一些解析处理操作,并调用backing store的接口进行io的操作,操作完成后,修改事件为EPOLLLOUT,就会触发调用到iscsi_tx_handler来发送响应给initiator。

1.3 函数调用栈

下面给出了iscsi_rx_handler的一些函数调用栈关系,其中涉及到与backing store中io处理接口的调用关系。给出下图作为参考。

2. backing store

tgt支持多种后端存储,比如rdwr,aio,sg,rbd,sheepdog等,默认的是rdwr,可以指定flag(O_SYNC|O_DIRECT)。了解清楚tgt的后端存储的处理模式,就可以添加新的后端存储用于支持自定义的功能。

其中主要的接口就是bs_open,bs_init,bs_cmd_submit,bs_close,bs_exit。 bs_open和bs_init就是做创建lun时的一些初始化操作,比如打开设备文件,创建处理现线程,注册处理回调函数等。 bs_cmd_submit:io请求到来时就会调用该函数进行处理。 bs_close和bs_exit就是删除lun的时候做一些销毁操作。 BS中支持同步和异步io两种模式(rdwr就是同步的,aio就是异步的),下面分别介绍这两种模式。

2.1 同步io

在同步io中,每个lun都会对应一个请求队列(pending_list),在bs_init时就会创建多个线程(目前新版本一个lun默认16个线程)。新请求到来时,调用bs_cmd_submit将请求添加到pending_list中,多个线程共享这个pending_list,分别从pending_list中取请求来进行处理。当没有请求时,这些线程就会等待在pending_list上,有新请求加入到pending_lsit后,就会唤醒等待的线程来进行处理。

2.2 异步io(aio)

tgt使用的是linux native aio来实现的,使用eventfd创建的fd将aio上下文和epoll联系起来。(具体可以参考aio与epoll结合起来如何使用的一些资料)。下面是一些具体的处理逻辑。

1)bs_aio_open:io_setup建立异步io上下文,然后afd=eventfd() ,将afd加到epoll中(回调函数bs_aio_get_completions) ,并且afd与aio的上下文关联。

2)bs_aio_cmd_submit:IO到来时调用,先把请求加到cmd_wait_list中,然后遍历list,确定此次能提交的io数并初始化iocb(因为限制了aio的最大处理个数为128,有些io还在处理中,当前提交的aio个数就有限),然后使用io_submit提交一批异步io。

3)IO处理完后,会通过afd触发EPOLLIN事件,调用回调函数bs_aio_get_completions进行处理,先read出当前完成的io数,然后调用io_getevents()获取出已完成io的信息,然后对每个完成的io调用bs_aio_comlete_one做一些结束的处理(修改处理状态),在这个函数中调用target_cmd_io_done,在target_cmd_io_done中会修改epoll的事件为EPOLLIN|EPOLLOUT,这样就会触发了EPOLLOUT事件,调用iscsi_tcp_event_handler,在这个函数里判断如果是EPOLLOUT,就会调用iscsi_tx_handler来发送响应。

3. 参考资料

http://stgt.sourceforge.net/ 
http://www.lenky.info/archives/2013/01/2183

转载:

http://www.sysnote.org/?p=170

iscsi target tgt架构的更多相关文章

  1. CentOS7 下安装 iSCSI Target(tgt) ,使用 Ceph rbd

    目录 一.iSCSI 介绍 1. iSCSI 定义 2. 几种常见的 iSCSI Target 3. 优缺点比较 二.安装步骤 1. 关闭防火墙 2. 关闭selinux 3. 通过 yum 安装 t ...

  2. iscsi target IET架构

    IET(iSCSI Enterprise Target)是内核态实现的iscsi target,相比于用户态实现的target(比如tgt),iet比较稳定,并且也算是历史悠久,io都直接经过内核态, ...

  3. iscsi介绍及iscsi target配置

    iSCSI 主要是透过 TCP/IP 的技术,将储存设备端透过 iSCSI target (iSCSI 目标) 功能,做成可以提供磁盘的服务器端,再透过 iSCSI initiator (iSCSI ...

  4. ISCSI target的两种安装方法

    1 tgt程序架构 tgt是用户态实现的iscsi target,而iet(iscsi enterprise target)是在内核态实现的target,tgt相比于iet来说,因为其用户态实现,方便 ...

  5. Linux tgtadm: Setup iSCSI Target ( SAN )

    Linux target framework (tgt) aims to simplify various SCSI target driver (iSCSI, Fibre Channel, SRP, ...

  6. iscsi target 之LIO配置

    LIO 配置 现在主流Linux都可以设置iSCSI,如STGT/TGT.LIO Target等.Linux-IO(LIO)Target是当前Linux标准的iSCSI target的开源实现,包含在 ...

  7. iscsi target 研究

    一.概述 目前 Linux 上主要有三个 iSCSI Target 实现: Linux SCSI Target – STGT / tgt     Linux-IO Target – LIO SCST ...

  8. 在 iSCSI Target 服务器中使用LVM创建和设置LUN(二)

    LUN是逻辑单元号,它与iSCSI存储服务器共享.iSCSI 目标器通过TCP/IP网络共享它的物理驱动器给发起程序(initiator).这些来自一个大型存储(SAN:Storage Area Ne ...

  9. 使用iSCSI Target创建集中式安全存储(一)

    iSCSI 是一种块级别的协议,用于通过TCP/IP网络共享原始存储设备,可以用已经存在的IP和以太网如网卡.交换机.路由器等通过iSCSI协议共享和访问存储.iSCSI target是一种由远程iS ...

随机推荐

  1. Python 基于python实现的http接口自动化测试框架(含源码)

    基于python实现的http+json协议接口自动化测试框架(含源码) by:授客 QQ:1033553122      欢迎加入软件性能测试交流 QQ群:7156436  由于篇幅问题,采用百度网 ...

  2. Android系统启动流程(四)Launcher启动过程与系统启动流程

    此前的文章我们学习了init进程.Zygote进程和SyetemServer进程的启动过程,这一篇文章我们就来学习Android系统启动流程的最后一步:Launcher的启动流程,并结合本系列的前三篇 ...

  3. java基础(十一) 枚举类型

    枚举类型Enum的简介 1.什么是枚举类型 枚举类型: 就是由一组具有名的值的有限集合组成新的类型.(即新的类). 好像还是不懂,别急,咱们先来看一下 为什么要引入枚举类型 在没有引入枚举类型前,当我 ...

  4. LeetCode 题解之Rotate List

    1.题目描述 2.题目分析 首先数出链表中的元素个数count,然后对k = k % count 求余数.接着将链表形成一个环,从最后一个元素开始,运动 count - k  步,此时节点的下一个节点 ...

  5. centos7 安装 jdk1.8

    首先是Linux的不同版本的额系统自带的配置是不一样的,比如centos6上有的自带的jdk环境的话要装1.8的就要进行卸载或者马上进行更改 jdk是java程序依赖的环境 首先查看你的系统下是否有j ...

  6. python 多进程和子进程1

    多进程的缓冲区 #多进程 process.py from multiprocessing import Process,current_process import time def func1(): ...

  7. [IDEA_4] IDEA 从 GitHub 上 pull 项目到本地

    0. 说明 通过参考的链接我们已经知道了怎么安装配置 Git  .GitHub ,如何使用 IDEA 将本地项目上传到 GitHub. 现在是学习怎么通过 IDEA 将项目从 GitHub pull ...

  8. 乘风破浪:LeetCode真题_022_Generate Parentheses

    乘风破浪:LeetCode真题_022_Generate Parentheses 一.前言 关于括号的题目,我们已经遇到过了验证正确性的题目,现在让我们生成合法的括号列表,怎么办呢?想来想去还是递归比 ...

  9. [ML学习笔记] 朴素贝叶斯算法(Naive Bayesian)

    [ML学习笔记] 朴素贝叶斯算法(Naive Bayesian) 贝叶斯公式 \[P(A\mid B) = \frac{P(B\mid A)P(A)}{P(B)}\] 我们把P(A)称为"先 ...

  10. 4、url控制系统

    第1节:简单配置 参考代码: from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/ ...