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

📄 iscsi-probe.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 4 页
字号:
        int host = -1, channel = -1, id = -1, lun = -1;        sprintf(devname, "/dev/sg%d", i);        if (get_device_scsi_quad(devname, &host, &channel, &id, &lun)) {            if ((host == session->host_no) && (channel == session->channel) && (id == session->target_id)) {                DEBUG_INIT4("iSCSI: generic device node %s = bus %d target %d LUN %d\n", devname, session->iscsi_bus, id, lun);                /* ensure the LUN dir exists */                sprintf(lun_dir, "lun%d/", lun);                ensure_directories_exist(session->target_link_dir, dir_mode);                link = lun_dir + strlen(lun_dir);                                strcpy(link, "generic");                unlink(session->target_link_dir); /* remove any existing symlink */                symlink(devname, session->target_link_dir); /* make a new symlink */            }        }    }    /* restore the session's target dir */    *lun_dir = '\0';}static void iscsi_update_cd_links(iscsi_session_t *session, int max_sr_devices, mode_t dir_mode){    int i;    char devname[20];    /* we've reserved enough space in session->target_link_dir so that we can use it to build pathnames */    char *lun_dir = session->target_link_dir + strlen(session->target_link_dir);    char *link;    /* FIXME: can we get the number of devices supported from the running kernel? */    for (i=0; i < max_sr_devices; i++) {        int host = -1, channel = -1, id = -1, lun = -1;            /* FIXME: the distribution may be using /dev/sr instead of /dev/scd */        sprintf(devname, "/dev/scd%d", i);        if (get_device_scsi_quad(devname, &host, &channel, &id, &lun)) {            if ((host == session->host_no) && (channel == session->channel) && (id == session->target_id)) {                DEBUG_INIT4("iSCSI: cdrom device node %s = bus %d target %d LUN %d\n", devname, session->iscsi_bus, id, lun);                                /* ensure the LUN dir exists */                sprintf(lun_dir, "lun%d/", lun);                ensure_directories_exist(session->target_link_dir, dir_mode);                link = lun_dir + strlen(lun_dir);                                strcpy(link, "cd");                unlink(session->target_link_dir); /* remove any existing symlink */                symlink(devname, session->target_link_dir); /* make a new symlink */            }        }    }    /* restore the session's target dir */    *lun_dir = '\0';}/* compute the intersection of the LUNS detected and configured, and probe each LUN */void iscsi_probe_luns(iscsi_session_t *session, uint32_t *lun_bitmap, scsi_device_info_t *device_info){    int l;    int detected = 0;    int probed = 0;    int activated = 0;    /* try wait for our turn to probe, to keep the device node ordering as repeatable as possible */    DEBUG_INIT4("iSCSI: session %p to %s waiting to probe LUNs at %lu, probe order %d\n",                 session, session->log_name, jiffies, session->probe_order);    if (!wait_for_probe_order(session)) {        DEBUG_INIT2("iSCSI: session %p to %s couldn't probe LUNs, error waiting for probe order\n",                     session, session->log_name);        return;    }        if (test_bit(SESSION_TERMINATING, &session->control_bits)) {        printk("iSCSI: session %p to %s terminated while waiting to probe LUNs\n", session, session->log_name);        goto done;    }    if (signal_pending(current)) {        printk("iSCSI: session %p ioctl killed while waiting to probe LUNs\n", session);        goto done;    }    /* make sure we're the only driver process trying to add or remove LUNs */    if (down_interruptible(&iscsi_lun_probe_mutex)) {        printk("iSCSI: session %p to %s interrupted while probing LUNs\n", session, session->log_name);        goto done;    }    /* need to set the host's max_channel, max_id, max_lun, since we     * zero them in iscsi_detect in order to disable the scan that     * occurs during scsi_register_host.       */    session->hba->host->max_id = ISCSI_MAX_TARGET_IDS_PER_CHANNEL;    session->hba->host->max_lun = ISCSI_MAX_LUNS_PER_TARGET;    session->hba->host->max_channel = ISCSI_MAX_CHANNELS_PER_HBA - 1; /* convert from count to index */    wmb();    DEBUG_INIT5("iSCSI: probing LUNs for session %p to %s at %lu, probe_order %d at %lu\n",                 session, session->log_name, jiffies, session->probe_order, jiffies);    for (l = 0; l < ISCSI_MAX_LUN; l++) {        if (test_bit(SESSION_TERMINATING, &session->control_bits))            goto give_up;        if (signal_pending(current))            goto give_up;        if (test_bit(l, session->luns_detected)) {            detected++;            /* if allowed and not already activated (successfully probed), probe it */            if ((lun_bitmap[l / 32] & (1 << (l % 32))) && !test_bit(l, session->luns_activated)) {                DEBUG_FLOW3("iSCSI: session %p probing LUN %d at %lu\n", session, l, jiffies);                iscsi_probe_lun(session, l);                probed++;                if (test_bit(l, session->luns_activated))                    activated++;            }        }    }    if (detected == 0) {        printk("iSCSI: no LUNs detected for session %p to %s\n", session, session->log_name);    }    else if (LOG_ENABLED(ISCSI_LOG_INIT)) {        printk("iSCSI: session %p to %s probed %d of %d LUNs detected, %d LUNs activated\n",               session, session->log_name, probed, detected, activated);    }    /* optionally set up a symlink tree.  We do this in the kernel so that we     * can guard it with the lun_probe_mutex.  The high-level SCSI drivers in Linux tend     * to crash if a device node is opened while the Scsi_Device is still being      * initialized, so we want to make sure we're not doing any probes when we open     * lots of device nodes.     */    if (session->target_link_dir[0] == '/') {        mm_segment_t oldfs = get_fs();                set_fs( get_ds() );                /* make the target dir, so that the user can always see the target has a session, even if         * LUN probing fails to find anything or no target drivers have attached.         */        ensure_directories_exist(session->target_link_dir, session->dir_mode);                if (device_info->max_sd_devices > 0) {            DEBUG_INIT2("iSCSI: session %p updating disk links under %s\n", session, session->target_link_dir);            iscsi_update_disk_links(session, device_info->max_sd_devices, device_info->max_sd_partitions, session->dir_mode);        }        if (device_info->max_sg_devices > 0) {            DEBUG_INIT2("iSCSI: session %p updating generic links under %s\n", session, session->target_link_dir);            iscsi_update_generic_links(session, device_info->max_sg_devices, session->dir_mode);        }        if (device_info->max_st_devices > 0) {            DEBUG_INIT2("iSCSI: session %p updating tape links under %s\n", session, session->target_link_dir);            iscsi_update_tape_links(session, device_info->max_st_devices, session->dir_mode);        }        if (device_info->max_sr_devices > 0) {            DEBUG_INIT2("iSCSI: session %p updating cdrom links under %s\n", session, session->target_link_dir);            iscsi_update_cd_links(session, device_info->max_sr_devices, session->dir_mode);        }                set_fs(oldfs);    }     give_up:    up(&iscsi_lun_probe_mutex); done:    /* clean up after wait_for_probe_order, and possibly start the next session probing */    iscsi_probe_finished(session);}typedef struct iscsi_cmnd {    struct timer_list timeout; /* timeout for the command */    struct semaphore done_sem;    volatile unsigned long flags;    Scsi_Cmnd sc;    unsigned int bufflen;    uint8_t buffer[1];} iscsi_cmnd_t;#define ISCSI_CMND_DONE_LATE 0#define ISCSI_CMND_TIMED_OUT 1/* callback function for Scsi_Cmnd's generated by the iSCSI driver itself */void iscsi_done(Scsi_Cmnd *sc){    iscsi_cmnd_t *c = (iscsi_cmnd_t *)sc->buffer;    if (c) {        if (test_bit(ISCSI_CMND_TIMED_OUT, &c->flags)) {#if DEBUG_QUEUE            if (LOG_ENABLED(ISCSI_LOG_QUEUE))                printk("iSCSI: iscsi cmnd %p to (%u %u %u %u), Cmd 0x%02x done at %lu, after timeout expired\n",                        c, c->sc.host->host_no, c->sc.channel, c->sc.target, c->sc.lun, c->sc.cmnd[0], jiffies);#endif            set_bit(ISCSI_CMND_DONE_LATE, &c->flags);            up(&c->done_sem);        }        else {#if DEBUG_QUEUE            if (LOG_ENABLED(ISCSI_LOG_QUEUE))                printk("iSCSI: iscsi cmnd %p to (%u %u %u %u), Cmd 0x%02x done at %lu\n",                        c, c->sc.host->host_no, c->sc.channel, c->sc.target, c->sc.lun, c->sc.cmnd[0], jiffies);#endif            up(&c->done_sem);        }    }}static void iscsi_times_out(unsigned long arg){    iscsi_cmnd_t *c = (iscsi_cmnd_t *)arg;    if (c) {        set_bit(ISCSI_CMND_TIMED_OUT, &c->flags);        up(&c->done_sem);    }}static int iscsi_do_cmnd(iscsi_session_t *session, iscsi_cmnd_t *c, unsigned int attempts_allowed){    int rc = 0;    Scsi_Cmnd *sc = NULL;    DECLARE_MIDLAYER_FLAGS;    if (c->sc.host) {#if DEBUG_FLOW        if (LOG_ENABLED(ISCSI_LOG_FLOW))            printk("iSCSI: session %p iscsi_do_cmnd %p to (%u %u %u %u), Cmd 0x%02x, %u retries, buffer %p, bufflen %u\n",                    session, c, c->sc.host->host_no, c->sc.channel, c->sc.target, c->sc.lun, c->sc.cmnd[0],                    attempts_allowed, c->sc.request_buffer, c->sc.request_bufflen);#endif    }    else {        printk("iSCSI: session %p iscsi_do_cmnd %p, buffer %p, bufflen %u, host %p\n",                session, c, c->sc.request_buffer, c->sc.request_bufflen, c->sc.host);        return 0;    }    if (!c->sc.request_buffer)        return 0;    if (!c->sc.request_bufflen)        return 0;    sc = &(c->sc);    init_timer(&c->timeout);    sc->retries = 0;    sc->allowed = attempts_allowed;     retry:    while (sc->retries++ < sc->allowed) {        if (signal_pending(current))            return 0;        if (test_bit(SESSION_TERMINATING, &session->control_bits))            return 0;        sc->result = 0;        memset(sc->sense_buffer, 0, sizeof(sc->sense_buffer));        memset(c->buffer, 0, c->bufflen);                /* try to queue the command */        for (;;) {            /* set a 30 second timer.  We don't use the one in the Scsi_Cmnd             * to avoid depending on the internals of the SCSI layer.             */            if (c->timeout.function != NULL) {                del_timer(&c->timeout);            }            c->flags = 0;            sema_init(&c->done_sem, 0);            c->timeout.data = (unsigned long)c;            c->timeout.expires = jiffies + (30 * HZ);            c->timeout.function = iscsi_times_out;            wmb();            if (signal_pending(current))                return 0;            if (test_bit(SESSION_TERMINATING, &session->control_bits))                return 0;            add_timer(&c->timeout);                        LOCK_MIDLAYER_LOCK(session->hba->host);            rc = iscsi_queue(sc, iscsi_done);            UNLOCK_MIDLAYER_LOCK(session->hba->host);                        if (rc == 0)                break; /* command queued successfully */            /* command not queued, wait a bit and try again */            set_current_state(TASK_UNINTERRUPTIBLE);            schedule_timeout(MSECS_TO_JIFFIES(10));        }                DEBUG_FLOW5("iSCSI: session %p queued iscsi_cmnd %p, buffer %p, bufflen %u, scsi_done %p\n",                     session, c, c->sc.request_buffer, c->sc.request_bufflen, c->sc.scsi_done);        /* wait til either the command completes, the timer expires,         * or we get signalled.         */        if (down_interruptible(&c->done_sem)) {            /* if we got signalled, squash the command and give up */            iscsi_squash_cmnd(session, sc);            return 0;        }        DEBUG_FLOW6("iSCSI: session %p hba %p host %p woken up by iscsi_cmnd %p, buffer %p, bufflen %u\n",                     session, session->hba, session->hba->host, c, c->sc.request_buffer, c->sc.request_bufflen);                if (test_bit(ISCSI_CMND_DONE_LATE, &c->flags)) {            /* command completed after the timer went off.             * if it took that long, something probably went wrong, try again.             */            printk("iSCSI: session %p iscsi cmnd %p to (%u %u %u %u) done late at %lu\n",                    session, c, sc->host->host_no, sc->channel, sc->target, sc->lun, jiffies);            goto retry;        }        else if (test_bit(ISCSI_CMND_TIMED_OUT, &c->flags)) {            /* the command timed out, squash it and retry */            printk("iSCSI: session %p iscsi cmnd %p to (%u %u %u %u) timed out at %lu\n",                    session, c, sc->host->host_no, sc->channel, sc->target, sc->lun, jiffies);            iscsi_squash_cmnd(session, sc);            goto retry;        }        else {            /* if the command completed, clear the timer, check the result,              * and decide if it needs to be retried.              */            del_timer(&c->timeout);            c->timeout.function = NULL;                        if (LOG_ENABLED(ISCSI_LOG_FLOW))                printk("iSCSI: session %p iscsi cmnd %p to (%u %u %u %u), Cmd 0x%02x, "                       "host byte 0x%x, SCSI status 0x%x\n",                        session, c, c->sc.host->host_no, c->sc.channel, c->sc.target, c->sc.lun, c->sc.cmnd[0],                        (sc->result >> 24) & 0xFF, sc->result & 0xFF);                        /* check the host byte */            switch (host_byte(sc->result)) {                case DID_OK:                    /* no problems so far */                    break;                case DID_NO_CONNECT:                    /* give up, we can't talk to the device */                    printk("iSCSI: session %p failing iscsi cmnd %p to (%u %u %u %u), Cmd 0x%02x, "                           "host byte 0x%x, SCSI status 0x%x\n",                            session, c, c->sc.host->host_no, c->sc.channel, c->sc.target, c->sc.lun, c->sc.cmnd[0],                            (sc->result >> 24) & 0xFF, sc->result & 0xFF);                    return 0;                case DID_ERROR:                case DID_SOFT_ERROR:                case DID_ABORT:

⌨️ 快捷键说明

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