前言

  去年公司设备(haisi3516)上需要提供iscsi的功能,于是花了几天时间探究了下。linux内核(2.6.xx)支持iscsi,只是我发现当时我们设备的内核编译时没有选上,于是重新编译了内核,以模块的形式加入即可。主要的驱动如下(加载的顺序很重要有依赖关系的):

iscsi整理

  下面是我收集总结的东西,希望对其他人有帮助(建议先在非嵌入式系统上做测试后...,那样简单些):

相关命令:

配置iscsi存储

[root@xifenfei ~]# iscsiadm -m discovery -t sendtargets -p 192.168.1.254:3260
[root@xifenfei ~]# iscsiadm -m node –T iqn.2006-01.com.openfiler:tsn.32b32087937b -p 192.168.1.254:3260 -l
[root@xifenfei ~]# iscsiadm -m node –T iqn.2006-01.com.openfiler:tsn.32b32087937b -p 192.168.1.254:3260
>--op update -n node.startup -v automatic

卸载iscsi存储

iscsiadm -m node --logoutall=all
iscsiadm -m node --op delete --targetname iqn.2006-01.com.openfiler:tsn.32b32087937b

增加iscsi存储

发现iscsi存储:iscsiadm -m discovery -t st -p ISCSI_IP
查看iscsi发现记录:iscsiadm -m node
登录iscsi存储:iscsiadm -m node -T LUN_NAME -p ISCSI_IP -l
开机自动: iscsiadm -m node –T LUN_NAME -p ISCSI_IP --op update -n node.startup -v automatic

删除iscsi存储

登出iscsi存储 iscsiadm -m node -T LUN_NAME -p ISCSI_IP -u
对出iscsi所有登录 iscsiadm -m node --logoutall=all
删除iscsi发现记录:iscsiadm -m node -o delete -T LUN_NAME -p ISCSI_IP

登入需验证码的节点

  1. 开启认证,*.使用-o同--op
iscsiadm -m node -T LUN_NAME -o update --name node.session.auth.authmethod --value=CHAP
  1. 添加用户
iscsiadm -m node -T LUN_NAME --op update --name node.session.auth.username --value=[用户名]

3. 添加密码

iscsiadm –m node –T LUN_NAME –op update –name node.session.auth.password –value=[密码]

参考: http://www.orasos.com/date/2012/06

查看当前会话

iscsiadm  -m session

下面是我写的一个简单的demo:



    头文件:
