Skip to contentSkip to conversation

Remove support for external plugins

PATCH Superseded Emil Velikov 4 participants 16 messages Jan 25, 2024 – Jan 29, 2024

Subsystems (2)

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover Remove support for external plugins

Hello everyone,

Here's v3 fixing a small bug with the previous patches, which was tripping the CI.

Link to the previous revision can be found below.

Thanks
Emil

- Link to v2: https://lore.kernel.org/r/[email protected]

---
Emil Velikov (8):
configure, README: introduce --enable-external-plugins
obexd: factor out external plugin support
bluetoothd: remove external-dummy plugin
bluetoothd: convert external sixaxis plugin to builtin
bluetoothd: factor out external plugin support
bluetoothd: don't export internal API
bluetoothd: change plugin loading alike obexd
android: export only (android) entrypoint from the modules

 Makefile.am              |  17 ++----
 Makefile.obexd           |   2 +
 Makefile.plugins         |   8 +--
 README                   |  13 +++++
 android/Makefile.am      |   3 +
 android/hal-audio.c      |   1 +
 android/hal-bluetooth.c  |   1 +
 android/hal-sco.c        |   1 +
 configure.ac             |  10 ++++
 obexd/src/obexd.h        |   2 +-
 obexd/src/plugin.c       |  93 +++++++++++++++++++++----------
 obexd/src/plugin.h       |   4 ++
 plugins/external-dummy.c |  28 ----------
 src/btd.h                |   2 +-
 src/plugin.c             | 140 +++++++++++++++++++++++++++++------------------
 src/plugin.h             |  16 ++++++
 16 files changed, 209 insertions(+), 132 deletions(-)

---
base-commit: a9d1f6f6a625607de6c3f5b7a40a3aac5f36c02b
change-id: 20240116-rm-ext-plugins-ba0b852a492b

Best regards,

Signature · 1 line
Emil Velikov <[email protected]>
#1 lore raw

PATCH v3 1/8 configure, README: introduce --enable-external-plugins

From: Emil Velikov <[email protected]>

As the README chunk says, disabled by default, since they rely on internal API/ABI and can break at any point.

Instead everyone affected should work and upstream their plugin into the bluez project.

---
 README       | 13 +++++++++++++
 configure.ac | 10 ++++++++++
 2 files changed, 23 insertions(+)
README +13 -0
index 7de7045a8..6c0777046 100644
@@ -249,6 +249,19 @@ For a working system, certain configuration options need to be enabled:
 		systems. The behavior of the deprecated tools may be unstable
 		or simply don't work anymore.
 
+	--enable-external-plugins
+
+		Enable support for external plugins
+
+		By default external plugins for bluetoothd and obexd are not
+		supported and thus disabled.
+
+		External plugins require access to internal, undocumented and
+		unversioned API in said daemons. As such they can break at any
+		time. If you have such plugins, enable this option and work
+		actively with the community to make said plugin part of the
+		upstream bluez project.
+
 	--enable-nfc
 
 		This option enable NFC pairing support.
configure.ac +10 -0
index cab5da581..5e353a1d6 100644
@@ -364,6 +364,16 @@ AC_ARG_ENABLE(deprecated, AS_HELP_STRING([--enable-deprecated],
 					[enable_deprecated=${enableval}])
 AM_CONDITIONAL(DEPRECATED, test "${enable_deprecated}" = "yes")
 
+AC_ARG_ENABLE(external-plugsin, AS_HELP_STRING([--enable-external-plugins],
+			[enable support for external plugins]),
+					[enable_external_plugins=${enableval}])
+AM_CONDITIONAL(EXTERNAL_PLUGINS, test "${enable_external_plugins}" = "yes")
+if (test "${enable_external_plugins}" = "yes"); then
+	AC_DEFINE(EXTERNAL_PLUGINS, 1, [Define if external plugin support is required])
+else
+	AC_DEFINE(EXTERNAL_PLUGINS, 0, [Define if external plugin support is required])
+fi
+
 AC_ARG_ENABLE(sixaxis, AS_HELP_STRING([--enable-sixaxis],
 		[enable sixaxis plugin]), [enable_sixaxis=${enableval}])
 AM_CONDITIONAL(SIXAXIS, test "${enable_sixaxis}" = "yes" &&
Signature · 1 line
2.43.0
#2 lore raw

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=819668

---Test result---

Test Summary:

CheckPatch                    FAIL      2.89 seconds
GitLint                       PASS      1.83 seconds
BuildEll                      PASS      23.99 seconds
BluezMake                     PASS      735.43 seconds
MakeCheck                     PASS      11.83 seconds
MakeDistcheck                 PASS      163.54 seconds
CheckValgrind                 PASS      226.28 seconds
CheckSmatch                   PASS      330.80 seconds
bluezmakeextell               PASS      107.89 seconds
IncrementalBuild              PASS      5466.84 seconds
ScanBuild                     PASS      954.84 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,v3,2/8] obexd: factor out external plugin support WARNING:LONG_LINE: line length of 86 exceeds 80 columns
#134: FILE: obexd/src/plugin.c:47:
+static gboolean add_external_plugin(void *handle, const struct obex_plugin_desc *desc)

/github/workspace/src/src/13529768.patch total: 0 errors, 1 warnings, 176 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/src/13529768.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.

[BlueZ,v3,5/8] bluetoothd: factor out external plugin support WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line #243: FILE: src/plugin.c:190:
+ * plugins are loaded. */

WARNING:TRAILING_SEMICOLON: macros should not use a trailing semicolon #318: FILE: src/plugin.h:51:
+#define BLUETOOTH_PLUGIN_DEFINE(name, version, priority, init, exit) \
+ const struct bluetooth_plugin_desc \
+ __bluetooth_builtin_ ## name = { \
+ #name, priority, init, exit \
+ };

