From: Michael Jeanson Date: Wed, 4 Nov 2020 15:00:31 +0000 (-0500) Subject: port: set shm size with ftruncate before writing X-Git-Tag: v2.13.0-rc1~464 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=053e6e240f3fb5b2427fb28f8f09c652e2bdb39a;p=lttng-ust.git port: set shm size with ftruncate before writing According to POSIX, the size of shared memory object must be set with ftruncate before writing to it. This happenen to work on Linux because the implementation simply creates files on a tmpfs but on FreeBSD it is implemented using actual shared memory objects and as such requires the size to be set first. Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers Change-Id: I048f65104d7c34142025337ec1f6777650bfd62f --- diff --git a/libringbuffer/shm.c b/libringbuffer/shm.c index 9160c218..566ed467 100644 --- a/libringbuffer/shm.c +++ b/libringbuffer/shm.c @@ -128,19 +128,27 @@ struct shm_object *_shm_object_table_alloc_shm(struct shm_object_table *table, } memcpy(obj->wait_fd, waitfd, sizeof(waitfd)); - /* create shm */ + /* + * Set POSIX shared memory object size + * + * First, use ftruncate() to set its size, some implementations won't + * allow writes past the size set by ftruncate. + * Then, use write() to fill it with zeros, this allows us to fully + * allocate it and detect a shortage of shm space without dealing with + * a SIGBUS. + */ shmfd = stream_fd; - ret = zero_file(shmfd, memory_map_size); - if (ret) { - PERROR("zero_file"); - goto error_zero_file; - } ret = ftruncate(shmfd, memory_map_size); if (ret) { PERROR("ftruncate"); goto error_ftruncate; } + ret = zero_file(shmfd, memory_map_size); + if (ret) { + PERROR("zero_file"); + goto error_zero_file; + } /* * Also ensure the file metadata is synced with the storage by using * fsync(2).