diff mbox series

[1/1] package/util-linux: fix libuuid build without pthread

Message ID 20250121210507.661525-1-ju.o@free.fr
State Superseded
Headers show
Series [1/1] package/util-linux: fix libuuid build without pthread | expand

Commit Message

Julien Olivain Jan. 21, 2025, 9:05 p.m. UTC
Since Buildroot commit [1], util-linux libuuid is failing to build
with uclibc toolchains, when there is no thread support
(that is, when BR2_PTHREADS_NONE=y).

Builds are failing with error:

    libuuid/src/gen_uuid.c:83:10: fatal error: pthread.h: No such file or directory
       83 | #include <pthread.h>
          |          ^~~~~~~~~~~

This failure is due to the upstream commit [2], which introduced the
pthread dependency.

This commit fixes the issue by adding a package patch, reimplementing
an equivalent behavior without using the pthread library.

Fixes:
https://autobuild.buildroot.org/results/e5856cf6f3b8512ededa17d20db2b330a478dd8e/

[1] https://gitlab.com/buildroot.org/buildroot/-/commit/f14929c657a7b1794dcd39ac469d2ad826465d98
[2] https://github.com/util-linux/util-linux/commit/25bd5396ab700623134b491f42a3280556cb674c

Signed-off-by: Julien Olivain <ju.o@free.fr>
---
Patch (build) tested in:
https://gitlab.com/jolivain/buildroot/-/pipelines/1634968321

Note: there was two build failures, unrelated to this patch.

The package patch was also tested at runtime, in qemu, with the code
reproducing the issue from:
https://github.com/util-linux/util-linux/issues/3009
util-linux 2.39.3 (previous Buildroot version) was compiling but could
generate duplicate uuids.
util-linux 2.40.2 with this patch is compiling, and does not generate
duplicate uuids.
---
 ...thread_atfork-usage-to-clear-uuidd-c.patch | 107 ++++++++++++++++++
 1 file changed, 107 insertions(+)
 create mode 100644 package/util-linux/0002-libuuid-remove-pthread_atfork-usage-to-clear-uuidd-c.patch
diff mbox series

Patch

diff --git a/package/util-linux/0002-libuuid-remove-pthread_atfork-usage-to-clear-uuidd-c.patch b/package/util-linux/0002-libuuid-remove-pthread_atfork-usage-to-clear-uuidd-c.patch
new file mode 100644
index 0000000000..068c1808d2
--- /dev/null
+++ b/package/util-linux/0002-libuuid-remove-pthread_atfork-usage-to-clear-uuidd-c.patch
@@ -0,0 +1,107 @@ 
+From ee06934d1819514ca2442054a47638ab9b190c44 Mon Sep 17 00:00:00 2001
+From: Julien Olivain <ju.o@free.fr>
+Date: Tue, 21 Jan 2025 21:13:19 +0100
+Subject: [PATCH] libuuid: remove pthread_atfork() usage to clear uuidd cache
+ at fork()
+
+libuuid had an issue [1] in which it was returning duplicated
+(non-unique) uuids after a fork(). This was due to a reuse of cached
+values.
+
+The commit [2] fixed this issue by registering a cache reset function
+with pthread_atfork(), which is one of the rare possible standard call
+to do that.
+
+Before commit [2], libuuid was not depending on the pthread library.
+Many packages (also not strongly requiring a pthread library) are
+using libuuid. Example of those libuuid users still working without
+pthread are: e2fsprogs, erofs-utils, f2fs-tools, mtd, parted, ...
+Commit [2] is now propagating this dependency on all those packages.
+
+While this is not an issue on most mainstream Linux distributions
+(which are all including a pthread library), this introduced many
+failures in Buildroot Linux. See [3] and [4]. In this case, Buildroot
+Linux includes several configurations without pthread support. Those
+are based on the uClibc-ng. See [5]. Those configurations can still be
+useful in specific cases (very low resource systems, debug sessions,
+bring-ups, ...). Most of the packages using libuuid are low level
+system tools. Bringing a pthread requirement on them would reduce
+the number of cases in which they can be used.
+
+This commit proposes an alternate implementation of the uuidd cache
+cleanup, without relying on pthread_atfork(). Instead, it records the
+PID of the owner process which initialized the cache, and invalidate
+it if is about to be used by another PID. Since the pthread library
+is no longer needed, build system files are also updated accordingly.
+
+[1] https://github.com/util-linux/util-linux/issues/3009
+[2] https://github.com/t-8ch/util-linux/commit/25bd5396ab700623134b491f42a3280556cb674c
+[3] https://buildroot.org/
+[4] https://autobuild.buildroot.org/?reason=util-linux-2.40.2
+[5] https://uclibc-ng.org/
+
+Upstream: Proposed: https://github.com/util-linux/util-linux/pull/3375
+[Julien: rebased on v2.40.2]
+Signed-off-by: Julien Olivain <ju.o@free.fr>
+---
+ libuuid/src/Makemodule.am |  2 +-
+ libuuid/src/gen_uuid.c    | 11 +++++------
+ 2 files changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/libuuid/src/Makemodule.am b/libuuid/src/Makemodule.am
+index 867ad7be5..be2781123 100644
+--- a/libuuid/src/Makemodule.am
++++ b/libuuid/src/Makemodule.am
+@@ -31,7 +31,7 @@ libuuid_la_SOURCES = \
+ EXTRA_libuuid_la_DEPENDENCIES = \
+ 	libuuid/src/libuuid.sym
+ 
+-libuuid_la_LIBADD       = $(LDADD) $(SOCKET_LIBS) -lpthread
++libuuid_la_LIBADD       = $(LDADD) $(SOCKET_LIBS)
+ 
+ libuuid_la_CFLAGS = \
+ 	$(AM_CFLAGS) \
+diff --git a/libuuid/src/gen_uuid.c b/libuuid/src/gen_uuid.c
+index 3b76ddc9a..2482c4789 100644
+--- a/libuuid/src/gen_uuid.c
++++ b/libuuid/src/gen_uuid.c
+@@ -80,8 +80,6 @@
+ #if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
+ #include <sys/syscall.h>
+ #endif
+-#include <pthread.h>
+-#include <signal.h>
+ 
+ #include "all-io.h"
+ #include "uuidP.h"
+@@ -589,6 +587,7 @@ THREAD_LOCAL struct {
+ 	int		last_used;
+ 	struct uuid	uu;
+ 	time_t		last_time;
++	pid_t		owner;
+ } uuidd_cache = {
+ 	.cache_size = CS_MIN,
+ };
+@@ -597,15 +596,15 @@ static void reset_uuidd_cache(void)
+ {
+ 	memset(&uuidd_cache, 0, sizeof(uuidd_cache));
+ 	uuidd_cache.cache_size = CS_MIN;
++	uuidd_cache.owner = getpid();
+ }
+ 
+ static int uuid_generate_time_generic(uuid_t out) {
+-	static volatile sig_atomic_t atfork_registered;
+ 	time_t	now;
+ 
+-	if (!atfork_registered) {
+-		pthread_atfork(NULL, NULL, reset_uuidd_cache);
+-		atfork_registered = 1;
++	/* avoid returning duplicate uuid from cache, in case of a fork() */
++	if (uuidd_cache.owner != getpid()) {
++		reset_uuidd_cache();
+ 	}
+ 
+ 	if (uuidd_cache.num > 0) { /* expire cache */
+-- 
+2.48.1
+