/github/workspace/src/src/13529772.patch total: 0 errors, 2 warnings, 211 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/src/13529772.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.

[BlueZ,v3,7/8] bluetoothd: change plugin loading alike obexd WARNING:ENOSYS: ENOSYS means 'invalid syscall nr' and nothing else #108: FILE: src/plugin.c:52:
+ if (err == -ENOSYS || err == -ENOTSUP)

/github/workspace/src/src/13529774.patch total: 0 errors, 1 warnings, 106 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/src/13529774.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.

---
Regards,
Linux Bluetooth

#3 lore raw

PATCH v3 2/8 obexd: factor out external plugin support

In reply to Emil Velikov

From: Emil Velikov <[email protected]>

As a whole all plugins should be built-in, otherwise they would be using internal, undocumented, unversioned, unstable API.

Flesh out the external plugin support into a few pre-processor blocks and simplify the normal path.

Hide the internal API (omit export-dynamic) when built without external plugins.

---
 Makefile.obexd     |  2 ++
 obexd/src/obexd.h  |  2 +-
 obexd/src/plugin.c | 93 ++++++++++++++++++++++++++++++++++++------------------
 obexd/src/plugin.h |  4 +++
 4 files changed, 70 insertions(+), 31 deletions(-)
Makefile.obexd +2 -0
index 5d1a4ff65..9175de2a4 100644
@@ -86,7 +86,9 @@ obexd_src_obexd_LDADD = lib/libbluetooth-internal.la \
 			$(ICAL_LIBS) $(DBUS_LIBS) $(LIBEBOOK_LIBS) \
 			$(LIBEDATASERVER_LIBS) $(GLIB_LIBS) -ldl
 
+if EXTERNAL_PLUGINS
 obexd_src_obexd_LDFLAGS = $(AM_LDFLAGS) -Wl,--export-dynamic
+endif
 
 obexd_src_obexd_CPPFLAGS = $(AM_CPPFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) \
 				$(ICAL_CFLAGS) -DOBEX_PLUGIN_BUILTIN \
obexd/src/obexd.h +1 -1
index fe312a65b..af5265da5 100644
@@ -18,7 +18,7 @@
 #define OBEX_MAS	(1 << 8)
 #define OBEX_MNS	(1 << 9)
 
-gboolean plugin_init(const char *pattern, const char *exclude);
+void plugin_init(const char *pattern, const char *exclude);
 void plugin_cleanup(void);
 
 gboolean manager_init(void);
obexd/src/plugin.c +63 -30

145 lines not on this page · raw message

obexd/src/plugin.h +4 -0
index a91746cbc..e1756b9bf 100644
@@ -20,10 +20,14 @@ struct obex_plugin_desc {
 			#name, init, exit \
 		};
 #else
+#if EXTERNAL_PLUGINS
 #define OBEX_PLUGIN_DEFINE(name,init,exit) \
 		extern struct obex_plugin_desc obex_plugin_desc \
 				__attribute__ ((visibility("default"))); \
 		const struct obex_plugin_desc obex_plugin_desc = { \
 			#name, init, exit \
 		};
+#else
+#error "Requested non built-in plugin, while external plugins is disabled"
+#endif
 #endif
Signature · 1 line
2.43.0
#4 lore raw

Re: [PATCH BlueZ v3 2/8] obexd: factor out external plugin support

Hi Emil,

Quoted 220 lines · On Wed, Jan 24, 2024 at 7:08 PM Emil Velikov via B4 Relay…

From: Emil Velikov <[email protected]>

As a whole all plugins should be built-in, otherwise they would be using internal, undocumented, unversioned, unstable API.

Flesh out the external plugin support into a few pre-processor blocks and simplify the normal path.

Hide the internal API (omit export-dynamic) when built without external plugins.

