All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Add udev mode to bluetoothd
@ 2009-06-11 17:38 Bastien Nocera
  2009-06-11 17:50 ` Marcel Holtmann
  0 siblings, 1 reply; 9+ messages in thread
From: Bastien Nocera @ 2009-06-11 17:38 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 131 bytes --]

As discussed on IRC.

Still needed:
- patch to wait for the bus to startup in udev mode
- udev rules
- unleash for testing

Cheers

[-- Attachment #2: 0001-Add-udev-mode-to-bluetoothd.patch --]
[-- Type: text/x-patch, Size: 5213 bytes --]

>From 3e9257b31efcffbb8583f99770604b40a04410b2 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Thu, 11 Jun 2009 18:33:35 +0100
Subject: [PATCH] Add udev mode to bluetoothd

Add --udev option to bluetoothd, to allow it to be started on-demand
from udev.

When a new adapter appears, udev would launch bluetoothd --udev.

To avoid problems with udev, bluetoothd --udev would only return
an error exit code if it wasn't already running and a real error
occurred.

When no more Bluetooth adapter are present on the system, bluetoothd
will exit after a 30 second timeout.
---
 src/dbus-common.c |   18 +++++++++++----
 src/hcid.h        |    3 ++
 src/main.c        |   63 +++++++++++++++++++++++++++++++++++++++++++++++++---
 src/manager.c     |    6 +++++
 4 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/src/dbus-common.c b/src/dbus-common.c
index b596909..d06d8e5 100644
--- a/src/dbus-common.c
+++ b/src/dbus-common.c
@@ -165,19 +165,27 @@ void hcid_dbus_exit(void)
 int hcid_dbus_init(void)
 {
 	DBusConnection *conn;
+	DBusError err;
 
-	conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, BLUEZ_NAME, NULL);
-	if (!conn)
-		return -1;
+	dbus_error_init(&err);
+
+	conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, BLUEZ_NAME, &err);
+	if (!conn) {
+		if (error != NULL && dbus_error_is_set(&err)) {
+			dbus_error_free(&err);
+			return -EIO;
+		}
+		return -EALREADY;
+	}
 
 	if (g_dbus_set_disconnect_function(conn, disconnect_callback,
 							NULL, NULL) == FALSE) {
 		dbus_connection_unref(conn);
-		return -1;
+		return -EIO;
 	}
 
 	if (!manager_init(conn, "/"))
-		return -1;
+		return -EIO;
 
 	set_dbus_connection(conn);
 
diff --git a/src/hcid.h b/src/hcid.h
index 4fbbef1..605dc06 100644
--- a/src/hcid.h
+++ b/src/hcid.h
@@ -85,6 +85,9 @@ void hci_req_queue_remove(int dev_id, bdaddr_t *dba);
 void start_security_manager(int hdev);
 void stop_security_manager(int hdev);
 
+void btd_start_exit_timer(void);
+void btd_stop_exit_timer(void);
+
 void set_pin_length(bdaddr_t *sba, int length);
 
 gboolean plugin_init(GKeyFile *config);
diff --git a/src/main.c b/src/main.c
index 0467fe1..8c2b475 100644
--- a/src/main.c
+++ b/src/main.c
@@ -27,6 +27,7 @@
 #include <config.h>
 #endif
 
+#include <errno.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -55,6 +56,8 @@
 #include "agent.h"
 #include "manager.h"
 
+#define LAST_ADAPTER_EXIT_TIMEOUT 30
+
 struct main_opts main_opts;
 
 static GKeyFile *load_config(const char *file)
@@ -331,6 +334,37 @@ static void sig_debug(int sig)
 
 static gboolean option_detach = TRUE;
 static gboolean option_debug = FALSE;
+static gboolean option_udev = FALSE;
+
+static guint last_adapter_timeout = 0;
+
+static gboolean exit_timeout(gpointer data)
+{
+	g_main_loop_quit(event_loop);
+	last_adapter_timeout = 0;
+	return FALSE;
+}
+
+void btd_start_exit_timer(void)
+{
+	if (option_udev == FALSE)
+		return;
+
+	if (last_adapter_timeout > 0)
+		g_source_remove(last_adapter_timeout);
+
+	last_adapter_timeout = g_timeout_add_seconds(LAST_ADAPTER_EXIT_TIMEOUT,
+						exit_timeout, NULL);
+}
+
+void btd_stop_exit_timer(void)
+{
+	if (last_adapter_timeout == 0)
+		return;
+
+	g_source_remove(last_adapter_timeout);
+	last_adapter_timeout = 0;
+}
 
 static GOptionEntry options[] = {
 	{ "nodaemon", 'n', G_OPTION_FLAG_REVERSE,
@@ -338,6 +372,8 @@ static GOptionEntry options[] = {
 				"Don't run as daemon in background" },
 	{ "debug", 'd', 0, G_OPTION_ARG_NONE, &option_debug,
 				"Enable debug information output" },
+	{ "udev", 'u', 0, G_OPTION_ARG_NONE, &option_udev,
+				"Run from udev mode of operation" },
 	{ NULL },
 };
 
@@ -363,9 +399,21 @@ int main(int argc, char *argv[])
 		exit(1);
 	}
 
+	if (option_udev == TRUE) {
+		int err;
+
+		option_detach = TRUE;
+		err = hcid_dbus_init();
+		if (err < 0) {
+			if (err == -EALREADY)
+				exit(0);
+			exit(1);
+		}
+	}
+
 	g_option_context_free(context);
 
-	if (option_detach == TRUE) {
+	if (option_detach == TRUE && option_udev == FALSE) {
 		if (daemon(0, 0)) {
 			perror("Can't start daemon");
 			exit(1);
@@ -399,9 +447,16 @@ int main(int argc, char *argv[])
 
 	agent_init();
 
-	if (hcid_dbus_init() < 0) {
-		error("Unable to get on D-Bus");
-		exit(1);
+	if (option_udev == FALSE) {
+		if (hcid_dbus_init() < 0) {
+			error("Unable to get on D-Bus");
+			exit(1);
+		}
+	} else {
+		if (daemon(0, 0)) {
+			perror("Can't start daemon");
+			exit(1);
+		}
 	}
 
 	start_sdp_server(mtu, main_opts.deviceid, SDP_SERVER_COMPAT);
diff --git a/src/manager.c b/src/manager.c
index db6d251..ab69e4e 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -43,6 +43,7 @@
 
 #include <gdbus.h>
 
+#include "hcid.h"
 #include "dbus-common.h"
 #include "logging.h"
 #include "adapter.h"
@@ -312,6 +313,9 @@ static void manager_remove_adapter(struct btd_adapter *adapter)
 			DBUS_TYPE_INVALID);
 
 	adapter_remove(adapter);
+
+	if (adapters == NULL)
+		btd_start_exit_timer();
 }
 
 void manager_cleanup(DBusConnection *conn, const char *path)
@@ -421,6 +425,8 @@ void manager_add_adapter(const char *path)
 			DBUS_TYPE_INVALID);
 
 	manager_update_adapters();
+
+	btd_stop_exit_timer();
 }
 
 int manager_register_adapter(int id, gboolean devup)
-- 
1.6.2.2


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

* Re: [PATCH] Add udev mode to bluetoothd
  2009-06-11 17:38 [PATCH] Add udev mode to bluetoothd Bastien Nocera
@ 2009-06-11 17:50 ` Marcel Holtmann
  2009-06-12  7:40   ` Stefan Seyfried
  0 siblings, 1 reply; 9+ messages in thread
From: Marcel Holtmann @ 2009-06-11 17:50 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: BlueZ development

Hi Bastien,

> As discussed on IRC.
> 
> Still needed:
> - patch to wait for the bus to startup in udev mode
> - udev rules
> - unleash for testing

patch has been applied. Thanks.

Regards

Marcel



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

* Re: [PATCH] Add udev mode to bluetoothd
  2009-06-11 17:50 ` Marcel Holtmann
@ 2009-06-12  7:40   ` Stefan Seyfried
  2009-06-12  8:28     ` Stefan Seyfried
  2009-06-12  8:40     ` Bastien Nocera
  0 siblings, 2 replies; 9+ messages in thread
From: Stefan Seyfried @ 2009-06-12  7:40 UTC (permalink / raw)
  To: linux-bluetooth

Marcel Holtmann wrote:
> Hi Bastien,
> 
>> As discussed on IRC.
>>
>> Still needed:
>> - patch to wait for the bus to startup in udev mode

Should we really do that? (What if the bus never appears?, how long should we
wait?)
The alternative (not overwhelmingly nice, I admit) would be to record
somewhere in the system that bluetoothd tried to start but could not due to
the missing bus and then start it "manually" by an init script that is
guaranteed to run after DBus is started.

I had patches for waiting for the bus long time ago and can dig them out if
wanted.

Best regards,

	Stefan
-- 
Stefan Seyfried
R&D Team Mobile Devices            |              "Any ideas, John?"
SUSE LINUX Products GmbH, Nürnberg | "Well, surrounding them's out."

This footer brought to you by insane German lawmakers:
SUSE Linux Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)

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

* Re: [PATCH] Add udev mode to bluetoothd
  2009-06-12  7:40   ` Stefan Seyfried
@ 2009-06-12  8:28     ` Stefan Seyfried
  2009-06-12 17:43       ` Bastien Nocera
  2009-06-12  8:40     ` Bastien Nocera
  1 sibling, 1 reply; 9+ messages in thread
From: Stefan Seyfried @ 2009-06-12  8:28 UTC (permalink / raw)
  To: linux-bluetooth

[-- Attachment #1: Type: text/plain, Size: 609 bytes --]

Stefan Seyfried wrote:

> I had patches for waiting for the bus long time ago and can dig them out if
> wanted.

Actually I quickly dug them out and adapted them to the current code.

I arbitrarily chose to stop waiting after 5 minutes. This timeout is certainly
 a topic that might need to be discussed.

Best regards,

	Stefan
-- 
Stefan Seyfried
R&D Team Mobile Devices            |              "Any ideas, John?"
SUSE LINUX Products GmbH, Nürnberg | "Well, surrounding them's out."

This footer brought to you by insane German lawmakers:
SUSE Linux Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)

[-- Attachment #2: 0001-Wait-for-system-bus-to-appear.patch --]
[-- Type: text/x-patch, Size: 1462 bytes --]

>From 8b41af8ac12e2cf0824af4f65e0ef47ffac3dcb8 Mon Sep 17 00:00:00 2001
From: Stefan Seyfried <seife@tuxbox-git.slipkontur.de>
Date: Fri, 12 Jun 2009 10:22:29 +0200
Subject: [PATCH] Wait for system bus to appear

If the system bus is not there when starting bluetoothd,
wait up to five minutes for it to appear and retry the
connection every five seconds.
---
 src/dbus-common.c |   21 ++++++++++++++++-----
 1 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/src/dbus-common.c b/src/dbus-common.c
index d06d8e5..dc648be 100644
--- a/src/dbus-common.c
+++ b/src/dbus-common.c
@@ -162,21 +162,32 @@ void hcid_dbus_exit(void)
 	dbus_connection_unref(conn);
 }
 
+#define MAX_DBUS_RETRY		60
 int hcid_dbus_init(void)
 {
 	DBusConnection *conn;
 	DBusError err;
+	int retry = 0;
 
-	dbus_error_init(&err);
+	do {
+		dbus_error_init(&err);
+		conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, BLUEZ_NAME, &err);
+		if (conn)
+			break;
 
-	conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, BLUEZ_NAME, &err);
-	if (!conn) {
 		if (error != NULL && dbus_error_is_set(&err)) {
 			dbus_error_free(&err);
-			return -EIO;
+			if (retry >= MAX_DBUS_RETRY)
+				return -EIO;
+			if (!retry)
+				info("Can't connect to system bus, will retry "
+					"%i times.", MAX_DBUS_RETRY);
+			sleep(5);
+			retry++;
+			continue;
 		}
 		return -EALREADY;
-	}
+	} while (1);
 
 	if (g_dbus_set_disconnect_function(conn, disconnect_callback,
 							NULL, NULL) == FALSE) {
-- 
1.6.3.2


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

* Re: [PATCH] Add udev mode to bluetoothd
  2009-06-12  7:40   ` Stefan Seyfried
  2009-06-12  8:28     ` Stefan Seyfried
@ 2009-06-12  8:40     ` Bastien Nocera
  2009-06-12 15:28       ` Marcel Holtmann
  1 sibling, 1 reply; 9+ messages in thread
From: Bastien Nocera @ 2009-06-12  8:40 UTC (permalink / raw)
  To: Stefan Seyfried; +Cc: linux-bluetooth

On Fri, 2009-06-12 at 09:40 +0200, Stefan Seyfried wrote:
> Marcel Holtmann wrote:
> > Hi Bastien,
> > 
> >> As discussed on IRC.
> >>
> >> Still needed:
> >> - patch to wait for the bus to startup in udev mode
> 
> Should we really do that? (What if the bus never appears?, how long should we
> wait?)
> The alternative (not overwhelmingly nice, I admit) would be to record
> somewhere in the system that bluetoothd tried to start but could not due to
> the missing bus and then start it "manually" by an init script that is
> guaranteed to run after DBus is started.

Under normal conditions, we'd exit(1) if started and the bus isn't
available, and udev would pick that up, marking our job as failed, and
relaunching us later in the boot process, under coldplug.

Marcel didn't like the idea though.

> I had patches for waiting for the bus long time ago and can dig them out if
> wanted.

Sure, as long as it's not bluez 3.x stuff :)


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

* Re: [PATCH] Add udev mode to bluetoothd
  2009-06-12  8:40     ` Bastien Nocera
