示例#1
0
/*
 * iser_tgt_svc_create()
 * Establish the CM service for inbound iSER service requests on the port
 * indicated by sr->sr_port.
 * idm_svc_req_t contains the service parameters.
 */
idm_status_t
iser_tgt_svc_create(idm_svc_req_t *sr, idm_svc_t *is)
{
    iser_svc_t		*iser_svc;

    int			rc;

    iser_svc = kmem_zalloc(sizeof (iser_svc_t), KM_SLEEP);
    is->is_iser_svc = (void *)iser_svc;

    idm_refcnt_init(&iser_svc->is_refcnt, iser_svc);

    list_create(&iser_svc->is_sbindlist, sizeof (iser_sbind_t),
                offsetof(iser_sbind_t, is_list_node));
    iser_svc->is_svcid = ibt_get_ip_sid(IPPROTO_TCP, sr->sr_port);

    /*
     * Register an iSER target service for the requested port
     * and set the iser_svc structure in the idm_svc handle.
     */
    rc = iser_register_service(is);
    if (rc != DDI_SUCCESS) {
        ISER_LOG(CE_NOTE, "iser_tgt_svc_create: iser_register_service "
                 "failed on port (%d): rc (0x%x)", sr->sr_port, rc);
        (void) ibt_release_ip_sid(iser_svc->is_svcid);
        list_destroy(&iser_svc->is_sbindlist);
        idm_refcnt_destroy(&iser_svc->is_refcnt);
        kmem_free(iser_svc, sizeof (iser_svc_t));
        return (IDM_STATUS_FAIL);
    }

    return (IDM_STATUS_SUCCESS);
}
示例#2
0
iscsit_sess_t *
iscsit_sess_create(iscsit_tgt_t *tgt, iscsit_conn_t *ict,
    uint32_t cmdsn, uint8_t *isid, uint16_t tag,
    char *initiator_name, char *target_name,
    uint8_t *error_class, uint8_t *error_detail)
{
	iscsit_sess_t *result;

	*error_class = ISCSI_STATUS_CLASS_SUCCESS;

	/*
	 * Even if this session create "fails" for some reason we still need
	 * to return a valid session pointer so that we can send the failed
	 * login response.
	 */
	result = kmem_zalloc(sizeof (*result), KM_SLEEP);

	/* Allocate TSIH */
	if ((result->ist_tsih = iscsit_tsih_alloc()) == ISCSI_UNSPEC_TSIH) {
		/* Out of TSIH's */
		*error_class = ISCSI_STATUS_CLASS_TARGET_ERR;
		*error_detail = ISCSI_LOGIN_STATUS_NO_RESOURCES;
		/*
		 * Continue initializing this session so we can use it
		 * to complete the login process.
		 */
	}

	idm_sm_audit_init(&result->ist_state_audit);
	mutex_init(&result->ist_sn_mutex, NULL, MUTEX_DEFAULT, NULL);
	mutex_init(&result->ist_mutex, NULL, MUTEX_DEFAULT, NULL);
	cv_init(&result->ist_cv, NULL, CV_DEFAULT, NULL);
	list_create(&result->ist_events, sizeof (sess_event_ctx_t),
	    offsetof(sess_event_ctx_t, se_ctx_node));
	list_create(&result->ist_conn_list, sizeof (iscsit_conn_t),
	    offsetof(iscsit_conn_t, ict_sess_ln));
	avl_create(&result->ist_task_list, iscsit_task_itt_compare,
	    sizeof (iscsit_task_t), offsetof(iscsit_task_t, it_sess_ln));
	result->ist_rxpdu_queue = kmem_zalloc(sizeof (iscsit_cbuf_t), KM_SLEEP);
	result->ist_state = SS_Q1_FREE;
	result->ist_last_state = SS_Q1_FREE;
	bcopy(isid, result->ist_isid, ISCSI_ISID_LEN);
	result->ist_tpgt_tag = tag;

	result->ist_tgt = tgt;
	/*
	 * cmdsn/expcmdsn do not advance during login phase.
	 */
	result->ist_expcmdsn = cmdsn;
	result->ist_maxcmdsn = result->ist_expcmdsn + 1;

	result->ist_initiator_name =
	    kmem_alloc(strlen(initiator_name) + 1, KM_SLEEP);
	(void) strcpy(result->ist_initiator_name, initiator_name);
	if (target_name) {
		/* A discovery session might not have a target name */
		result->ist_target_name =
		    kmem_alloc(strlen(target_name) + 1, KM_SLEEP);
		(void) strcpy(result->ist_target_name, target_name);
	}
	idm_refcnt_init(&result->ist_refcnt, result);

	/* Login code will fill in ist_stmf_sess if necessary */

	if (*error_class == ISCSI_STATUS_CLASS_SUCCESS) {
		/*
		 * Make sure the service is still enabled and if so get a global
		 * hold to represent this session.
		 */
		mutex_enter(&iscsit_global.global_state_mutex);
		if (iscsit_global.global_svc_state == ISE_ENABLED) {
			iscsit_global_hold();
			mutex_exit(&iscsit_global.global_state_mutex);

			/*
			 * Kick session state machine (also binds connection
			 * to session)
			 */
			iscsit_sess_sm_event(result, SE_CONN_IN_LOGIN, ict);

			*error_class = ISCSI_STATUS_CLASS_SUCCESS;
		} else {
			mutex_exit(&iscsit_global.global_state_mutex);
			*error_class = ISCSI_STATUS_CLASS_TARGET_ERR;
			*error_detail = ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE;
		}
	}

	/*
	 * As noted above we must return a session pointer even if something
	 * failed.  The resources will get freed later.
	 */
	return (result);
}