---
 Makefile.obexd     |  2 ++
 obexd/src/obexd.h  |  2 +-
 obexd/src/plugin.c | 93 ++++++++++++++++++++++++++++++++++++------------------
 obexd/src/plugin.h |  4 +++
 4 files changed, 70 insertions(+), 31 deletions(-)
Makefile.obexd +2 -0
index 5d1a4ff65..9175de2a4 100644
@@ -86,7 +86,9 @@ obexd_src_obexd_LDADD = lib/libbluetooth-internal.la \
                        $(ICAL_LIBS) $(DBUS_LIBS) $(LIBEBOOK_LIBS) \
                        $(LIBEDATASERVER_LIBS) $(GLIB_LIBS) -ldl
 
+if EXTERNAL_PLUGINS
 obexd_src_obexd_LDFLAGS = $(AM_LDFLAGS) -Wl,--export-dynamic
+endif
 
 obexd_src_obexd_CPPFLAGS = $(AM_CPPFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) \
                                $(ICAL_CFLAGS) -DOBEX_PLUGIN_BUILTIN \
obexd/src/obexd.h +1 -1
index fe312a65b..af5265da5 100644
@@ -18,7 +18,7 @@
 #define OBEX_MAS       (1 << 8)
 #define OBEX_MNS       (1 << 9)
 
-gboolean plugin_init(const char *pattern, const char *exclude);
+void plugin_init(const char *pattern, const char *exclude);
 void plugin_cleanup(void);
 
 gboolean manager_init(void);
obexd/src/plugin.c +63 -30
index a3eb24753..212299fa5 100644
@@ -37,11 +37,14 @@
 static GSList *plugins = NULL;
 
 struct obex_plugin {
+#if EXTERNAL_PLUGINS
        void *handle;
+#endif
        const struct obex_plugin_desc *desc;
 };
 
-static gboolean add_plugin(void *handle, const struct obex_plugin_desc *desc)
+#if EXTERNAL_PLUGINS
+static gboolean add_external_plugin(void *handle, const struct obex_plugin_desc *desc)
 {
        struct obex_plugin *plugin;
 
@@ -65,6 +68,26 @@ static gboolean add_plugin(void *handle, const struct obex_plugin_desc *desc)
 
        return TRUE;
 }
+#endif
+
+static void add_plugin(const struct obex_plugin_desc *desc)
+{
+       struct obex_plugin *plugin;
+
+       plugin = g_try_new0(struct obex_plugin, 1);
+       if (plugin == NULL)
+               return;
+
+       plugin->desc = desc;
+
+       if (desc->init() < 0) {
+               g_free(plugin);
+               return;
+       }
+
+       plugins = g_slist_append(plugins, plugin);
+       DBG("Plugin %s loaded", desc->name);
+}
 
 static gboolean check_plugin(const struct obex_plugin_desc *desc,
                                char **patterns, char **excludes)
@@ -93,42 +116,23 @@ static gboolean check_plugin(const struct obex_plugin_desc *desc,
 }
 
 
-#include "builtin.h"
-
-gboolean plugin_init(const char *pattern, const char *exclude)
+static void external_plugin_init(char **patterns, char **excludes)
 {
-       char **patterns = NULL;
-       char **excludes = NULL;
+#if EXTERNAL_PLUGINS
        GDir *dir;
        const char *file;
-       unsigned int i;
 
-       if (strlen(PLUGINDIR) == 0)
-               return FALSE;
-
-       if (pattern)
-               patterns = g_strsplit_set(pattern, ":, ", -1);
-
-       if (exclude)
-               excludes = g_strsplit_set(exclude, ":, ", -1);
-
-       DBG("Loading builtin plugins");
-
-       for (i = 0; __obex_builtin[i]; i++) {
-               if (check_plugin(__obex_builtin[i],
-                                       patterns, excludes) == FALSE)
-                       continue;
+       warn("Using external plugins is not officially supported.\n");
+       warn("Consider upstreaming your plugins into the BlueZ project.");
 
-               add_plugin(NULL,  __obex_builtin[i]);
-       }
+       if (strlen(PLUGINDIR) == 0)
+               return;
 
        DBG("Loading plugins %s", PLUGINDIR);
 
        dir = g_dir_open(PLUGINDIR, 0, NULL);
        if (!dir) {
-               g_strfreev(patterns);
-               g_strfreev(excludes);
-               return FALSE;
+               return;
        }
 
        while ((file = g_dir_read_name(dir)) != NULL) {
@@ -164,15 +168,42 @@ gboolean plugin_init(const char *pattern, const char *exclude)
                        continue;
                }
 
-               if (add_plugin(handle, desc) == FALSE)
+               if (add_external_plugin(handle, desc) == FALSE)
                        dlclose(handle);
        }
 
        g_dir_close(dir);