@ 2009-06-12 15:28       ` Marcel Holtmann
  2009-06-12 17:58         ` Bastien Nocera
  0 siblings, 1 reply; 9+ messages in thread
From: Marcel Holtmann @ 2009-06-12 15:28 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: Stefan Seyfried, linux-bluetooth

Hi Bastien,

> > >> As discussed on IRC.
> > >>
> > >> Still needed:
> > >> - patch to wait for the bus to startup in udev mode
> > 
> > Should we really do that? (What if the bus never appears?, how long should we
> > wait?)
> > The alternative (not overwhelmingly nice, I admit) would be to record
> > somewhere in the system that bluetoothd tried to start but could not due to
> > the missing bus and then start it "manually" by an init script that is
> > guaranteed to run after DBus is started.
> 
> Under normal conditions, we'd exit(1) if started and the bus isn't
> available, and udev would pick that up, marking our job as failed, and
> relaunching us later in the boot process, under coldplug.
> 
> Marcel didn't like the idea though.

so how does udev handle this exactly. We try bluetoothd and it fails,
then it tries again later? What time exactly? How often? Does this
affect the fast-boot effort?

Regards

Marcel



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

* Re: [PATCH] Add udev mode to bluetoothd
  2009-06-12  8:28     ` Stefan Seyfried
@ 2009-06-12 17:43       ` Bastien Nocera
  0 siblings, 0 replies; 9+ messages in thread
From: Bastien Nocera @ 2009-06-12 17:43 UTC (permalink / raw)
  To: Stefan Seyfried; +Cc: linux-bluetooth

On Fri, 2009-06-12 at 10:28 +0200, Stefan Seyfried wrote:
> Stefan Seyfried wrote:
> 
> > I had patches for waiting for the bus long time ago and can dig them out if
> > wanted.
> 
> Actually I quickly dug them out and adapted them to the current code.
> 
> I arbitrarily chose to stop waiting after 5 minutes. This timeout is certainly
>  a topic that might need to be discussed.

This patch won't work as part of the udev mode, as we don't daemonise
until we have a D-Bus connection. That would make udev hang for 5
minutes waiting for the helper to come back.


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

