STGT:target userspace utils
2013-10-30 18:42
183 查看
// tgt.h #ifndef __TGT_H__ #define __TGT_H__ #include <inttypes.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define TGT_IPC_ADDR "/var/run/tgtd.ipc_abstract_namespace" static int control_port=0; //defualt=3260 enum tgtadm_op { OP_NEW, //--op new OP_DELETE, //--op delete OP_SHOW, //--op show OP_BIND, //--op bind OP_UNBIND, //--op unbind OP_UPDATE, //--op update OP_STATS, //--op stat OP_START, //--op start OP_STOP, //--op stop }; enum tgtadm_mode { MODE_SYSTEM, // --mode system MODE_TARGET, // --mode target MODE_DEVICE, // --mode logicalunit MODE_PORTAL, // --mode portal MODE_LLD, // --mode lld MODE_SESSION, //--mode session MODE_CONNECTION,//--mode connection MODE_ACCOUNT, //--mode account }; enum tgtadm_errno { TGTADM_SUCCESS, TGTADM_UNKNOWN_ERR, TGTADM_NOMEM, TGTADM_NO_DRIVER, TGTADM_NO_TARGET, TGTADM_NO_LUN, TGTADM_NO_SESSION, TGTADM_NO_CONNECTION, TGTADM_NO_BINDING, TGTADM_TARGET_EXIST, TGTADM_LUN_EXIST, TGTADM_BINDING_EXIST, TGTADM_ACL_EXIST, TGTADM_ACL_NOEXIST, TGTADM_USER_EXIST, TGTADM_NO_USER, TGTADM_TOO_MANY_USER, TGTADM_INVALID_REQUEST, TGTADM_OUTACCOUNT_EXIST, TGTADM_TARGET_ACTIVE, TGTADM_LUN_ACTIVE, TGTADM_DRIVER_ACTIVE, TGTADM_UNSUPPORTED_OPERATION, TGTADM_UNKNOWN_PARAM, TGTADM_PREVENT_REMOVAL, }; typedef enum tgtadm_errno tgtadm_err; struct tgtadm_req { enum tgtadm_mode mode; enum tgtadm_op op; char lld[64]; uint32_t len; int32_t tid; uint64_t sid; uint64_t lun; uint32_t cid; uint32_t host_no; uint32_t device_type; uint32_t ac_dir; uint32_t pack; uint32_t force; }; struct tgtadm_rsp { uint32_t err; uint32_t len; }; struct concat_buf{ FILE *streamf; int err; int used; char *buf; size_t size; }; static const char *tgtadm_strerror(int err) { static const struct { enum tgtadm_errno err; char *desc; } errors[] = { { TGTADM_SUCCESS, "success" }, { TGTADM_UNKNOWN_ERR, "unknown error" }, { TGTADM_NOMEM, "out of memory" }, { TGTADM_NO_DRIVER, "can't find the driver" }, { TGTADM_NO_TARGET, "can't find the target" }, { TGTADM_NO_LUN, "can't find the logical unit" }, { TGTADM_NO_SESSION, "can't find the session" }, { TGTADM_NO_CONNECTION, "can't find the connection" }, { TGTADM_NO_BINDING, "can't find the binding" }, { TGTADM_TARGET_EXIST, "this target already exists" }, { TGTADM_BINDING_EXIST, "this binding already exists" }, { TGTADM_LUN_EXIST, "this logical unit number already exists" }, { TGTADM_ACL_EXIST, "this access control rule already exists" }, { TGTADM_ACL_NOEXIST, "this access control rule does not exist" }, { TGTADM_USER_EXIST, "this account already exists" }, { TGTADM_NO_USER, "can't find the account" }, { TGTADM_TOO_MANY_USER, "too many accounts" }, { TGTADM_INVALID_REQUEST, "invalid request" }, { TGTADM_OUTACCOUNT_EXIST, "this target already has an outgoing account" }, { TGTADM_TARGET_ACTIVE, "this target is still active" }, { TGTADM_LUN_ACTIVE, "this logical unit is still active" }, { TGTADM_DRIVER_ACTIVE, "this driver is busy" }, { TGTADM_UNSUPPORTED_OPERATION, "this operation isn't supported" }, { TGTADM_UNKNOWN_PARAM, "unknown parameter" }, { TGTADM_PREVENT_REMOVAL, "this device has Prevent Removal set" } }; int i; for (i = 0; i < ARRAY_SIZE(errors); ++i) if (errors[i].err == err) return errors[i].desc; return "(unknown tgtadm_errno)"; } #endif //tgt.c #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include "tgt.h" const char* LLD="iscsi"; void concat_buf_init(struct concat_buf *b){ b->streamf=open_memstream(&b->buf,&b->size); b->err=b->streamf?0:errno; b->used=0; } int concat_printf(struct concat_buf *b,const char*format,...){ va_list args; int nprinted; if(!b->err){ va_start(args,format); nprinted=vfprintf(b->streamf,format,args); if(nprinted>=0) b->used += nprinted; else{ b->err=nprinted; fclose(b->streamf); b->streamf =NULL; } va_end(args); } return b->err; } int concat_buf_finish(struct concat_buf *b){ if(b->streamf){ fclose(b->streamf); b->streamf=NULL; if(b->size) b->size++; //account for trailing NULL char } return b->err; } int concat_write(struct concat_buf *b, int fd, int offset) { concat_buf_finish(b); if (b->err) { errno = b->err; return -1; } if (b->size - offset > 0) return write(fd, b->buf + offset, b->size - offset); else { errno = EINVAL; return -1; } } void concat_buf_release(struct concat_buf *b) { concat_buf_finish(b); if (b->buf) { free(b->buf); memset(b, 0, sizeof(*b)); } } int tgt_mgmt_connect(int *fd){ int ret; struct sockaddr_un addr; char mgmt_path[256]; *fd = socket(AF_LOCAL, SOCK_STREAM, 0); if (*fd < 0) { printf("can't create a socket!\n"); return errno; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_LOCAL; sprintf(mgmt_path, "%s.%d", TGT_IPC_ADDR, control_port); strncpy(addr.sun_path, mgmt_path, sizeof(addr.sun_path)); ret = connect(*fd, (struct sockaddr *) &addr, sizeof(addr)); if (ret < 0) return errno; return 0; } int tgt_mgmt_rsp(int fd,struct tgtadm_req *req){ struct tgtadm_rsp rsp; int ret,rest,len; retry: ret=recv(fd,&rsp,sizeof(rsp),MSG_WAITALL); if(ret<0){ if(errno==EAGAIN) goto retry; else if(errno==EINTR) printf("interrupted by a signal!\n"); else printf("can't get the response!\n"); return errno; }else if(ret==0){ printf("tgtd closed the socket!\n"); return 0; }else if(ret!=sizeof(rsp)){ printf("a partial response!\n"); return 0; } if(rsp.err!=0){ printf("%s!\n",tgtadm_strerror(rsp.err)); return EINVAL; } rest=rsp.len-sizeof(rsp); if(!rest) return 0; while(rest){ char buf[4096]; memset(buf,0,sizeof(buf)); len=sizeof(buf)-1; len=(len<rest?len:rest); ret=read(fd,buf,len); if(ret<=0){ printf("\ncan't get the full response!\n"); return errno; } fputs(buf,stdout); rest-=len; } return 0; } int tgt_mgmt_req(struct tgtadm_req *req,struct concat_buf*b){ int ret,fd=0,done=0; req->len=sizeof(*req)+b->size; ret=tgt_mgmt_connect(&fd); if(ret<0){ printf("can't connect to tgt daemon !\n"); goto out; } ret=write(fd,req,sizeof(*req)); if(ret<0||ret!=sizeof(*req)){ printf("failed to send request hdr to tgt daemon!\n"); ret=errno; goto out; } while(done<b->size){ ret=concat_write(b,fd,done); if(ret>0) done+=ret; else if(errno!=EAGAIN){ printf("failed to send request buf to tgt daemon!\n"); ret=errno; goto out; } } printf("send to tgtd %d!\n",req->len); ret=tgt_mgmt_rsp(fd,req); out: if(fd>0) close(0); concat_buf_release(b); return ret; } int tgt_create_tgt(int tid,char *tgtname){ struct tgtadm_req adm_req={0},*req=&adm_req; struct concat_buf b; int ret; strcpy(req->lld,LLD);//default req->mode=1; //MODE_TARGET req->op=0; //OP_NEW req->tid=tid; req->sid=req->cid=req->host_no=0;//default req->lun=-1; //default req->device_type=0; //default TYPE_DISK req->ac_dir=0; //default 1=outgoing req->pack=0; //default req->force=0; //default 1=force concat_buf_init(&b); concat_printf(&b,"targetname=%s",tgtname); ret=concat_buf_finish(&b); if(ret){ printf("failed to create request,errno:%d\n",ret); exit(ret); } ret=tgt_mgmt_req(req,&b); return ret; } int tgt_delete_tgt(int tid){ struct tgtadm_req adm_req={0},*req=&adm_req; struct concat_buf b; int ret; strcpy(req->lld,LLD);//default req->mode=1; //MODE_TARGET req->op=1; //OP_DELETE req->tid=tid; req->sid=req->cid=req->host_no=0;//default req->lun=-1; //default req->device_type=req->ac_dir=req->pack=req->force=0; //default concat_buf_init(&b); ret=concat_buf_finish(&b); if(ret){ printf("failed to create request,errno:%d\n",ret); exit(ret); } ret=tgt_mgmt_req(req,&b); return ret; } int tgt_add_lun(int tid,int lunid,char *lunname){ struct tgtadm_req adm_req={0},*req=&adm_req; struct concat_buf b; int ret; strcpy(req->lld,LLD);//default req->mode=2; //MODE_DEVICE --mode logicalunit req->op=0; //OP_NEW req->tid=tid; req->sid=req->cid=req->host_no=0;//default req->lun=lunid; //default req->device_type=req->ac_dir=req->pack=req->force=0; //default concat_buf_init(&b); concat_printf(&b,"path=%s",lunname); ret=concat_buf_finish(&b); if(ret){ printf("failed to create request,errno:%d\n",ret); exit(ret); } ret=tgt_mgmt_req(req,&b); return ret; } int tgt_del_lun(int tid,int lunid){ struct tgtadm_req adm_req={0},*req=&adm_req; struct concat_buf b; int ret; strcpy(req->lld,LLD);//default req->mode=2; //MODE_DEVICE --mode logicalunit req->op=1; //OP_DELETE req->tid=tid; req->sid=req->cid=req->host_no=0;//default req->lun=lunid; //default req->device_type=req->ac_dir=req->pack=req->force=0; //default concat_buf_init(&b); ret=concat_buf_finish(&b); if(ret){ printf("failed to create request,errno:%d\n",ret); exit(ret); } ret=tgt_mgmt_req(req,&b); return ret; } int tgt_bind_initiator(int tid,int type,char*init_name){ struct tgtadm_req adm_req={0},*req=&adm_req; struct concat_buf b; int ret; strcpy(req->lld,LLD);//default req->mode=1; //MODE_TARGET req->op=3; //OP_BIND req->tid=tid; req->sid=req->cid=req->host_no=0;//default req->lun=-1; //default req->device_type=req->ac_dir=req->pack=req->force=0; //default concat_buf_init(&b); if(type==1){ concat_printf(&b,"initiator-address=%s",init_name); }else if(type==0){ concat_printf(&b,"initiator-name=%s",init_name); }else{ printf("type error: \n"); } ret=concat_buf_finish(&b); if(ret){ printf("failed to create request,errno:%d\n",ret); exit(ret); } ret=tgt_mgmt_req(req,&b); return ret; } int tgt_unbind_initiator(int tid,int type,char*init_name){ struct tgtadm_req adm_req={0},*req=&adm_req; struct concat_buf b; int ret; strcpy(req->lld,LLD); //default req->mode=1; //MODE_TARGET req->op=4; //OP_BIND req->tid=tid; req->sid=req->cid=req->host_no=0;//default req->lun=-1; //default req->device_type=req->ac_dir=req->pack=req->force=0; //default concat_buf_init(&b); if(type==1){ concat_printf(&b,"initiator-address=%s",init_name); }else if(type==0){ concat_printf(&b,"initiator-name=%s",init_name); }else{ printf("type error: \n"); } ret=concat_buf_finish(&b); if(ret){ printf("failed to create request,errno:%d\n",ret); exit(ret); } ret=tgt_mgmt_req(req,&b); return ret; } int tgt_show_tgt(int tid){ struct tgtadm_req adm_req={0},*req=&adm_req; struct concat_buf b; int ret; strcpy(req->lld,LLD); //default req->mode=1; //MODE_TARGET req->op=2; //OP_SHOW req->tid=tid?tid:-1; // 0=ALL req->sid=req->cid=req->host_no=0;//default req->lun=-1; //default req->device_type=req->ac_dir=req->pack=req->force=0; //default concat_buf_init(&b); ret=concat_buf_finish(&b); if(ret){ printf("failed to create request,errno:%d\n",ret); exit(ret); } ret=tgt_mgmt_req(req,&b); return ret; } int main(int argc,char*argv[]){ //tgt_show_tgt(0); //tgt_create_tgt(2,"guoming"); //tgt_add_lun(2,1,"/dev/sdb3"); //tgt_bind_initiator(1,1,"192.168.1.0/24"); //tgt_unbind_initiator(1,1,"ALL"); tgt_unbind_initiator(1,1,"192.168.1.180"); tgt_bind_initiator(1,0,"cgm88s"); //tgt_del_lun(2,1); //tgt_delete_tgt(2); }
相关文章推荐
- User space和Kernel space
- gpio Sysfs Interface for Userspace
- FUSE - implementing filesystems in user space
- 关于appfuseStruts2.0.1中AnnotationUtils.findAnnotation(User.class, Table.class) 报错问题
- Android.mk 移植示例--移植usbip userspace tools
- FUSE(Filesystem in userspace)(用户空间文件系统),user-space框架简单介绍
- java.lang.NoSuchMethodError: org.springframework.aop.framework.AopProxyUtils.getSingletonTarget
- GPIO Sysfs Interface for Userspace
- 添加Aop声明式事务处理java.lang.NoSuchMethodError: org.springframework.util.ClassUtils.isUserLevelMethod
- user-agent-utils - 用来解析User-Agent字符串的Java类库
- Linux 2.6.38 User-space interface for Crypto API
- tablespace user 数据文件表空间信息
- Kernel Space - User Space Interfaces_Mmap
- UserAgentUtils-1.13.jar
- user space to kernel space
- 『阿男的Linux内核世界』*12 Kernel Space和User Space*
- V4L2源代码之旅二:V4L2 sub-device userspace API
- createuserortablespace
- AR—如何在Unity中使用UserDefineTarget