From 7adcfacf9057c216beb99286e5f233e868865eae Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 21 Nov 2017 03:21:44 +0100 Subject: [PATCH 1/9] block/linux-aio: fix memory and fd leak RH-Author: Fam Zheng Message-id: <20171121032145.5681-2-famz@redhat.com> Patchwork-id: 77766 O-Subject: [RHEL-7.5 qemu-kvm PATCH v2 1/2] block/linux-aio: fix memory and fd leak Bugzilla: 1491434 RH-Acked-by: Stefan Hajnoczi RH-Acked-by: John Snow RH-Acked-by: Laurent Vivier From: Stefan Hajnoczi Hot unplugging -drive aio=native,file=test.img,format=raw images leaves the Linux AIO event notifier and struct qemu_laio_state allocated. Luckily nothing will use the event notifier after the BlockDriverState has been closed so the handler function is never called. It's still worth fixing this resource leak. Signed-off-by: Stefan Hajnoczi (cherry picked from commit abd269b7cf1f084a067731acb8f3272c193cb5f0) Signed-off-by: Fam Zheng Signed-off-by: Miroslav Rezanina Conflicts: block/linux-aio.c * Context is different: downstream we don't have raw_detach_aio_context() in raw_close(). * Downstream uses eventfd(2) instead of EventNotifier, so do close() directly here as well. --- block/linux-aio.c | 9 +++++++++ block/raw-aio.h | 1 + block/raw-posix.c | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/block/linux-aio.c b/block/linux-aio.c index 40041d1..43f14f3 100644 --- a/block/linux-aio.c +++ b/block/linux-aio.c @@ -225,3 +225,12 @@ out_free_state: g_free(s); return NULL; } + +void laio_cleanup(void *s_) +{ + struct qemu_laio_state *s = s_; + + qemu_aio_set_fd_handler(s->efd, NULL, NULL, NULL, NULL); + close(s->efd); + g_free(s); +} diff --git a/block/raw-aio.h b/block/raw-aio.h index 7ad0a8a..2dba2c6 100644 --- a/block/raw-aio.h +++ b/block/raw-aio.h @@ -34,6 +34,7 @@ /* linux-aio.c - Linux native implementation */ #ifdef CONFIG_LINUX_AIO void *laio_init(void); +void laio_cleanup(void *s); BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque, int type); diff --git a/block/raw-posix.c b/block/raw-posix.c index ed97bd4..c2b1be2 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1081,6 +1081,12 @@ static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs, static void raw_close(BlockDriverState *bs) { BDRVRawState *s = bs->opaque; + +#ifdef CONFIG_LINUX_AIO + if (s->use_aio) { + laio_cleanup(s->aio_ctx); + } +#endif if (s->fd >= 0) { qemu_close(s->fd); s->fd = -1; -- 1.8.3.1