Quellcode durchsuchen

Add ability to shut down iSCSI connection

tags/v0.9.3
Michael Brown vor 17 Jahren
Ursprung
Commit
ab242a760d
4 geänderte Dateien mit 49 neuen und 24 gelöschten Zeilen
  1. 16
    1
      src/drivers/scsi/iscsidev.c
  2. 5
    0
      src/include/gpxe/iscsi.h
  3. 25
    22
      src/net/tcp/iscsi.c
  4. 3
    1
      src/tests/iscsiboot.c

+ 16
- 1
src/drivers/scsi/iscsidev.c Datei anzeigen

@@ -46,7 +46,22 @@ static int iscsi_command ( struct scsi_device *scsi,
46 46
  * @v iscsidev		iSCSI device
47 47
  */
48 48
 int init_iscsidev ( struct iscsi_device *iscsidev ) {
49
+	int rc;
50
+
49 51
 	iscsidev->scsi.command = iscsi_command;
50 52
 	iscsidev->scsi.lun = iscsidev->iscsi.lun;
51
-	return init_scsidev ( &iscsidev->scsi );
53
+	rc = init_scsidev ( &iscsidev->scsi );
54
+	if ( rc != 0 ) {
55
+		fini_iscsidev ( iscsidev );
56
+	}
57
+	return rc;
58
+}
59
+
60
+/**
61
+ * Shut down iSCSI device
62
+ *
63
+ * @v iscsidev		iSCSI device
64
+ */
65
+void fini_iscsidev ( struct iscsi_device *iscsidev ) {
66
+	async_wait ( iscsi_shutdown ( &iscsidev->iscsi ) );
52 67
 }

+ 5
- 0
src/include/gpxe/iscsi.h Datei anzeigen

@@ -626,11 +626,15 @@ struct iscsi_session {
626 626
 /** Mask for all iSCSI "needs to send" flags */
627 627
 #define ISCSI_STATUS_STRINGS_MASK 0xff00
628 628
 
629
+/** iSCSI session is closing down */
630
+#define ISCSI_STATUS_CLOSING 0x00010000
631
+
629 632
 /** Maximum number of retries at connecting */
630 633
 #define ISCSI_MAX_RETRIES 2
631 634
 
632 635
 extern struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
633 636
 					      struct scsi_command *command );
637
+extern struct async_operation * iscsi_shutdown ( struct iscsi_session *iscsi );
634 638
 
635 639
 /** An iSCSI device */
636 640
 struct iscsi_device {
@@ -641,5 +645,6 @@ struct iscsi_device {
641 645
 };
642 646
 
643 647
 extern int init_iscsidev ( struct iscsi_device *iscsidev );
648
+extern void fini_iscsidev ( struct iscsi_device *iscsidev );
644 649
 
645 650
 #endif /* _GPXE_ISCSI_H */

+ 25
- 22
src/net/tcp/iscsi.c Datei anzeigen

@@ -104,24 +104,6 @@ static void iscsi_done ( struct iscsi_session *iscsi, int rc ) {
104 104
 	async_done ( &iscsi->aop, rc );
105 105
 }
106 106
 
107
-/**
108
- * Mark iSCSI operation as complete, and close TCP connection
109
- *
110
- * @v iscsi		iSCSI session
111
- * @v rc		Return status code
112
- */
113
-static void iscsi_close ( struct iscsi_session *iscsi, int rc ) {
114
-
115
-	/* Clear session status */
116
-	iscsi->status = 0;
117
-
118
-	/* Close TCP connection */
119
-	tcp_close ( &iscsi->tcp );
120
-
121
-	/* Mark iSCSI operation as complete */
122
-	iscsi_done ( iscsi, rc );
123
-}
124
-
125 107
 /****************************************************************************
126 108
  *
127 109
  * iSCSI SCSI command issuing
@@ -564,7 +546,7 @@ static void iscsi_handle_chap_a_value ( struct iscsi_session *iscsi,
564 546
 	/* Prepare for CHAP with MD5 */
565 547
 	if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
566 548
 		DBG ( "iSCSI %p could not initialise CHAP\n", iscsi );
567
-		iscsi_close ( iscsi, rc );
549
+		iscsi_done ( iscsi, rc );
568 550
 	}
569 551
 }