+#endif
+}
+
+#include "builtin.h"
+
+void plugin_init(const char *pattern, const char *exclude)
+{
+       char **patterns = NULL;
+       char **excludes = NULL;
+       unsigned int i;
+
+       if (pattern)
+               patterns = g_strsplit_set(pattern, ":, ", -1);
+
+       if (exclude)
+               excludes = g_strsplit_set(exclude, ":, ", -1);
+
+       DBG("Loading builtin plugins");
+
+       for (i = 0; __obex_builtin[i]; i++) {
+               if (check_plugin(__obex_builtin[i],
+                                       patterns, excludes) == FALSE)
+                       continue;
+
+               add_plugin(__obex_builtin[i]);
+       }
+
+       external_plugin_init(patterns, excludes);
+
        g_strfreev(patterns);
        g_strfreev(excludes);
-
-       return TRUE;
 }
 
 void plugin_cleanup(void)
@@ -187,8 +218,10 @@ void plugin_cleanup(void)
                if (plugin->desc->exit)
                        plugin->desc->exit();
 
+#if EXTERNAL_PLUGINS
                if (plugin->handle != NULL)
                        dlclose(plugin->handle);
+#endif
 
                g_free(plugin);
        }
obexd/src/plugin.h +4 -1
index a91746cbc..e1756b9bf 100644
@@ -20,10 +20,14 @@ struct obex_plugin_desc {
                        #name, init, exit \
                };
 #else
+#if EXTERNAL_PLUGINS
 #define OBEX_PLUGIN_DEFINE(name,init,exit) \
                extern struct obex_plugin_desc obex_plugin_desc \
                                __attribute__ ((visibility("default"))); \
                const struct obex_plugin_desc obex_plugin_desc = { \
                        #name, init, exit \
                };
+#else
+#error "Requested non built-in plugin, while external plugins is disabled"
+#endif
 #endif
 
--
Quoted 1 line

2.43.0

How about we do something like:

https://gist.github.com/Vudentz/0b8bcb78a8898614fc4848cbf44a0a9f

That way we leave it to the compiler to remove the dead code when linking but it still build checks which catches errors such as:

make --no-print-directory all-am
CC obexd/src/obexd-plugin.o
obexd/src/plugin.c: In function ‘external_plugin_init’:
obexd/src/plugin.c:123:9: error: implicit declaration of function ‘warn’ [-Werror=implicit-function-declaration]

  123 |         warn("Using external plugins is not officially supported.\n");
      |         ^~~~
Quoted 1 line
Signature · 1 line
Luiz Augusto von Dentz
#5 lore raw

Re: [PATCH BlueZ v3 2/8] obexd: factor out external plugin support

Hi Luiz,

On Fri, 26 Jan 2024 at 18:50, Luiz Augusto von Dentz <[email protected]> wrote:>> How about we do something like:

Quoted 6 lines

https://gist.github.com/Vudentz/0b8bcb78a8898614fc4848cbf44a0a9f

That way we leave it to the compiler to remove the dead code when linking but it still build checks which catches errors such as:

Not sure why I did not use that from the start. Considering I've done similar changes in the kernel :facepalm:

Thanks an updated series is on the list,
-Emil

#6 lore raw

PATCH v3 3/8 bluetoothd: remove external-dummy plugin

In reply to Emil Velikov

From: Emil Velikov <[email protected]>

The external plugins infra is getting deprecated and disabled by default. Remove this dummy plugin.

---
 Makefile.am              |  8 --------
 plugins/external-dummy.c | 28 ----------------------------
 2 files changed, 36 deletions(-)
Makefile.am +0 -8
index e738eb3a5..ea51b25cc 100644
@@ -293,14 +293,6 @@ builtin_ldadd =
 
 include Makefile.plugins
 
-if MAINTAINER_MODE
-plugin_LTLIBRARIES += plugins/external-dummy.la
-plugins_external_dummy_la_SOURCES = plugins/external-dummy.c
-plugins_external_dummy_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
-				    -no-undefined
-plugins_external_dummy_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
-endif
-
 pkglibexec_PROGRAMS += src/bluetoothd
 
 src_bluetoothd_SOURCES = $(builtin_sources) \
plugins/external-dummy.c deleted +0 -28
deleted file mode 100644
index 1c209e8b7..000000000
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "src/plugin.h"
-#include "src/log.h"
-
-static int dummy_init(void)
-{
-	DBG("");
-
-	return 0;
-}
-
-static void dummy_exit(void)
-{
-	DBG("");
-}
-
-BLUETOOTH_PLUGIN_DEFINE(external_dummy, VERSION,
-		BLUETOOTH_PLUGIN_PRIORITY_LOW, dummy_init, dummy_exit)
Signature · 1 line
2.43.0
#7 lore raw

PATCH v3 4/8 bluetoothd: convert external sixaxis plugin to builtin

In reply to Emil Velikov

From: Emil Velikov <[email protected]>

Convert the only known external plugin to built-in. It's a tiny 20K binary that distros ship a separate package for.

