diff --git a/systemd-logind-dont-second-guess-D-Bus-default-tim.patch b/systemd-logind-dont-second-guess-D-Bus-default-tim.patch new file mode 100644 index 0000000..0245211 --- /dev/null +++ b/systemd-logind-dont-second-guess-D-Bus-default-tim.patch @@ -0,0 +1,446 @@ +From 89250c82a01062775f8f840737a757125138fbce Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 10 Apr 2015 14:19:50 -0400 +Subject: [PATCH] systemd-logind: don't second guess D-Bus default timeout + +At the moment, the X server uses a non-default timeout for D-Bus +messages to systemd-logind. The only timeouts normally used with +D-Bus are: + +1) Infinite +2) Default + +Anything else is just as arbitrary as Default, and so rarely makes +sense to use instead of Default. + +Put another way, there's little reason to be fault tolerant against +a local root running daemon (logind), that in some configurations, the +X server already depends on for proper functionality. + +This commit changes systemd-logind to just use the default timeouts. + +https://bugzilla.redhat.com/show_bug.cgi?id=1209347 +--- + hw/xfree86/os-support/linux/systemd-logind.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c +index 57c87c0..4ad41a3 100644 +--- a/hw/xfree86/os-support/linux/systemd-logind.c ++++ b/hw/xfree86/os-support/linux/systemd-logind.c +@@ -13,62 +13,60 @@ + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Hans de Goede + */ + + #ifdef HAVE_XORG_CONFIG_H + #include + #endif + + #include + #include + #include + #include + + #include "os.h" + #include "dbus-core.h" + #include "xf86.h" + #include "xf86platformBus.h" + #include "xf86Xinput.h" + + #include "systemd-logind.h" + +-#define DBUS_TIMEOUT 500 /* Wait max 0.5 seconds */ +- + struct systemd_logind_info { + DBusConnection *conn; + char *session; + Bool active; + Bool vt_active; + }; + + static struct systemd_logind_info logind_info; + + static InputInfoPtr + systemd_logind_find_info_ptr_by_devnum(InputInfoPtr start, + int major, int minor) + { + InputInfoPtr pInfo; + + for (pInfo = start; pInfo; pInfo = pInfo->next) + if (pInfo->major == major && pInfo->minor == minor && + (pInfo->flags & XI86_SERVER_FD)) + return pInfo; + + return NULL; + } + + static void + systemd_logind_set_input_fd_for_all_devs(int major, int minor, int fd, + Bool enable) + { + InputInfoPtr pInfo; + + pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs, major, minor); +@@ -103,61 +101,61 @@ systemd_logind_take_fd(int _major, int _minor, const char *path, + if (strstr(path, "mouse")) + return -1; + + /* Check if we already have an InputInfo entry with this major, minor + * (shared device-nodes happen ie with Wacom tablets). */ + pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs, major, minor); + if (pInfo) { + LogMessage(X_INFO, "systemd-logind: returning pre-existing fd for %s %u:%u\n", + path, major, minor); + *paused_ret = FALSE; + return pInfo->fd; + } + + dbus_error_init(&error); + + msg = dbus_message_new_method_call("org.freedesktop.login1", info->session, + "org.freedesktop.login1.Session", "TakeDevice"); + if (!msg) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(info->conn, msg, +- DBUS_TIMEOUT, &error); ++ DBUS_TIMEOUT_USE_DEFAULT, &error); + if (!reply) { + LogMessage(X_ERROR, "systemd-logind: failed to take device %s: %s\n", + path, error.message); + goto cleanup; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_UNIX_FD, &fd, + DBUS_TYPE_BOOLEAN, &paused, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: TakeDevice %s: %s\n", + path, error.message); + goto cleanup; + } + + *paused_ret = paused; + + LogMessage(X_INFO, "systemd-logind: got fd for %s %u:%u fd %d paused %d\n", + path, major, minor, fd, paused); + + cleanup: + if (msg) + dbus_message_unref(msg); + if (reply) + dbus_message_unref(reply); + dbus_error_free(&error); + + return fd; + } + +@@ -180,61 +178,61 @@ systemd_logind_release_fd(int _major, int _minor, int fd) + * and minor, otherwise other InputInfo's are still referencing the fd. */ + pInfo = systemd_logind_find_info_ptr_by_devnum(xf86InputDevs, major, minor); + while (pInfo) { + matches++; + pInfo = systemd_logind_find_info_ptr_by_devnum(pInfo->next, major, minor); + } + if (matches > 1) { + LogMessage(X_INFO, "systemd-logind: not releasing fd for %u:%u, still in use\n", major, minor); + return; + } + + LogMessage(X_INFO, "systemd-logind: releasing fd for %u:%u\n", major, minor); + + dbus_error_init(&error); + + msg = dbus_message_new_method_call("org.freedesktop.login1", info->session, + "org.freedesktop.login1.Session", "ReleaseDevice"); + if (!msg) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(info->conn, msg, +- DBUS_TIMEOUT, &error); ++ DBUS_TIMEOUT_USE_DEFAULT, &error); + if (!reply) + LogMessage(X_ERROR, "systemd-logind: failed to release device: %s\n", + error.message); + + cleanup: + if (msg) + dbus_message_unref(msg); + if (reply) + dbus_message_unref(reply); + dbus_error_free(&error); + close: + if (fd != -1) + close(fd); + } + + int + systemd_logind_controls_session(void) + { + return logind_info.session ? 1 : 0; + } + + void + systemd_logind_vtenter(void) + { + struct systemd_logind_info *info = &logind_info; + InputInfoPtr pInfo; + int i; + + if (!info->session) + return; /* Not using systemd-logind */ +@@ -262,61 +260,61 @@ systemd_logind_vtenter(void) + + /* Do delayed input probing, this must be done after the above enabling */ + xf86InputEnableVTProbe(); + } + + static void + systemd_logind_ack_pause(struct systemd_logind_info *info, + dbus_int32_t minor, dbus_int32_t major) + { + DBusError error; + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + + dbus_error_init(&error); + + msg = dbus_message_new_method_call("org.freedesktop.login1", info->session, + "org.freedesktop.login1.Session", "PauseDeviceComplete"); + if (!msg) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(info->conn, msg, +- DBUS_TIMEOUT, &error); ++ DBUS_TIMEOUT_USE_DEFAULT, &error); + if (!reply) + LogMessage(X_ERROR, "systemd-logind: failed to ack pause: %s\n", + error.message); + + cleanup: + if (msg) + dbus_message_unref(msg); + if (reply) + dbus_message_unref(reply); + dbus_error_free(&error); + } + + static DBusHandlerResult + message_filter(DBusConnection * connection, DBusMessage * message, void *data) + { + struct systemd_logind_info *info = data; + struct xf86_platform_device *pdev = NULL; + InputInfoPtr pInfo = NULL; + int ack = 0, pause = 0, fd = -1; + DBusError error; + dbus_int32_t major, minor; + char *pause_str; + + if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + dbus_error_init(&error); + + if (dbus_message_is_signal(message, + "org.freedesktop.DBus", "NameOwnerChanged")) { +@@ -430,96 +428,96 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data) + } + + static void + connect_hook(DBusConnection *connection, void *data) + { + struct systemd_logind_info *info = data; + DBusError error; + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + dbus_int32_t arg; + char *session = NULL; + + dbus_error_init(&error); + + msg = dbus_message_new_method_call("org.freedesktop.login1", + "/org/freedesktop/login1", "org.freedesktop.login1.Manager", + "GetSessionByPID"); + if (!msg) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + arg = getpid(); + if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &arg, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(connection, msg, +- DBUS_TIMEOUT, &error); ++ DBUS_TIMEOUT_USE_DEFAULT, &error); + if (!reply) { + LogMessage(X_ERROR, "systemd-logind: failed to get session: %s\n", + error.message); + goto cleanup; + } + dbus_message_unref(msg); + + if (!dbus_message_get_args(reply, &error, DBUS_TYPE_OBJECT_PATH, &session, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: GetSessionByPID: %s\n", + error.message); + goto cleanup; + } + session = XNFstrdup(session); + + dbus_message_unref(reply); + reply = NULL; + + + msg = dbus_message_new_method_call("org.freedesktop.login1", + session, "org.freedesktop.login1.Session", "TakeControl"); + if (!msg) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + arg = FALSE; /* Don't forcibly take over over the session */ + if (!dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &arg, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(connection, msg, +- DBUS_TIMEOUT, &error); ++ DBUS_TIMEOUT_USE_DEFAULT, &error); + if (!reply) { + LogMessage(X_ERROR, "systemd-logind: TakeControl failed: %s\n", + error.message); + goto cleanup; + } + + dbus_bus_add_match(connection, + "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',path='/org/freedesktop/DBus'", + &error); + if (dbus_error_is_set(&error)) { + LogMessage(X_ERROR, "systemd-logind: could not add match: %s\n", + error.message); + goto cleanup; + } + + /* + * HdG: This is not useful with systemd <= 208 since the signal only + * contains invalidated property names there, rather than property, val + * pairs as it should. Instead we just use the first resume / pause now. + */ + #if 0 + snprintf(match, sizeof(match), + "type='signal',sender='org.freedesktop.login1',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='%s'", + session); + dbus_bus_add_match(connection, match, &error); + if (dbus_error_is_set(&error)) { + LogMessage(X_ERROR, "systemd-logind: could not add match: %s\n", + error.message); + goto cleanup; + } +@@ -537,61 +535,61 @@ connect_hook(DBusConnection *connection, void *data) + info->session = session; + info->vt_active = info->active = TRUE; /* The server owns the vt during init */ + session = NULL; + + cleanup: + free(session); + if (msg) + dbus_message_unref(msg); + if (reply) + dbus_message_unref(reply); + dbus_error_free(&error); + } + + static void + systemd_logind_release_control(struct systemd_logind_info *info) + { + DBusError error; + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + + dbus_error_init(&error); + + msg = dbus_message_new_method_call("org.freedesktop.login1", + info->session, "org.freedesktop.login1.Session", "ReleaseControl"); + if (!msg) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(info->conn, msg, +- DBUS_TIMEOUT, &error); ++ DBUS_TIMEOUT_USE_DEFAULT, &error); + if (!reply) { + LogMessage(X_ERROR, "systemd-logind: ReleaseControl failed: %s\n", + error.message); + goto cleanup; + } + + cleanup: + if (msg) + dbus_message_unref(msg); + if (reply) + dbus_message_unref(reply); + dbus_error_free(&error); + } + + static void + disconnect_hook(void *data) + { + struct systemd_logind_info *info = data; + + free(info->session); + info->session = NULL; + info->conn = NULL; + } + + static struct dbus_core_hook core_hook = { + .connect = connect_hook, + .disconnect = disconnect_hook, + .data = &logind_info, + }; + +-- +2.3.3 \ No newline at end of file diff --git a/systemd-logind-filter-out-non-signal-messages-from.patch b/systemd-logind-filter-out-non-signal-messages-from.patch new file mode 100644 index 0000000..af319c5 --- /dev/null +++ b/systemd-logind-filter-out-non-signal-messages-from.patch @@ -0,0 +1,90 @@ +From e90798c142dedc4fd296936b69fe34a40d0aa35a Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 10 Apr 2015 14:19:50 -0400 +Subject: [PATCH] systemd-logind: filter out non-signal messages from message + filter + +It's possible to receive a message reply in the message filter if a +previous message call timed out locally before the reply arrived. + +The message_filter function only handles signals, at the moment, and +does not properly handle message replies. + +This commit changes the message_filter function to filter out all +non-signal messages, including spurious message replies. + +https://bugzilla.redhat.com/show_bug.cgi?id=1209347 +--- + hw/xfree86/os-support/linux/systemd-logind.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c +index 49758f4..57c87c0 100644 +--- a/hw/xfree86/os-support/linux/systemd-logind.c ++++ b/hw/xfree86/os-support/linux/systemd-logind.c +@@ -286,60 +286,63 @@ systemd_logind_ack_pause(struct systemd_logind_info *info, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(info->conn, msg, + DBUS_TIMEOUT, &error); + if (!reply) + LogMessage(X_ERROR, "systemd-logind: failed to ack pause: %s\n", + error.message); + + cleanup: + if (msg) + dbus_message_unref(msg); + if (reply) + dbus_message_unref(reply); + dbus_error_free(&error); + } + + static DBusHandlerResult + message_filter(DBusConnection * connection, DBusMessage * message, void *data) + { + struct systemd_logind_info *info = data; + struct xf86_platform_device *pdev = NULL; + InputInfoPtr pInfo = NULL; + int ack = 0, pause = 0, fd = -1; + DBusError error; + dbus_int32_t major, minor; + char *pause_str; + ++ if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL) ++ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; ++ + dbus_error_init(&error); + + if (dbus_message_is_signal(message, + "org.freedesktop.DBus", "NameOwnerChanged")) { + char *name, *old_owner, *new_owner; + + dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &old_owner, + DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID); + if (dbus_error_is_set(&error)) { + LogMessage(X_ERROR, "systemd-logind: NameOwnerChanged: %s\n", + error.message); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (name && strcmp(name, "org.freedesktop.login1") == 0) + FatalError("systemd-logind disappeared (stopped/restarted?)\n"); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (strcmp(dbus_message_get_path(message), info->session) != 0) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (dbus_message_is_signal(message, "org.freedesktop.login1.Session", + "PauseDevice")) { + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_UINT32, &major, +-- +2.3.3 \ No newline at end of file diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 988e680..4df952f 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -45,7 +45,7 @@ Summary: X.Org X11 X server Name: xorg-x11-server Version: 1.17.1 -Release: 8%{?gitdate:.%{gitdate}}%{dist} +Release: 9%{?gitdate:.%{gitdate}}%{dist} URL: http://www.x.org License: MIT Group: User Interface/X @@ -88,6 +88,10 @@ Patch6030: xserver-1.6.99-right-of.patch # https://bugzilla.gnome.org/show_bug.cgi?id=737226 Patch6045: 0001-present-make-unflip-work-when-the-flip-window-is-des.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1209347 +Patch6055: systemd-logind-filter-out-non-signal-messages-from.patch +Patch6056: systemd-logind-dont-second-guess-D-Bus-default-tim.patch + Patch7025: 0001-Always-install-vbe-and-int10-sdk-headers.patch # do not upstream - do not even use here yet @@ -641,6 +645,12 @@ find %{inst_srcdir}/hw/xfree86 -name \*.c -delete %changelog +* Sat Apr 11 2015 Ray Strode 1.17.1-9 +- Handle logind timeouts more gracefuly. +- Bump timeouts so they don't happen in practice + Fixes X on some old optimus and other hybrid hardware + Related: #1209347 + * Thu Apr 09 2015 Adam Jackson 1.17.1-8 - Fix endian detection code (#1206060)