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