Make it a builtin, which allows distros to drop the separate package, it also enables us to compile out support for external modules - both in terms of extra code and hide the internal bluetoothd API.

This means that libudev.so is pulled in, which is fine since its ABI has been stable for over a decade.

---
 Makefile.plugins | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)
Makefile.plugins +3 -5
index 5880ed0df..7cf66fd59 100644
@@ -110,11 +110,9 @@ builtin_modules += battery
 builtin_sources += profiles/battery/battery.c
 
 if SIXAXIS
-plugin_LTLIBRARIES += plugins/sixaxis.la
-plugins_sixaxis_la_SOURCES = plugins/sixaxis.c
-plugins_sixaxis_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version
-plugins_sixaxis_la_LIBADD = $(UDEV_LIBS)
-plugins_sixaxis_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
+builtin_modules += sixaxis
+builtin_sources += plugins/sixaxis.c
+builtin_ldadd += $(UDEV_LIBS)
 endif
 
 if BAP
Signature · 1 line
2.43.0
#8 lore raw

PATCH v3 5/8 bluetoothd: factor out external plugin support

In reply to Emil Velikov

From: Emil Velikov <[email protected]>

As a whole all plugins should be built-in, otherwise they would be using internal, undocumented, unversioned, unstable API.

Flesh out the external plugin support into a few pre-processor blocks and simplify the normal path.

---
 Makefile.am  |  4 ---
 src/btd.h    |  2 +-
 src/plugin.c | 97 ++++++++++++++++++++++++++++++++++++++----------------------
 src/plugin.h | 16 ++++++++++
 4 files changed, 79 insertions(+), 40 deletions(-)
Makefile.am +0 -4
index ea51b25cc..1b82e8551 100644
@@ -51,11 +51,7 @@ EXTRA_DIST += src/bluetooth.service.in src/org.bluez.service
 
 plugindir = $(libdir)/bluetooth/plugins
 
-if MAINTAINER_MODE
-build_plugindir = $(abs_top_srcdir)/plugins/.libs
-else
 build_plugindir = $(plugindir)
-endif
 
 if MANPAGES
 man_MANS =
src/btd.h +1 -1
index b7e7ebd61..7166e2168 100644
@@ -155,7 +155,7 @@ struct btd_opts {
 
 extern struct btd_opts btd_opts;
 
-gboolean plugin_init(const char *enable, const char *disable);
+void plugin_init(const char *enable, const char *disable);
 void plugin_cleanup(void);
 
 void rfkill_init(void);
src/plugin.c +62 -35

159 lines not on this page · raw message

src/plugin.h +16 -0
index 8d0903f2d..a1984d536 100644
@@ -13,14 +13,19 @@
 
 struct bluetooth_plugin_desc {
 	const char *name;
+#if EXTERNAL_PLUGINS
 	const char *version;
+#endif
 	int priority;
 	int (*init) (void);
 	void (*exit) (void);
+#if EXTERNAL_PLUGINS
 	void *debug_start;
 	void *debug_stop;
+#endif
 };
 
+#if EXTERNAL_PLUGINS
 #ifdef BLUETOOTH_PLUGIN_BUILTIN
 #define BLUETOOTH_PLUGIN_DEFINE(name, version, priority, init, exit) \
 		const struct bluetooth_plugin_desc \
@@ -41,3 +46,14 @@ struct bluetooth_plugin_desc {
 			__start___debug, __stop___debug \
 		};
 #endif
+#else
+#ifdef BLUETOOTH_PLUGIN_BUILTIN
+#define BLUETOOTH_PLUGIN_DEFINE(name, version, priority, init, exit) \
+		const struct bluetooth_plugin_desc \
+		__bluetooth_builtin_ ## name = { \
+			#name, priority, init, exit \
+		};
+#else
+#error "Requested non built-in plugin, while external plugins is disabled"
+#endif
+#endif
Signature · 1 line
2.43.0
#9 lore raw

PATCH v3 6/8 bluetoothd: don't export internal API

In reply to Emil Velikov

From: Emil Velikov <[email protected]>

... when building without external plugins.

---
 Makefile.am | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
Makefile.am +4 -1
index 1b82e8551..b98519e84 100644
@@ -293,7 +293,6 @@ pkglibexec_PROGRAMS += src/bluetoothd
 
 src_bluetoothd_SOURCES = $(builtin_sources) \
 			$(attrib_sources) $(btio_sources) \
-			src/bluetooth.ver \
 			src/main.c src/log.h src/log.c \
 			src/backtrace.h src/backtrace.c \
 			src/rfkill.c src/btd.h src/sdpd.h \
@@ -325,8 +324,12 @@ src_bluetoothd_LDADD = lib/libbluetooth-internal.la \
 			src/libshared-glib.la \
 			$(BACKTRACE_LIBS) $(GLIB_LIBS) $(DBUS_LIBS) -ldl -lrt \
 			$(builtin_ldadd)
