⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iscsi_client.c

📁 一个iSCSI协议实现源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        iscsi_session_t *s;        unsigned int s_idx;        // printk("iscsi_client - PID %d iscsi_client_detect(%p) ENTRY\n", current->pid, tpnt);        /* probe should connect and login */        if ((s_idx = iscsi_client_probe()) >= 0) {                // printk ("iscsi_client - probe success\n");                /* Found - create an instance of this controller */                shpnt = scsi_register(tpnt, 0);                if (shpnt == NULL) {                        printk ("iscsi_client - iscsi_client_detect() SCSI Register failed :(\n");                        return 0;                }                shpnt->this_id = ISCSI_CLIENT_SCSI_ID;                s = &session[s_idx];                if (iscsi_client_start(s) != 0) {                        printk ("iscsi_client - iscsi_client_detect() Start failed :(\n");                        scsi_unregister (shpnt);                        sock_release(s->connection[0].sock);                        return 0;                }                                /* finally we'll store the session index as the unique_id */                shpnt->unique_id = s_idx;                                // printk("iscsi_client - PID %d iscsi_client_detect(%p) EXIT\n", current->pid, tpnt);                return 1;        }        return 0;}int iscsi_client_command(Scsi_Cmnd * SCpnt){        // printk ("iscsi_client - PID %d iscsi_client_command(%p) ENTRY\n", current->pid, SCpnt);                iscsi_client_queuecommand(SCpnt, iscsi_client_it_finished);        /* Wait for the command to complete */        while (!SCpnt->SCp.Status)                barrier();        // printk ("iscsi_client - PID %d iscsi_client_command(%p) EXIT\n", current->pid, SCpnt);        return SCpnt->result;}/* NOTE:  currently a scsi target AND a scsi host map to an iscsi_session * a scsi channal maps to an iscsi_connection.  We need to check * this and figure out what we should do if we want multiple * hosts and multiple targets  *  * We probably need to have a hosts data structure encapsulating  * the session data structure.  Who cares for now. */int iscsi_client_queuecommand(Scsi_Cmnd * SCpnt,                              void (*done) (Scsi_Cmnd *)){        iscsi_session_t *s;        iscsi_connection_t *c;        iscsi_header_t hdr;        struct iovec iov[2];        u32 num_iov;        // printk ("iscsi_client - PID %d iscsi_client_queuecommand(%p,%p) ENTRY\n", current->pid, SCpnt, done);        /* zero out the header */        memset (&hdr, 0, ISCSI_HDR_SIZE);        /* Verify the unique_id is a valid session */        if (SCpnt->host->unique_id > ISCSI_MAX_SESSIONS) {                printk ("iscsi_client:  iscsi_client_queuecommand() Bogus unique_id: %d\n",                        SCpnt->host->unique_id);                return -1;        }        s = &session[SCpnt->host->unique_id];        /* verify the session is in use */        if (!s->in_use) {                printk ("iscsi_client:  iscsi_client_queuecommand() Session not in use\n");                return -1;        }        /* ok, now we'll use the channel as the connection index */        if (SCpnt->channel > ISCSI_MAX_CONNECTIONS) {                printk ("iscsi_client:  iscsi_client_queuecommand() Bogus channel: %d\n",                        SCpnt->channel);                return -1;        }        c = &s->connection[SCpnt->channel];        /* ok now that we've dug out the appropriate connection to send over,         * let's store the current_command away.  Note this should be         * an enqueue, but we're only support 1 outstanding command         * at a time         */        s->current_command = SCpnt;        s->current_command->scsi_done = done;        s->current_command->SCp.Status = 0;        /* Finally, let's build a header and send on the pipe */        hdr.scsi_cmd.op = ISCSI_OP_SCSI_CMD;        if (SCpnt->cmd_len > 16) hdr.scsi_cmd.add_cdb = SCpnt->cmd_len - 16;        ASSERT (sizeof(SCpnt->lun) == 4)        hdr.scsi_cmd.lun = SCpnt->lun;        // printk ("iscsi_client - iscsi_client_queuecommand() Lun == %d,%d\n", SCpnt->lun, hdr.scsi_cmd.lun);        hdr.scsi_cmd.itt = s->itt++; /* ??? check me */        hdr.scsi_cmd.exp_data_len = SCpnt->request_bufflen;        hdr.scsi_cmd.cmd_rn = s->cmd_rn++;        hdr.scsi_cmd.exp_stat_rn = c->stat_rn++;        iov[0].iov_base = &hdr;        iov[0].iov_len = 48;        if (hdr.scsi_cmd.add_cdb) {                memcpy (hdr.scsi_cmd.cdb, SCpnt->cmnd, 16);                iov[1].iov_base = SCpnt->cmnd + 16;                iov[1].iov_len = hdr.scsi_cmd.add_cdb;                num_iov = 2;        } else {                memcpy (hdr.scsi_cmd.cdb, SCpnt->cmnd, SCpnt->cmd_len);                num_iov = 1;        }                if (iscsi_sendv (c->sock, iov, num_iov) < 0) {                printk ("iscsi_client:  iscsi_client_queuecommand() sendv() failed\n");        }        // printk ("iscsi_client - PID %d iscsi_client_queuecommand(%p,%p) EXIT\n", current->pid, SCpnt, done);        return 0;}/* need to get rid of abort and reset and use the * new eh_x mechanisms */int iscsi_client_abort(Scsi_Cmnd * SCpnt){        printk ("iscsi_client - PID %d iscsi_client_abort(%p) ENTRY\n",                 current->pid, SCpnt);        return SCSI_ABORT_SNOOZE;}int iscsi_client_reset(Scsi_Cmnd * SCpnt, unsigned int flags){        printk ("iscsi_client - PID %d iscsi_client_reset(%p,0x%x) ENTRY\n", current->pid, SCpnt, flags);        return SCSI_RESET_PUNT;}/* lifted from sym53c416.c:sym53c416_bios_param */int iscsi_client_bios_param(Disk *disk, kdev_t dev, int *ip){        int size;        printk ("iscsi_client - PID %d iscsi_client_bios_param(%p,%d,%p) ENTRY\n", current->pid, disk, dev, ip);        size = disk->capacity;        ip[0] = 64;                         /* heads                        */        ip[1] = 32;                         /* sectors                      */        if((ip[2] = size >> 11) > 1024) {   /* cylinders, test for big disk */                ip[0] = 255;                /* heads                        */                ip[1] = 63;                 /* sectors                      */                ip[2] = size / (255 * 63);  /* cylinders                    */        }        return 0;}/* Local definitions */static unsigned int iscsi_client_probe(void){        u16 port = ISCSI_PORT;        u32 addr = 0x1401010a; /* cypher (10.1.1.20) */        // u32 addr = 0x0100007f; /* localhost (127.0.0.1) */        // u32 addr = 0x0101010a; /* morpheus (10.1.1.1) */        struct sockaddr_in sin;        s32 error;        u16 i;        struct socket *sock;        // printk ("iscsi_client - PID %d iscsi_client_probe() ENTRY\n", current->pid);        /* find an open session */        for (i=0; i<ISCSI_MAX_SESSIONS; i++) {                if (!session[i].in_use) break;        }        if (i==ISCSI_MAX_SESSIONS) {                printk ("iscsi_client - iscsi_client_probe() No more sessions allowed\n");                return -1;        }        sock = session[i].connection[0].sock;        error = sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&sock);        if (error<0) {                printk("iscsi_client - iscsi_client_probe() Error during creation of socket\n");                return -1;        }                sin.sin_family = AF_INET;                /* somehow we need to get addr */        memcpy (&sin.sin_addr, &addr, sizeof(u32));        sin.sin_port = cpu_to_be16 (port);                // printk ("iscsi_client - iscsi_client_probe() Attempting to connect to host\n");                error = sock->ops->connect(sock,                                    (struct sockaddr *) &sin,                                    sizeof(struct sockaddr_in), 0);        if (error<0) {                printk("iscsi_client - iscsi_client_probe() Error during connection of socket\n");                sock_release(sock);                return -1;        }        session[i].in_use = TRUE;        session[i].num_connections = 1;	session[i].connection[0].sock = sock;        // printk ("iscsi_client - PID %d iscsi_client_probe() EXIT\n", current->pid);        return i;}static int iscsi_client_start (iscsi_session_t *s) {          // printk ("iscsi_client - PID %d iscsi_client_start(%p) ENTRY\n", current->pid, s);        /* allocate some memory for our use */        if ((scratch_pad = kmalloc (4096, GFP_KERNEL)) == NULL) {                printk("iscsi_client - iscsi_client_start() Error during kmalloc() allocation\n");                return -1;        }        /* Before getting ahead of ourselves and launching helper threads,         * let's login to the target and make sure we're in full-feature          * mode         */        if (iscsi_client_login(s, 0) != 0) {                printk("iscsi_client - iscsi_client_start() Error during iscsi_client_login()\n");                kfree (scratch_pad);                return -1;        }        // printk ("iscsi_client - PID %d iscsi_client_start(%p) EXIT\n", current->pid, s);        return 0;}static int iscsi_client_login(iscsi_session_t *s, u16 c_idx){        iscsi_header_t header;        struct iovec iov;                s32 len;        struct socket *sock;        // printk ("iscsi_client - PID %d iscsi_client_login(%p,%d) ENTRY\n", current->pid, s, c_idx);        sock = s->connection[c_idx].sock;                ASSERT (sizeof(header) == 48);        /* zero out header */        memset (&header, 0, ISCSI_HDR_SIZE);        header.login_cmd.op = ISCSI_OP_LOGIN_CMD;        /* spec doesn't yet define what version numbers should be         * so we'll just use version 0 for now         */        header.login_cmd.version_max = header.login_cmd.version_min = (u8) 0;        header.login_cmd.len = 0;        /* currently we only support 1 connection per session, so cid          * is meaningless         */        s->connection[c_idx].cid = header.login_cmd.cid = c_idx;        /* if the session id hasn't yet been established, we know this is         * the first connection in this session, so we'll generate          * initial values for the session         */        if (s->tsid == 0) {                s->isid = header.login_cmd.isid = isid++;                header.login_cmd.tsid = 0;                s->cmd_rn = (header.login_cmd.init_cmd_rn = 1) + 1;                s->itt = header.login_cmd.itt = 0; /* double check me */        } else {                s->num_connections++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -