Blob Blame Raw
From 7adcfacf9057c216beb99286e5f233e868865eae Mon Sep 17 00:00:00 2001
From: Fam Zheng <famz@redhat.com>
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 <famz@redhat.com>
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 <stefanha@redhat.com>
RH-Acked-by: John Snow <jsnow@redhat.com>
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>

From: Stefan Hajnoczi <stefanha@redhat.com>

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 <stefanha@redhat.com>
(cherry picked from commit abd269b7cf1f084a067731acb8f3272c193cb5f0)
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>

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