[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 3/6] iscsi: add support for iSCSI NOPs [v2]
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH 3/6] iscsi: add support for iSCSI NOPs [v2] |
Date: |
Tue, 22 Jan 2013 15:19:53 +0100 |
From: Peter Lieven <address@hidden>
This patch will send NOP-Out PDUs every 5 seconds to the iSCSI target.
If a consecutive number of NOP-In replies fail a reconnect is initiated.
iSCSI NOPs help to ensure that the connection to the target is still
operational.
This should not, but in reality may be the case even if the TCP connection is
still
alive if there are bugs in either the target or the initiator implementation.
v2:
- track the NOPs inside libiscsi so libiscsi can reset the counter
in case it initiates a reconnect.
Signed-off-by: Peter Lieven <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
block/iscsi.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/block/iscsi.c b/block/iscsi.c
index 259192f..2497789 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -48,6 +48,7 @@ typedef struct IscsiLun {
int block_size;
uint64_t num_blocks;
int events;
+ QEMUTimer *nop_timer;
} IscsiLun;
typedef struct IscsiAIOCB {
@@ -66,6 +67,9 @@ typedef struct IscsiAIOCB {
#endif
} IscsiAIOCB;
+#define NOP_INTERVAL 5000
+#define MAX_NOP_FAILURES 3
+
static void
iscsi_bh_cb(void *p)
{
@@ -768,6 +772,26 @@ static char *parse_initiator_name(const char *target)
}
}
+#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
+static void iscsi_nop_timed_event(void *opaque)
+{
+ IscsiLun *iscsilun = opaque;
+
+ if (iscsi_get_nops_in_flight(iscsilun->iscsi) > MAX_NOP_FAILURES) {
+ error_report("iSCSI: NOP timeout. Reconnecting...");
+ iscsi_reconnect(iscsilun->iscsi);
+ }
+
+ if (iscsi_nop_out_async(iscsilun->iscsi, NULL, NULL, 0, NULL) != 0) {
+ error_report("iSCSI: failed to sent NOP-Out. Disabling NOP messages.");
+ return;
+ }
+
+ qemu_mod_timer(iscsilun->nop_timer, qemu_get_clock_ms(rt_clock) +
NOP_INTERVAL);
+ iscsi_set_events(iscsilun);
+}
+#endif
+
/*
* We support iscsi url's on the form
* iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
@@ -928,6 +952,12 @@ static int iscsi_open(BlockDriverState *bs, const char
*filename, int flags)
ret = 0;
+#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
+ /* Set up a timer for sending out iSCSI NOPs */
+ iscsilun->nop_timer = qemu_new_timer_ms(rt_clock, iscsi_nop_timed_event,
iscsilun);
+ qemu_mod_timer(iscsilun->nop_timer, qemu_get_clock_ms(rt_clock) +
NOP_INTERVAL);
+#endif
+
out:
if (initiator_name != NULL) {
g_free(initiator_name);
@@ -953,6 +983,10 @@ static void iscsi_close(BlockDriverState *bs)
IscsiLun *iscsilun = bs->opaque;
struct iscsi_context *iscsi = iscsilun->iscsi;
+ if (iscsilun->nop_timer) {
+ qemu_del_timer(iscsilun->nop_timer);
+ qemu_free_timer(iscsilun->nop_timer);
+ }
qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL, NULL);
iscsi_destroy_context(iscsi);
memset(iscsilun, 0, sizeof(IscsiLun));
@@ -987,6 +1021,10 @@ static int iscsi_create(const char *filename,
QEMUOptionParameter *options)
if (ret != 0) {
goto out;
}
+ if (iscsilun->nop_timer) {
+ qemu_del_timer(iscsilun->nop_timer);
+ qemu_free_timer(iscsilun->nop_timer);
+ }
if (iscsilun->type != TYPE_DISK) {
ret = -ENODEV;
goto out;
--
1.8.1
- [Qemu-devel] [PULL 1.4 0/6] Pending SCSI patches for 1.4, Paolo Bonzini, 2013/01/22
- [Qemu-devel] [PATCH 1/6] iscsi: add iscsi_create support, Paolo Bonzini, 2013/01/22
- [Qemu-devel] [PATCH 2/6] iscsi: partly avoid iovec linearization in iscsi_aio_writev, Paolo Bonzini, 2013/01/22
- [Qemu-devel] [PATCH 4/6] scsi: fix segfault with 0-byte disk, Paolo Bonzini, 2013/01/22
- [Qemu-devel] [PATCH 5/6] lsi: use qbus_reset_all to reset SCSI bus, Paolo Bonzini, 2013/01/22
- [Qemu-devel] [PATCH 3/6] iscsi: add support for iSCSI NOPs [v2],
Paolo Bonzini <=
- [Qemu-devel] [PATCH 6/6] scsi: Drop useless null test in scsi_unit_attention(), Paolo Bonzini, 2013/01/22