From 93005ba7e790ca167849a8a8c6edf0bec9ee11e6 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 13 Sep 2019 17:00:27 +0200 Subject: [PATCH] vdagentd: Fix session lookup for new GNOME versions New GNOME versions have started to manage the session using the systemd user instance. The effect of this is that the spice-vdagent running in the user session is forked off (indirectly) from the systemd user instance and does technically not belong to any session. The correct way of handling this situation is to simply assume that the process belongs to the users graphical session. Add a heuristic to find the graphical session based on the UID, fixing spice-vdagent running on GNOME 3.34 with systemd integration. --- src/vdagentd/systemd-login.c | 53 +++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src/vdagentd/systemd-login.c b/src/vdagentd/systemd-login.c index a11b66d..69b2acf 100644 --- a/src/vdagentd/systemd-login.c +++ b/src/vdagentd/systemd-login.c @@ -286,15 +286,60 @@ const char *session_info_get_active_session(struct session_info *si) char *session_info_session_for_pid(struct session_info *si, uint32_t pid) { + int i; int r; + GStrv sessions = NULL; char *session = NULL; r = sd_pid_get_session(pid, &session); - if (r < 0) - syslog(LOG_ERR, "Error getting session for pid %u: %s", - pid, strerror(-r)); - else if (si->verbose) + if (r < 0) { + uid_t uid; + /* If the agent is running in a systemd managed session, then we simply + * assume it is part of the first graphical session we can find. */ + r = sd_pid_get_owner_uid(pid, &uid); + + if (r < 0) { + syslog(LOG_ERR, "Error getting owner UID for pid %u: %s", + pid, strerror(-r)); + goto out; + } + + if (sd_uid_get_sessions(uid, 0, &sessions) > 0) { + for (i = 0; sessions[i] != NULL; i++) { + char *session_type = NULL; + + r = sd_session_get_type(sessions[i], &session_type); + + if (r < 0) { + syslog(LOG_ERR, "Error getting session type for session %s: %s", + sessions[i], strerror(-r)); + continue; + } + + if (g_strcmp0(session_type, "wayland") == 0 || + g_strcmp0(session_type, "x11") == 0 || + g_strcmp0(session_type, "mir") == 0) { + + session = g_strdup(sessions[i]); + + free(session_type); + g_strfreev(sessions); + goto out; + } + + free(session_type); + } + } else { + syslog(LOG_ERR, "Error getting sessions for UID %d: %s", + (int) uid, strerror(-r)); + } + g_strfreev(sessions); + } + +out: + if (session && si->verbose) { syslog(LOG_INFO, "Session for pid %u: %s", pid, session); + } return session; } -- 2.21.0