The inflight fd code is guarded by #ifdef MFD_ALLOW_SEALING, which only tells us that the headers define the flag, not that memfd_create() is available in the C library. There are environments where the flag is defined but the link fails:
ld: error: libvhost-user.a(libvhost-user.c.o): undefined symbol: memfd_create Probe for memfd_create() with MFD_ALLOW_SEALING in the subproject's meson.build, using the same test QEMU's top-level meson.build uses for CONFIG_MEMFD, and guard the code with CONFIG_MEMFD instead. When memfd is not available, VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD is masked out as before, so the frontend never sends VHOST_USER_GET_INFLIGHT_FD. Signed-off-by: Tim Pambor <[email protected]> --- subprojects/libvhost-user/libvhost-user.c | 17 ++++++++--------- subprojects/libvhost-user/meson.build | 11 ++++++++++- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvhost-user/libvhost-user.c index 7ce73fba19..32b7ae82ce 100644 --- a/subprojects/libvhost-user/libvhost-user.c +++ b/subprojects/libvhost-user/libvhost-user.c @@ -85,7 +85,7 @@ int eventfd_read(int fd, eventfd_t *value) } #endif -#ifdef MFD_ALLOW_SEALING +#ifdef CONFIG_MEMFD #include <fcntl.h> #ifndef F_LINUX_SPECIFIC_BASE @@ -1963,13 +1963,12 @@ vu_get_protocol_features_exec(VuDev *dev, VhostUserMsg *vmsg) features |= dev->iface->get_protocol_features(dev); } -#ifndef MFD_ALLOW_SEALING +#ifndef CONFIG_MEMFD /* - * If MFD_ALLOW_SEALING is not defined, we are not able to handle - * VHOST_USER_GET_INFLIGHT_FD messages, since we can't create a memfd. - * Those messages are used only if VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD - * is negotiated. A device implementation can enable it, so let's mask - * it to avoid a runtime panic. + * Without memfd we are not able to handle VHOST_USER_GET_INFLIGHT_FD + * messages. Those messages are used only if + * VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD is negotiated. A device + * implementation can enable it, so let's mask it to avoid a runtime panic. */ features &= ~(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD); #endif @@ -2164,7 +2163,7 @@ vu_inflight_queue_size(uint16_t queue_size) sizeof(uint16_t), INFLIGHT_ALIGNMENT); } -#ifdef MFD_ALLOW_SEALING +#ifdef CONFIG_MEMFD static void * memfd_alloc(const char *name, size_t size, unsigned int flags, int *fd) { @@ -2231,7 +2230,7 @@ vu_get_inflight_fd(VuDev *dev, VhostUserMsg *vmsg) mmap_size = vu_inflight_queue_size(queue_size) * num_queues; -#ifdef MFD_ALLOW_SEALING +#ifdef CONFIG_MEMFD addr = memfd_alloc("vhost-inflight", mmap_size, F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL, &fd); diff --git a/subprojects/libvhost-user/meson.build b/subprojects/libvhost-user/meson.build index a18014e7f2..aa5894a642 100644 --- a/subprojects/libvhost-user/meson.build +++ b/subprojects/libvhost-user/meson.build @@ -11,10 +11,19 @@ add_project_arguments(cc.get_supported_arguments('-Wsign-compare', threads = dependency('threads') glib = dependency('glib-2.0') +vhost_user_flags = ['-D_GNU_SOURCE'] + +if cc.links(''' + #define _GNU_SOURCE + #include <sys/mman.h> + int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }''') + vhost_user_flags += '-DCONFIG_MEMFD' +endif + vhost_user = static_library('vhost-user', files('libvhost-user.c'), dependencies: threads, - c_args: '-D_GNU_SOURCE') + c_args: vhost_user_flags) executable('link-test', files('link-test.c'), link_whole: vhost_user) -- 2.55.0
