From patchwork Tue Dec 6 15:27:49 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 129743 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 73F141007D6 for ; Wed, 7 Dec 2011 03:57:28 +1100 (EST) Received: from localhost ([::1]:42654 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RXyKc-0001za-0Z for incoming@patchwork.ozlabs.org; Tue, 06 Dec 2011 11:57:26 -0500 Received: from eggs.gnu.org ([140.186.70.92]:38230) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RXwxQ-0003Eo-Dt for qemu-devel@nongnu.org; Tue, 06 Dec 2011 10:29:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RXwxJ-0000ep-9D for qemu-devel@nongnu.org; Tue, 06 Dec 2011 10:29:24 -0500 Received: from mail-ey0-f173.google.com ([209.85.215.173]:55812) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RXwxJ-0000FN-4O for qemu-devel@nongnu.org; Tue, 06 Dec 2011 10:29:17 -0500 Received: by mail-ey0-f173.google.com with SMTP id i10so5955043eaa.4 for ; Tue, 06 Dec 2011 07:29:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:subject:date:message-id:x-mailer:in-reply-to :references; bh=135uTE5Dr5Xdcev4B5/agK+0QPSLlDEfjmBOjDuXrco=; b=TC0hb4KP/w0jEKHy/SKxSqWy8hWgE3ExJJB48KpjkrlaTj8eHxV9jbrSL+ZAA0Fekt sytnrNCvx9cVRRHwdhkZR2Ee3O2Y5j+75zor7lK+THGf/1FgueNLf34C7II3rZWMh/7D 0YhTMMeYgod+7O/rGEBTAKJerptWRhyrk2Lu0= Received: by 10.50.185.138 with SMTP id fc10mr15308811igc.33.1323185356493; Tue, 06 Dec 2011 07:29:16 -0800 (PST) Received: from localhost.localdomain (93-34-178-147.ip50.fastwebnet.it. [93.34.178.147]) by mx.google.com with ESMTPS id ee6sm36334978igc.6.2011.12.06.07.29.14 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 06 Dec 2011 07:29:15 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 6 Dec 2011 16:27:49 +0100 Message-Id: <1323185272-2610-23-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.7.1 In-Reply-To: <1323185272-2610-1-git-send-email-pbonzini@redhat.com> References: <1323185272-2610-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.215.173 Subject: [Qemu-devel] [PATCH 22/25] qemu-nbd: move client handling to nbd.c 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 sets up the fd handler in nbd.c instead of qemu-nbd.c. It introduces NBDClient, which wraps the arguments to nbd_trip in a single structure, so that we can add a notifier to it. This way, qemu-nbd can know about disconnections. Signed-off-by: Paolo Bonzini --- nbd.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- nbd.h | 5 ++- qemu-nbd.c | 14 +++--------- 3 files changed, 66 insertions(+), 15 deletions(-) diff --git a/nbd.c b/nbd.c index 962cfc3..f479c30 100644 --- a/nbd.c +++ b/nbd.c @@ -600,6 +600,37 @@ struct NBDExport { QSIMPLEQ_HEAD(, NBDRequest) requests; }; +struct NBDClient { + int refcount; + void (*close)(NBDClient *client); + + NBDExport *exp; + int sock; +}; + +static void nbd_client_get(NBDClient *client) +{ + client->refcount++; +} + +static void nbd_client_put(NBDClient *client) +{ + if (--client->refcount == 0) { + g_free(client); + } +} + +static void nbd_client_close(NBDClient *client) +{ + qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL); + close(client->sock); + client->sock = -1; + if (client->close) { + client->close(client); + } + nbd_client_put(client); +} + static NBDRequest *nbd_request_get(NBDExport *exp) { NBDRequest *req; @@ -712,9 +743,11 @@ out: return rc; } -int nbd_trip(NBDExport *exp, int csock) +static int nbd_trip(NBDClient *client) { + NBDExport *exp = client->exp; NBDRequest *req = nbd_request_get(exp); + int csock = client->sock; struct nbd_request request; struct nbd_reply reply; int rc = -1; @@ -836,7 +869,30 @@ out: return rc; } -int nbd_negotiate(NBDExport *exp, int csock) +static void nbd_read(void *opaque) +{ + NBDClient *client = opaque; + + nbd_client_get(client); + if (nbd_trip(client) != 0) { + nbd_client_close(client); + } + + nbd_client_put(client); +} + +NBDClient *nbd_client_new(NBDExport *exp, int csock, + void (*close)(NBDClient *)) { - return nbd_send_negotiate(csock, exp->size, exp->nbdflags); + NBDClient *client; + if (nbd_send_negotiate(csock, exp->size, exp->nbdflags) == -1) { + return NULL; + } + client = g_malloc0(sizeof(NBDClient)); + client->refcount = 1; + client->exp = exp; + client->sock = csock; + client->close = close; + qemu_set_fd_handler2(csock, NULL, nbd_read, NULL, client); + return client; } diff --git a/nbd.h b/nbd.h index c77c2fd..a8382f0 100644 --- a/nbd.h +++ b/nbd.h @@ -76,11 +76,12 @@ int nbd_client(int fd); int nbd_disconnect(int fd); typedef struct NBDExport NBDExport; +typedef struct NBDClient NBDClient; NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size, uint32_t nbdflags); void nbd_export_close(NBDExport *exp); -int nbd_negotiate(NBDExport *exp, int csock); -int nbd_trip(NBDExport *exp, int csock); +NBDClient *nbd_client_new(NBDExport *exp, int csock, + void (*close)(NBDClient *)); #endif diff --git a/qemu-nbd.c b/qemu-nbd.c index 347c776..155b058 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -249,15 +249,10 @@ static int nbd_can_accept(void *opaque) return nb_fds < shared; } -static void nbd_read(void *opaque) +static void nbd_client_closed(NBDClient *client) { - int fd = (uintptr_t) opaque; - - if (nbd_trip(exp, fd) != 0) { - qemu_set_fd_handler2(fd, NULL, NULL, NULL, NULL); - close(fd); - nb_fds--; - } + nb_fds--; + qemu_notify_event(); } static void nbd_accept(void *opaque) @@ -268,8 +263,7 @@ static void nbd_accept(void *opaque) int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len); nbd_started = true; - if (fd != -1 && nbd_negotiate(exp, fd) != -1) { - qemu_set_fd_handler2(fd, NULL, nbd_read, NULL, (void *) (intptr_t) fd); + if (fd != -1 && nbd_client_new(exp, fd, nbd_client_closed)) { nb_fds++; } }