X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flogin%2Flogind.c;h=7452c5b82c125e06c8af6327a627c2d0f7ea9476;hb=cac2e345596b2743053c0285280b81794b3aaf10;hp=83b06afa3bbb121d33e60a942612f362ae9eda9b;hpb=036174b578f4c18fd2fefb9f5d87791ea2e01b5d;p=elogind.git diff --git a/src/login/logind.c b/src/login/logind.c index 83b06afa3..7452c5b82 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -81,9 +81,6 @@ static void manager_reset_config(Manager *m) { m->kill_only_users = strv_free(m->kill_only_users); m->kill_exclude_users = strv_free(m->kill_exclude_users); -#if 1 /// elogind needs an Add-On for sleep configuration - elogind_manager_reset_config(m); -#endif // 1 } static Manager *manager_new(void) { @@ -436,10 +433,71 @@ static int manager_enumerate_users(Manager *m) { return r; } +static int manager_attach_fds(Manager *m) { + _cleanup_strv_free_ char **fdnames = NULL; + int n, i, fd; + + /* Upon restart, PID1 will send us back all fds of session devices + * that we previously opened. Each file descriptor is associated + * with a given session. The session ids are passed through FDNAMES. */ + + n = sd_listen_fds_with_names(true, &fdnames); + if (n <= 0) + return n; + + for (i = 0; i < n; i++) { + struct stat st; + SessionDevice *sd; + Session *s; + char *id; + + fd = SD_LISTEN_FDS_START + i; + + id = startswith(fdnames[i], "session-"); + if (!id) + continue; + + s = hashmap_get(m->sessions, id); + if (!s) { + /* If the session doesn't exist anymore, the associated session + * device attached to this fd doesn't either. Let's simply close + * this fd. */ + log_debug("Failed to attach fd for unknown session: %s", id); + close_nointr(fd); + continue; + } + + if (fstat(fd, &st) < 0) { + /* The device is allowed to go away at a random point, in which + * case fstat failing is expected. */ + log_debug_errno(errno, "Failed to stat device fd for session %s: %m", id); + close_nointr(fd); + continue; + } + + sd = hashmap_get(s->devices, &st.st_rdev); + if (!sd) { + /* Weird we got an fd for a session device which wasn't + * recorded in the session state file... */ + log_warning("Got fd for missing session device [%u:%u] in session %s", + major(st.st_rdev), minor(st.st_rdev), s->id); + close_nointr(fd); + continue; + } + + log_debug("Attaching fd to session device [%u:%u] for session %s", + major(st.st_rdev), minor(st.st_rdev), s->id); + + session_device_attach_fd(sd, fd, s->was_active); + } + + return 0; +} + static int manager_enumerate_sessions(Manager *m) { _cleanup_closedir_ DIR *d = NULL; struct dirent *de; - int r = 0; + int r = 0, k; assert(m); @@ -454,7 +512,6 @@ static int manager_enumerate_sessions(Manager *m) { FOREACH_DIRENT(de, d, return -errno) { struct Session *s; - int k; if (!dirent_is_file(de)) continue; @@ -468,7 +525,6 @@ static int manager_enumerate_sessions(Manager *m) { k = manager_add_session(m, de->d_name, &s); if (k < 0) { log_error_errno(k, "Failed to add session by file name %s: %m", de->d_name); - r = k; continue; } @@ -480,6 +536,12 @@ static int manager_enumerate_sessions(Manager *m) { r = k; } + /* We might be restarted and PID1 could have sent us back the + * session device fds we previously saved. */ + k = manager_attach_fds(m); + if (k < 0) + log_warning_errno(k, "Failed to reattach session device fds: %m"); + return r; } @@ -730,7 +792,6 @@ static int manager_connect_bus(Manager *m) { #if 0 /// elogind has to setup its release agent return 0; #else - elogind_bus_setup_system(m); r = elogind_setup_cgroups_agent(m); return r; @@ -1047,10 +1108,10 @@ static int manager_parse_config_file(Manager *m) { assert(m); return config_parse_many_nulstr(PKGSYSCONFDIR "/logind.conf", - CONF_PATHS_NULSTR("systemd/logind.conf.d"), - "Login\0", - config_item_perf_lookup, logind_gperf_lookup, - false, m); + CONF_PATHS_NULSTR("systemd/logind.conf.d"), + "Login\0", + config_item_perf_lookup, logind_gperf_lookup, + false, m); #else const char* logind_conf = getenv("ELOGIND_CONF_FILE"); @@ -1076,6 +1137,10 @@ static int manager_dispatch_reload_signal(sd_event_source *s, const struct signa else log_info("Config file reloaded."); +#if 1 /// elogind needs an Add-On for sleep configuration + elogind_manager_reset_config(m); +#endif // 1 + return 0; } @@ -1096,6 +1161,10 @@ 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); +#endif // 1 + /* Connect to console */ r = manager_connect_console(m); if (r < 0) @@ -1204,6 +1273,12 @@ int main(int argc, char *argv[]) { Manager *m = NULL; int r; +#if 1 /// perform extra checks for elogind startup + r = elogind_startup(argc, argv); + if (r) + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +#endif // 0 + elogind_set_program_name(argv[0]); log_set_target(LOG_TARGET_AUTO); log_set_facility(LOG_AUTH); @@ -1216,11 +1291,13 @@ int main(int argc, char *argv[]) { umask(0022); +#if 0 /// elogind has some extra functionality at startup, argc can be != 1 if (argc != 1) { log_error("This program takes no arguments."); r = -EINVAL; goto finish; } +#endif // 0 r = mac_selinux_init(); if (r < 0) { @@ -1263,6 +1340,10 @@ int main(int argc, char *argv[]) { manager_parse_config_file(m); +#if 1 /// elogind needs an Add-On for sleep configuration + elogind_manager_reset_config(m); +#endif // 1 + r = manager_startup(m); if (r < 0) { log_error_errno(r, "Failed to fully start up daemon: %m");