From patchwork Mon Dec 3 19:34:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Lieven X-Patchwork-Id: 203421 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 140CC2C0092 for ; Tue, 4 Dec 2012 06:34:32 +1100 (EST) Received: from localhost ([::1]:46598 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tfbmg-0005AZ-KL for incoming@patchwork.ozlabs.org; Mon, 03 Dec 2012 14:34:30 -0500 Received: from eggs.gnu.org ([208.118.235.92]:33847) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TfbmZ-0005AU-CJ for qemu-devel@nongnu.org; Mon, 03 Dec 2012 14:34:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TfbmV-0001zK-4D for qemu-devel@nongnu.org; Mon, 03 Dec 2012 14:34:23 -0500 Received: from ssl.dlhnet.de ([91.198.192.8]:33791 helo=ssl.dlh.net) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TfbmU-0001x9-Qz for qemu-devel@nongnu.org; Mon, 03 Dec 2012 14:34:19 -0500 Received: from localhost (localhost [127.0.0.1]) by ssl.dlh.net (Postfix) with ESMTP id BCE9014CE3E; Mon, 3 Dec 2012 20:34:17 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at ssl.dlh.net Received: from ssl.dlh.net ([127.0.0.1]) by localhost (ssl.dlh.net [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zM-cdOjsakqZ; Mon, 3 Dec 2012 20:34:17 +0100 (CET) Received: from [82.141.7.8] (unknown [82.141.7.8]) by ssl.dlh.net (Postfix) with ESMTPSA id 1C05114CA5D; Mon, 3 Dec 2012 20:34:17 +0100 (CET) Message-ID: <50BCFEB8.2070703@dlhnet.de> Date: Mon, 03 Dec 2012 20:34:16 +0100 From: Peter Lieven User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120827 Thunderbird/15.0 MIME-Version: 1.0 To: "qemu-devel@nongnu.org" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 91.198.192.8 Cc: kwolf@redhat.com, Paolo Bonzini , ronnie sahlberg Subject: [Qemu-devel] [PATCH][RESEND] iscsi: add support for iSCSI NOPs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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. Reported-by: Ronnie Sahlberg Signed-off-by: Peter Lieven Acked-By: ronniesahlberg@gmail.com (Ronnie Sahlberg) --- block/iscsi.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/block/iscsi.c b/block/iscsi.c index d0b1a10..fab4c8b 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -47,6 +47,9 @@ typedef struct IscsiLun { int block_size; uint64_t num_blocks; int events; + + QEMUTimer *nop_timer; + int nops_in_flight; } IscsiLun; typedef struct IscsiAIOCB { @@ -72,6 +75,9 @@ struct IscsiTask { int complete; }; +#define NOP_INTERVAL 5000 +#define MAX_NOP_FAILURES 3 + static void iscsi_bh_cb(void *p) { @@ -925,6 +931,35 @@ static char *parse_initiator_name(const char *target) } } +static void iscsi_nop_cb(struct iscsi_context *iscsi, int status, void *command_data, void *private_data) +{ + IscsiLun *iscsilun = private_data; + + if (iscsilun) { + iscsilun->nops_in_flight = 0; + } +} + +static void iscsi_nop_timed_event(void *opaque) +{ + IscsiLun *iscsilun = opaque; + + if (iscsilun->nops_in_flight > MAX_NOP_FAILURES) { + error_report("iSCSI: NOP timeout. Reconnecting..."); + iscsi_reconnect(iscsilun->iscsi); + iscsilun->nops_in_flight = 0; + } + + if (iscsi_nop_out_async(iscsilun->iscsi, iscsi_nop_cb, NULL, 0, iscsilun) != 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); + iscsilun->nops_in_flight++; +} + /* * We support iscsi url's on the form * iscsi://[%@][:]// @@ -1036,6 +1071,10 @@ static int iscsi_open(BlockDriverState *bs, const char *filename, int flags) ret = 0; + /* 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); + out: if (initiator_name != NULL) { g_free(initiator_name); @@ -1058,6 +1097,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));