usr/src/uts/common/io/scsi/adapters/iscsi/iscsi_sess.c
changeset 9162 b011b0287065
parent 8866 df833c7386b7
child 9780 f59fdbf1f64b
equal deleted inserted replaced
9161:7dca69f75d8e 9162:b011b0287065
    31 #include "iscsi_targetparam.h"
    31 #include "iscsi_targetparam.h"
    32 
    32 
    33 #define	ISCSI_SESS_ENUM_TIMEOUT_DEFAULT	60
    33 #define	ISCSI_SESS_ENUM_TIMEOUT_DEFAULT	60
    34 #define	SCSI_INQUIRY_PQUAL_MASK 0xE0
    34 #define	SCSI_INQUIRY_PQUAL_MASK 0xE0
    35 
    35 
       
    36 boolean_t iscsi_sess_logging = B_FALSE;
    36 /*
    37 /*
    37  * used to store report lun information found
    38  * used to store report lun information found
    38  *
    39  *
    39  * lun_valid:	if TRUE means the entry contains a valid entry
    40  * lun_valid:	if TRUE means the entry contains a valid entry
    40  * lun_found:	if TRUE means the lun has been found in the sess_lun_list
    41  * lun_found:	if TRUE means the lun has been found in the sess_lun_list
   212 	isp->sess_expcmdsn		= 1;
   213 	isp->sess_expcmdsn		= 1;
   213 	isp->sess_maxcmdsn		= 1;
   214 	isp->sess_maxcmdsn		= 1;
   214 	isp->sess_last_err		= NoError;
   215 	isp->sess_last_err		= NoError;
   215 	isp->sess_tsid			= 0;
   216 	isp->sess_tsid			= 0;
   216 	isp->sess_type			= type;
   217 	isp->sess_type			= type;
       
   218 	idm_sm_audit_init(&isp->sess_state_audit);
   217 
   219 
   218 	/* copy default driver login parameters */
   220 	/* copy default driver login parameters */
   219 	bcopy(&ihp->hba_params, &isp->sess_params,
   221 	bcopy(&ihp->hba_params, &isp->sess_params,
   220 	    sizeof (iscsi_login_params_t));
   222 	    sizeof (iscsi_login_params_t));
   221 
   223 
   396 		 * attempt to login into the first connection in our connection
   398 		 * attempt to login into the first connection in our connection
   397 		 * list.  If this fails, we will try the next connection
   399 		 * list.  If this fails, we will try the next connection
   398 		 * in our list until end of the list.
   400 		 * in our list until end of the list.
   399 		 */
   401 		 */
   400 		while (icp != NULL) {
   402 		while (icp != NULL) {
   401 			if (iscsi_conn_state_machine(
   403 			if (iscsi_conn_online(icp) == ISCSI_STATUS_SUCCESS) {
   402 			    icp, ISCSI_CONN_EVENT_T1) ==
       
   403 			    ISCSI_STATUS_SUCCESS) {
       
   404 				mutex_exit(&icp->conn_state_mutex);
   404 				mutex_exit(&icp->conn_state_mutex);
   405 				break;
   405 				break;
   406 			} else {
   406 			} else {
   407 				mutex_exit(&icp->conn_state_mutex);
   407 				mutex_exit(&icp->conn_state_mutex);
   408 				icp = icp->conn_next;
   408 				icp = icp->conn_next;
   489 	if (!ISCSI_SUCCESS(rval)) {
   489 	if (!ISCSI_SUCCESS(rval)) {
   490 		return (rval);
   490 		return (rval);
   491 	}
   491 	}
   492 
   492 
   493 	/* The next step is to logout of the connections. */
   493 	/* The next step is to logout of the connections. */
       
   494 	rw_enter(&isp->sess_conn_list_rwlock, RW_WRITER);
   494 	icp = isp->sess_conn_list;
   495 	icp = isp->sess_conn_list;
   495 	while (icp != NULL) {
   496 	while (icp != NULL) {
   496 		rval = iscsi_conn_offline(icp);
   497 		rval = iscsi_conn_offline(icp);
   497 		if (ISCSI_SUCCESS(rval)) {
   498 		if (ISCSI_SUCCESS(rval)) {
   498 			/* Succes, Continue processing... */
   499 			/* Succes, Continue processing... */
   501 			/* Failure, Stop processing... */
   502 			/* Failure, Stop processing... */
   502 			rw_exit(&isp->sess_conn_list_rwlock);
   503 			rw_exit(&isp->sess_conn_list_rwlock);
   503 			return (rval);
   504 			return (rval);
   504 		}
   505 		}
   505 	}
   506 	}
       
   507 	rw_exit(&isp->sess_conn_list_rwlock);
   506 
   508 
   507 	/*
   509 	/*
   508 	 * At this point all connections should be in
   510 	 * At this point all connections should be in
   509 	 * a FREE state which will have pushed the session
   511 	 * a FREE state which will have pushed the session
   510 	 * to a FREE state.
   512 	 * to a FREE state.
   511 	 */
   513 	 */
   512 	ASSERT(isp->sess_state == ISCSI_SESS_STATE_FREE);
   514 	ASSERT(isp->sess_state == ISCSI_SESS_STATE_FREE ||
       
   515 	    isp->sess_state == ISCSI_SESS_STATE_FAILED);
   513 
   516 
   514 	/* Stop watchdog before destroying connections */
   517 	/* Stop watchdog before destroying connections */
   515 	if (isp->sess_wd_thread) {
   518 	if (isp->sess_wd_thread) {
   516 		iscsi_thread_destroy(isp->sess_wd_thread);
   519 		iscsi_thread_destroy(isp->sess_wd_thread);
   517 		isp->sess_wd_thread = NULL;
   520 		isp->sess_wd_thread = NULL;
   792 	}
   795 	}
   793 
   796 
   794 	return (B_TRUE);
   797 	return (B_TRUE);
   795 }
   798 }
   796 
   799 
       
   800 /*
       
   801  * iscsi_sess_reserve_itt - Used to reserve an ITT hash slot
       
   802  */
       
   803 iscsi_status_t
       
   804 iscsi_sess_reserve_scsi_itt(iscsi_cmd_t *icmdp)
       
   805 {
       
   806 	idm_task_t *itp;
       
   807 	iscsi_conn_t *icp = icmdp->cmd_conn;
       
   808 	itp = idm_task_alloc(icp->conn_ic);
       
   809 	if (itp == NULL)
       
   810 		return (ISCSI_STATUS_INTERNAL_ERROR);
       
   811 	itp->idt_private = icmdp;
       
   812 	icmdp->cmd_itp = itp;
       
   813 	icmdp->cmd_itt = itp->idt_tt;
       
   814 	return (ISCSI_STATUS_SUCCESS);
       
   815 }
       
   816 
       
   817 /*
       
   818  * iscsi_sess_release_scsi_itt - Used to release ITT hash slot
       
   819  */
       
   820 void
       
   821 iscsi_sess_release_scsi_itt(iscsi_cmd_t *icmdp)
       
   822 {
       
   823 	idm_task_free(icmdp->cmd_itp);
       
   824 }
   797 
   825 
   798 /*
   826 /*
   799  * iscsi_sess_reserve_itt - Used to reserve an ITT hash slot
   827  * iscsi_sess_reserve_itt - Used to reserve an ITT hash slot
   800  */
   828  */
   801 iscsi_status_t
   829 iscsi_status_t
   803 {
   831 {
   804 	/* If no more slots are open fail reservation */
   832 	/* If no more slots are open fail reservation */
   805 	if (isp->sess_cmd_table_count >= ISCSI_CMD_TABLE_SIZE) {
   833 	if (isp->sess_cmd_table_count >= ISCSI_CMD_TABLE_SIZE) {
   806 		return (ISCSI_STATUS_ITT_TABLE_FULL);
   834 		return (ISCSI_STATUS_ITT_TABLE_FULL);
   807 	}
   835 	}
       
   836 
       
   837 	/*
       
   838 	 * Keep itt values out of the range used by IDM
       
   839 	 */
       
   840 	if (isp->sess_itt < IDM_TASKIDS_MAX)
       
   841 		isp->sess_itt = IDM_TASKIDS_MAX;
   808 
   842 
   809 	/*
   843 	/*
   810 	 * Find the next available slot.  Normally its the
   844 	 * Find the next available slot.  Normally its the
   811 	 * slot pointed to by the session's sess_itt value.
   845 	 * slot pointed to by the session's sess_itt value.
   812 	 * If this is not true the table has become fragmented.
   846 	 * If this is not true the table has become fragmented.
   819 		isp->sess_itt++;
   853 		isp->sess_itt++;
   820 	}
   854 	}
   821 
   855 
   822 	/* reserve slot and update counters */
   856 	/* reserve slot and update counters */
   823 	icmdp->cmd_itt = isp->sess_itt;
   857 	icmdp->cmd_itt = isp->sess_itt;
   824 	isp->sess_cmd_table[icmdp->cmd_itt %
   858 	isp->sess_cmd_table[isp->sess_itt %
   825 	    ISCSI_CMD_TABLE_SIZE] = icmdp;
   859 	    ISCSI_CMD_TABLE_SIZE] = icmdp;
   826 	isp->sess_cmd_table_count++;
   860 	isp->sess_cmd_table_count++;
   827 	isp->sess_itt++;
   861 	isp->sess_itt++;
   828 
   862 
   829 	return (ISCSI_STATUS_SUCCESS);
   863 	return (ISCSI_STATUS_SUCCESS);
   945 
   979 
   946 	DTRACE_PROBE3(event, iscsi_sess_t *, isp,
   980 	DTRACE_PROBE3(event, iscsi_sess_t *, isp,
   947 	    char *, iscsi_sess_state_str(isp->sess_state),
   981 	    char *, iscsi_sess_state_str(isp->sess_state),
   948 	    char *, iscsi_sess_event_str(event));
   982 	    char *, iscsi_sess_event_str(event));
   949 
   983 
       
   984 	/* Audit event */
       
   985 	idm_sm_audit_event(&isp->sess_state_audit,
       
   986 	    SAS_ISCSI_SESS, isp->sess_state, event, NULL);
       
   987 
   950 	isp->sess_prev_state = isp->sess_state;
   988 	isp->sess_prev_state = isp->sess_state;
   951 	isp->sess_state_lbolt = ddi_get_lbolt();
   989 	isp->sess_state_lbolt = ddi_get_lbolt();
   952 
   990 
       
   991 	ISCSI_SESS_LOG(CE_NOTE,
       
   992 	    "DEBUG: sess_state: isp: %p state: %d event: %d",
       
   993 	    (void *)isp, isp->sess_state, event);
   953 	switch (isp->sess_state) {
   994 	switch (isp->sess_state) {
   954 	case ISCSI_SESS_STATE_FREE:
   995 	case ISCSI_SESS_STATE_FREE:
   955 		iscsi_sess_state_free(isp, event);
   996 		iscsi_sess_state_free(isp, event);
   956 		break;
   997 		break;
   957 	case ISCSI_SESS_STATE_LOGGED_IN:
   998 	case ISCSI_SESS_STATE_LOGGED_IN:
   966 	case ISCSI_SESS_STATE_FLUSHED:
  1007 	case ISCSI_SESS_STATE_FLUSHED:
   967 		iscsi_sess_state_flushed(isp, event);
  1008 		iscsi_sess_state_flushed(isp, event);
   968 		break;
  1009 		break;
   969 	default:
  1010 	default:
   970 		ASSERT(FALSE);
  1011 		ASSERT(FALSE);
       
  1012 	}
       
  1013 
       
  1014 	/* Audit state change */
       
  1015 	if (isp->sess_prev_state != isp->sess_state) {
       
  1016 		idm_sm_audit_state_change(&isp->sess_state_audit,
       
  1017 		    SAS_ISCSI_SESS, isp->sess_prev_state, isp->sess_state);
   971 	}
  1018 	}
   972 }
  1019 }
   973 
  1020 
   974 
  1021 
   975 /*
  1022 /*
  1753 	lun_start = 0;
  1800 	lun_start = 0;
  1754 	rw_enter(&isp->sess_lun_list_rwlock, RW_WRITER);
  1801 	rw_enter(&isp->sess_lun_list_rwlock, RW_WRITER);
  1755 	for (ilp = isp->sess_lun_list; ilp; ilp = ilp_next) {
  1802 	for (ilp = isp->sess_lun_list; ilp; ilp = ilp_next) {
  1756 		ilp_next = ilp->lun_next;
  1803 		ilp_next = ilp->lun_next;
  1757 
  1804 
  1758 		for (lun_count = lun_start;
  1805 		for (lun_count = lun_start; lun_count < lun_total;
  1759 		    lun_count < lun_total; lun_count++) {
  1806 		    lun_count++) {
  1760 		/*
  1807 			/*
  1761 		 * if the first lun in saved_replun_ptr buffer has already
  1808 			 * if the first lun in saved_replun_ptr buffer has
  1762 		 * been found we can move on and do not have to check this lun
  1809 			 * already been found we can move on and do not
  1763 		 * in the future
  1810 			 * have to check this lun in the future
  1764 		 */
  1811 			 */
  1765 			if (lun_count == lun_start &&
  1812 			if (lun_count == lun_start &&
  1766 			    saved_replun_ptr[lun_start].lun_found) {
  1813 			    saved_replun_ptr[lun_start].lun_found) {
  1767 				lun_start++;
  1814 				lun_start++;
  1768 				continue;
  1815 				continue;
  1769 			}
  1816 			}
  1810 				continue;
  1857 				continue;
  1811 			}
  1858 			}
  1812 			saved_replun_ptr[lun_count].lun_valid = B_TRUE;
  1859 			saved_replun_ptr[lun_count].lun_valid = B_TRUE;
  1813 			saved_replun_ptr[lun_count].lun_num = lun_num;
  1860 			saved_replun_ptr[lun_count].lun_num = lun_num;
  1814 			if (ilp->lun_num == lun_num) {
  1861 			if (ilp->lun_num == lun_num) {
  1815 			/*
  1862 				/*
  1816 			 * lun is found in the SCSI Report Lun buffer
  1863 				 * lun is found in the SCSI Report Lun buffer
  1817 			 * make sure the lun is in the ONLINE state
  1864 				 * make sure the lun is in the ONLINE state
  1818 			 */
  1865 				 */
  1819 				saved_replun_ptr[lun_count].lun_found = B_TRUE;
  1866 				saved_replun_ptr[lun_count].lun_found = B_TRUE;
  1820 					if ((ilp->lun_state &
  1867 					if ((ilp->lun_state &
  1821 					    ISCSI_LUN_STATE_OFFLINE) ||
  1868 					    ISCSI_LUN_STATE_OFFLINE) ||
  1822 					    (ilp->lun_state &
  1869 					    (ilp->lun_state &
  1823 					    ISCSI_LUN_STATE_INVALID)) {
  1870 					    ISCSI_LUN_STATE_INVALID)) {
  1835 				}
  1882 				}
  1836 			}
  1883 			}
  1837 		}
  1884 		}
  1838 
  1885 
  1839 		if (lun_count == lun_total) {
  1886 		if (lun_count == lun_total) {
  1840 		/*
  1887 			/*
  1841 		 * this lun we found in the sess->lun_list does not exist
  1888 			 * this lun we found in the sess->lun_list does
  1842 		 * anymore, need to offline this lun
  1889 			 * not exist anymore, need to offline this lun
  1843 		 */
  1890 			 */
  1844 
  1891 
  1845 			DTRACE_PROBE2(sess_reportluns_lun_no_longer_exists,
  1892 			DTRACE_PROBE2(sess_reportluns_lun_no_longer_exists,
  1846 			    int, ilp->lun_num, int, ilp->lun_state);
  1893 			    int, ilp->lun_num, int, ilp->lun_state);
  1847 
  1894 
  1848 			(void) iscsi_lun_destroy(ihp, ilp);
  1895 			(void) iscsi_lun_destroy(ihp, ilp);
  1864 			if (retrieve_lundata(lun_count, buf, isp,
  1911 			if (retrieve_lundata(lun_count, buf, isp,
  1865 			    &lun_num, &lun_addr_type) != ISCSI_STATUS_SUCCESS) {
  1912 			    &lun_num, &lun_addr_type) != ISCSI_STATUS_SUCCESS) {
  1866 				continue;
  1913 				continue;
  1867 			}
  1914 			}
  1868 		} else {
  1915 		} else {
  1869 		/*
  1916 			/*
  1870 		 * lun information is in the saved_replun buffer
  1917 			 * lun information is in the saved_replun buffer
  1871 		 *    if this lun has been found already, then we can move on
  1918 			 * if this lun has been found already,
  1872 		 */
  1919 			 * then we can move on
       
  1920 			 */
  1873 			if (saved_replun_ptr[lun_count].lun_found == B_TRUE) {
  1921 			if (saved_replun_ptr[lun_count].lun_found == B_TRUE) {
  1874 				continue;
  1922 				continue;
  1875 			}
  1923 			}
  1876 			lun_num = saved_replun_ptr[lun_count].lun_num;
  1924 			lun_num = saved_replun_ptr[lun_count].lun_num;
  1877 		}
  1925 		}