前言

  去年公司设备(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. Kotlin操作符重载:把标准操作加入到任何类中(KAD 17)

    作者:Antonio Leiva 时间:Mar 21, 2017 原文链接:https://antonioleiva.com/operator-overload-kotlin/ 就像其他每种语言一样, ...

  2. const char and static const char

    部分内容摘自:https://blog.csdn.net/ranhui_xia/article/details/32696669 The version with const char * will ...

  3. Ubuntu 常见错误及解决方法——长期不定时更新

    1. 修复 /etc/sudoers 文件损坏导致不能使用 sudo 命令 这是之前错误地编辑了 /etc/sudoers 这个文件导致的,因此撤销编辑即可,但由于已经不能使用 sudo 命令,因此不 ...

  4. 【转】 The user specified as a definer ('root'@'') does not exist when using LOCK TALBE

    在linux下,用mysql的导出语句: mysqldump -u root -pPasswd table >/home/lsf/test.sql 出现了 Got error: 1449: Th ...

  5. [剑指Offer] 23.二叉搜索树的后序遍历

    [思路]BST的后序序列的合法序列是,对于一个序列S,最后一个元素是x (也就是根),如果去掉最后一个元素的序列为T,那么T满足:T可以分成两段,前一段(左子树)小于x,后一段(右子树)大于x,且这两 ...

  6. BZOJ4361 isn(动态规划+树状数组+容斥原理)

    首先dp出长度为i的不下降子序列个数,显然这可以树状数组做到O(n2logn). 考虑最后剩下的序列是什么,如果不管是否合法只是将序列删至只剩i个数,那么方案数显然是f[i]*(n-i)!.如果不合法 ...

  7. [BZOJ3196][Tyvj1730]二逼平衡树

    [BZOJ3196][Tyvj1730]二逼平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询 \(k\) 在区间内的排名 查询区间内排名为 \ ...

  8. BZOJ 2820: YY的GCD | 数论

    题目: 题解: http://hzwer.com/6142.html #include<cstdio> #include<algorithm> #define N 100000 ...

  9. BZOJ 题解continue

    1041 圆上的整点 暴力枚举 会超时 这道题很像之前一次noip模拟题(当时的我还太水了(虽然现在也很水)) x2+y2=R2 考虑变型 x2=(R+y)(R-y) int d=gcd(R,y) i ...

  10. 【BZOJ 1724】[Usaco2006 Nov]Fence Repair 切割木板 堆+贪心

    堆对于stl priority_queue ,我们自己定义的类自己重载<,对于非自定义类我们默认大根堆,如若改成小根堆则写成std::priority<int,vector<int& ...