博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何利用procfs读取iSCSI Initiator IQN信息
阅读量:5758 次
发布时间:2019-06-18

本文共 3561 字,大约阅读时间需要 11 分钟。

在基于iSCSI构建的IP SAN系统中,为了便于targetd端对initiator进行访问权限管理和存储资源分配,有的客户通常需要尽可能早地得到initiatorIQN名称乃至其IP信息。常用的target管理工具targetadm虽然可以记录initiator登陆后的IQN名称和IP信息,但是它不能早在discovery session就发现initiatorIQN名称。虽然iSNS可以得到局域网范围内所有的iSCSI设备的名称,但是它配置比较复杂,为此可以考虑在iSCSI驱动中discovery session的时候就尽快拿到initiatorIQN。为此,我们需要找到合适的代码位置,然后用合适的接口把从内核驱动中得到的IQN信息告诉给用户。

阅读iSCSI驱动中的代码,不难找到discovery session的时候执行的代码,在iscsi_target_nego.c中的login nego函数中。类Unix系统设计中体现了一种良好的抽象哲学,就是几乎所有的数据实体都被抽象成一个统一的接口--文件,这样一些简单的基本工具就能完成大量复杂的操作。在Linux中也继承了这类特殊的伪文件系统,用于使用与文件接口统一的操作来完成各种功能,例如sysfsconfigfsprocfs。这些接口可以考虑用来实现我们的功能。

Sysfs

sysfs把设备驱动和总线根据其拓扑信息映射到文件系统,,它是Linux 2.6所提供的一种虚拟文件系统。这个文件系统不仅可以把装置(devices)和驱动程式(drivers)的资讯从kernel space输出到user space,也可以用来对装置和驱动程式做设定。

sysfs的目的是把一些原本在procfs中的,关于装置的部份独立出来,以[装置阶层架构}(device tree)的形式呈现。它把实际连接到系统上的设备和总线组织成一个分级的文件,用户空间的程序同样可以利用这些信息以实现和内核的交互。由于我的需求只是简单输出一个IQN信息,不影响也不涉及device tree,因此不采用这种接口。

Configfs

configfs是一种基于ram的伪文件系统,支持在用户空间通过目录文件访问接口配置内核对象。例如修改或者显示内核设置,更改一些开关等配置信息,适用于内核对象有众多复杂的配置。比如内核需要很多参数需要配置时,或者需要动态创建内核对象并且内核对象需要修改配置;此时用户可以写shell脚本就可以直接配置configfs。一个简单的configfs的结构实现步骤如下:

1.加入一个item;

2.定义show和 store操作;(show是向user space更新消息,用来显示内核或驱动的设置;store是从用户态王内核态输入并保存信息,用来更改内核或驱动设置)

3.相关的重要的数据结构:

顶层结构是struct configfs_subsystem,为configfs子系统结构,接着是struct config_group,是configfs目录和属性的容器,struct config_itemconfigfs目录,代表可配置的内核对象,struct configfs_attribute是目录下面的属性。

可见configfs还是比较复杂,特别是考虑到我的需求只是从驱动中读会一个信息,不涉及修改任何内核变量或者配置,因此也不考虑用这个接口。

Procfs

procfs是最早的伪文件系统,作为Linux内核信息的抽象文件接口,常常用来动态显示或者控制内核或驱动的信息。内核中的信息以及可调参数都被作为常规文件映射到一个目录树中,这样通过echocat之类的文件操作命令对系统信息进行查取和调整了。同时procfs也提供了一个接口,使得我们自己的内核模块或用户态程序可以通过procfs进行参数的传递。考虑到我们从内核驱动中得到IQN的需求,以及procfs的简单易用性,我们刚好可以用proc接口来查取IQN信息了。

Procfs依赖的头文件

同用户态编程一样,为了利用procfs接口,我们不需要从头到尾重新设计和实现procfs的所有细节,应该尽可能地用内核procfs模块业已提供的函数接口。在3.10.0的内核中,这些接口函数定义在linux source code目录下:include/linux/proc_fs.h

Procfs API

查看proc_fs.h,可以看到它提供了丰富的接口来快速实现procfs:

IQN Procfs的实现

在了解procfs的主要接口后,我们可以参考其他驱动中的procfs的实现,比如drivers/scsi/scsi_devinfo.cprocfs的实现,或者driver/char/rtc.c中的下面代码来实现自己的iqn procfs

static const struct file_operations rtc_proc_fops = {

.owner      = THIS_MODULE,

.open       = rtc_proc_open,

.read       = seq_read,

.llseek     = seq_lseek,

.release    = single_release,

};

实现读取IQNprocfs主要的步骤如下:

1.在模块初始化的时候调用proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent,const struct file_operations *proc_fops)来创建/proc下的端点;

2.定义并实现读取initiator IQN必需的file_operations

static const struct file_operations iscsi_iqn_get_fops = {

.owner      = THIS_MODULE,

.open       = proc_iscsi_iqninfo_open,

.read       = proc_iscsi_iqninfo_read,

.write      = NULL,

.llseek     = NULL,

.release    = NULL,

};

3.在模块卸载的时候实现exit操作,释放资源,当设备退出或者驱动removed的时候调用下面的函数:remove_proc_entry("scsi/device_info", NULL);

4.在新的discovery session 认证过程中,记录当前initiatorIQN,为了便于管理所有的IQN,可以把它们组织成list

5.代码开发完功能验证完成后,可以参考下面的步骤进行部署:

编译和手动加载:

cd /root/linux-3.10.0-229.el7/drivers/target/iscsi;

make -C /lib/modules/3.10.0-229.el7.x86_64/build M=`pwd` modules

cp iscsi_target_mod.ko /lib/modules/3.10.0-229.el7.x86_64/kernel/drivers/target/iscsi

modprobe iscsi_target_mod -f

设置开机自动加载更新:

update /etc/sysconfig/modules/ls.modules

添加iscsi_target_mod的安装:

[root@localhost modules]# tail ls.modules

/sbin/modinfo -F filename iscsi_target_mod  > /dev/null 2>&1
if [ $? -eq 0 ]; then
        /sbin/modprobe iscsi_target_mod -f
fi

参考链接:

1.http://blog.csdn.net/liumangxiong/article/details/12154865

2.http://www.linuxidc.com/Linux/2014-01/95688.htm

3.http://blog.csdn.net/liumangxiong/article/details/12154865

4.http://blog.csdn.net/cjsycyl/article/details/13091951

本文转自存储之厨51CTO博客,原文链接:http://blog.51cto.com/xiamachao/1856761 ,如需转载请自行联系原作者

你可能感兴趣的文章
phpcms v9 csdn老手记录
查看>>
C++调用C#库简单例程
查看>>
实验三+018+李滨
查看>>
react 楼层按需加载 @loadable/component
查看>>
express 与 mvc
查看>>
设计模式基础
查看>>
Leetcode c语言-Container With Most Water
查看>>
Ubuntu 服务器443端口证书配置
查看>>
usaco Arithmetic Progressions
查看>>
使用记事本编写java程序并编译
查看>>
iOS 推送
查看>>
pta l3-20(至多删三个字符)
查看>>
没事写写css
查看>>
web.coofig 配置跨域问题
查看>>
将不确定变成确定~frameset页面不能正确加载
查看>>
springboot + kafka
查看>>
leetcode House Robber
查看>>
(最新)各大公司Java后端开发面试题总结
查看>>
CSS——NO.6(盒模型)
查看>>
初识设计模式(1)---单例、工厂、注册树
查看>>