+
+if EXTERNAL_PLUGINS
+src_bluetoothd_SOURCES += src/bluetooth.ver
 src_bluetoothd_LDFLAGS = $(AM_LDFLAGS) -Wl,--export-dynamic \
 				-Wl,--version-script=$(srcdir)/src/bluetooth.ver
+endif
 
 src_bluetoothd_DEPENDENCIES = lib/libbluetooth-internal.la \
 				gdbus/libgdbus-internal.la \
Signature · 1 line
2.43.0
#10 lore raw

PATCH v3 7/8 bluetoothd: change plugin loading alike obexd

In reply to Emil Velikov

From: Emil Velikov <[email protected]>

Currently, we print "Loading foobar" for every plugin, before we try the respective init() callback. Instead we handle the latter in a bunch, at the end of the process.

Do the init() call early, print "Loaded" once it's actually successful and drop the no-longer "active" tracking.

---
 src/plugin.c | 53 +++++++++++++++++++++++++++++------------------------
 1 file changed, 29 insertions(+), 24 deletions(-)
src/plugin.c +29 -24
index ae9406375..3895792bc 100644
@@ -32,7 +32,6 @@ struct bluetooth_plugin {
 #if EXTERNAL_PLUGINS
 	void *handle;
 #endif
-	gboolean active;
 	const struct bluetooth_plugin_desc *desc;
 };
 
@@ -44,6 +43,22 @@ static int compare_priority(gconstpointer a, gconstpointer b)
 	return plugin2->desc->priority - plugin1->desc->priority;
 }
 
+static int init_plugin(const struct bluetooth_plugin_desc *desc)
+{
+	int err;
+
+	err = desc->init();
+	if (err < 0) {
+		if (err == -ENOSYS || err == -ENOTSUP)
+			warn("System does not support %s plugin",
+						desc->name);
+		else
+			error("Failed to init %s plugin",
+						desc->name);
+	}
+	return err;
+}
+
 #if EXTERNAL_PLUGINS
 static gboolean add_external_plugin(void *handle,
 				const struct bluetooth_plugin_desc *desc)
@@ -58,19 +73,22 @@ static gboolean add_external_plugin(void *handle,
 		return FALSE;
 	}
 
-	DBG("Loading %s plugin", desc->name);
-
 	plugin = g_try_new0(struct bluetooth_plugin, 1);
 	if (plugin == NULL)
 		return FALSE;
 
 	plugin->handle = handle;
-	plugin->active = FALSE;
 	plugin->desc = desc;
 
+	if (init_plugin(desc) < 0) {
+		g_free(plugin);
+		return FALSE;
+	}
+
 	__btd_enable_debug(desc->debug_start, desc->debug_stop);
 
 	plugins = g_slist_insert_sorted(plugins, plugin, compare_priority);
+	DBG("Plugin %s loaded", desc->name);
 
 	return TRUE;
 }
@@ -88,7 +106,13 @@ static void add_plugin(const struct bluetooth_plugin_desc *desc)
 
 	plugin->desc = desc;
 
+	if (init_plugin(desc) < 0) {
+		g_free(plugin);
+		return;
+	}
+
 	plugins = g_slist_insert_sorted(plugins, plugin, compare_priority);
