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