LCOV - code coverage report
Current view: top level - login - logind.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 0 653 0.0 %
Date: 2019-08-23 13:36:53 Functions: 0 30 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 620 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <errno.h>
       4                 :            : #include <fcntl.h>
       5                 :            : #include <string.h>
       6                 :            : #include <unistd.h>
       7                 :            : 
       8                 :            : #include "sd-daemon.h"
       9                 :            : #include "sd-device.h"
      10                 :            : 
      11                 :            : #include "alloc-util.h"
      12                 :            : #include "bus-error.h"
      13                 :            : #include "bus-util.h"
      14                 :            : #include "cgroup-util.h"
      15                 :            : #include "def.h"
      16                 :            : #include "device-util.h"
      17                 :            : #include "dirent-util.h"
      18                 :            : #include "fd-util.h"
      19                 :            : #include "format-util.h"
      20                 :            : #include "fs-util.h"
      21                 :            : #include "logind-dbus.h"
      22                 :            : #include "logind-seat-dbus.h"
      23                 :            : #include "logind-session-dbus.h"
      24                 :            : #include "logind-user-dbus.h"
      25                 :            : #include "logind.h"
      26                 :            : #include "main-func.h"
      27                 :            : #include "parse-util.h"
      28                 :            : #include "process-util.h"
      29                 :            : #include "selinux-util.h"
      30                 :            : #include "signal-util.h"
      31                 :            : #include "strv.h"
      32                 :            : #include "terminal-util.h"
      33                 :            : #include "udev-util.h"
      34                 :            : 
      35                 :            : static Manager* manager_unref(Manager *m);
      36         [ #  # ]:          0 : DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_unref);
      37                 :            : 
      38                 :          0 : static int manager_new(Manager **ret) {
      39                 :          0 :         _cleanup_(manager_unrefp) Manager *m = NULL;
      40                 :            :         int r;
      41                 :            : 
      42         [ #  # ]:          0 :         assert(ret);
      43                 :            : 
      44                 :          0 :         m = new(Manager, 1);
      45         [ #  # ]:          0 :         if (!m)
      46                 :          0 :                 return -ENOMEM;
      47                 :            : 
      48                 :          0 :         *m = (Manager) {
      49                 :            :                 .console_active_fd = -1,
      50                 :            :                 .reserve_vt_fd = -1,
      51                 :          0 :                 .idle_action_not_before_usec = now(CLOCK_MONOTONIC),
      52                 :            :         };
      53                 :            : 
      54                 :          0 :         m->devices = hashmap_new(&string_hash_ops);
      55                 :          0 :         m->seats = hashmap_new(&string_hash_ops);
      56                 :          0 :         m->sessions = hashmap_new(&string_hash_ops);
      57                 :          0 :         m->sessions_by_leader = hashmap_new(NULL);
      58                 :          0 :         m->users = hashmap_new(NULL);
      59                 :          0 :         m->inhibitors = hashmap_new(&string_hash_ops);
      60                 :          0 :         m->buttons = hashmap_new(&string_hash_ops);
      61                 :            : 
      62                 :          0 :         m->user_units = hashmap_new(&string_hash_ops);
      63                 :          0 :         m->session_units = hashmap_new(&string_hash_ops);
      64                 :            : 
      65   [ #  #  #  #  :          0 :         if (!m->devices || !m->seats || !m->sessions || !m->sessions_by_leader || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units)
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
      66                 :          0 :                 return -ENOMEM;
      67                 :            : 
      68                 :          0 :         r = sd_event_default(&m->event);
      69         [ #  # ]:          0 :         if (r < 0)
      70                 :          0 :                 return r;
      71                 :            : 
      72                 :          0 :         r = sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
      73         [ #  # ]:          0 :         if (r < 0)
      74                 :          0 :                 return r;
      75                 :            : 
      76                 :          0 :         r = sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
      77         [ #  # ]:          0 :         if (r < 0)
      78                 :          0 :                 return r;
      79                 :            : 
      80                 :          0 :         (void) sd_event_set_watchdog(m->event, true);
      81                 :            : 
      82                 :          0 :         manager_reset_config(m);
      83                 :            : 
      84                 :          0 :         *ret = TAKE_PTR(m);
      85                 :          0 :         return 0;
      86                 :            : }
      87                 :            : 
      88                 :          0 : static Manager* manager_unref(Manager *m) {
      89                 :            :         Session *session;
      90                 :            :         User *u;
      91                 :            :         Device *d;
      92                 :            :         Seat *s;
      93                 :            :         Inhibitor *i;
      94                 :            :         Button *b;
      95                 :            : 
      96         [ #  # ]:          0 :         if (!m)
      97                 :          0 :                 return NULL;
      98                 :            : 
      99         [ #  # ]:          0 :         while ((session = hashmap_first(m->sessions)))
     100                 :          0 :                 session_free(session);
     101                 :            : 
     102         [ #  # ]:          0 :         while ((u = hashmap_first(m->users)))
     103                 :          0 :                 user_free(u);
     104                 :            : 
     105         [ #  # ]:          0 :         while ((d = hashmap_first(m->devices)))
     106                 :          0 :                 device_free(d);
     107                 :            : 
     108         [ #  # ]:          0 :         while ((s = hashmap_first(m->seats)))
     109                 :          0 :                 seat_free(s);
     110                 :            : 
     111         [ #  # ]:          0 :         while ((i = hashmap_first(m->inhibitors)))
     112                 :          0 :                 inhibitor_free(i);
     113                 :            : 
     114         [ #  # ]:          0 :         while ((b = hashmap_first(m->buttons)))
     115                 :          0 :                 button_free(b);
     116                 :            : 
     117                 :          0 :         hashmap_free(m->devices);
     118                 :          0 :         hashmap_free(m->seats);
     119                 :          0 :         hashmap_free(m->sessions);
     120                 :          0 :         hashmap_free(m->sessions_by_leader);
     121                 :          0 :         hashmap_free(m->users);
     122                 :          0 :         hashmap_free(m->inhibitors);
     123                 :          0 :         hashmap_free(m->buttons);
     124                 :          0 :         hashmap_free(m->brightness_writers);
     125                 :            : 
     126                 :          0 :         hashmap_free(m->user_units);
     127                 :          0 :         hashmap_free(m->session_units);
     128                 :            : 
     129                 :          0 :         sd_event_source_unref(m->idle_action_event_source);
     130                 :          0 :         sd_event_source_unref(m->inhibit_timeout_source);
     131                 :          0 :         sd_event_source_unref(m->scheduled_shutdown_timeout_source);
     132                 :          0 :         sd_event_source_unref(m->nologin_timeout_source);
     133                 :          0 :         sd_event_source_unref(m->wall_message_timeout_source);
     134                 :            : 
     135                 :          0 :         sd_event_source_unref(m->console_active_event_source);
     136                 :          0 :         sd_event_source_unref(m->lid_switch_ignore_event_source);
     137                 :            : 
     138                 :            : #if ENABLE_UTMP
     139                 :          0 :         sd_event_source_unref(m->utmp_event_source);
     140                 :            : #endif
     141                 :            : 
     142                 :          0 :         safe_close(m->console_active_fd);
     143                 :            : 
     144                 :          0 :         sd_device_monitor_unref(m->device_seat_monitor);
     145                 :          0 :         sd_device_monitor_unref(m->device_monitor);
     146                 :          0 :         sd_device_monitor_unref(m->device_vcsa_monitor);
     147                 :          0 :         sd_device_monitor_unref(m->device_button_monitor);
     148                 :            : 
     149         [ #  # ]:          0 :         if (m->unlink_nologin)
     150                 :          0 :                 (void) unlink_or_warn("/run/nologin");
     151                 :            : 
     152                 :          0 :         bus_verify_polkit_async_registry_free(m->polkit_registry);
     153                 :            : 
     154                 :          0 :         sd_bus_flush_close_unref(m->bus);
     155                 :          0 :         sd_event_unref(m->event);
     156                 :            : 
     157                 :          0 :         safe_close(m->reserve_vt_fd);
     158                 :            : 
     159                 :          0 :         strv_free(m->kill_only_users);
     160                 :          0 :         strv_free(m->kill_exclude_users);
     161                 :            : 
     162                 :          0 :         free(m->scheduled_shutdown_type);
     163                 :          0 :         free(m->scheduled_shutdown_tty);
     164                 :          0 :         free(m->wall_message);
     165                 :          0 :         free(m->action_job);
     166                 :            : 
     167                 :          0 :         return mfree(m);
     168                 :            : }
     169                 :            : 
     170                 :          0 : static int manager_enumerate_devices(Manager *m) {
     171                 :          0 :         _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
     172                 :            :         sd_device *d;
     173                 :            :         int r;
     174                 :            : 
     175         [ #  # ]:          0 :         assert(m);
     176                 :            : 
     177                 :            :         /* Loads devices from udev and creates seats for them as
     178                 :            :          * necessary */
     179                 :            : 
     180                 :          0 :         r = sd_device_enumerator_new(&e);
     181         [ #  # ]:          0 :         if (r < 0)
     182                 :          0 :                 return r;
     183                 :            : 
     184                 :          0 :         r = sd_device_enumerator_add_match_tag(e, "master-of-seat");
     185         [ #  # ]:          0 :         if (r < 0)
     186                 :          0 :                 return r;
     187                 :            : 
     188         [ #  # ]:          0 :         FOREACH_DEVICE(e, d) {
     189                 :            :                 int k;
     190                 :            : 
     191                 :          0 :                 k = manager_process_seat_device(m, d);
     192         [ #  # ]:          0 :                 if (k < 0)
     193                 :          0 :                         r = k;
     194                 :            :         }
     195                 :            : 
     196                 :          0 :         return r;
     197                 :            : }
     198                 :            : 
     199                 :          0 : static int manager_enumerate_buttons(Manager *m) {
     200                 :          0 :         _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
     201                 :            :         sd_device *d;
     202                 :            :         int r;
     203                 :            : 
     204         [ #  # ]:          0 :         assert(m);
     205                 :            : 
     206                 :            :         /* Loads buttons from udev */
     207                 :            : 
     208         [ #  # ]:          0 :         if (manager_all_buttons_ignored(m))
     209                 :          0 :                 return 0;
     210                 :            : 
     211                 :          0 :         r = sd_device_enumerator_new(&e);
     212         [ #  # ]:          0 :         if (r < 0)
     213                 :          0 :                 return r;
     214                 :            : 
     215                 :          0 :         r = sd_device_enumerator_add_match_subsystem(e, "input", true);
     216         [ #  # ]:          0 :         if (r < 0)
     217                 :          0 :                 return r;
     218                 :            : 
     219                 :          0 :         r = sd_device_enumerator_add_match_tag(e, "power-switch");
     220         [ #  # ]:          0 :         if (r < 0)
     221                 :          0 :                 return r;
     222                 :            : 
     223         [ #  # ]:          0 :         FOREACH_DEVICE(e, d) {
     224                 :            :                 int k;
     225                 :            : 
     226                 :          0 :                 k = manager_process_button_device(m, d);
     227         [ #  # ]:          0 :                 if (k < 0)
     228                 :          0 :                         r = k;
     229                 :            :         }
     230                 :            : 
     231                 :          0 :         return r;
     232                 :            : }
     233                 :            : 
     234                 :          0 : static int manager_enumerate_seats(Manager *m) {
     235                 :          0 :         _cleanup_closedir_ DIR *d = NULL;
     236                 :            :         struct dirent *de;
     237                 :          0 :         int r = 0;
     238                 :            : 
     239         [ #  # ]:          0 :         assert(m);
     240                 :            : 
     241                 :            :         /* This loads data about seats stored on disk, but does not
     242                 :            :          * actually create any seats. Removes data of seats that no
     243                 :            :          * longer exist. */
     244                 :            : 
     245                 :          0 :         d = opendir("/run/systemd/seats");
     246         [ #  # ]:          0 :         if (!d) {
     247         [ #  # ]:          0 :                 if (errno == ENOENT)
     248                 :          0 :                         return 0;
     249                 :            : 
     250         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to open /run/systemd/seats: %m");
     251                 :            :         }
     252                 :            : 
     253   [ #  #  #  #  :          0 :         FOREACH_DIRENT(de, d, return -errno) {
                   #  # ]
     254                 :            :                 Seat *s;
     255                 :            :                 int k;
     256                 :            : 
     257         [ #  # ]:          0 :                 if (!dirent_is_file(de))
     258                 :          0 :                         continue;
     259                 :            : 
     260                 :          0 :                 s = hashmap_get(m->seats, de->d_name);
     261         [ #  # ]:          0 :                 if (!s) {
     262         [ #  # ]:          0 :                         if (unlinkat(dirfd(d), de->d_name, 0) < 0)
     263         [ #  # ]:          0 :                                 log_warning("Failed to remove /run/systemd/seats/%s: %m",
     264                 :            :                                             de->d_name);
     265                 :          0 :                         continue;
     266                 :            :                 }
     267                 :            : 
     268                 :          0 :                 k = seat_load(s);
     269         [ #  # ]:          0 :                 if (k < 0)
     270                 :          0 :                         r = k;
     271                 :            :         }
     272                 :            : 
     273                 :          0 :         return r;
     274                 :            : }
     275                 :            : 
     276                 :          0 : static int manager_enumerate_linger_users(Manager *m) {
     277                 :          0 :         _cleanup_closedir_ DIR *d = NULL;
     278                 :            :         struct dirent *de;
     279                 :          0 :         int r = 0;
     280                 :            : 
     281         [ #  # ]:          0 :         assert(m);
     282                 :            : 
     283                 :          0 :         d = opendir("/var/lib/systemd/linger");
     284         [ #  # ]:          0 :         if (!d) {
     285         [ #  # ]:          0 :                 if (errno == ENOENT)
     286                 :          0 :                         return 0;
     287                 :            : 
     288         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to open /var/lib/systemd/linger/: %m");
     289                 :            :         }
     290                 :            : 
     291   [ #  #  #  #  :          0 :         FOREACH_DIRENT(de, d, return -errno) {
                   #  # ]
     292                 :            :                 int k;
     293                 :            : 
     294         [ #  # ]:          0 :                 if (!dirent_is_file(de))
     295                 :          0 :                         continue;
     296                 :            : 
     297                 :          0 :                 k = manager_add_user_by_name(m, de->d_name, NULL);
     298         [ #  # ]:          0 :                 if (k < 0)
     299         [ #  # ]:          0 :                         r = log_warning_errno(k, "Couldn't add lingering user %s, ignoring: %m", de->d_name);
     300                 :            :         }
     301                 :            : 
     302                 :          0 :         return r;
     303                 :            : }
     304                 :            : 
     305                 :          0 : static int manager_enumerate_users(Manager *m) {
     306                 :          0 :         _cleanup_closedir_ DIR *d = NULL;
     307                 :            :         struct dirent *de;
     308                 :            :         int r, k;
     309                 :            : 
     310         [ #  # ]:          0 :         assert(m);
     311                 :            : 
     312                 :            :         /* Add lingering users */
     313                 :          0 :         r = manager_enumerate_linger_users(m);
     314                 :            : 
     315                 :            :         /* Read in user data stored on disk */
     316                 :          0 :         d = opendir("/run/systemd/users");
     317         [ #  # ]:          0 :         if (!d) {
     318         [ #  # ]:          0 :                 if (errno == ENOENT)
     319                 :          0 :                         return 0;
     320                 :            : 
     321         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to open /run/systemd/users: %m");
     322                 :            :         }
     323                 :            : 
     324   [ #  #  #  #  :          0 :         FOREACH_DIRENT(de, d, return -errno) {
                   #  # ]
     325                 :            :                 User *u;
     326                 :            : 
     327         [ #  # ]:          0 :                 if (!dirent_is_file(de))
     328                 :          0 :                         continue;
     329                 :            : 
     330                 :          0 :                 k = manager_add_user_by_name(m, de->d_name, &u);
     331         [ #  # ]:          0 :                 if (k < 0) {
     332         [ #  # ]:          0 :                         r = log_warning_errno(k, "Failed to add user by file name %s, ignoring: %m", de->d_name);
     333                 :          0 :                         continue;
     334                 :            :                 }
     335                 :            : 
     336                 :          0 :                 user_add_to_gc_queue(u);
     337                 :            : 
     338                 :          0 :                 k = user_load(u);
     339         [ #  # ]:          0 :                 if (k < 0)
     340                 :          0 :                         r = k;
     341                 :            :         }
     342                 :            : 
     343                 :          0 :         return r;
     344                 :            : }
     345                 :            : 
     346                 :          0 : static int parse_fdname(const char *fdname, char **session_id, dev_t *dev) {
     347                 :          0 :         _cleanup_strv_free_ char **parts = NULL;
     348                 :          0 :         _cleanup_free_ char *id = NULL;
     349                 :            :         unsigned major, minor;
     350                 :            :         int r;
     351                 :            : 
     352                 :          0 :         parts = strv_split(fdname, "-");
     353         [ #  # ]:          0 :         if (!parts)
     354                 :          0 :                 return -ENOMEM;
     355         [ #  # ]:          0 :         if (strv_length(parts) != 5)
     356                 :          0 :                 return -EINVAL;
     357                 :            : 
     358         [ #  # ]:          0 :         if (!streq(parts[0], "session"))
     359                 :          0 :                 return -EINVAL;
     360                 :            : 
     361                 :          0 :         id = strdup(parts[1]);
     362         [ #  # ]:          0 :         if (!id)
     363                 :          0 :                 return -ENOMEM;
     364                 :            : 
     365         [ #  # ]:          0 :         if (!streq(parts[2], "device"))
     366                 :          0 :                 return -EINVAL;
     367                 :            : 
     368                 :          0 :         r = safe_atou(parts[3], &major);
     369         [ #  # ]:          0 :         if (r < 0)
     370                 :          0 :                 return r;
     371                 :          0 :         r = safe_atou(parts[4], &minor);
     372         [ #  # ]:          0 :         if (r < 0)
     373                 :          0 :                 return r;
     374                 :            : 
     375                 :          0 :         *dev = makedev(major, minor);
     376                 :          0 :         *session_id = TAKE_PTR(id);
     377                 :            : 
     378                 :          0 :         return 0;
     379                 :            : }
     380                 :            : 
     381                 :          0 : static int deliver_fd(Manager *m, const char *fdname, int fd) {
     382                 :          0 :         _cleanup_free_ char *id = NULL;
     383                 :            :         SessionDevice *sd;
     384                 :            :         struct stat st;
     385                 :            :         Session *s;
     386                 :            :         dev_t dev;
     387                 :            :         int r;
     388                 :            : 
     389         [ #  # ]:          0 :         assert(m);
     390         [ #  # ]:          0 :         assert(fd >= 0);
     391                 :            : 
     392                 :          0 :         r = parse_fdname(fdname, &id, &dev);
     393         [ #  # ]:          0 :         if (r < 0)
     394         [ #  # ]:          0 :                 return log_debug_errno(r, "Failed to parse fd name %s: %m", fdname);
     395                 :            : 
     396                 :          0 :         s = hashmap_get(m->sessions, id);
     397         [ #  # ]:          0 :         if (!s)
     398                 :            :                 /* If the session doesn't exist anymore, the associated session device attached to this fd
     399                 :            :                  * doesn't either. Let's simply close this fd. */
     400         [ #  # ]:          0 :                 return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Failed to attach fd for unknown session: %s", id);
     401                 :            : 
     402         [ #  # ]:          0 :         if (fstat(fd, &st) < 0)
     403                 :            :                 /* The device is allowed to go away at a random point, in which case fstat() failing is
     404                 :            :                  * expected. */
     405         [ #  # ]:          0 :                 return log_debug_errno(errno, "Failed to stat device fd for session %s: %m", id);
     406                 :            : 
     407   [ #  #  #  # ]:          0 :         if (!S_ISCHR(st.st_mode) || st.st_rdev != dev)
     408         [ #  # ]:          0 :                 return log_debug_errno(SYNTHETIC_ERRNO(ENODEV), "Device fd doesn't point to the expected character device node");
     409                 :            : 
     410                 :          0 :         sd = hashmap_get(s->devices, &dev);
     411         [ #  # ]:          0 :         if (!sd)
     412                 :            :                 /* Weird, we got an fd for a session device which wasn't recorded in the session state
     413                 :            :                  * file... */
     414         [ #  # ]:          0 :                 return log_warning_errno(SYNTHETIC_ERRNO(ENODEV), "Got fd for missing session device [%u:%u] in session %s",
     415                 :            :                                          major(dev), minor(dev), s->id);
     416                 :            : 
     417         [ #  # ]:          0 :         log_debug("Attaching fd to session device [%u:%u] for session %s",
     418                 :            :                   major(dev), minor(dev), s->id);
     419                 :            : 
     420                 :          0 :         session_device_attach_fd(sd, fd, s->was_active);
     421                 :          0 :         return 0;
     422                 :            : }
     423                 :            : 
     424                 :          0 : static int manager_attach_fds(Manager *m) {
     425                 :          0 :         _cleanup_strv_free_ char **fdnames = NULL;
     426                 :            :         int n;
     427                 :            : 
     428                 :            :         /* Upon restart, PID1 will send us back all fds of session devices that we previously opened. Each
     429                 :            :          * file descriptor is associated with a given session. The session ids are passed through FDNAMES. */
     430                 :            : 
     431                 :          0 :         n = sd_listen_fds_with_names(true, &fdnames);
     432         [ #  # ]:          0 :         if (n < 0)
     433         [ #  # ]:          0 :                 return log_warning_errno(n, "Failed to acquire passed fd list: %m");
     434         [ #  # ]:          0 :         if (n == 0)
     435                 :          0 :                 return 0;
     436                 :            : 
     437         [ #  # ]:          0 :         for (int i = 0; i < n; i++) {
     438                 :          0 :                 int fd = SD_LISTEN_FDS_START + i;
     439                 :            : 
     440         [ #  # ]:          0 :                 if (deliver_fd(m, fdnames[i], fd) >= 0)
     441                 :          0 :                         continue;
     442                 :            : 
     443                 :            :                 /* Hmm, we couldn't deliver the fd to any session device object? If so, let's close the fd */
     444                 :          0 :                 safe_close(fd);
     445                 :            : 
     446                 :            :                 /* Remove from fdstore as well */
     447                 :          0 :                 (void) sd_notifyf(false,
     448                 :            :                                   "FDSTOREREMOVE=1\n"
     449                 :          0 :                                   "FDNAME=%s", fdnames[i]);
     450                 :            :         }
     451                 :            : 
     452                 :          0 :         return 0;
     453                 :            : }
     454                 :            : 
     455                 :          0 : static int manager_enumerate_sessions(Manager *m) {
     456                 :          0 :         _cleanup_closedir_ DIR *d = NULL;
     457                 :            :         struct dirent *de;
     458                 :          0 :         int r = 0, k;
     459                 :            : 
     460         [ #  # ]:          0 :         assert(m);
     461                 :            : 
     462                 :            :         /* Read in session data stored on disk */
     463                 :          0 :         d = opendir("/run/systemd/sessions");
     464         [ #  # ]:          0 :         if (!d) {
     465         [ #  # ]:          0 :                 if (errno == ENOENT)
     466                 :          0 :                         return 0;
     467                 :            : 
     468         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to open /run/systemd/sessions: %m");
     469                 :            :         }
     470                 :            : 
     471   [ #  #  #  #  :          0 :         FOREACH_DIRENT(de, d, return -errno) {
                   #  # ]
     472                 :            :                 struct Session *s;
     473                 :            : 
     474         [ #  # ]:          0 :                 if (!dirent_is_file(de))
     475                 :          0 :                         continue;
     476                 :            : 
     477                 :          0 :                 k = manager_add_session(m, de->d_name, &s);
     478         [ #  # ]:          0 :                 if (k < 0) {
     479         [ #  # ]:          0 :                         r = log_warning_errno(k, "Failed to add session by file name %s, ignoring: %m", de->d_name);
     480                 :          0 :                         continue;
     481                 :            :                 }
     482                 :            : 
     483                 :          0 :                 session_add_to_gc_queue(s);
     484                 :            : 
     485                 :          0 :                 k = session_load(s);
     486         [ #  # ]:          0 :                 if (k < 0)
     487                 :          0 :                         r = k;
     488                 :            :         }
     489                 :            : 
     490                 :            :         /* We might be restarted and PID1 could have sent us back the session device fds we previously
     491                 :            :          * saved. */
     492                 :          0 :         (void) manager_attach_fds(m);
     493                 :            : 
     494                 :          0 :         return r;
     495                 :            : }
     496                 :            : 
     497                 :          0 : static int manager_enumerate_inhibitors(Manager *m) {
     498                 :          0 :         _cleanup_closedir_ DIR *d = NULL;
     499                 :            :         struct dirent *de;
     500                 :          0 :         int r = 0;
     501                 :            : 
     502         [ #  # ]:          0 :         assert(m);
     503                 :            : 
     504                 :          0 :         d = opendir("/run/systemd/inhibit");
     505         [ #  # ]:          0 :         if (!d) {
     506         [ #  # ]:          0 :                 if (errno == ENOENT)
     507                 :          0 :                         return 0;
     508                 :            : 
     509         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to open /run/systemd/inhibit: %m");
     510                 :            :         }
     511                 :            : 
     512   [ #  #  #  #  :          0 :         FOREACH_DIRENT(de, d, return -errno) {
                   #  # ]
     513                 :            :                 int k;
     514                 :            :                 Inhibitor *i;
     515                 :            : 
     516         [ #  # ]:          0 :                 if (!dirent_is_file(de))
     517                 :          0 :                         continue;
     518                 :            : 
     519                 :          0 :                 k = manager_add_inhibitor(m, de->d_name, &i);
     520         [ #  # ]:          0 :                 if (k < 0) {
     521         [ #  # ]:          0 :                         r = log_warning_errno(k, "Couldn't add inhibitor %s, ignoring: %m", de->d_name);
     522                 :          0 :                         continue;
     523                 :            :                 }
     524                 :            : 
     525                 :          0 :                 k = inhibitor_load(i);
     526         [ #  # ]:          0 :                 if (k < 0)
     527                 :          0 :                         r = k;
     528                 :            :         }
     529                 :            : 
     530                 :          0 :         return r;
     531                 :            : }
     532                 :            : 
     533                 :          0 : static int manager_dispatch_seat_udev(sd_device_monitor *monitor, sd_device *device, void *userdata) {
     534                 :          0 :         Manager *m = userdata;
     535                 :            : 
     536         [ #  # ]:          0 :         assert(m);
     537         [ #  # ]:          0 :         assert(device);
     538                 :            : 
     539                 :          0 :         manager_process_seat_device(m, device);
     540                 :          0 :         return 0;
     541                 :            : }
     542                 :            : 
     543                 :          0 : static int manager_dispatch_device_udev(sd_device_monitor *monitor, sd_device *device, void *userdata) {
     544                 :          0 :         Manager *m = userdata;
     545                 :            : 
     546         [ #  # ]:          0 :         assert(m);
     547         [ #  # ]:          0 :         assert(device);
     548                 :            : 
     549                 :          0 :         manager_process_seat_device(m, device);
     550                 :          0 :         return 0;
     551                 :            : }
     552                 :            : 
     553                 :          0 : static int manager_dispatch_vcsa_udev(sd_device_monitor *monitor, sd_device *device, void *userdata) {
     554                 :          0 :         Manager *m = userdata;
     555                 :            :         const char *name;
     556                 :            : 
     557         [ #  # ]:          0 :         assert(m);
     558         [ #  # ]:          0 :         assert(device);
     559                 :            : 
     560                 :            :         /* Whenever a VCSA device is removed try to reallocate our
     561                 :            :          * VTs, to make sure our auto VTs never go away. */
     562                 :            : 
     563   [ #  #  #  # ]:          0 :         if (sd_device_get_sysname(device, &name) >= 0 &&
     564         [ #  # ]:          0 :             startswith(name, "vcsa") &&
     565                 :          0 :             device_for_action(device, DEVICE_ACTION_REMOVE))
     566                 :          0 :                 seat_preallocate_vts(m->seat0);
     567                 :            : 
     568                 :          0 :         return 0;
     569                 :            : }
     570                 :            : 
     571                 :          0 : static int manager_dispatch_button_udev(sd_device_monitor *monitor, sd_device *device, void *userdata) {
     572                 :          0 :         Manager *m = userdata;
     573                 :            : 
     574         [ #  # ]:          0 :         assert(m);
     575         [ #  # ]:          0 :         assert(device);
     576                 :            : 
     577                 :          0 :         manager_process_button_device(m, device);
     578                 :          0 :         return 0;
     579                 :            : }
     580                 :            : 
     581                 :          0 : static int manager_dispatch_console(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
     582                 :          0 :         Manager *m = userdata;
     583                 :            : 
     584         [ #  # ]:          0 :         assert(m);
     585         [ #  # ]:          0 :         assert(m->seat0);
     586         [ #  # ]:          0 :         assert(m->console_active_fd == fd);
     587                 :            : 
     588                 :          0 :         seat_read_active_vt(m->seat0);
     589                 :          0 :         return 0;
     590                 :            : }
     591                 :            : 
     592                 :          0 : static int manager_reserve_vt(Manager *m) {
     593                 :          0 :         _cleanup_free_ char *p = NULL;
     594                 :            : 
     595         [ #  # ]:          0 :         assert(m);
     596                 :            : 
     597         [ #  # ]:          0 :         if (m->reserve_vt <= 0)
     598                 :          0 :                 return 0;
     599                 :            : 
     600         [ #  # ]:          0 :         if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
     601                 :          0 :                 return log_oom();
     602                 :            : 
     603                 :          0 :         m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
     604         [ #  # ]:          0 :         if (m->reserve_vt_fd < 0) {
     605                 :            : 
     606                 :            :                 /* Don't complain on VT-less systems */
     607         [ #  # ]:          0 :                 if (errno != ENOENT)
     608         [ #  # ]:          0 :                         log_warning_errno(errno, "Failed to pin reserved VT: %m");
     609                 :          0 :                 return -errno;
     610                 :            :         }
     611                 :            : 
     612                 :          0 :         return 0;
     613                 :            : }
     614                 :            : 
     615                 :          0 : static int manager_connect_bus(Manager *m) {
     616                 :            :         int r;
     617                 :            : 
     618         [ #  # ]:          0 :         assert(m);
     619         [ #  # ]:          0 :         assert(!m->bus);
     620                 :            : 
     621                 :          0 :         r = sd_bus_default_system(&m->bus);
     622         [ #  # ]:          0 :         if (r < 0)
     623         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to connect to system bus: %m");
     624                 :            : 
     625                 :          0 :         r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
     626         [ #  # ]:          0 :         if (r < 0)
     627         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to add manager object vtable: %m");
     628                 :            : 
     629                 :          0 :         r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
     630         [ #  # ]:          0 :         if (r < 0)
     631         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to add seat object vtable: %m");
     632                 :            : 
     633                 :          0 :         r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
     634         [ #  # ]:          0 :         if (r < 0)
     635         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to add seat enumerator: %m");
     636                 :            : 
     637                 :          0 :         r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
     638         [ #  # ]:          0 :         if (r < 0)
     639         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to add session object vtable: %m");
     640                 :            : 
     641                 :          0 :         r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m);
     642         [ #  # ]:          0 :         if (r < 0)
     643         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to add session enumerator: %m");
     644                 :            : 
     645                 :          0 :         r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
     646         [ #  # ]:          0 :         if (r < 0)
     647         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to add user object vtable: %m");
     648                 :            : 
     649                 :          0 :         r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m);
     650         [ #  # ]:          0 :         if (r < 0)
     651         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to add user enumerator: %m");
     652                 :            : 
     653                 :          0 :         r = sd_bus_match_signal_async(
     654                 :            :                         m->bus,
     655                 :            :                         NULL,
     656                 :            :                         "org.freedesktop.systemd1",
     657                 :            :                         "/org/freedesktop/systemd1",
     658                 :            :                         "org.freedesktop.systemd1.Manager",
     659                 :            :                         "JobRemoved",
     660                 :            :                         match_job_removed, NULL, m);
     661         [ #  # ]:          0 :         if (r < 0)
     662         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to request match for JobRemoved: %m");
     663                 :            : 
     664                 :          0 :         r = sd_bus_match_signal_async(
     665                 :            :                         m->bus,
     666                 :            :                         NULL,
     667                 :            :                         "org.freedesktop.systemd1",
     668                 :            :                         "/org/freedesktop/systemd1",
     669                 :            :                         "org.freedesktop.systemd1.Manager",
     670                 :            :                         "UnitRemoved",
     671                 :            :                         match_unit_removed, NULL, m);
     672         [ #  # ]:          0 :         if (r < 0)
     673         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to request match for UnitRemoved: %m");
     674                 :            : 
     675                 :          0 :         r = sd_bus_match_signal_async(
     676                 :            :                         m->bus,
     677                 :            :                         NULL,
     678                 :            :                         "org.freedesktop.systemd1",
     679                 :            :                         NULL,
     680                 :            :                         "org.freedesktop.DBus.Properties",
     681                 :            :                         "PropertiesChanged",
     682                 :            :                         match_properties_changed, NULL, m);
     683         [ #  # ]:          0 :         if (r < 0)
     684         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to request match for PropertiesChanged: %m");
     685                 :            : 
     686                 :          0 :         r = sd_bus_match_signal_async(
     687                 :            :                         m->bus,
     688                 :            :                         NULL,
     689                 :            :                         "org.freedesktop.systemd1",
     690                 :            :                         "/org/freedesktop/systemd1",
     691                 :            :                         "org.freedesktop.systemd1.Manager",
     692                 :            :                         "Reloading",
     693                 :            :                         match_reloading, NULL, m);
     694         [ #  # ]:          0 :         if (r < 0)
     695         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to request match for Reloading: %m");
     696                 :            : 
     697                 :          0 :         r = sd_bus_call_method_async(
     698                 :            :                         m->bus,
     699                 :            :                         NULL,
     700                 :            :                         "org.freedesktop.systemd1",
     701                 :            :                         "/org/freedesktop/systemd1",
     702                 :            :                         "org.freedesktop.systemd1.Manager",
     703                 :            :                         "Subscribe",
     704                 :            :                         NULL, NULL,
     705                 :            :                         NULL);
     706         [ #  # ]:          0 :         if (r < 0)
     707         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to enable subscription: %m");
     708                 :            : 
     709                 :          0 :         r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.login1", 0, NULL, NULL);
     710         [ #  # ]:          0 :         if (r < 0)
     711         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to request name: %m");
     712                 :            : 
     713                 :          0 :         r = sd_bus_attach_event(m->bus, m->event, SD_EVENT_PRIORITY_NORMAL);
     714         [ #  # ]:          0 :         if (r < 0)
     715         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to attach bus to event loop: %m");
     716                 :            : 
     717                 :          0 :         return 0;
     718                 :            : }
     719                 :            : 
     720                 :          0 : static int manager_vt_switch(sd_event_source *src, const struct signalfd_siginfo *si, void *data) {
     721                 :          0 :         Manager *m = data;
     722                 :            :         Session *active, *iter;
     723                 :            : 
     724                 :            :         /*
     725                 :            :          * We got a VT-switch signal and we have to acknowledge it immediately.
     726                 :            :          * Preferably, we'd just use m->seat0->active->vtfd, but unfortunately,
     727                 :            :          * old user-space might run multiple sessions on a single VT, *sigh*.
     728                 :            :          * Therefore, we have to iterate all sessions and find one with a vtfd
     729                 :            :          * on the requested VT.
     730                 :            :          * As only VTs with active controllers have VT_PROCESS set, our current
     731                 :            :          * notion of the active VT might be wrong (for instance if the switch
     732                 :            :          * happens while we setup VT_PROCESS). Therefore, read the current VT
     733                 :            :          * first and then use s->active->vtnr as reference. Note that this is
     734                 :            :          * not racy, as no further VT-switch can happen as long as we're in
     735                 :            :          * synchronous VT_PROCESS mode.
     736                 :            :          */
     737                 :            : 
     738         [ #  # ]:          0 :         assert(m->seat0);
     739                 :          0 :         seat_read_active_vt(m->seat0);
     740                 :            : 
     741                 :          0 :         active = m->seat0->active;
     742   [ #  #  #  # ]:          0 :         if (!active || active->vtnr < 1) {
     743                 :          0 :                 _cleanup_close_ int fd = -1;
     744                 :            :                 int r;
     745                 :            : 
     746                 :            :                 /* We are requested to acknowledge the VT-switch signal by the kernel but
     747                 :            :                  * there's no registered sessions for the current VT. Normally this
     748                 :            :                  * shouldn't happen but something wrong might have happened when we tried
     749                 :            :                  * to release the VT. Better be safe than sorry, and try to release the VT
     750                 :            :                  * one more time otherwise the user will be locked with the current VT. */
     751                 :            : 
     752         [ #  # ]:          0 :                 log_warning("Received VT_PROCESS signal without a registered session, restoring VT.");
     753                 :            : 
     754                 :            :                 /* At this point we only have the kernel mapping for referring to the
     755                 :            :                  * current VT. */
     756                 :          0 :                 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
     757         [ #  # ]:          0 :                 if (fd < 0) {
     758         [ #  # ]:          0 :                         log_warning_errno(fd, "Failed to open, ignoring: %m");
     759                 :          0 :                         return 0;
     760                 :            :                 }
     761                 :            : 
     762                 :          0 :                 r = vt_release(fd, true);
     763         [ #  # ]:          0 :                 if (r < 0)
     764         [ #  # ]:          0 :                         log_warning_errno(r, "Failed to release VT, ignoring: %m");
     765                 :            : 
     766                 :          0 :                 return 0;
     767                 :            :         }
     768                 :            : 
     769         [ #  # ]:          0 :         if (active->vtfd >= 0) {
     770                 :          0 :                 session_leave_vt(active);
     771                 :            :         } else {
     772         [ #  # ]:          0 :                 LIST_FOREACH(sessions_by_seat, iter, m->seat0->sessions) {
     773   [ #  #  #  # ]:          0 :                         if (iter->vtnr == active->vtnr && iter->vtfd >= 0) {
     774                 :          0 :                                 session_leave_vt(iter);
     775                 :          0 :                                 break;
     776                 :            :                         }
     777                 :            :                 }
     778                 :            :         }
     779                 :            : 
     780                 :          0 :         return 0;
     781                 :            : }
     782                 :            : 
     783                 :          0 : static int manager_connect_console(Manager *m) {
     784                 :            :         int r;
     785                 :            : 
     786         [ #  # ]:          0 :         assert(m);
     787         [ #  # ]:          0 :         assert(m->console_active_fd < 0);
     788                 :            : 
     789                 :            :         /* On certain systems (such as S390, Xen, and containers) /dev/tty0 does not exist (as there is no VC), so
     790                 :            :          * don't fail if we can't open it. */
     791                 :            : 
     792         [ #  # ]:          0 :         if (access("/dev/tty0", F_OK) < 0)
     793                 :          0 :                 return 0;
     794                 :            : 
     795                 :          0 :         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
     796         [ #  # ]:          0 :         if (m->console_active_fd < 0) {
     797                 :            : 
     798                 :            :                 /* On some systems /dev/tty0 may exist even though /sys/class/tty/tty0 does not. These are broken, but
     799                 :            :                  * common. Let's complain but continue anyway. */
     800         [ #  # ]:          0 :                 if (errno == ENOENT) {
     801         [ #  # ]:          0 :                         log_warning_errno(errno, "System has /dev/tty0 but not /sys/class/tty/tty0/active which is broken, ignoring: %m");
     802                 :          0 :                         return 0;
     803                 :            :                 }
     804                 :            : 
     805         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to open /sys/class/tty/tty0/active: %m");
     806                 :            :         }
     807                 :            : 
     808                 :          0 :         r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m);
     809         [ #  # ]:          0 :         if (r < 0)
     810         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to watch foreground console: %m");
     811                 :            : 
     812                 :            :         /*
     813                 :            :          * SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used
     814                 :            :          * as VT-acquire signal. We ignore any acquire-events (yes, we still
     815                 :            :          * have to provide a valid signal-number for it!) and acknowledge all
     816                 :            :          * release events immediately.
     817                 :            :          */
     818                 :            : 
     819         [ #  # ]:          0 :         if (SIGRTMIN + 1 > SIGRTMAX)
     820         [ #  # ]:          0 :                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
     821                 :            :                                        "Not enough real-time signals available: %u-%u",
     822                 :            :                                        SIGRTMIN, SIGRTMAX);
     823                 :            : 
     824         [ #  # ]:          0 :         assert_se(ignore_signals(SIGRTMIN + 1, -1) >= 0);
     825         [ #  # ]:          0 :         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGRTMIN, -1) >= 0);
     826                 :            : 
     827                 :          0 :         r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m);
     828         [ #  # ]:          0 :         if (r < 0)
     829         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to subscribe to signal: %m");
     830                 :            : 
     831                 :          0 :         return 0;
     832                 :            : }
     833                 :            : 
     834                 :          0 : static int manager_connect_udev(Manager *m) {
     835                 :            :         int r;
     836                 :            : 
     837         [ #  # ]:          0 :         assert(m);
     838         [ #  # ]:          0 :         assert(!m->device_seat_monitor);
     839         [ #  # ]:          0 :         assert(!m->device_monitor);
     840         [ #  # ]:          0 :         assert(!m->device_vcsa_monitor);
     841         [ #  # ]:          0 :         assert(!m->device_button_monitor);
     842                 :            : 
     843                 :          0 :         r = sd_device_monitor_new(&m->device_seat_monitor);
     844         [ #  # ]:          0 :         if (r < 0)
     845                 :          0 :                 return r;
     846                 :            : 
     847                 :          0 :         r = sd_device_monitor_filter_add_match_tag(m->device_seat_monitor, "master-of-seat");
     848         [ #  # ]:          0 :         if (r < 0)
     849                 :          0 :                 return r;
     850                 :            : 
     851                 :          0 :         r = sd_device_monitor_attach_event(m->device_seat_monitor, m->event);
     852         [ #  # ]:          0 :         if (r < 0)
     853                 :          0 :                 return r;
     854                 :            : 
     855                 :          0 :         r = sd_device_monitor_start(m->device_seat_monitor, manager_dispatch_seat_udev, m);
     856         [ #  # ]:          0 :         if (r < 0)
     857                 :          0 :                 return r;
     858                 :            : 
     859                 :          0 :         (void) sd_event_source_set_description(sd_device_monitor_get_event_source(m->device_seat_monitor), "logind-seat-monitor");
     860                 :            : 
     861                 :          0 :         r = sd_device_monitor_new(&m->device_monitor);
     862         [ #  # ]:          0 :         if (r < 0)
     863                 :          0 :                 return r;
     864                 :            : 
     865                 :          0 :         r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "input", NULL);
     866         [ #  # ]:          0 :         if (r < 0)
     867                 :          0 :                 return r;
     868                 :            : 
     869                 :          0 :         r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "graphics", NULL);
     870         [ #  # ]:          0 :         if (r < 0)
     871                 :          0 :                 return r;
     872                 :            : 
     873                 :          0 :         r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "drm", NULL);
     874         [ #  # ]:          0 :         if (r < 0)
     875                 :          0 :                 return r;
     876                 :            : 
     877                 :          0 :         r = sd_device_monitor_attach_event(m->device_monitor, m->event);
     878         [ #  # ]:          0 :         if (r < 0)
     879                 :          0 :                 return r;
     880                 :            : 
     881                 :          0 :         r = sd_device_monitor_start(m->device_monitor, manager_dispatch_device_udev, m);
     882         [ #  # ]:          0 :         if (r < 0)
     883                 :          0 :                 return r;
     884                 :            : 
     885                 :          0 :         (void) sd_event_source_set_description(sd_device_monitor_get_event_source(m->device_monitor), "logind-device-monitor");
     886                 :            : 
     887                 :            :         /* Don't watch keys if nobody cares */
     888         [ #  # ]:          0 :         if (!manager_all_buttons_ignored(m)) {
     889                 :          0 :                 r = sd_device_monitor_new(&m->device_button_monitor);
     890         [ #  # ]:          0 :                 if (r < 0)
     891                 :          0 :                         return r;
     892                 :            : 
     893                 :          0 :                 r = sd_device_monitor_filter_add_match_tag(m->device_button_monitor, "power-switch");
     894         [ #  # ]:          0 :                 if (r < 0)
     895                 :          0 :                         return r;
     896                 :            : 
     897                 :          0 :                 r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_button_monitor, "input", NULL);
     898         [ #  # ]:          0 :                 if (r < 0)
     899                 :          0 :                         return r;
     900                 :            : 
     901                 :          0 :                 r = sd_device_monitor_attach_event(m->device_button_monitor, m->event);
     902         [ #  # ]:          0 :                 if (r < 0)
     903                 :          0 :                         return r;
     904                 :            : 
     905                 :          0 :                 r = sd_device_monitor_start(m->device_button_monitor, manager_dispatch_button_udev, m);
     906         [ #  # ]:          0 :                 if (r < 0)
     907                 :          0 :                         return r;
     908                 :            : 
     909                 :          0 :                 (void) sd_event_source_set_description(sd_device_monitor_get_event_source(m->device_button_monitor), "logind-button-monitor");
     910                 :            :         }
     911                 :            : 
     912                 :            :         /* Don't bother watching VCSA devices, if nobody cares */
     913   [ #  #  #  # ]:          0 :         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
     914                 :            : 
     915                 :          0 :                 r = sd_device_monitor_new(&m->device_vcsa_monitor);
     916         [ #  # ]:          0 :                 if (r < 0)
     917                 :          0 :                         return r;
     918                 :            : 
     919                 :          0 :                 r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_vcsa_monitor, "vc", NULL);
     920         [ #  # ]:          0 :                 if (r < 0)
     921                 :          0 :                         return r;
     922                 :            : 
     923                 :          0 :                 r = sd_device_monitor_attach_event(m->device_vcsa_monitor, m->event);
     924         [ #  # ]:          0 :                 if (r < 0)
     925                 :          0 :                         return r;
     926                 :            : 
     927                 :          0 :                 r = sd_device_monitor_start(m->device_vcsa_monitor, manager_dispatch_vcsa_udev, m);
     928         [ #  # ]:          0 :                 if (r < 0)
     929                 :          0 :                         return r;
     930                 :            : 
     931                 :          0 :                 (void) sd_event_source_set_description(sd_device_monitor_get_event_source(m->device_vcsa_monitor), "logind-vcsa-monitor");
     932                 :            :         }
     933                 :            : 
     934                 :          0 :         return 0;
     935                 :            : }
     936                 :            : 
     937                 :          0 : static void manager_gc(Manager *m, bool drop_not_started) {
     938                 :            :         Seat *seat;
     939                 :            :         Session *session;
     940                 :            :         User *user;
     941                 :            : 
     942         [ #  # ]:          0 :         assert(m);
     943                 :            : 
     944         [ #  # ]:          0 :         while ((seat = m->seat_gc_queue)) {
     945   [ #  #  #  #  :          0 :                 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
             #  #  #  # ]
     946                 :          0 :                 seat->in_gc_queue = false;
     947                 :            : 
     948         [ #  # ]:          0 :                 if (seat_may_gc(seat, drop_not_started)) {
     949                 :          0 :                         seat_stop(seat, false);
     950                 :          0 :                         seat_free(seat);
     951                 :            :                 }
     952                 :            :         }
     953                 :            : 
     954         [ #  # ]:          0 :         while ((session = m->session_gc_queue)) {
     955   [ #  #  #  #  :          0 :                 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
             #  #  #  # ]
     956                 :          0 :                 session->in_gc_queue = false;
     957                 :            : 
     958                 :            :                 /* First, if we are not closing yet, initiate stopping */
     959   [ #  #  #  # ]:          0 :                 if (session_may_gc(session, drop_not_started) &&
     960                 :          0 :                     session_get_state(session) != SESSION_CLOSING)
     961                 :          0 :                         (void) session_stop(session, false);
     962                 :            : 
     963                 :            :                 /* Normally, this should make the session referenced
     964                 :            :                  * again, if it doesn't then let's get rid of it
     965                 :            :                  * immediately */
     966         [ #  # ]:          0 :                 if (session_may_gc(session, drop_not_started)) {
     967                 :          0 :                         (void) session_finalize(session);
     968                 :          0 :                         session_free(session);
     969                 :            :                 }
     970                 :            :         }
     971                 :            : 
     972         [ #  # ]:          0 :         while ((user = m->user_gc_queue)) {
     973   [ #  #  #  #  :          0 :                 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
             #  #  #  # ]
     974                 :          0 :                 user->in_gc_queue = false;
     975                 :            : 
     976                 :            :                 /* First step: queue stop jobs */
     977         [ #  # ]:          0 :                 if (user_may_gc(user, drop_not_started))
     978                 :          0 :                         (void) user_stop(user, false);
     979                 :            : 
     980                 :            :                 /* Second step: finalize user */
     981         [ #  # ]:          0 :                 if (user_may_gc(user, drop_not_started)) {
     982                 :          0 :                         (void) user_finalize(user);
     983                 :          0 :                         user_free(user);
     984                 :            :                 }
     985                 :            :         }
     986                 :          0 : }
     987                 :            : 
     988                 :          0 : static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
     989                 :          0 :         Manager *m = userdata;
     990                 :            :         struct dual_timestamp since;
     991                 :            :         usec_t n, elapse;
     992                 :            :         int r;
     993                 :            : 
     994         [ #  # ]:          0 :         assert(m);
     995                 :            : 
     996         [ #  # ]:          0 :         if (m->idle_action == HANDLE_IGNORE ||
     997         [ #  # ]:          0 :             m->idle_action_usec <= 0)
     998                 :          0 :                 return 0;
     999                 :            : 
    1000                 :          0 :         n = now(CLOCK_MONOTONIC);
    1001                 :            : 
    1002                 :          0 :         r = manager_get_idle_hint(m, &since);
    1003         [ #  # ]:          0 :         if (r <= 0)
    1004                 :            :                 /* Not idle. Let's check if after a timeout it might be idle then. */
    1005                 :          0 :                 elapse = n + m->idle_action_usec;
    1006                 :            :         else {
    1007                 :            :                 /* Idle! Let's see if it's time to do something, or if
    1008                 :            :                  * we shall sleep for longer. */
    1009                 :            : 
    1010         [ #  # ]:          0 :                 if (n >= since.monotonic + m->idle_action_usec &&
    1011   [ #  #  #  # ]:          0 :                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
    1012         [ #  # ]:          0 :                         log_info("System idle. Doing %s operation.", handle_action_to_string(m->idle_action));
    1013                 :            : 
    1014                 :          0 :                         manager_handle_action(m, 0, m->idle_action, false, false);
    1015                 :          0 :                         m->idle_action_not_before_usec = n;
    1016                 :            :                 }
    1017                 :            : 
    1018                 :          0 :                 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
    1019                 :            :         }
    1020                 :            : 
    1021         [ #  # ]:          0 :         if (!m->idle_action_event_source) {
    1022                 :            : 
    1023                 :          0 :                 r = sd_event_add_time(
    1024                 :            :                                 m->event,
    1025                 :            :                                 &m->idle_action_event_source,
    1026                 :            :                                 CLOCK_MONOTONIC,
    1027                 :            :                                 elapse, USEC_PER_SEC*30,
    1028                 :            :                                 manager_dispatch_idle_action, m);
    1029         [ #  # ]:          0 :                 if (r < 0)
    1030         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to add idle event source: %m");
    1031                 :            : 
    1032                 :          0 :                 r = sd_event_source_set_priority(m->idle_action_event_source, SD_EVENT_PRIORITY_IDLE+10);
    1033         [ #  # ]:          0 :                 if (r < 0)
    1034         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to set idle event source priority: %m");
    1035                 :            :         } else {
    1036                 :          0 :                 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
    1037         [ #  # ]:          0 :                 if (r < 0)
    1038         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to set idle event timer: %m");
    1039                 :            : 
    1040                 :          0 :                 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
    1041         [ #  # ]:          0 :                 if (r < 0)
    1042         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to enable idle event timer: %m");
    1043                 :            :         }
    1044                 :            : 
    1045                 :          0 :         return 0;
    1046                 :            : }
    1047                 :            : 
    1048                 :          0 : static int manager_dispatch_reload_signal(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
    1049                 :          0 :         Manager *m = userdata;
    1050                 :            :         int r;
    1051                 :            : 
    1052                 :          0 :         manager_reset_config(m);
    1053                 :          0 :         r = manager_parse_config_file(m);
    1054         [ #  # ]:          0 :         if (r < 0)
    1055         [ #  # ]:          0 :                 log_warning_errno(r, "Failed to parse config file, using defaults: %m");
    1056                 :            :         else
    1057         [ #  # ]:          0 :                 log_info("Config file reloaded.");
    1058                 :            : 
    1059                 :          0 :         return 0;
    1060                 :            : }
    1061                 :            : 
    1062                 :          0 : static int manager_startup(Manager *m) {
    1063                 :            :         int r;
    1064                 :            :         Seat *seat;
    1065                 :            :         Session *session;
    1066                 :            :         User *user;
    1067                 :            :         Button *button;
    1068                 :            :         Inhibitor *inhibitor;
    1069                 :            :         Iterator i;
    1070                 :            : 
    1071         [ #  # ]:          0 :         assert(m);
    1072                 :            : 
    1073                 :          0 :         r = sd_event_add_signal(m->event, NULL, SIGHUP, manager_dispatch_reload_signal, m);
    1074         [ #  # ]:          0 :         if (r < 0)
    1075         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to register SIGHUP handler: %m");
    1076                 :            : 
    1077                 :            :         /* Connect to utmp */
    1078                 :          0 :         manager_connect_utmp(m);
    1079                 :            : 
    1080                 :            :         /* Connect to console */
    1081                 :          0 :         r = manager_connect_console(m);
    1082         [ #  # ]:          0 :         if (r < 0)
    1083                 :          0 :                 return r;
    1084                 :            : 
    1085                 :            :         /* Connect to udev */
    1086                 :          0 :         r = manager_connect_udev(m);
    1087         [ #  # ]:          0 :         if (r < 0)
    1088         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to create udev watchers: %m");
    1089                 :            : 
    1090                 :            :         /* Connect to the bus */
    1091                 :          0 :         r = manager_connect_bus(m);
    1092         [ #  # ]:          0 :         if (r < 0)
    1093                 :          0 :                 return r;
    1094                 :            : 
    1095                 :            :         /* Instantiate magic seat 0 */
    1096                 :          0 :         r = manager_add_seat(m, "seat0", &m->seat0);
    1097         [ #  # ]:          0 :         if (r < 0)
    1098         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to add seat0: %m");
    1099                 :            : 
    1100                 :          0 :         r = manager_set_lid_switch_ignore(m, 0 + m->holdoff_timeout_usec);
    1101         [ #  # ]:          0 :         if (r < 0)
    1102         [ #  # ]:          0 :                 log_warning_errno(r, "Failed to set up lid switch ignore event source: %m");
    1103                 :            : 
    1104                 :            :         /* Deserialize state */
    1105                 :          0 :         r = manager_enumerate_devices(m);
    1106         [ #  # ]:          0 :         if (r < 0)
    1107         [ #  # ]:          0 :                 log_warning_errno(r, "Device enumeration failed: %m");
    1108                 :            : 
    1109                 :          0 :         r = manager_enumerate_seats(m);
    1110         [ #  # ]:          0 :         if (r < 0)
    1111         [ #  # ]:          0 :                 log_warning_errno(r, "Seat enumeration failed: %m");
    1112                 :            : 
    1113                 :          0 :         r = manager_enumerate_users(m);
    1114         [ #  # ]:          0 :         if (r < 0)
    1115         [ #  # ]:          0 :                 log_warning_errno(r, "User enumeration failed: %m");
    1116                 :            : 
    1117                 :          0 :         r = manager_enumerate_sessions(m);
    1118         [ #  # ]:          0 :         if (r < 0)
    1119         [ #  # ]:          0 :                 log_warning_errno(r, "Session enumeration failed: %m");
    1120                 :            : 
    1121                 :          0 :         r = manager_enumerate_inhibitors(m);
    1122         [ #  # ]:          0 :         if (r < 0)
    1123         [ #  # ]:          0 :                 log_warning_errno(r, "Inhibitor enumeration failed: %m");
    1124                 :            : 
    1125                 :          0 :         r = manager_enumerate_buttons(m);
    1126         [ #  # ]:          0 :         if (r < 0)
    1127         [ #  # ]:          0 :                 log_warning_errno(r, "Button enumeration failed: %m");
    1128                 :            : 
    1129                 :            :         /* Remove stale objects before we start them */
    1130                 :          0 :         manager_gc(m, false);
    1131                 :            : 
    1132                 :            :         /* Reserve the special reserved VT */
    1133                 :          0 :         manager_reserve_vt(m);
    1134                 :            : 
    1135                 :            :         /* Read in utmp if it exists */
    1136                 :          0 :         manager_read_utmp(m);
    1137                 :            : 
    1138                 :            :         /* And start everything */
    1139         [ #  # ]:          0 :         HASHMAP_FOREACH(seat, m->seats, i)
    1140                 :          0 :                 (void) seat_start(seat);
    1141                 :            : 
    1142         [ #  # ]:          0 :         HASHMAP_FOREACH(user, m->users, i)
    1143                 :          0 :                 (void) user_start(user);
    1144                 :            : 
    1145         [ #  # ]:          0 :         HASHMAP_FOREACH(session, m->sessions, i)
    1146                 :          0 :                 (void) session_start(session, NULL, NULL);
    1147                 :            : 
    1148         [ #  # ]:          0 :         HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
    1149                 :          0 :                 (void) inhibitor_start(inhibitor);
    1150                 :            : 
    1151                 :            :                 /* Let's see if the inhibitor is dead now, then remove it */
    1152         [ #  # ]:          0 :                 if (inhibitor_is_orphan(inhibitor)) {
    1153                 :          0 :                         inhibitor_stop(inhibitor);
    1154                 :          0 :                         inhibitor_free(inhibitor);
    1155                 :            :                 }
    1156                 :            :         }
    1157                 :            : 
    1158         [ #  # ]:          0 :         HASHMAP_FOREACH(button, m->buttons, i)
    1159                 :          0 :                 button_check_switches(button);
    1160                 :            : 
    1161                 :          0 :         manager_dispatch_idle_action(NULL, 0, m);
    1162                 :            : 
    1163                 :          0 :         return 0;
    1164                 :            : }
    1165                 :            : 
    1166                 :          0 : static int manager_run(Manager *m) {
    1167                 :            :         int r;
    1168                 :            : 
    1169         [ #  # ]:          0 :         assert(m);
    1170                 :            : 
    1171                 :            :         for (;;) {
    1172                 :          0 :                 r = sd_event_get_state(m->event);
    1173         [ #  # ]:          0 :                 if (r < 0)
    1174                 :          0 :                         return r;
    1175         [ #  # ]:          0 :                 if (r == SD_EVENT_FINISHED)
    1176                 :          0 :                         return 0;
    1177                 :            : 
    1178                 :          0 :                 manager_gc(m, true);
    1179                 :            : 
    1180                 :          0 :                 r = manager_dispatch_delayed(m, false);
    1181         [ #  # ]:          0 :                 if (r < 0)
    1182                 :          0 :                         return r;
    1183         [ #  # ]:          0 :                 if (r > 0)
    1184                 :          0 :                         continue;
    1185                 :            : 
    1186                 :          0 :                 r = sd_event_run(m->event, (uint64_t) -1);
    1187         [ #  # ]:          0 :                 if (r < 0)
    1188                 :          0 :                         return r;
    1189                 :            :         }
    1190                 :            : }
    1191                 :            : 
    1192                 :          0 : static int run(int argc, char *argv[]) {
    1193                 :          0 :         _cleanup_(manager_unrefp) Manager *m = NULL;
    1194                 :            :         int r;
    1195                 :            : 
    1196                 :          0 :         log_set_facility(LOG_AUTH);
    1197                 :          0 :         log_setup_service();
    1198                 :            : 
    1199                 :          0 :         umask(0022);
    1200                 :            : 
    1201         [ #  # ]:          0 :         if (argc != 1) {
    1202         [ #  # ]:          0 :                 log_error("This program takes no arguments.");
    1203                 :          0 :                 return -EINVAL;
    1204                 :            :         }
    1205                 :            : 
    1206                 :          0 :         r = mac_selinux_init();
    1207         [ #  # ]:          0 :         if (r < 0)
    1208         [ #  # ]:          0 :                 return log_error_errno(r, "Could not initialize labelling: %m");
    1209                 :            : 
    1210                 :            :         /* Always create the directories people can create inotify watches in. Note that some applications might check
    1211                 :            :          * for the existence of /run/systemd/seats/ to determine whether logind is available, so please always make
    1212                 :            :          * sure these directories are created early on and unconditionally. */
    1213                 :          0 :         (void) mkdir_label("/run/systemd/seats", 0755);
    1214                 :          0 :         (void) mkdir_label("/run/systemd/users", 0755);
    1215                 :          0 :         (void) mkdir_label("/run/systemd/sessions", 0755);
    1216                 :            : 
    1217         [ #  # ]:          0 :         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGHUP, SIGTERM, SIGINT, SIGCHLD, -1) >= 0);
    1218                 :            : 
    1219                 :          0 :         r = manager_new(&m);
    1220         [ #  # ]:          0 :         if (r < 0)
    1221         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to allocate manager object: %m");
    1222                 :            : 
    1223                 :          0 :         (void) manager_parse_config_file(m);
    1224                 :            : 
    1225                 :          0 :         r = manager_startup(m);
    1226         [ #  # ]:          0 :         if (r < 0)
    1227         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to fully start up daemon: %m");
    1228                 :            : 
    1229         [ #  # ]:          0 :         log_debug("systemd-logind running as pid "PID_FMT, getpid_cached());
    1230                 :          0 :         (void) sd_notify(false,
    1231                 :            :                          "READY=1\n"
    1232                 :            :                          "STATUS=Processing requests...");
    1233                 :            : 
    1234                 :          0 :         r = manager_run(m);
    1235                 :            : 
    1236         [ #  # ]:          0 :         log_debug("systemd-logind stopped as pid "PID_FMT, getpid_cached());
    1237                 :          0 :         (void) sd_notify(false,
    1238                 :            :                          "STOPPING=1\n"
    1239                 :            :                          "STATUS=Shutting down...");
    1240                 :            : 
    1241                 :          0 :         return r;
    1242                 :            : }
    1243                 :            : 
    1244                 :          0 : DEFINE_MAIN_FUNCTION(run);

Generated by: LCOV version 1.14