david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

Add ability to shut down iSCSI connection

This commit is contained in:
Michael Brown 2006-12-21 17:17:47 +00:00
parent 7ce3df65c2
commit ab242a760d
4 changed files with 49 additions and 24 deletions

View File

@ -46,7 +46,22 @@ static int iscsi_command ( struct scsi_device *scsi,
* @v iscsidev iSCSI device
*/
int init_iscsidev ( struct iscsi_device *iscsidev ) {
int rc;
iscsidev->scsi.command = iscsi_command;
iscsidev->scsi.lun = iscsidev->iscsi.lun;
return init_scsidev ( &iscsidev->scsi );
rc = init_scsidev ( &iscsidev->scsi );
if ( rc != 0 ) {
fini_iscsidev ( iscsidev );
}
return rc;
}
/**
* Shut down iSCSI device
*
* @v iscsidev iSCSI device
*/
void fini_iscsidev ( struct iscsi_device *iscsidev ) {
async_wait ( iscsi_shutdown ( &iscsidev->iscsi ) );
}

View File

@ -626,11 +626,15 @@ struct iscsi_session {
/** Mask for all iSCSI "needs to send" flags */
#define ISCSI_STATUS_STRINGS_MASK 0xff00
/** iSCSI session is closing down */
#define ISCSI_STATUS_CLOSING 0x00010000
/** Maximum number of retries at connecting */
#define ISCSI_MAX_RETRIES 2
extern struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
struct scsi_command *command );
extern struct async_operation * iscsi_shutdown ( struct iscsi_session *iscsi );
/** An iSCSI device */
struct iscsi_device {
@ -641,5 +645,6 @@ struct iscsi_device {
};
extern int init_iscsidev ( struct iscsi_device *iscsidev );
extern void fini_iscsidev ( struct iscsi_device *iscsidev );
#endif /* _GPXE_ISCSI_H */

View File

@ -104,24 +104,6 @@ static void iscsi_done ( struct iscsi_session *iscsi, int rc ) {
async_done ( &iscsi->aop, rc );
}
/**
* Mark iSCSI operation as complete, and close TCP connection
*
* @v iscsi iSCSI session
* @v rc Return status code
*/
static void iscsi_close ( struct iscsi_session *iscsi, int rc ) {
/* Clear session status */
iscsi->status = 0;
/* Close TCP connection */
tcp_close ( &iscsi->tcp );
/* Mark iSCSI operation as complete */
iscsi_done ( iscsi, rc );
}
/****************************************************************************
*
* iSCSI SCSI command issuing
@ -564,7 +546,7 @@ static void iscsi_handle_chap_a_value ( struct iscsi_session *iscsi,
/* Prepare for CHAP with MD5 */
if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
DBG ( "iSCSI %p could not initialise CHAP\n", iscsi );
iscsi_close ( iscsi, rc );
iscsi_done ( iscsi, rc );
}
}
@ -722,7 +704,7 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
/* Buffer up the PDU data */
if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
DBG ( "iSCSI %p could not buffer login response\n", iscsi );
iscsi_close ( iscsi, rc );
iscsi_done ( iscsi, rc );
return;
}
if ( remaining )
@ -747,7 +729,7 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
if ( response->status_class != 0 ) {
printf ( "iSCSI login failure: class %02x detail %02x\n",
response->status_class, response->status_detail );
iscsi_close ( iscsi, -EPERM );
iscsi_done ( iscsi, -EPERM );
return;
}
@ -765,7 +747,7 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
default:
DBG ( "iSCSI %p got invalid response flags %02x\n",
iscsi, response->flags );
iscsi_close ( iscsi, -EIO );
iscsi_done ( iscsi, -EIO );
return;
}
}
@ -1122,10 +1104,17 @@ static void iscsi_newdata ( struct tcp_connection *conn, void *data,
*/
static void iscsi_closed ( struct tcp_connection *conn, int status ) {
struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
int session_status = iscsi->status;
/* Clear session status */
iscsi->status = 0;
/* If we are deliberately closing down, exit cleanly */
if ( session_status & ISCSI_STATUS_CLOSING ) {
iscsi_done ( iscsi, status );
return;
}
/* Retry connection if within the retry limit, otherwise fail */
if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) {
DBG ( "iSCSI %p retrying connection\n", iscsi );
@ -1192,3 +1181,17 @@ struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
return &iscsi->aop;
}
/**
* Close down iSCSI session
*
* @v iscsi iSCSI session
* @ret aop Asynchronous operation
*/
struct async_operation * iscsi_shutdown ( struct iscsi_session *iscsi ) {
if ( iscsi->status ) {
iscsi->status |= ISCSI_STATUS_CLOSING;
tcp_close ( &iscsi->tcp );
}
return &iscsi->aop;
}

View File

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