* Re: [PATCH] Add udev mode to bluetoothd
  2009-06-12 15:28       ` Marcel Holtmann
@ 2009-06-12 17:58         ` Bastien Nocera
  2009-06-13 19:51           ` Marcel Holtmann
  0 siblings, 1 reply; 9+ messages in thread
From: Bastien Nocera @ 2009-06-12 17:58 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Stefan Seyfried, linux-bluetooth

On Fri, 2009-06-12 at 17:28 +0200, Marcel Holtmann wrote:
> Hi Bastien,
> 
> > > >> As discussed on IRC.
> > > >>
> > > >> Still needed:
> > > >> - patch to wait for the bus to startup in udev mode
> > > 
> > > Should we really do that? (What if the bus never appears?, how long should we
> > > wait?)
> > > The alternative (not overwhelmingly nice, I admit) would be to record
> > > somewhere in the system that bluetoothd tried to start but could not due to
> > > the missing bus and then start it "manually" by an init script that is
> > > guaranteed to run after DBus is started.
> > 
> > Under normal conditions, we'd exit(1) if started and the bus isn't
> > available, and udev would pick that up, marking our job as failed, and
> > relaunching us later in the boot process, under coldplug.
> > 
> > Marcel didn't like the idea though.
> 
> so how does udev handle this exactly. We try bluetoothd and it fails,
> then it tries again later? What time exactly? How often? Does this
> affect the fast-boot effort?

It will try to start up bluetooth as soon as it sees the device on
startup. bluetoothd will fail to start, as D-Bus isn't started, with an
exit code of 1.

udev notes the failure, and saves the rules to /dev/.udev/*.

The initscripts carry on, filesystems are mounted rw, D-Bus is started,
then a udev "coldplug" is started (still part of the initscripts), and
bluetoothd is started as expected.

I built some test packages yesterday, and Petr tested those, and it
seems to work as expected.

If you fancy trying out on an F-12 system (the SRPM can be re-used on
F-11, just remove the libgudev-devel BuildRequires line):
http://koji.fedoraproject.org/koji/buildinfo?buildID=105952

So as far as I'm concerned, the only thing missing is getting the rules
into bluez.

Marcel, do you want the udev rules installed by default? The cost would
be an attempted run at bluetoothd on each adapter insertion, but it
would still work as expected if bluetoothd was started from an
initscript.

Cheers

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

* Re: [PATCH] Add udev mode to bluetoothd
  2009-06-12 17:58         ` Bastien Nocera
@ 2009-06-13 19:51           ` Marcel Holtmann
  0 siblings, 0 replies; 9+ messages in thread
From: Marcel Holtmann @ 2009-06-13 19:51 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: Stefan Seyfried, linux-bluetooth

Hi Bastien,

> > > Under normal conditions, we'd exit(1) if started and the bus isn't
> > > available, and udev would pick that up, marking our job as failed, and
> > > relaunching us later in the boot process, under coldplug.
> > > 
> > > Marcel didn't like the idea though.
> > 
> > so how does udev handle this exactly. We try bluetoothd and it fails,
> > then it tries again later? What time exactly? How often? Does this
> > affect the fast-boot effort?
> 
> It will try to start up bluetooth as soon as it sees the device on
> startup. bluetoothd will fail to start, as D-Bus isn't started, with an
> exit code of 1.
> 
> udev notes the failure, and saves the rules to /dev/.udev/*.
> 
> The initscripts carry on, filesystems are mounted rw, D-Bus is started,
> then a udev "coldplug" is started (still part of the initscripts), and
> bluetoothd is started as expected.
> 
> I built some test packages yesterday, and Petr tested those, and it
> seems to work as expected.
> 
> If you fancy trying out on an F-12 system (the SRPM can be re-used on
> F-11, just remove the libgudev-devel BuildRequires line):
> http://koji.fedoraproject.org/koji/buildinfo?buildID=105952
> 
> So as far as I'm concerned, the only thing missing is getting the rules
> into bluez.
> 
> Marcel, do you want the udev rules installed by default? The cost would
> be an attempted run at bluetoothd on each adapter insertion, but it
> would still work as expected if bluetoothd was started from an
> initscript.

I have no problem triggering bluetoothd from udev every time we add a
new adapter. And unless we try it, we never know. I am a little bit
concerned about the boot time implications of this.

Send me a patch with the rules installation and lets make it default. We
see how far we get. I do hate init scripts anyway and if they get too
complex it costs us actually more time at boot than just starting the
daemon.

Regards

Marcel



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

end of thread, other threads:[~2009-06-13 19:51 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-11 17:38 [PATCH] Add udev mode to bluetoothd Bastien Nocera
2009-06-11 17:50 ` Marcel Holtmann
2009-06-12  7:40   ` Stefan Seyfried
2009-06-12  8:28     ` Stefan Seyfried
2009-06-12 17:43       ` Bastien Nocera
2009-06-12  8:40     ` Bastien Nocera
2009-06-12 15:28       ` Marcel Holtmann
2009-06-12 17:58         ` Bastien Nocera
2009-06-13 19:51           ` Marcel Holtmann

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.