All of lore.kernel.org
 help / color / mirror / Atom feed
* [nft PATCH v4] configure: Implement --enable-profiling option
@ 2026-02-12 20:50 Phil Sutter
  2026-02-13 11:35 ` Florian Westphal
  0 siblings, 1 reply; 3+ messages in thread
From: Phil Sutter @ 2026-02-12 20:50 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, Florian Westphal

This will set compiler flag --coverage so code coverage may be inspected
using gcov.

In order to successfully profile processes which are killed or
interrupted as well, add a signal handler for those cases which calls
exit(). This is relevant for test cases invoking nft monitor.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since v3:
- Avoid illegal exit() call in signal handler by use of signalfd()

Changes since v2:
- Include profiling option value in configure's final status report
- Fix build for --enable-profiling
- Add copyright statement to new source file

Changes since v1:
- Add src/profiling.c and include/profiling.h to keep conditionally
  built code separate
---
 .gitignore          |  5 +++++
 Makefile.am         | 21 +++++++++++++++++++
 configure.ac        | 10 ++++++++-
 include/profiling.h | 12 +++++++++++
 src/mnl.c           |  9 +++++++-
 src/profiling.c     | 51 +++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 106 insertions(+), 2 deletions(-)
 create mode 100644 include/profiling.h
 create mode 100644 src/profiling.c

diff --git a/.gitignore b/.gitignore
index 719829b65d212..8673393fac397 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,11 @@ nftversion.h
 # cscope files
 /cscope.*
 
+# gcov-related
+*.gcda
+*.gcno
+*.gcov
+
 # Generated by tests
 *.payload.got
 tests/build/tests.log
diff --git a/Makefile.am b/Makefile.am
index bff746b53a0b4..efc11e44e0b59 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -96,6 +96,7 @@ noinst_HEADERS = \
 	include/owner.h \
 	include/parser.h \
 	include/payload.h \
+	include/profiling.h \
 	include/proto.h \
 	include/rt.h \
 	include/rule.h \
@@ -163,6 +164,10 @@ AM_CFLAGS = \
 
 AM_YFLAGS = -d -Wno-yacc
 
+if BUILD_PROFILING
+AM_CFLAGS += --coverage
+endif
+
 ###############################################################################
 
 BUILT_SOURCES += src/parser_bison.h
@@ -264,6 +269,10 @@ src_libnftables_la_SOURCES += \
 	$(NULL)
 endif
 
+if BUILD_PROFILING
+src_libnftables_la_SOURCES += src/profiling.c
+endif
+
 src_libnftables_la_LDFLAGS = \
 	-version-info "${libnftables_LIBVERSION}" \
 	-Wl,--version-script="$(srcdir)/src//libnftables.map" \
@@ -453,3 +462,15 @@ TESTS = tests/build/run-tests.sh \
 	tests/py/nft-test.py \
 	tests/shell/run-tests.sh
 endif
+
+all_c_sources = $(filter %.c,$(src_libnftables_la_SOURCES)) $(src_nft_SOURCES)
+if BUILD_MINIGMP
+all_c_sources += $(src_libminigmp_la_SOURCES)
+endif
+if BUILD_AFL
+all_c_sources += $(tools_nft_afl_SOURCES)
+endif
+CLEANFILES += src/libparser_la-parser_bison.gcno
+CLEANFILES += src/libparser_la-scanner.gcno
+CLEANFILES += $(all_c_sources:.c=.gcno)
+CLEANFILES += $(src_nft_SOURCES:.c=.gcda)
diff --git a/configure.ac b/configure.ac
index 022608627908a..0d3ee2ac89f69 100644
--- a/configure.ac
+++ b/configure.ac
@@ -156,6 +156,13 @@ AC_ARG_ENABLE([distcheck],
 	      [enable_distcheck=yes], [])
 AM_CONDITIONAL([BUILD_DISTCHECK], [test "x$enable_distcheck" = "xyes"])
 
+AC_ARG_ENABLE([profiling],
+	      AS_HELP_STRING([--enable-profiling], [build for use of gcov/gprof]),
+	      [enable_profiling="$enableval"], [enable_profiling="no"])
+AM_CONDITIONAL([BUILD_PROFILING], [test "x$enable_profiling" = xyes])
+AM_COND_IF([BUILD_PROFILING],
+	   [AC_DEFINE([BUILD_PROFILING], [1], [Define for profiling])])
+
 AC_CONFIG_FILES([					\
 		Makefile				\
 		libnftables.pc				\
@@ -170,7 +177,8 @@ echo "
   use mini-gmp:			${with_mini_gmp}
   enable man page:              ${enable_man_doc}
   libxtables support:		${with_xtables}
-  json output support:          ${with_json}"
+  json output support:          ${with_json}
+  collect profiling data:       ${enable_profiling}"
 
 if test "x$unitdir" != "x"; then
 AC_SUBST([unitdir])
diff --git a/include/profiling.h b/include/profiling.h
new file mode 100644
index 0000000000000..78abd31d4315d
--- /dev/null
+++ b/include/profiling.h
@@ -0,0 +1,12 @@
+#ifndef NFTABLES_PROFILING_H
+#define NFTABLES_PROFILING_H
+
+#ifdef BUILD_PROFILING
+int get_signalfd(void);
+void check_signalfd(int fd);
+#else
+static inline int get_signalfd(void) { return -1; }
+static inline void check_signalfd(int fd) { /* empty */ }
+#endif
+
+#endif /* NFTABLES_PROFILING_H */
diff --git a/src/mnl.c b/src/mnl.c
index eee0a33ceaeb4..3f3ef82a25cb5 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -39,6 +39,7 @@
 #include <errno.h>
 #include <utils.h>
 #include <nftables.h>
+#include <profiling.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter_arp.h>
 
@@ -2390,6 +2391,7 @@ int mnl_nft_event_listener(struct mnl_socket *nf_sock, unsigned int debug_mask,
 	unsigned int bufsiz = NFTABLES_NLEVENT_BUFSIZ;
 	int fd = mnl_socket_get_fd(nf_sock);
 	char buf[NFT_NLMSG_MAXSIZE];
+	int sigfd = get_signalfd();
 	fd_set readfds;
 	int ret;
 
@@ -2401,11 +2403,16 @@ int mnl_nft_event_listener(struct mnl_socket *nf_sock, unsigned int debug_mask,
 	while (1) {
 		FD_ZERO(&readfds);
 		FD_SET(fd, &readfds);
+		if (sigfd != -1)
+			FD_SET(sigfd, &readfds);
 
-		ret = select(fd + 1, &readfds, NULL, NULL, NULL);
+		ret = select(max(fd, sigfd) + 1, &readfds, NULL, NULL, NULL);
 		if (ret < 0)
 			return -1;
 
+		if (FD_ISSET(sigfd, &readfds))
+			check_signalfd(sigfd);
+
 		if (FD_ISSET(fd, &readfds)) {
 			ret = mnl_socket_recvfrom(nf_sock, buf, sizeof(buf));
 			if (ret < 0) {
diff --git a/src/profiling.c b/src/profiling.c
new file mode 100644
index 0000000000000..34d91cc1746ec
--- /dev/null
+++ b/src/profiling.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) Red Hat GmbH.  Author: Phil Sutter <phil@nwl.cc>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 (or any
+ * later) as published by the Free Software Foundation.
+ */
+
+#include <nft.h>
+#include <profiling.h>
+
+#include <sys/signalfd.h>
+#include <signal.h>
+#include <stdio.h>
+
+int get_signalfd(void)
+{
+	sigset_t mask;
+	int fd;
+
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGTERM);
+	sigaddset(&mask, SIGINT);
+
+	fd = signalfd(-1, &mask, 0);
+	if (fd < 0) {
+		perror("signalfd()");
+		return fd;
+	}
+	if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
+		perror("sigprocmask()");
+		close(fd);
+		return -1;
+	}
+	return fd;
+}
+
+void check_signalfd(int fd)
+{
+	struct signalfd_siginfo info;
+
+	if (read(fd, &info, sizeof(info)) < (signed)sizeof(info))
+		return;
+
+	switch (info.ssi_signo) {
+	case SIGTERM:
+		exit(143);
+	case SIGINT:
+		exit(130);
+	}
+}
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-02-13 13:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-12 20:50 [nft PATCH v4] configure: Implement --enable-profiling option Phil Sutter
2026-02-13 11:35 ` Florian Westphal
2026-02-13 13:09   ` Phil Sutter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.