+	DBG("Plugin %s loaded", desc->name);
 }
 
 static gboolean enable_plugin(const char *name, char **cli_enable,
@@ -181,7 +205,6 @@ static void external_plugin_init(char **cli_disabled, char **cli_enabled)
 
 void plugin_init(const char *enable, const char *disable)
 {
-	GSList *list;
 	char **cli_disabled = NULL;
 	char **cli_enabled = NULL;
 	unsigned int i;
@@ -208,24 +231,6 @@ void plugin_init(const char *enable, const char *disable)
 
 	external_plugin_init(cli_enabled, cli_disabled);
 
-	for (list = plugins; list; list = list->next) {
-		struct bluetooth_plugin *plugin = list->data;
-		int err;
-
-		err = plugin->desc->init();
-		if (err < 0) {
-			if (err == -ENOSYS || err == -ENOTSUP)
-				warn("System does not support %s plugin",
-							plugin->desc->name);
-			else
-				error("Failed to init %s plugin",
-							plugin->desc->name);
-			continue;
-		}
-
-		plugin->active = TRUE;
-	}
-
 	g_strfreev(cli_enabled);
 	g_strfreev(cli_disabled);
 }
@@ -239,7 +244,7 @@ void plugin_cleanup(void)
 	for (list = plugins; list; list = list->next) {
 		struct bluetooth_plugin *plugin = list->data;
 
-		if (plugin->active == TRUE && plugin->desc->exit)
+		if (plugin->desc->exit)
 			plugin->desc->exit();
 
 #if EXTERNAL_PLUGINS
Signature · 1 line
2.43.0
#11 lore raw

PATCH v3 8/8 android: export only (android) entrypoint from the modules

In reply to Emil Velikov

From: Emil Velikov <[email protected]>

The android specific modules, have a designated HMI entrypoint. Hide everything else with -fvisibility=hidden.

---
 android/Makefile.am     | 3 +++
 android/hal-audio.c     | 1 +
 android/hal-bluetooth.c | 1 +
 android/hal-sco.c       | 1 +
 4 files changed, 6 insertions(+)
android/Makefile.am +3 -0
index 309910147..e3756e89c 100644
@@ -96,6 +96,7 @@ android_bluetooth_default_la_SOURCES = android/hal.h android/hal-bluetooth.c \
 					android/hal-log.h \
 					android/hal-ipc.h android/hal-ipc.c \
 					android/hal-utils.h android/hal-utils.c
+android_bluetooth_default_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
 android_bluetooth_default_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/android
 android_bluetooth_default_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
 					-no-undefined
@@ -195,6 +196,7 @@ android_audio_a2dp_default_la_SOURCES = android/audio-msg.h \
 					android/hardware/audio_effect.h \
 					android/hardware/hardware.h \
 					android/system/audio.h
+android_audio_a2dp_default_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
 android_audio_a2dp_default_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/android \
 					$(SBC_CFLAGS)
 android_audio_a2dp_default_la_LIBADD = $(SBC_LIBS) -lrt
@@ -212,6 +214,7 @@ android_audio_sco_default_la_SOURCES = android/hal-log.h \
 					android/audio_utils/resampler.c \
 					android/audio_utils/resampler.h \
 					android/system/audio.h
+android_audio_sco_default_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
 android_audio_sco_default_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/android
 android_audio_sco_default_la_LIBADD = $(SPEEXDSP_LIBS) -lrt
 android_audio_sco_default_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
android/hal-audio.c +1 -0
index d37d6098c..f3d9b40a6 100644
@@ -1618,6 +1618,7 @@ static struct hw_module_methods_t hal_module_methods = {
 	.open = audio_open,
 };
 
+__attribute__ ((visibility("default")))
 struct audio_module HAL_MODULE_INFO_SYM = {
 	.common = {
 		.tag = HARDWARE_MODULE_TAG,
android/hal-bluetooth.c +1 -0
index d4442e620..7d1e5ac63 100644
@@ -1117,6 +1117,7 @@ static struct hw_module_methods_t bluetooth_module_methods = {
 	.open = open_bluetooth,
 };
 
+__attribute__ ((visibility("default")))
 struct hw_module_t HAL_MODULE_INFO_SYM = {
 	.tag = HARDWARE_MODULE_TAG,
 	.version_major = 1,
android/hal-sco.c +1 -0
index d7c08a68b..3d66ad357 100644
@@ -1507,6 +1507,7 @@ static struct hw_module_methods_t hal_module_methods = {
 	.open = sco_open,
 };
 
+__attribute__ ((visibility("default")))
 struct audio_module HAL_MODULE_INFO_SYM = {
 	.common = {
 		.tag = HARDWARE_MODULE_TAG,
Signature · 1 line
2.43.0
#12 lore raw
In reply to Emil Velikov

Hi,

Quoted 7 lines · On Thu, 25 Jan 2024 at 01:07, Emil Velikov via B4 Relay…

Hello everyone,

Here's v3 fixing a small bug with the previous patches, which was tripping the CI.

Link to the previous revision can be found below.

Just a comment that external plugins support was added to avoid udev dependency (from sixaxis) in bluetoothd.
(not that I have strong opinion on this, just a note, I don't remember exactly why it was done, maybe Marcel recalls?)

Quoted 34 lines

Thanks
Emil

- Link to v2: https://lore.kernel.org/r/[email protected]

---
Emil Velikov (8):
configure, README: introduce --enable-external-plugins
obexd: factor out external plugin support
bluetoothd: remove external-dummy plugin
bluetoothd: convert external sixaxis plugin to builtin
bluetoothd: factor out external plugin support
bluetoothd: don't export internal API
bluetoothd: change plugin loading alike obexd
android: export only (android) entrypoint from the modules

 Makefile.am              |  17 ++----
 Makefile.obexd           |   2 +
 Makefile.plugins         |   8 +--
 README                   |  13 +++++
 android/Makefile.am      |   3 +
 android/hal-audio.c      |   1 +
 android/hal-bluetooth.c  |   1 +
 android/hal-sco.c        |   1 +
 configure.ac             |  10 ++++
 obexd/src/obexd.h        |   2 +-
 obexd/src/plugin.c       |  93 +++++++++++++++++++++----------
 obexd/src/plugin.h       |   4 ++
 plugins/external-dummy.c |  28 ----------
 src/btd.h                |   2 +-
 src/plugin.c             | 140 +++++++++++++++++++++++++++++------------------
 src/plugin.h             |  16 ++++++
 16 files changed, 209 insertions(+), 132 deletions(-)
Quoted 9 lines

---
base-commit: a9d1f6f6a625607de6c3f5b7a40a3aac5f36c02b
change-id: 20240116-rm-ext-plugins-ba0b852a492b

Best regards,
--
Emil Velikov <[email protected]>

--
pozdrawiam
Szymon K. Janc

#13 lore raw
Quoted 11 lines · Szymon Janc

Hi,

Quoted 6 lines · On Thu, 25 Jan 2024 at 01:07, Emil Velikov via B4 Relay…

Hello everyone,

Here's v3 fixing a small bug with the previous patches, which was tripping the CI.

Quoted 7 lines
Quoted 1 line

Link to the previous revision can be found below.

Just a comment that external plugins support was added to avoid udev dependency (from sixaxis) in bluetoothd.
(not that I have strong opinion on this, just a note, I don't remember exactly why it was done, maybe Marcel recalls?)

Thanks, I may have some ideas why.

About 10 years ago (or so) some distributions were shipping libudev.so.0 while others libudev.so.1. The ABI break was minimal, although it was a thing.
I remember us doing all sorts of hacks in Mesa trying to pick the correct one, esp when your system can have .1 while the game (or its chroot-like environment) has .0 and vice-versa.

I would imagine a similar issue was observed in bluez - but I can only speculate.

Over the last 5+ years, literally all supported distributions have moved for libudev.so.1 and the Steam games (and runtime) has both with some compat quirks to avoid explosions.

HTH o/
Emil

#14 lore raw

Hi Emil,

Quoted 30 lines · Emil Velikov
Quoted 11 lines · Szymon Janc

Hi,

Quoted 6 lines · On Thu, 25 Jan 2024 at 01:07, Emil Velikov via B4 Relay…

Hello everyone,

Here's v3 fixing a small bug with the previous patches, which was tripping the CI.

Quoted 7 lines
Quoted 1 line

Link to the previous revision can be found below.

Just a comment that external plugins support was added to avoid udev dependency (from sixaxis) in bluetoothd.
(not that I have strong opinion on this, just a note, I don't remember exactly why it was done, maybe Marcel recalls?)

Thanks, I may have some ideas why.

About 10 years ago (or so) some distributions were shipping libudev.so.0 while others libudev.so.1. The ABI break was minimal, although it was a thing.
I remember us doing all sorts of hacks in Mesa trying to pick the correct one, esp when your system can have .1 while the game (or its chroot-like environment) has .0 and vice-versa.

Quoted 6 lines

I would imagine a similar issue was observed in bluez - but I can only speculate.

Over the last 5+ years, literally all supported distributions have moved for libudev.so.1 and the Steam games (and runtime) has both with some compat quirks to avoid explosions.

I was considering applying this week but if you want to respin this set to sort out the dependency Im fine with, but I don't think it would hurt to have a libudev dependency provide we have some means to disable it in case the system don't intend to support sixaxis plugin.

Signature · 1 line
Luiz Augusto von Dentz
#15 lore raw

Hi Luiz,

Quoted 37 lines · Luiz Augusto von Dentz

Hi Emil,

Quoted 33 lines · Emil Velikov
Quoted 11 lines · Szymon Janc

Hi,

Quoted 6 lines · On Thu, 25 Jan 2024 at 01:07, Emil Velikov via B4 Relay…

Hello everyone,

Here's v3 fixing a small bug with the previous patches, which was tripping the CI.

Quoted 7 lines
Quoted 1 line

Link to the previous revision can be found below.

Just a comment that external plugins support was added to avoid udev dependency (from sixaxis) in bluetoothd.
(not that I have strong opinion on this, just a note, I don't remember exactly why it was done, maybe Marcel recalls?)

Thanks, I may have some ideas why.

About 10 years ago (or so) some distributions were shipping libudev.so.0 while others libudev.so.1. The ABI break was minimal, although it was a thing.
I remember us doing all sorts of hacks in Mesa trying to pick the correct one, esp when your system can have .1 while the game (or its chroot-like environment) has .0 and vice-versa.

I would imagine a similar issue was observed in bluez - but I can only speculate.

Quoted 9 lines
Quoted 3 lines

Over the last 5+ years, literally all supported distributions have moved for libudev.so.1 and the Steam games (and runtime) has both with some compat quirks to avoid explosions.

I was considering applying this week but if you want to respin this set to sort out the dependency Im fine with, but I don't think it would hurt to have a libudev dependency provide we have some means to disable it in case the system don't intend to support sixaxis plugin.

I don't think I follow: what do you mean with "sort out the dependency"?

Sixaxis is no different to midi where it a) pulls a third-party library (udev vs alsa) and b) it can be disabled at build. Technically one can dlopen/dlsym libudev.so, although that should probably be deferred until needed IMHO.

Thanks
Emil