summaryrefslogtreecommitdiff
path: root/src/login/logind.c
diff options
context:
space:
mode:
authorMark Hindley <mark@hindley.org.uk>2018-11-12 09:10:28 +0000
committerMark Hindley <mark@hindley.org.uk>2018-11-12 09:21:21 +0000
commit2cc17d30309a1db16cccbf376a59ae40e47b6959 (patch)
treecd51ee95799631af348ebae8630a69219bee99cd /src/login/logind.c
parentae65e91a5439f395e0da0cd8ffda95d6289849e1 (diff)
parentd4a3f291e3955648ea1d29e674b0f8f9b1556257 (diff)
Merge remote-tracking branch 'upstream/v239-stable' into merge_upstream.
Diffstat (limited to 'src/login/logind.c')
-rw-r--r--src/login/logind.c79
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) {