#ifndef __JISCSI_H_
#define __JISCSI_H_ typedef struct JISCSI_S {
char ip[32];
short port;
char target_name[512];
int bchap;
char username[512];
char userpass[64];
char discname[512];
char discpass[64];
}JISCSI_T; int jiscsi_init(char *name, int timeout);
int jiscsi_uninit(void);
int jiscsi_attach_target(JISCSI_T *stpJiscsi, int timeout);
int jiscsi_detach_target(JISCSI_T *stpJiscsi, int timeout); #endif /*__JISCSI_H_*/ c文件:
#include <stdio.h>
#include <string.h>
#include <stdlib.h> #include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <pthread.h> #include "jiscsi.h" #define ISCSI_LOGIN "iscsiadm -m node -T %s -p %s:%d -l 2>&1"
#define ISCSI_LOGOUT "iscsiadm -m node -T %s -p %s:%d -u 2>&1"
#define ISCSI_EN_CHAP "iscsiadm -m node -T %s --op update --name node.session.auth.authmethod --value=CHAP 2>&1"
#define ISCSI_ADD_USER "iscsiadm -m node -T %s --op update --name node.session.auth.username --value=%s 2>&1"
#define ISCSI_ADD_PASS "iscsiadm -m node -T %s --op update --name node.session.auth.password --value=%s 2>&1"
#define ISCSI_DISCOVERY_EX "iscsiadm -m discovery -t st -p %s:%d 2>&1 | cut -d ' ' -f 2"
#define ISCSI_DISCOVERY "iscsiadm -m discovery -t st -p %s:%d 2>&1"
#define ISCSI_SESSION_STATUS "iscsiadm -m session" static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; typedef struct {
char *cmd;
char *buf;
}ARG_T; enum JISCSI_RET {
SYSERR = -4,
TIMEOUT,
ARGV_INVALID,
FAILED,
SUCCESSED,
}; static void *do_work(void *arg)
{
ARG_T *stpArg = arg;
char *buf = stpArg->buf;
char *cmd = stpArg->cmd; pthread_detach(pthread_self()); /* pthread_mutex_lock(&mutex);*/ FILE *fp = popen(cmd, "r");
if (NULL == fp) {
perror("popen");
return NULL;
} fread(buf, 1, 1024, fp);
pclose(fp); pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex); pthread_exit(NULL);
} static int exec_cmd(char *cmd, char *findstr, int time)
{
if (NULL == cmd || NULL == findstr)
return ARGV_INVALID; char buf[1024];
ARG_T stArg = {.buf = buf, .cmd = cmd}; pthread_t tid;
pthread_mutex_lock(&mutex);
if (pthread_create(&tid, NULL, do_work, &stArg) < 0) {
perror("pthread_create");
return SYSERR;
} struct timeval now;
struct timespec timeout; gettimeofday(&now, NULL);
timeout.tv_sec = now.tv_sec+time;
timeout.tv_nsec= now.tv_usec; int ret = pthread_cond_timedwait(&cond, &mutex, &timeout);
if(ret == ETIMEDOUT) {
pthread_mutex_unlock(&mutex);
printf("timeout!!!\n");
return TIMEOUT;
} pthread_mutex_unlock(&mutex); if (NULL == strstr(buf, findstr))
return FAILED; memset(buf, 0, 1024); //? return SUCCESSED;
} static int jsystem(char *cmd)
{
int ret = -1;
int status = system(cmd);
if (-1 == status) {
ret = -1;
printf("error!!maybe fork failed...\n");
} else if (WIFEXITED(status)) {
ret = WEXITSTATUS(status);
printf("normal termination, exit status = %d\n", ret);
} else if (WIFSIGNALED(status)) {
ret = WEXITSTATUS(status);
printf("abnormal termination,signal number =%d\n", WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
ret = WEXITSTATUS(status);
printf("process stopped, signal number =%d\n", WSTOPSIG(status));
}
return ret;
} #define J_EXEC_CMD(cmd) do {int ret; if ((ret = jsystem(cmd)) != 0) return ret;}while(0)
/*void process_cfg_file()*/
/*{*/
/* J_EXEC_CMD("iscsiadm -m node -L all 2>&1"); */
/*}*/ static int jiscsi_set_own_name(char *name)
{
char cmd[1024]; sprintf(cmd, "sed -i 's/\(InitiatorName=\).*/\1%s/g' /etc/iscsi/initiatorname.iscsi", name);
return jsystem(cmd);
} int jiscsi_init(char *name, int timeout)
{
system("insmod crc32c.ko; insmod scsi_mod.ko; insmod scsi_transport_iscsi.ko; \
insmod libiscsi.ko; insmod libiscsi_tcp.ko; insmod iscsi_tcp.ko; insmod sd_mod.ko ");
system("mkdir /etc/iscsi 2>&1");
system("mkdir -p /var/lock/iscsi 2>&1");
system("cp iscsid.conf initiatorname.iscsi /etc/iscsi/ 2>&1");
system("ln -s `pwd`/iscsid /sbin/iscsid ");
system("ln -s `pwd`/iscsiadm /sbin/iscsiadm "); if (NULL != name)
jiscsi_set_own_name(name); system("iscsid &"); return exec_cmd("ps | grep iscsid | grep -v grep", "iscsid", timeout); /* int ret = exec_cmd("ps | grep iscsid | grep -v iscsid", "iscsid");*/
/* //read configuration file, and execute it */
/* process_cfg_file();*/
/* return ret;*/
} int jiscsi_uninit(void)
{
J_EXEC_CMD("iscsiadm -m node -U all 2>&1");
return SUCCESSED;
} static int get_target_names(char *ip, short port, char name_buf[], int buf_size)
{
char cmd[1024];
sprintf(cmd, ISCSI_DISCOVERY_EX, ip, port); FILE *fp = popen(cmd, "r");
if (NULL == fp) {
perror("popen");
return FAILED;
} fread(name_buf, 1, buf_size>2048?2048:buf_size, fp); /* printf("buf:%s\n", name_buf);*/
pclose(fp);
return SUCCESSED;
} static int check_target_is_valid(char *buf_names, char *target_name)
{
return strstr(buf_names, target_name) == NULL ? SUCCESSED:FAILED;
} int jiscsi_attach_target(JISCSI_T *stpJiscsi, int timeout)
{
if (NULL == stpJiscsi)
return ARGV_INVALID; char cmd[1024];
char buf_names[2048]; if (get_target_names(stpJiscsi->ip, stpJiscsi->port, buf_names, 2048) < 0)
return FAILED; if (!check_target_is_valid(buf_names, stpJiscsi->target_name))
return FAILED; if (stpJiscsi->bchap) {
sprintf(cmd, ISCSI_EN_CHAP, stpJiscsi->target_name);
J_EXEC_CMD(cmd);
sprintf(cmd, ISCSI_ADD_USER, stpJiscsi->target_name, stpJiscsi->username);
J_EXEC_CMD(cmd);
sprintf(cmd, ISCSI_ADD_PASS, stpJiscsi->target_name, stpJiscsi->userpass);
J_EXEC_CMD(cmd);
}
sprintf(cmd, ISCSI_LOGIN, stpJiscsi->target_name, stpJiscsi->ip, stpJiscsi->port);
/* printf("cmd:%s\n", cmd);*/
return exec_cmd(cmd, "success", timeout);
} int jiscsi_detach_target(JISCSI_T *stpJiscsi, int timeout)
{
if (NULL == stpJiscsi)
return ARGV_INVALID; char cmd[1024];
sprintf(cmd, ISCSI_LOGOUT, stpJiscsi->target_name, stpJiscsi->ip, stpJiscsi->port);
return exec_cmd(cmd, "success", timeout);
} //for test
void help(void)
{
printf( "-d: means discovery mode, depend -a [-p]\n" \
"-l: means login mode, depend -a [-p] [-T] -t\n" \
"-u: means logout mode, depend -a [-p] [-T] -t\n" \
"-i: means init iscsi\n" \
"-I: means uninit iscsi\n" \
"-a: means set ipaddr, need ip argument\n" \
"-p: means set port, need port argument, default is 3260\n" \
"-t: means set target name, need target name argument\n" \
"-T: means set timeout time(s), need timeout argument, default is 2s\n"\
"-c: means use chap, need username*password argument, eg -c jxj*123456\n"\
"-s: means display current iscsi status\n"); printf( "eg: init iscsi ./jiscsi -i\n"\
"eg: disp status ./jiscsi -s\n"\
"eg: discovery ./jiscsi -d -a xxx.xxx.xxx.xxx it will take back target_name\n"\
"target_name like: iqn.skysan.cn.com.bwstor:1343989129\n"\
"eg: login ./jiscsi -l -a xxx.xxx.xxx.xxx -t target_name\n"\
"eg: login ./jiscsi -u -a xxx.xxx.xxx.xxx -t target_name\n"); } int main(int argc, char *argv[])
{
int c;
int ret = -1;
int mode = 0, timeout = 2;
JISCSI_T stJiscsi = {.port = 3260}; //handle input
/* opterr = 0;*/
while(-1 != (c = getopt(argc, argv, ":dlup:a:t:T:hsc:iI"))) {
switch(c) {
case 'd':
mode = 1;
break;
case 'l':
mode = 2;
break;
case 'u':
mode = 3;
break;
case 'a':
printf("ipaddr:%s\n", optarg);
strcpy(stJiscsi.ip, optarg);
break;
case 'c':
printf("username*password:%s\n", optarg);
if (sscanf(optarg, "%[^\*]*%s", stJiscsi.username, stJiscsi.userpass) != 2) {
printf("argument is invalid!!!\n");
printf("-c: means use chap, need username*password argument, eg -c jxj*123456\n");
return -1;
}
/* printf("username%s password:%s\n", stJiscsi.username, stJiscsi.userpass);*/
stJiscsi.bchap = 1;
break;
case 'p':
printf("port:%s\n", optarg);
stJiscsi.port = atoi(optarg);
break;
case 't':
printf("target name:%s\n", optarg);
strcpy(stJiscsi.target_name, optarg);
break;
case 'T':
printf("time:%s\n", optarg);
timeout = atoi(optarg);
break;
case 's':
mode = 4;
break;
case 'i':
ret = jiscsi_init(NULL, 2);
printf("jiscsi_init ret: %d\n", ret);
return 0;
case 'I':
ret = jiscsi_uninit();
printf("jiscsi_uninit ret: %d\n", ret);
return 0;
case 'h':
help();
return 0;
case '?':
printf("invalid option \'%c\'\n", optopt);
return -1;
case ':':
printf(": option \'%c\' need argument\n", optopt);
return -1;
default:
printf("default invalid option \'%c\' ret:%d\n", optopt, c);
return -1;
}
} //execute
char cmd[1024];
switch(mode) {
case 1:
sprintf(cmd, ISCSI_DISCOVERY, stJiscsi.ip, stJiscsi.port);
J_EXEC_CMD(cmd);
break;
case 2:
ret = jiscsi_attach_target(&stJiscsi, timeout);
printf("jiscsi_attach_target ret:%d\n", ret);
break;
case 3:
ret = jiscsi_detach_target(&stJiscsi, timeout);
printf("jiscsi_detach_target ret:%d\n", ret);
break;
case 4:
J_EXEC_CMD(ISCSI_SESSION_STATUS);
break;
default:
printf("argument is invalid\n");
help();
return -1;
} return 0;
/* JISCSI_T stJiscsi1 = {.ip = "192.168.1.251", .port = 3260, */
/* .target_name = "iqn.2012-11.com.example:storage.sdb1", .bchap = 1, */
/* .username = "rongp", .userpass = "123456abcdef"}; */
/**/
/* JISCSI_T stJiscsi2 = {.ip = "192.168.1.251", .port = 3260, */
/* .target_name = "iqn.2012-11.com.example:storage.sdb2", .bchap = 0, */
/* .username = "", .userpass = ""}; */
/**/
/* JISCSI_T stJiscsi3 = {.ip = "192.168.1.251", .port = 3260, */
/* .target_name = "iqn.2012-11.com.example:storage.sdb3", .bchap = 0, */
/* .username = "", .userpass = ""}; */
/*#if 0*/
/* int ret = jiscsi_attach_target(&stJiscsi1, 1);*/
/* printf("ret :%d\n", ret);*/
/* ret = jiscsi_attach_target(&stJiscsi2, 1);*/
/* printf("ret :%d\n", ret);*/
/* ret = jiscsi_attach_target(&stJiscsi3, 1);*/
/* printf("ret :%d\n", ret);*/
/*#else */
/* jiscsi_detach_target(&stJiscsi1, 1);*/
/* jiscsi_detach_target(&stJiscsi2, 1);*/
/* jiscsi_detach_target(&stJiscsi3, 1);*/
/*#endif*/
}

完!

2013年8月

嵌入式上 iscsi实现的更多相关文章

  1. Windows Server上iSCSI的Best Practices

    Installing and Configuring Microsoft iSCSI Initiator http://technet.microsoft.com/en-us/library/ee33 ...

  2. FFMPEG在嵌入式硬件上应用之 —— 基本环境搭建及编译

    前段时间在翻看电脑里面资料时,发现了以前做的在嵌入式硬件上面运行以ffmepg为基础,以嵌入式硬件解码的多媒体播放工作,发现都快忘记完了.今日得闲整理温习了一下ffmpeg在嵌入式上的运用,这里给大家 ...

  3. Ice-E(Embedded Internet Communications Engine)移植到s3c2440A(arm9)linux(2.6.12)上的

    2009-03-26 18:31:31 原文链接 1.前言 ICE-E是ICE在嵌入式上运行的一个版本,与ICE比较如下: Category Ice 3.3.0 Ice-E 1.3.0 Thread ...

  4. 嵌入式web服务器

    要实现在PC上通过网页控制连接到嵌入式开发板的相机. 限于开发板的环境,不能选择appche等大型web服务器,选择了boa. 要想pc端跨平台,那就不能用ActiveX控件,如果仅在windows平 ...

  5. 在腾讯云上创建您的SQL Cluster(3)

    版权声明:本文由李斯达原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/250 来源:腾云阁 https://www.qclo ...

  6. 作为一个新人,怎样学习嵌入式Linux,(韦东山)

    很早以前在网上看到的韦东山老师写的文章,复制到自己的博客,方便自己以后看. 在学习嵌入式Linux之前,肯定要有C语言基础.汇编基础有没有无所谓(就那么几条汇编指令,用到了一看就会). C语言要学到什 ...

  7. Qt 框架的图形性能高(OpenGL上的系统效率高),网络性能低,开发效率高,Quick是可以走硬件加速——Qt中分为好几套图形系统,差不多代表了2D描画的发展史。最经典的软描画系统

    -----图形性能部分-----Qt的widgets部分,运行时的图像渲染性能是一般的,因为大部分的界面内容都是Qt自绘,没有走硬件加速,也就是说很多图形内容都是CPU算出来的.但是widgets底层 ...

  8. 作为一个新人,如何学习嵌入式Linux?

    作为一个新人.如何学习嵌入式Linux?我一直在问太多次,特写文章来回答这个问题. 在学习嵌入式Linux之前.肯定要有C语言基础.汇编基础有没有无所谓(就那么几条汇编指令,用到了一看就会).C语言要 ...

  9. 作为一个新人,怎样学习嵌入式Linux

    作为一个新人,怎样学习嵌入式Linux?被问过太多次,特写这篇文章来回答一下. 在学习嵌入式Linux之前,肯定要有C语言基础.汇编基础有没有无所谓(就那么几条汇编指令,用到了一看就会). C语言要学 ...

随机推荐

  1. Linux-Ps命令使用

    ps -ef | grep java ps aux | grep java ps aux 是用BSD的格式来显示Java进程 显示的项目有: USER        PID %CPU %MEM    ...

  2. 第十六篇 Python之迭代器与生成器

    一.迭代器 一. 递归和迭代 生活实例说明什么是递归和迭代 A想去腾达大厦,问B怎么走路,B 说我不知道,我给你问问C,C也不知道,C又去问D,D知道,把路告诉了C,C又告诉B,B最后告诉A, 这就是 ...

  3. (原创)像极了爱情的详解排序二叉树,一秒get

    排序二叉树(建立.查找.删除) 二叉树我们已经非常熟悉了,但是除了寻常的储存数据.遍历结构,我们还能用二叉树做什么呢? 我们都知道不同的遍历方式会对相同的树中产生不同的序列结果,排序二叉树就是利用二叉 ...

  4. The Erdös-Straus Conjecture 题解

    题面 Description The Brocard Erdös-Straus conjecture is that for any integern > 2 , there are posit ...

  5. Visual Studio 2003安装包

    点击下载

  6. [译]在Python中如何使用额enumerate 和 zip 来迭代两个列表和它们的index?

    enumerate - 迭代一个列表的index和item <Python Cookbook>(Recipe 4.4)描述了如何使用enumerate迭代item和index. 例子如下: ...

  7. jquery UI 跟随学习笔记——拖拽(Draggable)

    引言 这周暂时没有任务下达,所以老大给我的任务就是熟悉jquery相关插件,我就先选择了jquery UI插件,以及jquery库学习. 我用了两天的时候熟悉Interactions模块中的Dragg ...

  8. android桌面悬浮窗仿QQ手机管家加速效果

    主要还是用到了WindowManager对桌面悬浮进行管理. 需要一个火箭的悬浮窗 一个发射台悬浮窗  ,判断火箭是否放到了发射台,如果放上了,则使用AsyTask 慢慢将火箭的图片往上移.结束后., ...

  9. spring环境搭建(简单实例)

    1使用Maven导入需要的依赖(在project标签下) <properties> <spring_version>3.2.2.RELEASE</spring_versi ...

  10. clientHeight & clientWidth & offsetHeight & offsetWidth & outerWidth & innerWidth & outerWidth & outerHeight

    clientHeight & clientWidth & offsetHeight & offsetWidth MDN https://developer.mozilla.or ...