From dcff1035dfdfb4c76634df64a5359ac18749f7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 23 Oct 2017 15:18:07 +0100 Subject: [PATCH] memfd: split qemu_memfd_alloc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a function to only create a memfd, without mmap. The function is used in the following memory backend. Signed-off-by: Marc-André Lureau Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20171023141815.17709-2-marcandre.lureau@redhat.com> Signed-off-by: Eduardo Habkost --- include/qemu/memfd.h | 1 + util/memfd.c | 61 ++++++++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/include/qemu/memfd.h b/include/qemu/memfd.h index 745a8c501e..41c24d807c 100644 --- a/include/qemu/memfd.h +++ b/include/qemu/memfd.h @@ -16,6 +16,7 @@ #define F_SEAL_WRITE 0x0008 /* prevent writes */ #endif +int qemu_memfd_create(const char *name, size_t size, unsigned int seals); void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals, int *fd); void qemu_memfd_free(void *ptr, size_t size, int fd); diff --git a/util/memfd.c b/util/memfd.c index 412e94a405..3a82505f8d 100644 --- a/util/memfd.c +++ b/util/memfd.c @@ -53,6 +53,38 @@ static int memfd_create(const char *name, unsigned int flags) #define MFD_ALLOW_SEALING 0x0002U #endif +int qemu_memfd_create(const char *name, size_t size, unsigned int seals) +{ + int mfd = -1; + +#ifdef CONFIG_LINUX + unsigned int flags = MFD_CLOEXEC; + + if (seals) { + flags |= MFD_ALLOW_SEALING; + } + + mfd = memfd_create(name, flags); + if (mfd < 0) { + return -1; + } + + if (ftruncate(mfd, size) == -1) { + perror("ftruncate"); + close(mfd); + return -1; + } + + if (seals && fcntl(mfd, F_ADD_SEALS, seals) == -1) { + perror("fcntl"); + close(mfd); + return -1; + } +#endif + + return mfd; +} + /* * This is a best-effort helper for shared memory allocation, with * optional sealing. The helper will do his best to allocate using @@ -63,35 +95,14 @@ void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals, int *fd) { void *ptr; - int mfd = -1; + int mfd = qemu_memfd_create(name, size, seals); - *fd = -1; - -#ifdef CONFIG_LINUX - if (seals) { - mfd = memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC); + /* some systems have memfd without sealing */ + if (mfd == -1) { + mfd = qemu_memfd_create(name, size, 0); } if (mfd == -1) { - /* some systems have memfd without sealing */ - mfd = memfd_create(name, MFD_CLOEXEC); - seals = 0; - } -#endif - - if (mfd != -1) { - if (ftruncate(mfd, size) == -1) { - perror("ftruncate"); - close(mfd); - return NULL; - } - - if (seals && fcntl(mfd, F_ADD_SEALS, seals) == -1) { - perror("fcntl"); - close(mfd); - return NULL; - } - } else { const char *tmpdir = g_get_tmp_dir(); gchar *fname;