570 552
 
@@ -722,7 +704,7 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
722 704
 	/* Buffer up the PDU data */
723 705
 	if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
724 706
 		DBG ( "iSCSI %p could not buffer login response\n", iscsi );
725
-		iscsi_close ( iscsi, rc );
707
+		iscsi_done ( iscsi, rc );
726 708
 		return;
727 709
 	}
728 710
 	if ( remaining )
@@ -747,7 +729,7 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
747 729
 	if ( response->status_class != 0 ) {
748 730
 		printf ( "iSCSI login failure: class %02x detail %02x\n",
749 731
 			 response->status_class, response->status_detail );
750
-		iscsi_close ( iscsi, -EPERM );
732
+		iscsi_done ( iscsi, -EPERM );
751 733
 		return;
752 734
 	}
753 735
 
@@ -765,7 +747,7 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
765 747
 		default:
766 748
 			DBG ( "iSCSI %p got invalid response flags %02x\n",
767 749
 			      iscsi, response->flags );
768
-			iscsi_close ( iscsi, -EIO );
750
+			iscsi_done ( iscsi, -EIO );
769 751
 			return;
770 752
 		}
771 753
 	}
@@ -1122,10 +1104,17 @@ static void iscsi_newdata ( struct tcp_connection *conn, void *data,
1122 1104
  */
1123 1105
 static void iscsi_closed ( struct tcp_connection *conn, int status ) {
1124 1106
 	struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
1107
+	int session_status = iscsi->status;
1125 1108
 
1126 1109
 	/* Clear session status */
1127 1110
 	iscsi->status = 0;
1128 1111
 
1112
+	/* If we are deliberately closing down, exit cleanly */
1113
+	if ( session_status & ISCSI_STATUS_CLOSING ) {
1114
+		iscsi_done ( iscsi, status );
1115
+		return;
1116
+	}
1117
+
1129 1118
 	/* Retry connection if within the retry limit, otherwise fail */
1130 1119
 	if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) {
1131 1120
 		DBG ( "iSCSI %p retrying connection\n", iscsi );
@@ -1192,3 +1181,17 @@ struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
1192 1181
 
1193 1182
 	return &iscsi->aop;
1194 1183
 }
1184
+
1185
+/**
1186
+ * Close down iSCSI session
1187
+ *
1188
+ * @v iscsi		iSCSI session
1189
+ * @ret aop		Asynchronous operation
1190
+ */
1191
+struct async_operation * iscsi_shutdown ( struct iscsi_session *iscsi ) {
1192
+	if ( iscsi->status ) {
1193
+		iscsi->status |= ISCSI_STATUS_CLOSING;
1194
+		tcp_close ( &iscsi->tcp );
1195
+	}
1196
+	return &iscsi->aop;
1197
+}

+ 3
- 1
src/tests/iscsiboot.c Datei anzeigen

@@ -32,7 +32,7 @@ int test_iscsiboot ( const char *initiator_iqn,
32 32
 	printf ( "Initialising %s\n", target_iqn );
33 33
 	if ( ( rc = init_iscsidev ( &test_iscsidev ) ) != 0 ) {
34 34
 		printf ( "Could not reach %s: %s\n", target_iqn,
35
-			 strerror ( errno ) );
35
+			 strerror ( rc ) );
36 36
 		return rc;
37 37
 	}
38 38
 	ibft_fill_data ( netdev, initiator_iqn, target, target_iqn );
@@ -49,5 +49,7 @@ int test_iscsiboot ( const char *initiator_iqn,
49 49
 	printf ( "Unregistering BIOS drive %#02x\n", drive.drive );
50 50
 	unregister_int13_drive ( &drive );
51 51
 
52
+	fini_iscsidev ( &test_iscsidev );
53
+
52 54
 	return rc;
53 55
 }

Laden…
Abbrechen
Speichern