diff options
author | Mark Hindley <mark@hindley.org.uk> | 2018-11-12 09:10:28 +0000 |
---|---|---|
committer | Mark Hindley <mark@hindley.org.uk> | 2018-11-12 09:21:21 +0000 |
commit | 2cc17d30309a1db16cccbf376a59ae40e47b6959 (patch) | |
tree | cd51ee95799631af348ebae8630a69219bee99cd /src/login/logind.c | |
parent | ae65e91a5439f395e0da0cd8ffda95d6289849e1 (diff) | |
parent | d4a3f291e3955648ea1d29e674b0f8f9b1556257 (diff) |
Merge remote-tracking branch 'upstream/v239-stable' into merge_upstream.
Diffstat (limited to 'src/login/logind.c')
-rw-r--r-- | src/login/logind.c | 79 |
1 files changed, 54 insertions, 25 deletions
diff --git a/src/login/logind.c b/src/login/logind.c index c7acb05cb..558733b30 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -45,28 +45,35 @@ static int manager_new(Manager **ret) { assert(ret); - m = new0(Manager, 1); + m = new(Manager, 1); if (!m) return -ENOMEM; - m->console_active_fd = -1; -#if 0 /// UNNEEDED by elogind - m->reserve_vt_fd = -1; + *m = (Manager) { + .console_active_fd = -1, +#if 0 /// elogind does not support autospawning of vts + .reserve_vt_fd = -1, #endif // 0 + }; m->idle_action_not_before_usec = now(CLOCK_MONOTONIC); m->devices = hashmap_new(&string_hash_ops); m->seats = hashmap_new(&string_hash_ops); m->sessions = hashmap_new(&string_hash_ops); + m->sessions_by_leader = hashmap_new(NULL); m->users = hashmap_new(NULL); m->inhibitors = hashmap_new(&string_hash_ops); m->buttons = hashmap_new(&string_hash_ops); +#if 0 /// elogind does not support units m->user_units = hashmap_new(&string_hash_ops); m->session_units = hashmap_new(&string_hash_ops); - if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units) + if (!m->devices || !m->seats || !m->sessions || !m->sessions_by_leader || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units) +#else + if (!m->devices || !m->seats || !m->sessions || !m->sessions_by_leader || !m->users || !m->inhibitors || !m->buttons) +#endif // 0 return -ENOMEM; #if 1 /// elogind needs some more data @@ -82,6 +89,7 @@ static int manager_new(Manager **ret) { if (r < 0) return r; +#if 0 /// elogind uses its own signal handler, installed at elogind_manager_startup() r = sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL); if (r < 0) return r; @@ -89,6 +97,7 @@ static int manager_new(Manager **ret) { r = sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL); if (r < 0) return r; +#endif // 0 (void) sd_event_set_watchdog(m->event, true); @@ -130,12 +139,15 @@ static Manager* manager_unref(Manager *m) { hashmap_free(m->devices); hashmap_free(m->seats); hashmap_free(m->sessions); + hashmap_free(m->sessions_by_leader); hashmap_free(m->users); hashmap_free(m->inhibitors); hashmap_free(m->buttons); +#if 0 /// elogind does not support systemd units. hashmap_free(m->user_units); hashmap_free(m->session_units); +#endif // 0 sd_event_source_unref(m->idle_action_event_source); sd_event_source_unref(m->inhibit_timeout_source); @@ -150,6 +162,10 @@ static Manager* manager_unref(Manager *m) { sd_event_source_unref(m->udev_button_event_source); sd_event_source_unref(m->lid_switch_ignore_event_source); +#if ENABLE_UTMP + sd_event_source_unref(m->utmp_event_source); +#endif + safe_close(m->console_active_fd); udev_monitor_unref(m->udev_seat_monitor); @@ -852,28 +868,28 @@ static int manager_connect_console(Manager *m) { assert(m); assert(m->console_active_fd < 0); - /* On certain architectures (S390 and Xen, and containers), - /dev/tty0 does not exist, so don't fail if we can't open - it. */ + /* On certain systems (such as S390, Xen, and containers) /dev/tty0 does not exist (as there is no VC), so + * don't fail if we can't open it. */ + if (access("/dev/tty0", F_OK) < 0) return 0; m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC); if (m->console_active_fd < 0) { - /* On some systems the device node /dev/tty0 may exist - * even though /sys/class/tty/tty0 does not. */ - if (errno == ENOENT) + /* On some systems /dev/tty0 may exist even though /sys/class/tty/tty0 does not. These are broken, but + * common. Let's complain but continue anyway. */ + if (errno == ENOENT) { + log_warning_errno(errno, "System has /dev/tty0 but not /sys/class/tty/tty0/active which is broken, ignoring: %m"); return 0; + } return log_error_errno(errno, "Failed to open /sys/class/tty/tty0/active: %m"); } r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m); - if (r < 0) { - log_error("Failed to watch foreground console"); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to watch foreground console: %m"); /* * SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used @@ -892,7 +908,7 @@ static int manager_connect_console(Manager *m) { r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m); if (r < 0) - return r; + return log_error_errno(r, "Failed to subscribe to signal: %m"); return 0; } @@ -1018,13 +1034,13 @@ static void manager_gc(Manager *m, bool drop_not_started) { /* First, if we are not closing yet, initiate stopping */ if (session_may_gc(session, drop_not_started) && session_get_state(session) != SESSION_CLOSING) - session_stop(session, false); + (void) session_stop(session, false); /* Normally, this should make the session referenced * again, if it doesn't then let's get rid of it * immediately */ if (session_may_gc(session, drop_not_started)) { - session_finalize(session); + (void) session_finalize(session); session_free(session); } } @@ -1035,11 +1051,11 @@ static void manager_gc(Manager *m, bool drop_not_started) { /* First step: queue stop jobs */ if (user_may_gc(user, drop_not_started)) - user_stop(user, false); + (void) user_stop(user, false); /* Second step: finalize user */ if (user_may_gc(user, drop_not_started)) { - user_finalize(user); + (void) user_finalize(user); user_free(user); } } @@ -1137,9 +1153,15 @@ static int manager_startup(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to register SIGHUP handler: %m"); -#if 1 /// elogind needs some extra preparations before connecting... - elogind_manager_startup(m); +#if 1 /// install elogind specific signal handlers + r = elogind_manager_startup(m); + if (r < 0) + return log_error_errno(r, "Failed to register elogind signal handlers: %m"); #endif // 1 + + /* Connect to utmp */ + manager_connect_utmp(m); + /* Connect to console */ r = manager_connect_console(m); if (r < 0) @@ -1197,15 +1219,18 @@ static int manager_startup(Manager *m) { manager_reserve_vt(m); #endif // 0 + /* Read in utmp if it exists */ + manager_read_utmp(m); + /* And start everything */ HASHMAP_FOREACH(seat, m->seats, i) - seat_start(seat); + (void) seat_start(seat); HASHMAP_FOREACH(user, m->users, i) - user_start(user); + (void) user_start(user); HASHMAP_FOREACH(session, m->sessions, i) - session_start(session, NULL); + (void) session_start(session, NULL, NULL); HASHMAP_FOREACH(inhibitor, m->inhibitors, i) inhibitor_start(inhibitor); @@ -1307,7 +1332,11 @@ int main(int argc, char *argv[]) { return log_error_errno(r, "Failed to create /run/systemd/machines : %m"); #endif // 0 +#if 0 /// elogind also blocks SIGQUIT, and installs a signal handler for it assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGHUP, SIGTERM, SIGINT, -1) >= 0); +#else + assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGHUP, SIGTERM, SIGINT, SIGQUIT, -1) >= 0); +#endif // 0 r = manager_new(&m); if (r < 0) { |