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: |
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 } |