From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:39783) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TEKfn-0001px-NB for qemu-devel@nongnu.org; Wed, 19 Sep 2012 09:50:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TEKfh-0005j5-0A for qemu-devel@nongnu.org; Wed, 19 Sep 2012 09:50:39 -0400 Received: from mail-pb0-f45.google.com ([209.85.160.45]:56240) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TEKfg-0005IH-Pl for qemu-devel@nongnu.org; Wed, 19 Sep 2012 09:50:32 -0400 Received: by mail-pb0-f45.google.com with SMTP id rp12so2503409pbb.4 for ; Wed, 19 Sep 2012 06:50:32 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Wed, 19 Sep 2012 15:49:53 +0200 Message-Id: <1348062596-30446-10-git-send-email-pbonzini@redhat.com> In-Reply-To: <1348062596-30446-1-git-send-email-pbonzini@redhat.com> References: <1348062596-30446-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 09/12] qemu-nbd: rewrite termination conditions to use a state machine List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Use a simple state machine with the following states: - RUNNING => accepting connections - TERMINATE => main loop must call nbd_export_close/put, and not accept connections anymore - TERMINATING => waiting for pending requests to finish - TERMINATED => the NBDExport has been closed Signed-off-by: Paolo Bonzini --- qemu-nbd.c | 37 +++++++++++++++++++++++++++---------- 1 file modificato, 27 inserzioni(+), 10 rimozioni(-) diff --git a/qemu-nbd.c b/qemu-nbd.c index 8b87dea..15bcd08 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -41,8 +41,8 @@ static NBDExport *exp; static int verbose; static char *srcpath; static char *sockpath; -static bool sigterm_reported; -static bool nbd_started; +static int persistent = 0; +static enum { RUNNING, TERMINATE, TERMINATING, TERMINATED } state; static int shared = 1; static int nb_fds; @@ -186,7 +186,7 @@ static int find_partition(BlockDriverState *bs, int partition, static void termsig_handler(int signum) { - sigterm_reported = true; + state = TERMINATE; qemu_notify_event(); } @@ -269,10 +269,20 @@ static int nbd_can_accept(void *opaque) return nb_fds < shared; } +static void nbd_export_closed(NBDExport *exp) +{ + assert(state == TERMINATING); + state = TERMINATED; +} + static void nbd_client_closed(NBDClient *client) { nb_fds--; + if (nb_fds == 0 && !persistent && state == RUNNING) { + state = TERMINATE; + } qemu_notify_event(); + nbd_client_put(client); } static void nbd_accept(void *opaque) @@ -282,7 +292,11 @@ static void nbd_accept(void *opaque) socklen_t addr_len = sizeof(addr); int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len); - nbd_started = true; + if (state >= TERMINATE) { + close(fd); + return; + } + if (fd >= 0 && nbd_client_new(exp, fd, nbd_client_closed)) { nb_fds++; } @@ -329,7 +343,6 @@ int main(int argc, char **argv) int partition = -1; int ret; int fd; - int persistent = 0; bool seen_cache = false; #ifdef CONFIG_LINUX_AIO bool seen_aio = false; @@ -546,7 +559,7 @@ int main(int argc, char **argv) } } - exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, NULL); + exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, nbd_export_closed); if (sockpath) { fd = unix_socket_incoming(sockpath); @@ -581,14 +594,18 @@ int main(int argc, char **argv) err(EXIT_FAILURE, "Could not chdir to root directory"); } + state = RUNNING; do { main_loop_wait(false); - } while (!sigterm_reported && (persistent || !nbd_started || nb_fds > 0)); + if (state == TERMINATE) { + state = TERMINATING; + nbd_export_close(exp); + nbd_export_put(exp); + exp = NULL; + } + } while (state != TERMINATED); - nbd_export_close(exp); - nbd_export_put(exp); bdrv_close(bs); - if (sockpath) { unlink(sockpath); } -- 1.7.12