Bugzilla – Attachment 547343 Details for
Bug 802525
dbus hung on rtkit upgrade
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
IDP Log In
|
Forgot Password
[patch]
dbus-fall-back-to-old-run-directory.patch
dbus-fall-back-to-old-run-directory.patch (text/plain), 11.70 KB, created by
Hans Petter Jansson
on 2013-07-10 01:26:24 UTC
(
hide
)
Description:
dbus-fall-back-to-old-run-directory.patch
Filename:
MIME Type:
Creator:
Hans Petter Jansson
Created:
2013-07-10 01:26:24 UTC
Size:
11.70 KB
patch
obsolete
>diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c >index 6f81c74..96416c6 100644 >--- a/dbus/dbus-bus.c >+++ b/dbus/dbus-bus.c >@@ -421,6 +421,153 @@ _dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connec > _DBUS_UNLOCK (bus); > } > >+static dbus_bool_t >+internal_register (DBusConnection *connection, >+ int timeout_milliseconds, >+ DBusError *error) >+{ >+ DBusMessage *message, *reply; >+ char *name; >+ BusData *bd; >+ dbus_bool_t retval; >+ >+ _dbus_return_val_if_fail (connection != NULL, FALSE); >+ _dbus_return_val_if_error_is_set (error, FALSE); >+ >+ retval = FALSE; >+ message = NULL; >+ reply = NULL; >+ >+ _DBUS_LOCK (bus_datas); >+ >+ bd = ensure_bus_data (connection); >+ if (bd == NULL) >+ { >+ _DBUS_SET_OOM (error); >+ goto out; >+ } >+ >+ if (bd->unique_name != NULL) >+ { >+ _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n", >+ bd->unique_name); >+ /* Success! */ >+ retval = TRUE; >+ goto out; >+ } >+ >+ message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, >+ DBUS_PATH_DBUS, >+ DBUS_INTERFACE_DBUS, >+ "Hello"); >+ >+ if (!message) >+ { >+ _DBUS_SET_OOM (error); >+ goto out; >+ } >+ >+ reply = dbus_connection_send_with_reply_and_block (connection, message, timeout_milliseconds, error); >+ >+ if (reply == NULL) >+ goto out; >+ else if (dbus_set_error_from_message (error, reply)) >+ goto out; >+ else if (!dbus_message_get_args (reply, error, >+ DBUS_TYPE_STRING, &name, >+ DBUS_TYPE_INVALID)) >+ goto out; >+ >+ bd->unique_name = _dbus_strdup (name); >+ if (bd->unique_name == NULL) >+ { >+ _DBUS_SET_OOM (error); >+ goto out; >+ } >+ >+ retval = TRUE; >+ >+ out: >+ _DBUS_UNLOCK (bus_datas); >+ >+ if (message) >+ dbus_message_unref (message); >+ >+ if (reply) >+ dbus_message_unref (reply); >+ >+ return retval; >+} >+ >+static DBusConnection * >+internal_open_and_register (const char *address, dbus_bool_t private, int timeout_milliseconds, DBusError *error) >+{ >+ DBusConnection *connection; >+ >+ if (private) >+ connection = dbus_connection_open_private (address, error); >+ else >+ connection = dbus_connection_open (address, error); >+ >+ if (!connection) >+ { >+ goto out; >+ } >+ >+ if (!internal_register (connection, timeout_milliseconds, error)) >+ { >+ _dbus_connection_close_possibly_shared (connection); >+ dbus_connection_unref (connection); >+ connection = NULL; >+ goto out; >+ } >+ >+out: >+ return connection; >+} >+ >+/* When the D-Bus upgrade that moves /var/run/dbus/ to /run/dbus/ is applied, >+ * D-Bus cannot be restarted with the new socket in /run/, because the session >+ * wouldn't be able to cope with it. We end up with a daemon listening on >+ * /var/run/dbus/system_bus_socket, but clients will now try to register >+ * with it on /run/dbus/system_bus_socket, causing the upgrade, and eventually >+ * critical parts of the user's session, to hang. >+ * >+ * The workaround is inelegant, but probably good enough: We allow the initial >+ * attempt to time out quickly and fall back to trying the old default address. >+ * If that fails too, we go back to blocking on the initial address. */ >+ >+#define OLD_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=/var/run/dbus/system_bus_socket" >+#define INITIAL_TIMEOUT_MILLISECONDS 250 >+#define INCREMENT_TIMEOUT_MILLISECONDS 250 >+#define MAX_TIMEOUT_MILLISECONDS 10000 >+ >+static DBusConnection * >+internal_open_and_register_with_fallback (const char *address, dbus_bool_t private, DBusError *error) >+{ >+ DBusConnection *connection = NULL; >+ int timeout_milliseconds; >+ >+ for (timeout_milliseconds = INITIAL_TIMEOUT_MILLISECONDS; >+ connection == NULL && timeout_milliseconds < MAX_TIMEOUT_MILLISECONDS; >+ timeout_milliseconds += INCREMENT_TIMEOUT_MILLISECONDS) >+ { >+ connection = internal_open_and_register (address, private, timeout_milliseconds, NULL); >+ >+ if (!connection && !strcmp (address, DBUS_SYSTEM_BUS_DEFAULT_ADDRESS)) >+ connection = internal_open_and_register (OLD_SYSTEM_BUS_DEFAULT_ADDRESS, private, timeout_milliseconds, NULL); >+ } >+ >+ if (!connection) >+ { >+ /* We couldn't register with any of the sockets; fall back to original behavior, blocking >+ * forever or returning an error. */ >+ connection = internal_open_and_register (address, private, -1, error); >+ } >+ >+ return connection; >+} >+ > static DBusConnection * > internal_bus_get (DBusBusType type, > dbus_bool_t private, >@@ -474,21 +621,10 @@ internal_bus_get (DBusBusType type, > goto out; > } > >- if (private) >- connection = dbus_connection_open_private (address, error); >- else >- connection = dbus_connection_open (address, error); >- >- if (!connection) >- { >- goto out; >- } >+ connection = internal_open_and_register_with_fallback (address, private, error); > >- if (!dbus_bus_register (connection, error)) >+ if (!connection) > { >- _dbus_connection_close_possibly_shared (connection); >- dbus_connection_unref (connection); >- connection = NULL; > goto out; > } > >diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c >index 66315b3..467379a 100644 >--- a/dbus/dbus-connection.c >+++ b/dbus/dbus-connection.c >@@ -348,7 +348,7 @@ static void _dbus_connection_update_dispatch_status_and_unlock (DB > static void _dbus_connection_last_unref (DBusConnection *connection); > static void _dbus_connection_acquire_dispatch (DBusConnection *connection); > static void _dbus_connection_release_dispatch (DBusConnection *connection); >-static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection); >+static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection, int timeout_milliseconds); > static void _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection); > static dbus_bool_t _dbus_connection_get_is_connected_unlocked (DBusConnection *connection); > static dbus_bool_t _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection, >@@ -2367,7 +2367,7 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending) > DBusConnection *connection; > dbus_uint32_t client_serial; > DBusTimeout *timeout; >- int timeout_milliseconds, elapsed_milliseconds; >+ int timeout_milliseconds = -1, elapsed_milliseconds; > > _dbus_assert (pending != NULL); > >@@ -2379,7 +2379,12 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending) > connection = _dbus_pending_call_get_connection_and_lock (pending); > > /* Flush message queue - note, can affect dispatch status */ >- _dbus_connection_flush_unlocked (connection); >+ >+ timeout = _dbus_pending_call_get_timeout_unlocked (pending); >+ if (timeout) >+ timeout_milliseconds = dbus_timeout_get_interval (timeout); >+ >+ _dbus_connection_flush_unlocked (connection, timeout_milliseconds); > > client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending); > >@@ -3555,7 +3560,7 @@ dbus_connection_send_with_reply_and_block (DBusConnection *connection, > * @param connection the connection. > */ > static DBusDispatchStatus >-_dbus_connection_flush_unlocked (DBusConnection *connection) >+_dbus_connection_flush_unlocked (DBusConnection *connection, int timeout_milliseconds) > { > /* We have to specify DBUS_ITERATION_DO_READING here because > * otherwise we could have two apps deadlock if they are both doing >@@ -3563,20 +3568,36 @@ _dbus_connection_flush_unlocked (DBusConnection *connection) > * dispatch status. > */ > DBusDispatchStatus status; >+ long start_tv_sec, start_tv_usec; >+ long tv_sec, tv_usec; >+ int elapsed_milliseconds = 0; > > HAVE_LOCK_CHECK (connection); >+ >+ _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec); > > while (connection->n_outgoing > 0 && > _dbus_connection_get_is_connected_unlocked (connection)) > { > _dbus_verbose ("doing iteration in\n"); >+ >+ if (timeout_milliseconds >= 0) >+ { >+ _dbus_get_monotonic_time (&tv_sec, &tv_usec); >+ elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 + >+ (tv_usec - start_tv_usec) / 1000; >+ >+ if (elapsed_milliseconds >= timeout_milliseconds) >+ break; >+ } >+ > HAVE_LOCK_CHECK (connection); > _dbus_connection_do_iteration_unlocked (connection, > NULL, > DBUS_ITERATION_DO_READING | > DBUS_ITERATION_DO_WRITING | > DBUS_ITERATION_BLOCK, >- -1); >+ timeout_milliseconds - elapsed_milliseconds); > } > > HAVE_LOCK_CHECK (connection); >@@ -3606,7 +3627,7 @@ dbus_connection_flush (DBusConnection *connection) > > CONNECTION_LOCK (connection); > >- status = _dbus_connection_flush_unlocked (connection); >+ status = _dbus_connection_flush_unlocked (connection, -1); > > HAVE_LOCK_CHECK (connection); > /* Unlocks and calls out to user code */ >diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c >index e9bd9ef..0d04006 100644 >--- a/dbus/dbus-sysdeps-unix.c >+++ b/dbus/dbus-sysdeps-unix.c >@@ -773,6 +773,51 @@ _dbus_write_two (int fd, > * which is probably a good idea. > */ > >+static int >+connect_with_timeout (const char *path, >+ int fd, >+ const struct sockaddr *addr, >+ socklen_t addrlen, >+ DBusError *error) >+{ >+ struct pollfd poll_fd; >+ >+ _DBUS_ASSERT_ERROR_IS_CLEAR (error); >+ >+ if (!_dbus_set_fd_nonblocking (fd, error)) >+ { >+ _dbus_close (fd, NULL); >+ return -1; >+ } >+ >+ connect (fd, addr, addrlen); >+ >+ poll_fd.fd = fd; >+ poll_fd.events = POLLOUT | POLLERR | POLLNVAL; >+ >+ if (poll (&poll_fd, 1, 250) < 1) >+ { >+ dbus_set_error (error, >+ _dbus_error_from_errno (errno), >+ "Failed to connect to socket %s: %s", >+ path, _dbus_strerror (errno)); >+ _dbus_close (fd, NULL); >+ return -1; >+ } >+ >+ if (!(poll_fd.revents & POLLOUT)) >+ { >+ dbus_set_error (error, >+ _dbus_error_from_errno (errno), >+ "Failed to connect to socket %s: %s", >+ path, _dbus_strerror (errno)); >+ _dbus_close (fd, NULL); >+ return -1; >+ } >+ >+ return 0; >+} >+ > /** > * Creates a socket and connects it to the UNIX domain socket at the > * given path. The connection fd is returned, and is set up as >@@ -851,7 +896,14 @@ _dbus_connect_unix_socket (const char *path, > strncpy (addr.sun_path, path, path_len); > } > >- if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) >+ if ((!strcmp (path, DBUS_SYSTEM_BUS_DEFAULT_ADDRESS) || >+ (!strncmp (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS, "unix:path=", strlen ("unix:path=")) && >+ !strcmp (path, DBUS_SYSTEM_BUS_DEFAULT_ADDRESS + strlen ("unix:path=")))) && >+ connect_with_timeout (path, fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len, error) < 0) >+ { >+ return -1; >+ } >+ else if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) > { > dbus_set_error (error, > _dbus_error_from_errno (errno),
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
Attachments on
bug 802525
:
524392
|
524393
|
525839
|
526127
| 547343