|
Lines 50-55
from the copyright holder.
Link Here
|
| 50 |
# include <sys/vt.h> |
50 |
# include <sys/vt.h> |
| 51 |
#endif |
51 |
#endif |
| 52 |
|
52 |
|
|
|
53 |
#ifdef WITH_SYSTEMD |
| 54 |
# include <systemd/sd-login.h> |
| 55 |
# include <systemd/sd-daemon.h> |
| 56 |
|
| 57 |
#define SYSTEMD_FAILURE_LIMIT 25 |
| 58 |
|
| 59 |
static int systemdMonitorInit(void); |
| 60 |
static void systemdMonitorDeinit(); |
| 61 |
static int systemdStartDisplay(char *); |
| 62 |
static void systemdCheckAdded(char **); |
| 63 |
static void systemdCheckRemoved(char **); |
| 64 |
static void systemdHandleChange(); |
| 65 |
|
| 66 |
sd_login_monitor *systemd_monitor = NULL; |
| 67 |
int systemd_monitor_fd = -1; |
| 68 |
#endif |
| 69 |
|
| 53 |
static void sigHandler(int n); |
70 |
static void sigHandler(int n); |
| 54 |
static int scanConfigs(int force); |
71 |
static int scanConfigs(int force); |
| 55 |
static void startDisplay(struct display *d); |
72 |
static void startDisplay(struct display *d); |
|
Lines 308-314
main(int argc, char **argv)
Link Here
|
| 308 |
#ifdef XDMCP |
325 |
#ifdef XDMCP |
| 309 |
updateListenSockets(); |
326 |
updateListenSockets(); |
| 310 |
#endif |
327 |
#endif |
|
|
328 |
|
| 329 |
#ifdef WITH_SYSTEMD |
| 330 |
if (systemdMonitorInit()) |
| 331 |
systemdHandleChange(); |
| 332 |
#endif |
| 333 |
|
| 311 |
mainLoop(); |
334 |
mainLoop(); |
|
|
335 |
#ifdef WITH_SYSTEMD |
| 336 |
systemdMonitorDeinit(); |
| 337 |
#endif |
| 312 |
closeCtrl(0); |
338 |
closeCtrl(0); |
| 313 |
if (sdRec.how) { |
339 |
if (sdRec.how) { |
| 314 |
int pid; |
340 |
int pid; |
|
Lines 1280-1285
mainLoop(void)
Link Here
|
| 1280 |
} |
1306 |
} |
| 1281 |
continue; |
1307 |
continue; |
| 1282 |
} |
1308 |
} |
|
|
1309 |
logError("STARTING"); |
| 1310 |
#ifdef WITH_SYSTEMD |
| 1311 |
if (systemd_monitor_fd >= 0 && FD_ISSET(systemd_monitor_fd, &reads)) { |
| 1312 |
systemdHandleChange(); |
| 1313 |
sd_login_monitor_flush(systemd_monitor); |
| 1314 |
continue; |
| 1315 |
} |
| 1316 |
#endif |
| 1283 |
#ifdef XDMCP |
1317 |
#ifdef XDMCP |
| 1284 |
if (processListenSockets(&reads)) |
1318 |
if (processListenSockets(&reads)) |
| 1285 |
continue; |
1319 |
continue; |
|
Lines 1304-1309
mainLoop(void)
Link Here
|
| 1304 |
} |
1338 |
} |
| 1305 |
} |
1339 |
} |
| 1306 |
|
1340 |
|
|
|
1341 |
#ifdef WITH_SYSTEMD |
| 1342 |
static int |
| 1343 |
systemdMonitorInit(void) |
| 1344 |
{ |
| 1345 |
if (sd_booted() <= 0) { |
| 1346 |
logError("Didn't boot with systemd, automatic multiseat won't be enabled\n"); |
| 1347 |
return False; |
| 1348 |
} |
| 1349 |
|
| 1350 |
int check = sd_login_monitor_new("seat", &systemd_monitor); |
| 1351 |
if (check < 0) { |
| 1352 |
logError("Can't get systemd monitor: %d, automatic multiseat won't be enabled\n", check); |
| 1353 |
return False; |
| 1354 |
} |
| 1355 |
|
| 1356 |
systemd_monitor_fd = sd_login_monitor_get_fd(systemd_monitor); |
| 1357 |
if (systemd_monitor_fd < 0) { |
| 1358 |
logError("Can't retrieve file descriptor from the systemd monitor: %d, automatic multiseat won't be enabled\n", systemd_monitor_fd); |
| 1359 |
sd_login_monitor_unref(systemd_monitor); |
| 1360 |
systemd_monitor_fd = -1; |
| 1361 |
return False; |
| 1362 |
} |
| 1363 |
|
| 1364 |
registerInput(systemd_monitor_fd); |
| 1365 |
return True; |
| 1366 |
} |
| 1367 |
|
| 1368 |
static void |
| 1369 |
systemdMonitorDeinit(void) |
| 1370 |
{ |
| 1371 |
if (systemd_monitor) { |
| 1372 |
sd_login_monitor_unref(systemd_monitor); |
| 1373 |
} |
| 1374 |
systemd_monitor_fd = -1; |
| 1375 |
} |
| 1376 |
|
| 1377 |
static int |
| 1378 |
systemdStartDisplay(char *seat) |
| 1379 |
{ |
| 1380 |
struct display *link = NULL; |
| 1381 |
for (link = displays; link; link = link-> next) { |
| 1382 |
if (link->status == reserve) |
| 1383 |
break; |
| 1384 |
} |
| 1385 |
if (!link) { |
| 1386 |
logError("There's not enough reserve displays for all your seats/sessions"); |
| 1387 |
return False; |
| 1388 |
} |
| 1389 |
if (!strDup((&link->systemd_seat), seat)) { |
| 1390 |
return False; |
| 1391 |
} |
| 1392 |
#ifdef HAVE_VTS |
| 1393 |
link->serverVT = 0; |
| 1394 |
#endif |
| 1395 |
link->status = notRunning; |
| 1396 |
link->stillThere = True; |
| 1397 |
link->authorize = True; |
| 1398 |
link->displayType = dLocal | dPermanent; |
| 1399 |
link->reqSrvVT = -1; |
| 1400 |
link->serverPid = -1; |
| 1401 |
return True; |
| 1402 |
} |
| 1403 |
|
| 1404 |
static void |
| 1405 |
systemdCheckAdded(char **seat_names) |
| 1406 |
{ |
| 1407 |
char **iter_name; |
| 1408 |
struct display *link; |
| 1409 |
for (iter_name = seat_names; *iter_name; iter_name++) { |
| 1410 |
if (strcmp(*iter_name, "seat0") == 0) |
| 1411 |
continue; /* ignore the main seat */ |
| 1412 |
int can_graphical = sd_seat_can_graphical(*iter_name); |
| 1413 |
for (link = displays; link; link = link->next) { |
| 1414 |
if (!link->systemd_seat) |
| 1415 |
continue; |
| 1416 |
/* see if the can_graphical property didn't change */ |
| 1417 |
if (strcmp(*iter_name, link->systemd_seat) == 0) { |
| 1418 |
if (!can_graphical) { |
| 1419 |
free(link->systemd_seat); |
| 1420 |
link->systemd_seat = NULL; |
| 1421 |
rStopDisplay(link, DS_RESERVE); |
| 1422 |
} |
| 1423 |
break; |
| 1424 |
} |
| 1425 |
} |
| 1426 |
/* the display wasn't found */ |
| 1427 |
if (!link) { |
| 1428 |
if (can_graphical) { |
| 1429 |
/* if starting the display failed, skip this round until the next change */ |
| 1430 |
if (!systemdStartDisplay(*iter_name)) |
| 1431 |
break; |
| 1432 |
} |
| 1433 |
} |
| 1434 |
} |
| 1435 |
} |
| 1436 |
|
| 1437 |
static void |
| 1438 |
systemdCheckRemoved(char **seat_names) |
| 1439 |
{ |
| 1440 |
char **iter_name; |
| 1441 |
struct display *link; |
| 1442 |
for (link = displays; link; link = link->next) { |
| 1443 |
for (iter_name = seat_names; *iter_name; iter_name++) { |
| 1444 |
if (strcmp(*iter_name, "seat0") == 0) |
| 1445 |
continue; /* ignore the main seat */ |
| 1446 |
if (link->systemd_seat && strcmp(*iter_name, link->systemd_seat) == 0) |
| 1447 |
break; |
| 1448 |
} |
| 1449 |
if (!(*iter_name) && link->systemd_seat) { /* was not found, stop this one */ |
| 1450 |
free(link->systemd_seat); |
| 1451 |
link->systemd_seat = NULL; |
| 1452 |
rStopDisplay(link, DS_RESERVE); |
| 1453 |
} |
| 1454 |
} |
| 1455 |
} |
| 1456 |
|
| 1457 |
static void |
| 1458 |
systemdHandleChange(void) |
| 1459 |
{ |
| 1460 |
static int failures = 0; |
| 1461 |
char **seat_names; |
| 1462 |
char **iter_name; |
| 1463 |
int check; |
| 1464 |
if ((check = sd_get_seats(&seat_names)) < 0) { |
| 1465 |
logError("Can't obtain systemd seats, error %d\n", -check); |
| 1466 |
failures++; |
| 1467 |
if (failures >= SYSTEMD_FAILURE_LIMIT) { |
| 1468 |
logError("%u failed calls to sd_get_seats, disabling systemd multi-seat support\n", SYSTEMD_FAILURE_LIMIT); |
| 1469 |
systemdMonitorDeinit(); |
| 1470 |
} |
| 1471 |
return; |
| 1472 |
} |
| 1473 |
|
| 1474 |
if (!check) |
| 1475 |
return; |
| 1476 |
|
| 1477 |
systemdCheckAdded(seat_names); |
| 1478 |
systemdCheckRemoved(seat_names); |
| 1479 |
|
| 1480 |
for (iter_name = seat_names; *iter_name; iter_name++) |
| 1481 |
free(*iter_name); |
| 1482 |
free(seat_names); |
| 1483 |
} |
| 1484 |
#endif |
| 1485 |
|
| 1307 |
static void |
1486 |
static void |
| 1308 |
checkDisplayStatus(struct display *d) |
1487 |
checkDisplayStatus(struct display *d) |
| 1309 |
{ |
1488 |
{ |