NOP count in flight of client generated NOP-Outs
This patch adds the abilitiy to libiscsi to count the number of consecutive outstanding NOPs. With this ability its fairly easy to implement a keepalive check with NOPs in your application. Periodically (e.g. every 5 secs) create a NOP-Out with: iscsi_nop_out_async(iscsi, NULL, NULL, 0, NULL); At that time check the number of consecutive missing NOP-Ins with iscsi_get_nops_in_flight(iscsi) > N. Where N is the number of missing NOP-Ins you will allow. Please note that it is legitime for the Target to ignore a NOP if the load is very high as those packet are mark as IMMEDIATE. Signed-off-by: Peter Lieven <pl@kamp.de>
This commit is contained in:
@@ -95,6 +95,7 @@ struct iscsi_context {
|
||||
int is_loggedin;
|
||||
int is_reconnecting;
|
||||
int bind_interfaces_cnt;
|
||||
int nops_in_flight;
|
||||
|
||||
int chap_a;
|
||||
int chap_i;
|
||||
@@ -122,7 +123,7 @@ struct iscsi_context {
|
||||
int no_auto_reconnect;
|
||||
int reconnect_deferred;
|
||||
int reconnect_max_retries;
|
||||
|
||||
|
||||
int log_level;
|
||||
iscsi_log_fn log_fn;
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ struct sockaddr;
|
||||
|
||||
/* FEATURES */
|
||||
#define LIBISCSI_FEATURE_IOVECTOR (1)
|
||||
#define LIBISCSI_FEATURE_NOP_COUNTER (1)
|
||||
|
||||
#define MAX_STRING_SIZE (255)
|
||||
|
||||
@@ -474,10 +475,17 @@ struct iscsi_discovery_address {
|
||||
* structure containing the data returned from
|
||||
* the server.
|
||||
* ISCSI_STATUS_CANCELLED: Discovery was aborted. Command_data is NULL.
|
||||
*
|
||||
* The callback may be NULL if you only want to let libiscsi count the in-flight
|
||||
* NOPs.
|
||||
*/
|
||||
EXTERN int iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
unsigned char *data, int len, void *private_data);
|
||||
|
||||
|
||||
/* read out the number of consecutive nop outs that did not receive an answer */
|
||||
EXTERN int iscsi_get_nops_in_flight(struct iscsi_context *iscsi);
|
||||
|
||||
struct scsi_task;
|
||||
|
||||
enum iscsi_task_mgmt_funcs {
|
||||
|
||||
@@ -14,6 +14,7 @@ iscsi_get_fd
|
||||
iscsi_get_lba_status_sync
|
||||
iscsi_get_lba_status_task
|
||||
iscsi_get_target_address
|
||||
iscsi_get_nops_in_flight
|
||||
iscsi_inquiry_sync
|
||||
iscsi_inquiry_task
|
||||
iscsi_is_logged_in
|
||||
|
||||
@@ -12,6 +12,7 @@ iscsi_get_fd
|
||||
iscsi_get_lba_status_sync
|
||||
iscsi_get_lba_status_task
|
||||
iscsi_get_target_address
|
||||
iscsi_get_nops_in_flight
|
||||
iscsi_inquiry_sync
|
||||
iscsi_inquiry_task
|
||||
iscsi_is_logged_in
|
||||
|
||||
14
lib/nop.c
14
lib/nop.c
@@ -81,6 +81,8 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
return -1;
|
||||
}
|
||||
|
||||
iscsi->nops_in_flight++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -130,6 +132,12 @@ iscsi_process_nop_out_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
||||
{
|
||||
struct iscsi_data data;
|
||||
|
||||
iscsi->nops_in_flight = 0;
|
||||
|
||||
if (pdu->callback == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
data.data = NULL;
|
||||
data.size = 0;
|
||||
|
||||
@@ -137,7 +145,13 @@ iscsi_process_nop_out_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
||||
data.data = in->data;
|
||||
data.size = in->data_pos;
|
||||
}
|
||||
|
||||
pdu->callback(iscsi, SCSI_STATUS_GOOD, &data, pdu->private_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iscsi_get_nops_in_flight(struct iscsi_context *iscsi)
|
||||
{
|
||||
return iscsi->nops_in_flight;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user