Test-tool: call iscsi_service on MP devices once every second so we respond to NOP

The test tool is simplistic and uses the synchronous API. In this API
we will only poll() the socket and process events during the lifetime of any
iscsi_*_sync() calls.

A problem with this approach arises with multipath tests. When iscsi-test-cu
is used with multiple devices we will first open a session for each
multipath leg, but then as most tests are only using the first device we end
up with creating secondary sessions we don't do any iscsi_*_sync() calls on
for very long times. If a target is set up to send NOPs on these
secondary paths it will not get any responses and eventually tear down the
connection.

To avoid this, try to make sure we service any secondary paths we have
created by calling iscsi_service(POLLIN|POLLOUT) every few seconds
to make sure we do service and respond to any NOPs.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
This commit is contained in:
Ronnie Sahlberg
2015-12-15 21:55:03 -08:00
parent 0407cf6aed
commit 5532325042

View File

@@ -34,6 +34,7 @@
#include <poll.h>
#include <fnmatch.h>
#include <errno.h>
#include <time.h>
#ifdef HAVE_SG_IO
#include <fcntl.h>
@@ -46,6 +47,7 @@
#include "scsi-lowlevel.h"
#include "iscsi-private.h"
#include "iscsi-support.h"
#include "iscsi-multipath.h"
/*****************************************************************
@@ -269,7 +271,11 @@ static size_t iov_tot_len(struct scsi_iovec *iov, int niov)
static struct scsi_task *send_scsi_command(struct scsi_device *sdev, struct scsi_task *task, struct iscsi_data *d)
{
static time_t last_time = 0;
if (sdev->iscsi_url) {
time_t current_time = time(NULL);
if (sdev->error_str != NULL) {
free(discard_const(sdev->error_str));
sdev->error_str = NULL;
@@ -279,6 +285,22 @@ static struct scsi_task *send_scsi_command(struct scsi_device *sdev, struct scsi
sdev->error_str = strdup(iscsi_get_error(sdev->iscsi_ctx));
}
if (current_time > last_time + 1) {
int i;
/* Device [0] is where we are doing all the I/O
* so it will always work the socket and respond
* to NOPs from the target.
* But we need to trigger a service event every
* now and then on all the other devices to ensure that
* we detect and respond to any NOPs.
*/
for (i = 1; i < mp_num_sds; i++) {
iscsi_service(mp_sds[i]->iscsi_ctx, POLLIN|POLLOUT);
}
last_time = current_time;
}
return task;
}