Annotation of /trunk/kdebase-workspace/patches/kdebase-workspace-4.11-kdm-logind-multiseat.patch
Parent Directory | Revision Log
Revision 2272 -
(hide annotations)
(download)
Sat Aug 24 09:44:18 2013 UTC (11 years, 1 month ago) by niro
File size: 14329 byte(s)
Sat Aug 24 09:44:18 2013 UTC (11 years, 1 month ago) by niro
File size: 14329 byte(s)
-multi seat support with systemd
1 | niro | 2272 | diff -up kde-workspace-4.10.90/CMakeLists.txt.kdm_logind kde-workspace-4.10.90/CMakeLists.txt |
2 | --- kde-workspace-4.10.90/CMakeLists.txt.kdm_logind 2013-06-27 16:27:30.199895076 -0500 | ||
3 | +++ kde-workspace-4.10.90/CMakeLists.txt 2013-06-27 16:30:25.167008304 -0500 | ||
4 | @@ -128,6 +128,13 @@ if(Q_WS_X11) | ||
5 | endif() | ||
6 | endif(Q_WS_X11) | ||
7 | |||
8 | +macro_optional_find_package(Systemd) | ||
9 | +set_package_properties(Systemd PROPERTIES DESCRIPTION "Init and service manager for Linux" | ||
10 | + URL "http://www.freedesktop.org/wiki/Software/systemd" | ||
11 | + TYPE OPTIONAL | ||
12 | + PURPOSE "Provides automatic multi-seat, session and power management features" | ||
13 | + ) | ||
14 | + | ||
15 | macro_optional_find_package(GLIB2 2.0) | ||
16 | set_package_properties(GLIB2 PROPERTIES DESCRIPTION "Low-level core library for data structure handling, portability wrappers, etc." | ||
17 | URL "http://www.gtk.org" | ||
18 | diff -up kde-workspace-4.10.90/cmake/modules/CMakeLists.txt.kdm_logind kde-workspace-4.10.90/cmake/modules/CMakeLists.txt | ||
19 | --- kde-workspace-4.10.90/cmake/modules/CMakeLists.txt.kdm_logind 2013-06-10 13:51:11.000000000 -0500 | ||
20 | +++ kde-workspace-4.10.90/cmake/modules/CMakeLists.txt 2013-06-27 16:27:30.199895076 -0500 | ||
21 | @@ -8,6 +8,7 @@ set(cmakeFiles FindCkConnector.cmake | ||
22 | FindOpenGLES.cmake | ||
23 | FindPAM.cmake | ||
24 | FindSensors.cmake | ||
25 | + FindSystemd.cmake | ||
26 | PkgConfigGetVar.cmake | ||
27 | UnixAuth.cmake ) | ||
28 | |||
29 | diff -up kde-workspace-4.10.90/cmake/modules/FindSystemd.cmake.kdm_logind kde-workspace-4.10.90/cmake/modules/FindSystemd.cmake | ||
30 | --- kde-workspace-4.10.90/cmake/modules/FindSystemd.cmake.kdm_logind 2013-06-27 16:27:30.200895065 -0500 | ||
31 | +++ kde-workspace-4.10.90/cmake/modules/FindSystemd.cmake 2013-06-27 16:27:30.200895065 -0500 | ||
32 | @@ -0,0 +1,39 @@ | ||
33 | +# Finds systemd and its libraries | ||
34 | +# Not a huge module but sufficient for now | ||
35 | +# Uses the same semantics as pkg_check_modules, i.e. ${LIB}{_FOUND,_INCLUDE_DIR,_LIBRARIES} | ||
36 | +# where ${LIB} can be one of the following: | ||
37 | +# LIBSYSTEMD_JOURNAL, SYSTEMD, LIBSYSTEMD_DAEMON, LIBSYSTEMD_LOGIN, LIBSYSTEMD_ID128 | ||
38 | +# | ||
39 | +# Copyright: Red Hat, Inc. 2013 | ||
40 | +# Author: Martin Briza <mbriza@redhat.com> | ||
41 | +# | ||
42 | +# Distributed under the BSD license. See COPYING-CMAKE-SCRIPTS for details. | ||
43 | + | ||
44 | +#defining any of these disables systemd support | ||
45 | +if (NOT LIBSYSTEMD_JOURNAL_FOUND AND | ||
46 | + NOT SYSTEMD_FOUND AND | ||
47 | + NOT LIBSYSTEMD_DAEMON_FOUND AND | ||
48 | + NOT LIBSYSTEMD_LOGIN_FOUND AND | ||
49 | + NOT LIBSYSTEMD_ID128_FOUND) | ||
50 | +find_package(PkgConfig) | ||
51 | +if (PKG_CONFIG_FOUND) | ||
52 | + pkg_check_modules(LIBSYSTEMD_JOURNAL QUIET "libsystemd-journal") | ||
53 | + pkg_check_modules(SYSTEMD QUIET "systemd") | ||
54 | + pkg_check_modules(LIBSYSTEMD_DAEMON QUIET "libsystemd-daemon") | ||
55 | + pkg_check_modules(LIBSYSTEMD_LOGIN QUIET "libsystemd-login") | ||
56 | + pkg_check_modules(LIBSYSTEMD_ID128 QUIET "libsystemd-id128") | ||
57 | +endif (PKG_CONFIG_FOUND) | ||
58 | + | ||
59 | +if (SYSTEMD_FOUND) | ||
60 | + message(STATUS "Found systemd") | ||
61 | +endif(SYSTEMD_FOUND) | ||
62 | + | ||
63 | +mark_as_advanced(LIBSYSTEMD_JOURNAL_FOUND SYSTEMD_FOUND LIBSYSTEMD_DAEMON_FOUND LIBSYSTEMD_LOGIN_FOUND LIBSYSTEMD_ID128_FOUND) | ||
64 | +mark_as_advanced(LIBSYSTEMD_JOURNAL_INCLUDE_DIR SYSTEMD_INCLUDE_DIR LIBSYSTEMD_DAEMON_INCLUDE_DIR LIBSYSTEMD_LOGIN_INCLUDE_DIR LIBSYSTEMD_ID128_INCLUDE_DIR) | ||
65 | +mark_as_advanced(LIBSYSTEMD_JOURNAL_LIBRARIES SYSTEMD_LIBRARIES LIBSYSTEMD_DAEMON_LIBRARIES LIBSYSTEMD_LOGIN_LIBRARIES LIBSYSTEMD_ID128_LIBRARIES) | ||
66 | + | ||
67 | +endif (NOT LIBSYSTEMD_JOURNAL_FOUND AND | ||
68 | + NOT SYSTEMD_FOUND AND | ||
69 | + NOT LIBSYSTEMD_DAEMON_FOUND AND | ||
70 | + NOT LIBSYSTEMD_LOGIN_FOUND AND | ||
71 | + NOT LIBSYSTEMD_ID128_FOUND) | ||
72 | diff -up kde-workspace-4.10.90/kdm/backend/CMakeLists.txt.kdm_logind kde-workspace-4.10.90/kdm/backend/CMakeLists.txt | ||
73 | --- kde-workspace-4.10.90/kdm/backend/CMakeLists.txt.kdm_logind 2013-05-28 13:38:21.000000000 -0500 | ||
74 | +++ kde-workspace-4.10.90/kdm/backend/CMakeLists.txt 2013-06-27 16:27:30.201895054 -0500 | ||
75 | @@ -45,6 +45,10 @@ if (SECURE_RPC) | ||
76 | rpcauth.c | ||
77 | ) | ||
78 | endif (SECURE_RPC) | ||
79 | +if(LIBSYSTEMD_LOGIN_FOUND AND LIBSYSTEMD_DAEMON_FOUND) | ||
80 | + add_definitions( -DWITH_SYSTEMD=1 ) | ||
81 | + set(KDM_SYSTEMD_LIBRARIES ${LIBSYSTEMD_DAEMON_LIBRARIES} ${LIBSYSTEMD_LOGIN_LIBRARIES} ) | ||
82 | +endif(LIBSYSTEMD_LOGIN_FOUND AND LIBSYSTEMD_DAEMON_FOUND) | ||
83 | macro_add_file_dependencies(dm.h ${confci}) | ||
84 | macro_add_file_dependencies(error.c ${CMAKE_CURRENT_SOURCE_DIR}/printf.c) | ||
85 | kde4_add_executable(kdm NOGUI ${kdm_SRCS}) | ||
86 | @@ -60,6 +64,7 @@ target_link_libraries( kdm | ||
87 | ${NSL_LIBRARIES} | ||
88 | ${RESOLV_LIBRARIES} | ||
89 | ${SOCKET_LIBRARIES} | ||
90 | + ${KDM_SYSTEMD_LIBRARIES} | ||
91 | ) | ||
92 | if (CKCONNECTOR_FOUND) | ||
93 | include_directories(${CKCONNECTOR_INCLUDE_DIR} ${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR}) | ||
94 | diff -up kde-workspace-4.10.90/kdm/backend/dm.c.kdm_logind kde-workspace-4.10.90/kdm/backend/dm.c | ||
95 | --- kde-workspace-4.10.90/kdm/backend/dm.c.kdm_logind 2013-06-27 16:27:30.184895241 -0500 | ||
96 | +++ kde-workspace-4.10.90/kdm/backend/dm.c 2013-06-27 16:27:30.201895054 -0500 | ||
97 | @@ -50,6 +50,23 @@ from the copyright holder. | ||
98 | # include <sys/vt.h> | ||
99 | #endif | ||
100 | |||
101 | +#ifdef WITH_SYSTEMD | ||
102 | +# include <systemd/sd-login.h> | ||
103 | +# include <systemd/sd-daemon.h> | ||
104 | + | ||
105 | +#define SYSTEMD_FAILURE_LIMIT 25 | ||
106 | + | ||
107 | + static int systemdMonitorInit(void); | ||
108 | + static void systemdMonitorDeinit(); | ||
109 | + static int systemdStartDisplay(char *); | ||
110 | + static void systemdCheckAdded(char **); | ||
111 | + static void systemdCheckRemoved(char **); | ||
112 | + static void systemdHandleChange(); | ||
113 | + | ||
114 | + sd_login_monitor *systemd_monitor = NULL; | ||
115 | + int systemd_monitor_fd = -1; | ||
116 | +#endif | ||
117 | + | ||
118 | static void sigHandler(int n); | ||
119 | static int scanConfigs(int force); | ||
120 | static void startDisplay(struct display *d); | ||
121 | @@ -308,7 +325,16 @@ main(int argc, char **argv) | ||
122 | #ifdef XDMCP | ||
123 | updateListenSockets(); | ||
124 | #endif | ||
125 | + | ||
126 | +#ifdef WITH_SYSTEMD | ||
127 | + if (systemdMonitorInit()) | ||
128 | + systemdHandleChange(); | ||
129 | +#endif | ||
130 | + | ||
131 | mainLoop(); | ||
132 | +#ifdef WITH_SYSTEMD | ||
133 | + systemdMonitorDeinit(); | ||
134 | +#endif | ||
135 | closeCtrl(0); | ||
136 | if (sdRec.how) { | ||
137 | int pid; | ||
138 | @@ -1280,6 +1306,14 @@ mainLoop(void) | ||
139 | } | ||
140 | continue; | ||
141 | } | ||
142 | + logError("STARTING"); | ||
143 | +#ifdef WITH_SYSTEMD | ||
144 | + if (systemd_monitor_fd >= 0 && FD_ISSET(systemd_monitor_fd, &reads)) { | ||
145 | + systemdHandleChange(); | ||
146 | + sd_login_monitor_flush(systemd_monitor); | ||
147 | + continue; | ||
148 | + } | ||
149 | +#endif | ||
150 | #ifdef XDMCP | ||
151 | if (processListenSockets(&reads)) | ||
152 | continue; | ||
153 | @@ -1304,6 +1338,151 @@ mainLoop(void) | ||
154 | } | ||
155 | } | ||
156 | |||
157 | +#ifdef WITH_SYSTEMD | ||
158 | +static int | ||
159 | +systemdMonitorInit(void) | ||
160 | +{ | ||
161 | + if (sd_booted() <= 0) { | ||
162 | + logError("Didn't boot with systemd, automatic multiseat won't be enabled\n"); | ||
163 | + return False; | ||
164 | + } | ||
165 | + | ||
166 | + int check = sd_login_monitor_new("seat", &systemd_monitor); | ||
167 | + if (check < 0) { | ||
168 | + logError("Can't get systemd monitor: %d, automatic multiseat won't be enabled\n", check); | ||
169 | + return False; | ||
170 | + } | ||
171 | + | ||
172 | + systemd_monitor_fd = sd_login_monitor_get_fd(systemd_monitor); | ||
173 | + if (systemd_monitor_fd < 0) { | ||
174 | + logError("Can't retrieve file descriptor from the systemd monitor: %d, automatic multiseat won't be enabled\n", systemd_monitor_fd); | ||
175 | + sd_login_monitor_unref(systemd_monitor); | ||
176 | + systemd_monitor_fd = -1; | ||
177 | + return False; | ||
178 | + } | ||
179 | + | ||
180 | + registerInput(systemd_monitor_fd); | ||
181 | + return True; | ||
182 | +} | ||
183 | + | ||
184 | +static void | ||
185 | +systemdMonitorDeinit(void) | ||
186 | +{ | ||
187 | + if (systemd_monitor) { | ||
188 | + sd_login_monitor_unref(systemd_monitor); | ||
189 | + } | ||
190 | + systemd_monitor_fd = -1; | ||
191 | +} | ||
192 | + | ||
193 | +static int | ||
194 | +systemdStartDisplay(char *seat) | ||
195 | +{ | ||
196 | + struct display *link = NULL; | ||
197 | + for (link = displays; link; link = link-> next) { | ||
198 | + if (link->status == reserve) | ||
199 | + break; | ||
200 | + } | ||
201 | + if (!link) { | ||
202 | + logError("There's not enough reserve displays for all your seats/sessions"); | ||
203 | + return False; | ||
204 | + } | ||
205 | + if (!strDup((&link->systemd_seat), seat)) { | ||
206 | + return False; | ||
207 | + } | ||
208 | +#ifdef HAVE_VTS | ||
209 | + link->serverVT = 0; | ||
210 | +#endif | ||
211 | + link->status = notRunning; | ||
212 | + link->stillThere = True; | ||
213 | + link->authorize = True; | ||
214 | + link->displayType = dLocal | dPermanent; | ||
215 | + link->reqSrvVT = -1; | ||
216 | + link->serverPid = -1; | ||
217 | + return True; | ||
218 | +} | ||
219 | + | ||
220 | +static void | ||
221 | +systemdCheckAdded(char **seat_names) | ||
222 | +{ | ||
223 | + char **iter_name; | ||
224 | + struct display *link; | ||
225 | + for (iter_name = seat_names; *iter_name; iter_name++) { | ||
226 | + if (strcmp(*iter_name, "seat0") == 0) | ||
227 | + continue; /* ignore the main seat */ | ||
228 | + int can_graphical = sd_seat_can_graphical(*iter_name); | ||
229 | + for (link = displays; link; link = link->next) { | ||
230 | + if (!link->systemd_seat) | ||
231 | + continue; | ||
232 | + /* see if the can_graphical property didn't change */ | ||
233 | + if (strcmp(*iter_name, link->systemd_seat) == 0) { | ||
234 | + if (!can_graphical) { | ||
235 | + free(link->systemd_seat); | ||
236 | + link->systemd_seat = NULL; | ||
237 | + rStopDisplay(link, DS_RESERVE); | ||
238 | + } | ||
239 | + break; | ||
240 | + } | ||
241 | + } | ||
242 | + /* the display wasn't found */ | ||
243 | + if (!link) { | ||
244 | + if (can_graphical) { | ||
245 | + /* if starting the display failed, skip this round until the next change */ | ||
246 | + if (!systemdStartDisplay(*iter_name)) | ||
247 | + break; | ||
248 | + } | ||
249 | + } | ||
250 | + } | ||
251 | +} | ||
252 | + | ||
253 | +static void | ||
254 | +systemdCheckRemoved(char **seat_names) | ||
255 | +{ | ||
256 | + char **iter_name; | ||
257 | + struct display *link; | ||
258 | + for (link = displays; link; link = link->next) { | ||
259 | + for (iter_name = seat_names; *iter_name; iter_name++) { | ||
260 | + if (strcmp(*iter_name, "seat0") == 0) | ||
261 | + continue; /* ignore the main seat */ | ||
262 | + if (link->systemd_seat && strcmp(*iter_name, link->systemd_seat) == 0) | ||
263 | + break; | ||
264 | + } | ||
265 | + if (!(*iter_name) && link->systemd_seat) { /* was not found, stop this one */ | ||
266 | + free(link->systemd_seat); | ||
267 | + link->systemd_seat = NULL; | ||
268 | + rStopDisplay(link, DS_RESERVE); | ||
269 | + } | ||
270 | + } | ||
271 | +} | ||
272 | + | ||
273 | +static void | ||
274 | +systemdHandleChange(void) | ||
275 | +{ | ||
276 | + static int failures = 0; | ||
277 | + char **seat_names; | ||
278 | + char **iter_name; | ||
279 | + int check; | ||
280 | + if ((check = sd_get_seats(&seat_names)) < 0) { | ||
281 | + logError("Can't obtain systemd seats, error %d\n", -check); | ||
282 | + failures++; | ||
283 | + if (failures >= SYSTEMD_FAILURE_LIMIT) { | ||
284 | + logError("%u failed calls to sd_get_seats, disabling systemd multi-seat support\n", SYSTEMD_FAILURE_LIMIT); | ||
285 | + systemdMonitorDeinit(); | ||
286 | + } | ||
287 | + return; | ||
288 | + } | ||
289 | + | ||
290 | + if (!check) | ||
291 | + return; | ||
292 | + | ||
293 | + systemdCheckAdded(seat_names); | ||
294 | + systemdCheckRemoved(seat_names); | ||
295 | + | ||
296 | + for (iter_name = seat_names; *iter_name; iter_name++) | ||
297 | + free(*iter_name); | ||
298 | + free(seat_names); | ||
299 | +} | ||
300 | +#endif | ||
301 | + | ||
302 | static void | ||
303 | checkDisplayStatus(struct display *d) | ||
304 | { | ||
305 | diff -up kde-workspace-4.10.90/kdm/backend/dm.h.kdm_logind kde-workspace-4.10.90/kdm/backend/dm.h | ||
306 | --- kde-workspace-4.10.90/kdm/backend/dm.h.kdm_logind 2013-06-27 16:27:30.184895241 -0500 | ||
307 | +++ kde-workspace-4.10.90/kdm/backend/dm.h 2013-06-27 16:27:30.201895054 -0500 | ||
308 | @@ -306,6 +306,9 @@ struct display { | ||
309 | char *greeterAuthFile; /* file to store authorization for greeter in */ | ||
310 | |||
311 | int plymouth_is_running; /* Plymouth's status */ | ||
312 | +#ifdef WITH_SYSTEMD | ||
313 | + char *systemd_seat; | ||
314 | +#endif | ||
315 | }; | ||
316 | |||
317 | #define d_location 1 | ||
318 | diff -up kde-workspace-4.10.90/kdm/backend/server.c.kdm_logind kde-workspace-4.10.90/kdm/backend/server.c | ||
319 | --- kde-workspace-4.10.90/kdm/backend/server.c.kdm_logind 2013-06-27 16:27:30.184895241 -0500 | ||
320 | +++ kde-workspace-4.10.90/kdm/backend/server.c 2013-06-27 16:27:30.201895054 -0500 | ||
321 | @@ -43,6 +43,7 @@ from the copyright holder. | ||
322 | #include <stdio.h> | ||
323 | #include <signal.h> | ||
324 | |||
325 | +#define SYSTEMD_X_WRAPPER "/lib/systemd/systemd-multi-seat-x" | ||
326 | |||
327 | struct display *startingServer; | ||
328 | time_t serverTimeout = TO_INF; | ||
329 | @@ -55,9 +56,18 @@ prepareServerArgv(struct display *d, con | ||
330 | char vtstr[8]; | ||
331 | #endif | ||
332 | |||
333 | - if (!(argv = parseArgs(0, d->serverCmd)) || | ||
334 | - !(argv = addStrArr(argv, d->name, -1))) | ||
335 | +#if WITH_SYSTEMD | ||
336 | + FILE *tmpFile = NULL; | ||
337 | + if ((tmpFile = fopen(SYSTEMD_X_WRAPPER, "rb")) != NULL && fclose(tmpFile) == 0) { | ||
338 | + if (!(argv = parseArgs(0, SYSTEMD_X_WRAPPER)) || !(argv = addStrArr(argv, d->name, -1))) { | ||
339 | + exit(47); | ||
340 | + } | ||
341 | + } | ||
342 | + else | ||
343 | +#endif | ||
344 | + if (!(argv = parseArgs(0, d->serverCmd)) || !(argv = addStrArr(argv, d->name, -1))) { | ||
345 | exit(47); | ||
346 | + } | ||
347 | #ifdef HAVE_VTS | ||
348 | if (d->serverVT && | ||
349 | !(argv = addStrArr(argv, vtstr, | ||
350 | @@ -70,6 +80,25 @@ prepareServerArgv(struct display *d, con | ||
351 | if (!changeUser(d->serverUID, d->authFile)) | ||
352 | exit(47); | ||
353 | |||
354 | +#ifdef WITH_SYSTEMD | ||
355 | + if (d->systemd_seat) { | ||
356 | + if (!(argv = parseArgs(argv, "-seat"))) | ||
357 | + exit(47); | ||
358 | + if (!(argv = parseArgs(argv, d->systemd_seat))) | ||
359 | + exit(47); | ||
360 | + if (!(argv = parseArgs(argv, "-layout"))) | ||
361 | + exit(47); | ||
362 | + if (!(argv = parseArgs(argv, d->systemd_seat))) | ||
363 | + exit(47); | ||
364 | + } | ||
365 | + else { | ||
366 | + if (!(argv = parseArgs(argv, "-seat"))) | ||
367 | + exit(47); | ||
368 | + if (!(argv = parseArgs(argv, "seat0"))) | ||
369 | + exit(47); | ||
370 | + } | ||
371 | +#endif | ||
372 | + | ||
373 | return argv; | ||
374 | } | ||
375 | |||
376 | --- kde-workspace-4.10.2/kdm/backend/client.c.kdm_logind | ||
377 | +++ kde-workspace-4.10.2/kdm/backend/client.c | ||
378 | @@ -1461,6 +1461,14 @@ startClient(volatile int *pid) | ||
379 | #endif | ||
380 | userEnviron = inheritEnv(env, envvars); | ||
381 | env = systemEnv(0, curuser); | ||
382 | +#ifdef WITH_SYSTEMD | ||
383 | + if (td->systemd_seat) { | ||
384 | + char *envbuf; | ||
385 | + ASPrintf(&envbuf, "XDG_SEAT=%s", td->systemd_seat); | ||
386 | + pam_putenv(pamh, envbuf); | ||
387 | + env = setEnv(env, "XDG_SEAT", td->systemd_seat); | ||
388 | + } | ||
389 | +#endif | ||
390 | systemEnviron = setEnv(env, "HOME", p->pw_dir); | ||
391 | debug("user environment:\n%[|''>'\n's" | ||
392 | "system environment:\n%[|''>'\n's" | ||
393 | --- kde-workspace-4.10.2/kdm/backend/session.c.kdm_logind | ||
394 | +++ kde-workspace-4.10.2/kdm/backend/session.c | ||
395 | @@ -437,6 +437,10 @@ openGreeter() | ||
396 | |||
397 | grttalk.pipe = &grtproc.pipe; | ||
398 | env = systemEnv(dupEnv(), 0); | ||
399 | +#ifdef WITH_SYSTEMD | ||
400 | + if (td->systemd_seat) | ||
401 | + env = setEnv(env, "XDG_SEAT", td->systemd_seat); | ||
402 | +#endif | ||
403 | if (gOpen(&grtproc, (char **)0, "_greet", env, name, | ||
404 | greeterUID, td->greeterAuthFile, &td->gpipe)) | ||
405 | sessionExit(EX_UNMANAGE_DPY); |