Let's factor it out so we can reuse it. Signed-off-by: David Hildenbrand <da...@redhat.com> Signed-off-by: Steve Sistare <steven.sist...@oracle.com> Reviewed-by: Peter Xu <pet...@redhat.com> --- backends/hostmem-shm.c | 45 ++++--------------------------------------- include/qemu/osdep.h | 1 + meson.build | 8 ++++++-- util/oslib-posix.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ util/oslib-win32.c | 6 ++++++ 5 files changed, 69 insertions(+), 43 deletions(-)
diff --git a/backends/hostmem-shm.c b/backends/hostmem-shm.c index 5551ba7..fabee41 100644 --- a/backends/hostmem-shm.c +++ b/backends/hostmem-shm.c @@ -25,11 +25,9 @@ struct HostMemoryBackendShm { static bool shm_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) { - g_autoptr(GString) shm_name = g_string_new(NULL); g_autofree char *backend_name = NULL; uint32_t ram_flags; - int fd, oflag; - mode_t mode; + int fd; if (!backend->size) { error_setg(errp, "can't create shm backend with size 0"); @@ -41,48 +39,13 @@ shm_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) return false; } - /* - * Let's use `mode = 0` because we don't want other processes to open our - * memory unless we share the file descriptor with them. - */ - mode = 0; - oflag = O_RDWR | O_CREAT | O_EXCL; - backend_name = host_memory_backend_get_name(backend); - - /* - * Some operating systems allow creating anonymous POSIX shared memory - * objects (e.g. FreeBSD provides the SHM_ANON constant), but this is not - * defined by POSIX, so let's create a unique name. - * - * From Linux's shm_open(3) man-page: - * For portable use, a shared memory object should be identified - * by a name of the form /somename;" - */ - g_string_printf(shm_name, "/qemu-" FMT_pid "-shm-%s", getpid(), - backend_name); - - fd = shm_open(shm_name->str, oflag, mode); + fd = qemu_shm_alloc(backend->size, errp); if (fd < 0) { - error_setg_errno(errp, errno, - "failed to create POSIX shared memory"); - return false; - } - - /* - * We have the file descriptor, so we no longer need to expose the - * POSIX shared memory object. However it will remain allocated as long as - * there are file descriptors pointing to it. - */ - shm_unlink(shm_name->str); - - if (ftruncate(fd, backend->size) == -1) { - error_setg_errno(errp, errno, - "failed to resize POSIX shared memory to %" PRIu64, - backend->size); - close(fd); return false; } + /* Let's do the same as memory-backend-ram,share=on would do. */ + backend_name = host_memory_backend_get_name(backend); ram_flags = RAM_SHARED; ram_flags |= backend->reserve ? 0 : RAM_NORESERVE; diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index b94fb5f..112ebdf 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -509,6 +509,7 @@ int qemu_daemon(int nochdir, int noclose); void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared, bool noreserve); void qemu_anon_ram_free(void *ptr, size_t size); +int qemu_shm_alloc(size_t size, Error **errp); #ifdef _WIN32 #define HAVE_CHARDEV_SERIAL 1 diff --git a/meson.build b/meson.build index b715ea7..2e709c9 100644 --- a/meson.build +++ b/meson.build @@ -3706,9 +3706,13 @@ libqemuutil = static_library('qemuutil', build_by_default: false, sources: util_ss.sources() + stub_ss.sources() + genh, dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc]) +qemuutil_deps = [event_loop_base] +if host_os != 'windows' + qemuutil_deps += [rt] +endif qemuutil = declare_dependency(link_with: libqemuutil, sources: genh + version_res, - dependencies: [event_loop_base]) + dependencies: qemuutil_deps) if have_system or have_user decodetree = generator(find_program('scripts/decodetree.py'), @@ -4362,7 +4366,7 @@ if have_tools subdir('contrib/elf2dmp') executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), - dependencies: qemuutil, + dependencies: [qemuutil, rt], install: true) if have_vhost_user diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 7a542cb..2bb34da 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -931,3 +931,55 @@ void qemu_close_all_open_fd(const int *skip, unsigned int nskip) qemu_close_all_open_fd_fallback(skip, nskip, open_max); } } + +int qemu_shm_alloc(size_t size, Error **errp) +{ + g_autoptr(GString) shm_name = g_string_new(NULL); + int fd, oflag, cur_sequence; + static int sequence; + mode_t mode; + + cur_sequence = qatomic_fetch_inc(&sequence); + + /* + * Let's use `mode = 0` because we don't want other processes to open our + * memory unless we share the file descriptor with them. + */ + mode = 0; + oflag = O_RDWR | O_CREAT | O_EXCL; + + /* + * Some operating systems allow creating anonymous POSIX shared memory + * objects (e.g. FreeBSD provides the SHM_ANON constant), but this is not + * defined by POSIX, so let's create a unique name. + * + * From Linux's shm_open(3) man-page: + * For portable use, a shared memory object should be identified + * by a name of the form /somename;" + */ + g_string_printf(shm_name, "/qemu-" FMT_pid "-shm-%d", getpid(), + cur_sequence); + + fd = shm_open(shm_name->str, oflag, mode); + if (fd < 0) { + error_setg_errno(errp, errno, + "failed to create POSIX shared memory"); + return -1; + } + + /* + * We have the file descriptor, so we no longer need to expose the + * POSIX shared memory object. However it will remain allocated as long as + * there are file descriptors pointing to it. + */ + shm_unlink(shm_name->str); + + if (ftruncate(fd, size) == -1) { + error_setg_errno(errp, errno, + "failed to resize POSIX shared memory to %zu", size); + close(fd); + return -1; + } + + return fd; +} diff --git a/util/oslib-win32.c b/util/oslib-win32.c index b623830..b735163 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -877,3 +877,9 @@ void qemu_win32_map_free(void *ptr, HANDLE h, Error **errp) } CloseHandle(h); } + +int qemu_shm_alloc(size_t size, Error **errp) +{ + error_setg(errp, "Shared memory is not supported."); + return -1; +} -- 1.8.3.1