如何利用procfs读取iSCSI Initiator IQN信息

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

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

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_item是configfs目录,代表可配置的内核对象,struct
configfs_attribute是目录下面的属性。

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

Procfs

procfs是最早的伪文件系统,作为Linux内核信息的抽象文件接口,常常用来动态显示或者控制内核或驱动的信息。内核中的信息以及可调参数都被作为常规文件映射到一个目录树中,这样通过echo或cat之类的文件操作命令对系统信息进行查取和调整了。同时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.c中procfs的实现,或者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,

};

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

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 认证过程中,记录当前initiator的IQN,为了便于管理所有的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的安装:

[[email protected]
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

时间: 2024-12-10 13:55:32

如何利用procfs读取iSCSI Initiator IQN信息的相关文章

iscsi initiator端Note

iscsi initiator端    (1)安装open-scsi      sudo  apt-get install open-iscsi open-iscsi-utils     (2)发现iscsi target      sudo iscsiadm -m discovery -t sendtargets -p 192.168.35.17      显示信息如下:      192.168.35.17:3260,1 iqn.2013-02.node2    (3)使用target   

Ubuntu 下iscsi initiator的安装与使用

Ubuntu下比较方便好用的initiator是open iscsi,这里将要简要介绍它的使用方法: 1.安装: sudo apt-get install open-iscsi 2.chap设置 如果ip-san上设置了chap(没有设置chap的话,可以略去这一步),则要修改/etc/iscsi/iscsid.conf,找到以下内容,去掉前面的#,然后将用户名.密码改为san上设置好的密码 node.session.auth.authmethod = CHAPnode.session.auth

利用XPath读取Xml文件

之所以要引入XPath的概念,目的就是为了在匹配XML文档结构树时能够准确地找到某一个节点元素.可以把XPath比作文件管理路径:通过文件管理路 径,可以按照一定的规则查找到所需要的文件:同样,依据XPath所制定的规则,也可以很方便地找到XML结构文档树中的任何一个节点. 不过,由于XPath可应用于不止一个的标准,因此W3C将其独立出来作为XSLT的配套标准颁布,它是XSLT以及我们后面要讲到的XPointer的重要组成部分. 在介绍XPath的匹配规则之前,我们先来看一些有关XPath的基

vbs读取文件内的信息将非有效数据移动到指定路径

vbs读取文件内的信息将非有效数据移动到指定路径 之前我们介绍了,通过读取文件内的信息将相同的数据拷贝到指定目录,执行后我们可以利用有效的信息,但是时间长的话服务器上的可用空间也会越来越多,所以再次就想通过vbs脚本来判断数据是否有用,来提高服务器的可用空间. 思路是这样的,通过从domino目录下导出有效的数据,然后通过本地的数据盘进行比对,将无效的数据库移动到其他盘操作,如果在不影响数据完整性的情况下在做删除,那如何操作呢,首先是定义一个xlsx文件(1.xlss),文件可以任意命名,但是需

iscsi initiator 配置

###iSCSI initiator 配置 1. Linux下iscsi initiator 安装: 在OracleLinux-R6-U4-Server-x86_64-dvd.iso中,找到匹配该系统的iscsi initiator版本iscsi-initiator-utils- 6.2.0.873-2.0.1.el6.x86_64.rpm: 通过rpm -ivh 安装 2. 启动iscsi服务 cd /etc/init.d ./iscsi start chkconfig iscsi on 3.

利用OpenXml读取、导出Excel

OpenXml是通过 XML 文档提供行集视图.由于OPENXML 是行集提供程序,因此可在会出现行集提供程序(如表.视图或 OPENROWSET 函数)的 Transact-SQL 语句中使用 OPENXML. 效果图: 使用它的时候,首选的下载安装这个程序集,下载地址:http://www.microsoft.com/en-us/download/details.aspx?id=30425 安装好了在项目当中引用如下2个 前台弹出框用的是 jBox这个js插件,我用了ajax请求的方式来上传

JAVA基础-输入输出:1.编写TextRw.java的Java应用程序,程序完成的功能是:首先向TextRw.txt中写入自己的学号和姓名,读取TextRw.txt中信息并将其显示在屏幕上。

1.编写TextRw.java的Java应用程序,程序完成的功能是:首先向TextRw.txt中写入自己的学号和姓名,读取TextRw.txt中信息并将其显示在屏幕上. package Test03; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOExceptio

JAVA 读取计算机中相关信息

java读取 计算机 cup号 读取版本 显卡 ................. package com.swt.common.util; import java.io.BufferedReader; import java.io.File; import java.io.FileWriter; import java.io.InputStreamReader; import java.io.LineNumberReader; /** * 获取硬件信息 * @author luoxf * */

GOEXIF读取和写入EXIF信息

能够读取和写入EXIF信息,使得图像处理程序在不改变原有图片内容.不添加多余文件的情况下可以保存参数信息,非常有价值. 这方面中英文资料比较少,经过较长时间的研究和集成,我在网络相关资料的基础上完成了GOEXIF,实现了MFC上的直接读取和写入. 读取 EXIFINFO m_exifinfo;FILE* hFile=fopen(FilePathName.c_str(),"rb");if (hFile){memset(&m_exifinfo,0,sizeof(EXIFINFO))