LCOV - code coverage report
Current view: top level - core - manager.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 700 2318 30.2 %
Date: 2019-08-23 13:36:53 Functions: 76 146 52.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 341 2123 16.1 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <errno.h>
       4                 :            : #include <fcntl.h>
       5                 :            : #include <linux/kd.h>
       6                 :            : #include <signal.h>
       7                 :            : #include <string.h>
       8                 :            : #include <sys/epoll.h>
       9                 :            : #include <sys/inotify.h>
      10                 :            : #include <sys/ioctl.h>
      11                 :            : #include <sys/reboot.h>
      12                 :            : #include <sys/timerfd.h>
      13                 :            : #include <sys/wait.h>
      14                 :            : #include <unistd.h>
      15                 :            : 
      16                 :            : #if HAVE_AUDIT
      17                 :            : #include <libaudit.h>
      18                 :            : #endif
      19                 :            : 
      20                 :            : #include "sd-daemon.h"
      21                 :            : #include "sd-messages.h"
      22                 :            : #include "sd-path.h"
      23                 :            : 
      24                 :            : #include "all-units.h"
      25                 :            : #include "alloc-util.h"
      26                 :            : #include "audit-fd.h"
      27                 :            : #include "boot-timestamps.h"
      28                 :            : #include "bus-common-errors.h"
      29                 :            : #include "bus-error.h"
      30                 :            : #include "bus-kernel.h"
      31                 :            : #include "bus-util.h"
      32                 :            : #include "clean-ipc.h"
      33                 :            : #include "clock-util.h"
      34                 :            : #include "dbus-job.h"
      35                 :            : #include "dbus-manager.h"
      36                 :            : #include "dbus-unit.h"
      37                 :            : #include "dbus.h"
      38                 :            : #include "dirent-util.h"
      39                 :            : #include "env-util.h"
      40                 :            : #include "escape.h"
      41                 :            : #include "exec-util.h"
      42                 :            : #include "execute.h"
      43                 :            : #include "exit-status.h"
      44                 :            : #include "fd-util.h"
      45                 :            : #include "fileio.h"
      46                 :            : #include "fs-util.h"
      47                 :            : #include "hashmap.h"
      48                 :            : #include "io-util.h"
      49                 :            : #include "install.h"
      50                 :            : #include "label.h"
      51                 :            : #include "locale-setup.h"
      52                 :            : #include "log.h"
      53                 :            : #include "macro.h"
      54                 :            : #include "manager.h"
      55                 :            : #include "memory-util.h"
      56                 :            : #include "missing.h"
      57                 :            : #include "mkdir.h"
      58                 :            : #include "parse-util.h"
      59                 :            : #include "path-lookup.h"
      60                 :            : #include "path-util.h"
      61                 :            : #include "plymouth-util.h"
      62                 :            : #include "process-util.h"
      63                 :            : #include "ratelimit.h"
      64                 :            : #include "rlimit-util.h"
      65                 :            : #include "rm-rf.h"
      66                 :            : #include "serialize.h"
      67                 :            : #include "signal-util.h"
      68                 :            : #include "socket-util.h"
      69                 :            : #include "special.h"
      70                 :            : #include "stat-util.h"
      71                 :            : #include "string-table.h"
      72                 :            : #include "string-util.h"
      73                 :            : #include "strv.h"
      74                 :            : #include "strxcpyx.h"
      75                 :            : #include "syslog-util.h"
      76                 :            : #include "terminal-util.h"
      77                 :            : #include "time-util.h"
      78                 :            : #include "transaction.h"
      79                 :            : #include "umask-util.h"
      80                 :            : #include "unit-name.h"
      81                 :            : #include "user-util.h"
      82                 :            : #include "virt.h"
      83                 :            : #include "watchdog.h"
      84                 :            : 
      85                 :            : #define NOTIFY_RCVBUF_SIZE (8*1024*1024)
      86                 :            : #define CGROUPS_AGENT_RCVBUF_SIZE (8*1024*1024)
      87                 :            : 
      88                 :            : /* Initial delay and the interval for printing status messages about running jobs */
      89                 :            : #define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
      90                 :            : #define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
      91                 :            : #define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
      92                 :            : 
      93                 :            : /* If there are more than 1K bus messages queue across our API and direct buses, then let's not add more on top until
      94                 :            :  * the queue gets more empty. */
      95                 :            : #define MANAGER_BUS_BUSY_THRESHOLD 1024LU
      96                 :            : 
      97                 :            : /* How many units and jobs to process of the bus queue before returning to the event loop. */
      98                 :            : #define MANAGER_BUS_MESSAGE_BUDGET 100U
      99                 :            : 
     100                 :            : static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
     101                 :            : static int manager_dispatch_cgroups_agent_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
     102                 :            : static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
     103                 :            : static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
     104                 :            : static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
     105                 :            : static int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
     106                 :            : static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
     107                 :            : static int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
     108                 :            : static int manager_dispatch_sigchld(sd_event_source *source, void *userdata);
     109                 :            : static int manager_dispatch_timezone_change(sd_event_source *source, const struct inotify_event *event, void *userdata);
     110                 :            : static int manager_run_environment_generators(Manager *m);
     111                 :            : static int manager_run_generators(Manager *m);
     112                 :            : 
     113                 :         24 : static void manager_watch_jobs_in_progress(Manager *m) {
     114                 :            :         usec_t next;
     115                 :            :         int r;
     116                 :            : 
     117         [ -  + ]:         24 :         assert(m);
     118                 :            : 
     119                 :            :         /* We do not want to show the cylon animation if the user
     120                 :            :          * needs to confirm service executions otherwise confirmation
     121                 :            :          * messages will be screwed by the cylon animation. */
     122         [ -  + ]:         24 :         if (!manager_is_confirm_spawn_disabled(m))
     123                 :          0 :                 return;
     124                 :            : 
     125         [ -  + ]:         24 :         if (m->jobs_in_progress_event_source)
     126                 :          0 :                 return;
     127                 :            : 
     128                 :         24 :         next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
     129                 :         24 :         r = sd_event_add_time(
     130                 :            :                         m->event,
     131                 :            :                         &m->jobs_in_progress_event_source,
     132                 :            :                         CLOCK_MONOTONIC,
     133                 :            :                         next, 0,
     134                 :            :                         manager_dispatch_jobs_in_progress, m);
     135         [ -  + ]:         24 :         if (r < 0)
     136                 :          0 :                 return;
     137                 :            : 
     138                 :         24 :         (void) sd_event_source_set_description(m->jobs_in_progress_event_source, "manager-jobs-in-progress");
     139                 :            : }
     140                 :            : 
     141                 :            : #define CYLON_BUFFER_EXTRA (2*STRLEN(ANSI_RED) + STRLEN(ANSI_HIGHLIGHT_RED) + 2*STRLEN(ANSI_NORMAL))
     142                 :            : 
     143                 :          0 : static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) {
     144                 :          0 :         char *p = buffer;
     145                 :            : 
     146         [ #  # ]:          0 :         assert(buflen >= CYLON_BUFFER_EXTRA + width + 1);
     147         [ #  # ]:          0 :         assert(pos <= width+1); /* 0 or width+1 mean that the center light is behind the corner */
     148                 :            : 
     149         [ #  # ]:          0 :         if (pos > 1) {
     150         [ #  # ]:          0 :                 if (pos > 2)
     151                 :          0 :                         p = mempset(p, ' ', pos-2);
     152         [ #  # ]:          0 :                 if (log_get_show_color())
     153                 :          0 :                         p = stpcpy(p, ANSI_RED);
     154                 :          0 :                 *p++ = '*';
     155                 :            :         }
     156                 :            : 
     157   [ #  #  #  # ]:          0 :         if (pos > 0 && pos <= width) {
     158         [ #  # ]:          0 :                 if (log_get_show_color())
     159                 :          0 :                         p = stpcpy(p, ANSI_HIGHLIGHT_RED);
     160                 :          0 :                 *p++ = '*';
     161                 :            :         }
     162                 :            : 
     163         [ #  # ]:          0 :         if (log_get_show_color())
     164                 :          0 :                 p = stpcpy(p, ANSI_NORMAL);
     165                 :            : 
     166         [ #  # ]:          0 :         if (pos < width) {
     167         [ #  # ]:          0 :                 if (log_get_show_color())
     168                 :          0 :                         p = stpcpy(p, ANSI_RED);
     169                 :          0 :                 *p++ = '*';
     170         [ #  # ]:          0 :                 if (pos < width-1)
     171                 :          0 :                         p = mempset(p, ' ', width-1-pos);
     172         [ #  # ]:          0 :                 if (log_get_show_color())
     173                 :          0 :                         strcpy(p, ANSI_NORMAL);
     174                 :            :         }
     175                 :          0 : }
     176                 :            : 
     177                 :         12 : void manager_flip_auto_status(Manager *m, bool enable) {
     178         [ -  + ]:         12 :         assert(m);
     179                 :            : 
     180         [ -  + ]:         12 :         if (enable) {
     181         [ #  # ]:          0 :                 if (m->show_status == SHOW_STATUS_AUTO)
     182                 :          0 :                         manager_set_show_status(m, SHOW_STATUS_TEMPORARY);
     183                 :            :         } else {
     184         [ -  + ]:         12 :                 if (m->show_status == SHOW_STATUS_TEMPORARY)
     185                 :          0 :                         manager_set_show_status(m, SHOW_STATUS_AUTO);
     186                 :            :         }
     187                 :         12 : }
     188                 :            : 
     189                 :          0 : static void manager_print_jobs_in_progress(Manager *m) {
     190                 :          0 :         _cleanup_free_ char *job_of_n = NULL;
     191                 :            :         Iterator i;
     192                 :            :         Job *j;
     193                 :          0 :         unsigned counter = 0, print_nr;
     194                 :            :         char cylon[6 + CYLON_BUFFER_EXTRA + 1];
     195                 :            :         unsigned cylon_pos;
     196                 :          0 :         char time[FORMAT_TIMESPAN_MAX], limit[FORMAT_TIMESPAN_MAX] = "no limit";
     197                 :            :         uint64_t x;
     198                 :            : 
     199         [ #  # ]:          0 :         assert(m);
     200         [ #  # ]:          0 :         assert(m->n_running_jobs > 0);
     201                 :            : 
     202                 :          0 :         manager_flip_auto_status(m, true);
     203                 :            : 
     204                 :          0 :         print_nr = (m->jobs_in_progress_iteration / JOBS_IN_PROGRESS_PERIOD_DIVISOR) % m->n_running_jobs;
     205                 :            : 
     206         [ #  # ]:          0 :         HASHMAP_FOREACH(j, m->jobs, i)
     207   [ #  #  #  # ]:          0 :                 if (j->state == JOB_RUNNING && counter++ == print_nr)
     208                 :          0 :                         break;
     209                 :            : 
     210                 :            :         /* m->n_running_jobs must be consistent with the contents of m->jobs,
     211                 :            :          * so the above loop must have succeeded in finding j. */
     212         [ #  # ]:          0 :         assert(counter == print_nr + 1);
     213         [ #  # ]:          0 :         assert(j);
     214                 :            : 
     215                 :          0 :         cylon_pos = m->jobs_in_progress_iteration % 14;
     216         [ #  # ]:          0 :         if (cylon_pos >= 8)
     217                 :          0 :                 cylon_pos = 14 - cylon_pos;
     218                 :          0 :         draw_cylon(cylon, sizeof(cylon), 6, cylon_pos);
     219                 :            : 
     220                 :          0 :         m->jobs_in_progress_iteration++;
     221                 :            : 
     222         [ #  # ]:          0 :         if (m->n_running_jobs > 1) {
     223         [ #  # ]:          0 :                 if (asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs) < 0)
     224                 :          0 :                         job_of_n = NULL;
     225                 :            :         }
     226                 :            : 
     227                 :          0 :         format_timespan(time, sizeof(time), now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC);
     228         [ #  # ]:          0 :         if (job_get_timeout(j, &x) > 0)
     229                 :          0 :                 format_timespan(limit, sizeof(limit), x - j->begin_usec, 1*USEC_PER_SEC);
     230                 :            : 
     231                 :          0 :         manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
     232                 :            :                               "%sA %s job is running for %s (%s / %s)",
     233                 :            :                               strempty(job_of_n),
     234                 :          0 :                               job_type_to_string(j->type),
     235                 :          0 :                               unit_status_string(j->unit),
     236                 :            :                               time, limit);
     237                 :          0 : }
     238                 :            : 
     239                 :          0 : static int have_ask_password(void) {
     240                 :          0 :         _cleanup_closedir_ DIR *dir;
     241                 :            :         struct dirent *de;
     242                 :            : 
     243                 :          0 :         dir = opendir("/run/systemd/ask-password");
     244         [ #  # ]:          0 :         if (!dir) {
     245         [ #  # ]:          0 :                 if (errno == ENOENT)
     246                 :          0 :                         return false;
     247                 :            :                 else
     248                 :          0 :                         return -errno;
     249                 :            :         }
     250                 :            : 
     251   [ #  #  #  # ]:          0 :         FOREACH_DIRENT_ALL(de, dir, return -errno) {
     252         [ #  # ]:          0 :                 if (startswith(de->d_name, "ask."))
     253                 :          0 :                         return true;
     254                 :            :         }
     255                 :          0 :         return false;
     256                 :            : }
     257                 :            : 
     258                 :          0 : static int manager_dispatch_ask_password_fd(sd_event_source *source,
     259                 :            :                                             int fd, uint32_t revents, void *userdata) {
     260                 :          0 :         Manager *m = userdata;
     261                 :            : 
     262         [ #  # ]:          0 :         assert(m);
     263                 :            : 
     264                 :          0 :         (void) flush_fd(fd);
     265                 :            : 
     266                 :          0 :         m->have_ask_password = have_ask_password();
     267         [ #  # ]:          0 :         if (m->have_ask_password < 0)
     268                 :            :                 /* Log error but continue. Negative have_ask_password
     269                 :            :                  * is treated as unknown status. */
     270         [ #  # ]:          0 :                 log_error_errno(m->have_ask_password, "Failed to list /run/systemd/ask-password: %m");
     271                 :            : 
     272                 :          0 :         return 0;
     273                 :            : }
     274                 :            : 
     275                 :         68 : static void manager_close_ask_password(Manager *m) {
     276         [ -  + ]:         68 :         assert(m);
     277                 :            : 
     278                 :         68 :         m->ask_password_event_source = sd_event_source_unref(m->ask_password_event_source);
     279                 :         68 :         m->ask_password_inotify_fd = safe_close(m->ask_password_inotify_fd);
     280                 :         68 :         m->have_ask_password = -EINVAL;
     281                 :         68 : }
     282                 :            : 
     283                 :          0 : static int manager_check_ask_password(Manager *m) {
     284                 :            :         int r;
     285                 :            : 
     286         [ #  # ]:          0 :         assert(m);
     287                 :            : 
     288         [ #  # ]:          0 :         if (!m->ask_password_event_source) {
     289         [ #  # ]:          0 :                 assert(m->ask_password_inotify_fd < 0);
     290                 :            : 
     291                 :          0 :                 (void) mkdir_p_label("/run/systemd/ask-password", 0755);
     292                 :            : 
     293                 :          0 :                 m->ask_password_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
     294         [ #  # ]:          0 :                 if (m->ask_password_inotify_fd < 0)
     295         [ #  # ]:          0 :                         return log_error_errno(errno, "Failed to create inotify object: %m");
     296                 :            : 
     297         [ #  # ]:          0 :                 if (inotify_add_watch(m->ask_password_inotify_fd, "/run/systemd/ask-password", IN_CREATE|IN_DELETE|IN_MOVE) < 0) {
     298         [ #  # ]:          0 :                         log_error_errno(errno, "Failed to watch \"/run/systemd/ask-password\": %m");
     299                 :          0 :                         manager_close_ask_password(m);
     300                 :          0 :                         return -errno;
     301                 :            :                 }
     302                 :            : 
     303                 :          0 :                 r = sd_event_add_io(m->event, &m->ask_password_event_source,
     304                 :            :                                     m->ask_password_inotify_fd, EPOLLIN,
     305                 :            :                                     manager_dispatch_ask_password_fd, m);
     306         [ #  # ]:          0 :                 if (r < 0) {
     307         [ #  # ]:          0 :                         log_error_errno(errno, "Failed to add event source for /run/systemd/ask-password: %m");
     308                 :          0 :                         manager_close_ask_password(m);
     309                 :          0 :                         return -errno;
     310                 :            :                 }
     311                 :            : 
     312                 :          0 :                 (void) sd_event_source_set_description(m->ask_password_event_source, "manager-ask-password");
     313                 :            : 
     314                 :            :                 /* Queries might have been added meanwhile... */
     315                 :          0 :                 manager_dispatch_ask_password_fd(m->ask_password_event_source,
     316                 :            :                                                  m->ask_password_inotify_fd, EPOLLIN, m);
     317                 :            :         }
     318                 :            : 
     319                 :          0 :         return m->have_ask_password;
     320                 :            : }
     321                 :            : 
     322                 :          0 : static int manager_watch_idle_pipe(Manager *m) {
     323                 :            :         int r;
     324                 :            : 
     325         [ #  # ]:          0 :         assert(m);
     326                 :            : 
     327         [ #  # ]:          0 :         if (m->idle_pipe_event_source)
     328                 :          0 :                 return 0;
     329                 :            : 
     330         [ #  # ]:          0 :         if (m->idle_pipe[2] < 0)
     331                 :          0 :                 return 0;
     332                 :            : 
     333                 :          0 :         r = sd_event_add_io(m->event, &m->idle_pipe_event_source, m->idle_pipe[2], EPOLLIN, manager_dispatch_idle_pipe_fd, m);
     334         [ #  # ]:          0 :         if (r < 0)
     335         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to watch idle pipe: %m");
     336                 :            : 
     337                 :          0 :         (void) sd_event_source_set_description(m->idle_pipe_event_source, "manager-idle-pipe");
     338                 :            : 
     339                 :          0 :         return 0;
     340                 :            : }
     341                 :            : 
     342                 :         68 : static void manager_close_idle_pipe(Manager *m) {
     343         [ -  + ]:         68 :         assert(m);
     344                 :            : 
     345                 :         68 :         m->idle_pipe_event_source = sd_event_source_unref(m->idle_pipe_event_source);
     346                 :            : 
     347                 :         68 :         safe_close_pair(m->idle_pipe);
     348                 :         68 :         safe_close_pair(m->idle_pipe + 2);
     349                 :         68 : }
     350                 :            : 
     351                 :         44 : static int manager_setup_time_change(Manager *m) {
     352                 :            :         int r;
     353                 :            : 
     354         [ -  + ]:         44 :         assert(m);
     355                 :            : 
     356         [ +  - ]:         44 :         if (MANAGER_IS_TEST_RUN(m))
     357                 :         44 :                 return 0;
     358                 :            : 
     359                 :          0 :         m->time_change_event_source = sd_event_source_unref(m->time_change_event_source);
     360                 :          0 :         m->time_change_fd = safe_close(m->time_change_fd);
     361                 :            : 
     362                 :          0 :         m->time_change_fd = time_change_fd();
     363         [ #  # ]:          0 :         if (m->time_change_fd < 0)
     364         [ #  # ]:          0 :                 return log_error_errno(m->time_change_fd, "Failed to create timer change timer fd: %m");
     365                 :            : 
     366                 :          0 :         r = sd_event_add_io(m->event, &m->time_change_event_source, m->time_change_fd, EPOLLIN, manager_dispatch_time_change_fd, m);
     367         [ #  # ]:          0 :         if (r < 0)
     368         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to create time change event source: %m");
     369                 :            : 
     370                 :            :         /* Schedule this slightly earlier than the .timer event sources */
     371                 :          0 :         r = sd_event_source_set_priority(m->time_change_event_source, SD_EVENT_PRIORITY_NORMAL-1);
     372         [ #  # ]:          0 :         if (r < 0)
     373         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to set priority of time change event sources: %m");
     374                 :            : 
     375                 :          0 :         (void) sd_event_source_set_description(m->time_change_event_source, "manager-time-change");
     376                 :            : 
     377         [ #  # ]:          0 :         log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd.");
     378                 :            : 
     379                 :          0 :         return 0;
     380                 :            : }
     381                 :            : 
     382                 :         44 : static int manager_read_timezone_stat(Manager *m) {
     383                 :            :         struct stat st;
     384                 :            :         bool changed;
     385                 :            : 
     386         [ -  + ]:         44 :         assert(m);
     387                 :            : 
     388                 :            :         /* Read the current stat() data of /etc/localtime so that we detect changes */
     389         [ -  + ]:         44 :         if (lstat("/etc/localtime", &st) < 0) {
     390         [ #  # ]:          0 :                 log_debug_errno(errno, "Failed to stat /etc/localtime, ignoring: %m");
     391                 :          0 :                 changed = m->etc_localtime_accessible;
     392                 :          0 :                 m->etc_localtime_accessible = false;
     393                 :            :         } else {
     394                 :            :                 usec_t k;
     395                 :            : 
     396                 :         44 :                 k = timespec_load(&st.st_mtim);
     397   [ -  +  #  # ]:         44 :                 changed = !m->etc_localtime_accessible || k != m->etc_localtime_mtime;
     398                 :            : 
     399                 :         44 :                 m->etc_localtime_mtime = k;
     400                 :         44 :                 m->etc_localtime_accessible = true;
     401                 :            :         }
     402                 :            : 
     403                 :         44 :         return changed;
     404                 :            : }
     405                 :            : 
     406                 :         44 : static int manager_setup_timezone_change(Manager *m) {
     407                 :         44 :         _cleanup_(sd_event_source_unrefp) sd_event_source *new_event = NULL;
     408                 :            :         int r;
     409                 :            : 
     410         [ -  + ]:         44 :         assert(m);
     411                 :            : 
     412         [ +  - ]:         44 :         if (MANAGER_IS_TEST_RUN(m))
     413                 :         44 :                 return 0;
     414                 :            : 
     415                 :            :         /* We watch /etc/localtime for three events: change of the link count (which might mean removal from /etc even
     416                 :            :          * though another link might be kept), renames, and file close operations after writing. Note we don't bother
     417                 :            :          * with IN_DELETE_SELF, as that would just report when the inode is removed entirely, i.e. after the link count
     418                 :            :          * went to zero and all fds to it are closed.
     419                 :            :          *
     420                 :            :          * Note that we never follow symlinks here. This is a simplification, but should cover almost all cases
     421                 :            :          * correctly.
     422                 :            :          *
     423                 :            :          * Note that we create the new event source first here, before releasing the old one. This should optimize
     424                 :            :          * behaviour as this way sd-event can reuse the old watch in case the inode didn't change. */
     425                 :            : 
     426                 :          0 :         r = sd_event_add_inotify(m->event, &new_event, "/etc/localtime",
     427                 :            :                                  IN_ATTRIB|IN_MOVE_SELF|IN_CLOSE_WRITE|IN_DONT_FOLLOW, manager_dispatch_timezone_change, m);
     428         [ #  # ]:          0 :         if (r == -ENOENT) {
     429                 :            :                 /* If the file doesn't exist yet, subscribe to /etc instead, and wait until it is created either by
     430                 :            :                  * O_CREATE or by rename() */
     431                 :            : 
     432         [ #  # ]:          0 :                 log_debug_errno(r, "/etc/localtime doesn't exist yet, watching /etc instead.");
     433                 :          0 :                 r = sd_event_add_inotify(m->event, &new_event, "/etc",
     434                 :            :                                          IN_CREATE|IN_MOVED_TO|IN_ONLYDIR, manager_dispatch_timezone_change, m);
     435                 :            :         }
     436         [ #  # ]:          0 :         if (r < 0)
     437         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to create timezone change event source: %m");
     438                 :            : 
     439                 :            :         /* Schedule this slightly earlier than the .timer event sources */
     440                 :          0 :         r = sd_event_source_set_priority(new_event, SD_EVENT_PRIORITY_NORMAL-1);
     441         [ #  # ]:          0 :         if (r < 0)
     442         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to set priority of timezone change event sources: %m");
     443                 :            : 
     444                 :          0 :         sd_event_source_unref(m->timezone_change_event_source);
     445                 :          0 :         m->timezone_change_event_source = TAKE_PTR(new_event);
     446                 :            : 
     447                 :          0 :         return 0;
     448                 :            : }
     449                 :            : 
     450                 :          0 : static int enable_special_signals(Manager *m) {
     451                 :          0 :         _cleanup_close_ int fd = -1;
     452                 :            : 
     453         [ #  # ]:          0 :         assert(m);
     454                 :            : 
     455         [ #  # ]:          0 :         if (MANAGER_IS_TEST_RUN(m))
     456                 :          0 :                 return 0;
     457                 :            : 
     458                 :            :         /* Enable that we get SIGINT on control-alt-del. In containers
     459                 :            :          * this will fail with EPERM (older) or EINVAL (newer), so
     460                 :            :          * ignore that. */
     461   [ #  #  #  #  :          0 :         if (reboot(RB_DISABLE_CAD) < 0 && !IN_SET(errno, EPERM, EINVAL))
                   #  # ]
     462         [ #  # ]:          0 :                 log_warning_errno(errno, "Failed to enable ctrl-alt-del handling: %m");
     463                 :            : 
     464                 :          0 :         fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
     465         [ #  # ]:          0 :         if (fd < 0) {
     466                 :            :                 /* Support systems without virtual console */
     467         [ #  # ]:          0 :                 if (fd != -ENOENT)
     468         [ #  # ]:          0 :                         log_warning_errno(errno, "Failed to open /dev/tty0: %m");
     469                 :            :         } else {
     470                 :            :                 /* Enable that we get SIGWINCH on kbrequest */
     471         [ #  # ]:          0 :                 if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
     472         [ #  # ]:          0 :                         log_warning_errno(errno, "Failed to enable kbrequest handling: %m");
     473                 :            :         }
     474                 :            : 
     475                 :          0 :         return 0;
     476                 :            : }
     477                 :            : 
     478                 :            : #define RTSIG_IF_AVAILABLE(signum) (signum <= SIGRTMAX ? signum : -1)
     479                 :            : 
     480                 :         44 : static int manager_setup_signals(Manager *m) {
     481                 :         44 :         struct sigaction sa = {
     482                 :            :                 .sa_handler = SIG_DFL,
     483                 :            :                 .sa_flags = SA_NOCLDSTOP|SA_RESTART,
     484                 :            :         };
     485                 :            :         sigset_t mask;
     486                 :            :         int r;
     487                 :            : 
     488         [ -  + ]:         44 :         assert(m);
     489                 :            : 
     490         [ -  + ]:         44 :         assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
     491                 :            : 
     492                 :            :         /* We make liberal use of realtime signals here. On
     493                 :            :          * Linux/glibc we have 30 of them (with the exception of Linux
     494                 :            :          * on hppa, see below), between SIGRTMIN+0 ... SIGRTMIN+30
     495                 :            :          * (aka SIGRTMAX). */
     496                 :            : 
     497         [ -  + ]:         44 :         assert_se(sigemptyset(&mask) == 0);
     498   [ +  -  +  -  :        396 :         sigset_add_many(&mask,
             +  -  +  - ]
     499                 :            :                         SIGCHLD,     /* Child died */
     500                 :            :                         SIGTERM,     /* Reexecute daemon */
     501                 :            :                         SIGHUP,      /* Reload configuration */
     502                 :            :                         SIGUSR1,     /* systemd/upstart: reconnect to D-Bus */
     503                 :            :                         SIGUSR2,     /* systemd: dump status */
     504                 :            :                         SIGINT,      /* Kernel sends us this on control-alt-del */
     505                 :            :                         SIGWINCH,    /* Kernel sends us this on kbrequest (alt-arrowup) */
     506                 :            :                         SIGPWR,      /* Some kernel drivers and upsd send us this on power failure */
     507                 :            : 
     508                 :            :                         SIGRTMIN+0,  /* systemd: start default.target */
     509                 :         44 :                         SIGRTMIN+1,  /* systemd: isolate rescue.target */
     510                 :         44 :                         SIGRTMIN+2,  /* systemd: isolate emergency.target */
     511                 :         44 :                         SIGRTMIN+3,  /* systemd: start halt.target */
     512                 :         44 :                         SIGRTMIN+4,  /* systemd: start poweroff.target */
     513                 :         44 :                         SIGRTMIN+5,  /* systemd: start reboot.target */
     514                 :         44 :                         SIGRTMIN+6,  /* systemd: start kexec.target */
     515                 :            : 
     516                 :            :                         /* ... space for more special targets ... */
     517                 :            : 
     518                 :         44 :                         SIGRTMIN+13, /* systemd: Immediate halt */
     519                 :         44 :                         SIGRTMIN+14, /* systemd: Immediate poweroff */
     520                 :         44 :                         SIGRTMIN+15, /* systemd: Immediate reboot */
     521                 :         44 :                         SIGRTMIN+16, /* systemd: Immediate kexec */
     522                 :            : 
     523                 :            :                         /* ... space for more immediate system state changes ... */
     524                 :            : 
     525                 :         44 :                         SIGRTMIN+20, /* systemd: enable status messages */
     526                 :         44 :                         SIGRTMIN+21, /* systemd: disable status messages */
     527                 :         44 :                         SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
     528                 :         44 :                         SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
     529                 :         44 :                         SIGRTMIN+24, /* systemd: Immediate exit (--user only) */
     530                 :            : 
     531                 :            :                         /* .. one free signal here ... */
     532                 :            : 
     533                 :            :                         /* Apparently Linux on hppa had fewer RT signals until v3.18,
     534                 :            :                          * SIGRTMAX was SIGRTMIN+25, and then SIGRTMIN was lowered,
     535                 :            :                          * see commit v3.17-7614-g1f25df2eff.
     536                 :            :                          *
     537                 :            :                          * We cannot unconditionally make use of those signals here,
     538                 :            :                          * so let's use a runtime check. Since these commands are
     539                 :            :                          * accessible by different means and only really a safety
     540                 :            :                          * net, the missing functionality on hppa shouldn't matter.
     541                 :            :                          */
     542                 :            : 
     543                 :         88 :                         RTSIG_IF_AVAILABLE(SIGRTMIN+26), /* systemd: set log target to journal-or-kmsg */
     544                 :         88 :                         RTSIG_IF_AVAILABLE(SIGRTMIN+27), /* systemd: set log target to console */
     545                 :         88 :                         RTSIG_IF_AVAILABLE(SIGRTMIN+28), /* systemd: set log target to kmsg */
     546                 :         88 :                         RTSIG_IF_AVAILABLE(SIGRTMIN+29), /* systemd: set log target to syslog-or-kmsg (obsolete) */
     547                 :            : 
     548                 :            :                         /* ... one free signal here SIGRTMIN+30 ... */
     549                 :            :                         -1);
     550         [ -  + ]:         44 :         assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
     551                 :            : 
     552                 :         44 :         m->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
     553         [ -  + ]:         44 :         if (m->signal_fd < 0)
     554                 :          0 :                 return -errno;
     555                 :            : 
     556                 :         44 :         r = sd_event_add_io(m->event, &m->signal_event_source, m->signal_fd, EPOLLIN, manager_dispatch_signal_fd, m);
     557         [ -  + ]:         44 :         if (r < 0)
     558                 :          0 :                 return r;
     559                 :            : 
     560                 :         44 :         (void) sd_event_source_set_description(m->signal_event_source, "manager-signal");
     561                 :            : 
     562                 :            :         /* Process signals a bit earlier than the rest of things, but later than notify_fd processing, so that the
     563                 :            :          * notify processing can still figure out to which process/service a message belongs, before we reap the
     564                 :            :          * process. Also, process this before handling cgroup notifications, so that we always collect child exit
     565                 :            :          * status information before detecting that there's no process in a cgroup. */
     566                 :         44 :         r = sd_event_source_set_priority(m->signal_event_source, SD_EVENT_PRIORITY_NORMAL-6);
     567         [ -  + ]:         44 :         if (r < 0)
     568                 :          0 :                 return r;
     569                 :            : 
     570         [ -  + ]:         44 :         if (MANAGER_IS_SYSTEM(m))
     571                 :          0 :                 return enable_special_signals(m);
     572                 :            : 
     573                 :         44 :         return 0;
     574                 :            : }
     575                 :            : 
     576                 :         56 : static char** sanitize_environment(char **l) {
     577                 :            : 
     578                 :            :         /* Let's remove some environment variables that we need ourselves to communicate with our clients */
     579                 :         56 :         strv_env_unset_many(
     580                 :            :                         l,
     581                 :            :                         "EXIT_CODE",
     582                 :            :                         "EXIT_STATUS",
     583                 :            :                         "INVOCATION_ID",
     584                 :            :                         "JOURNAL_STREAM",
     585                 :            :                         "LISTEN_FDNAMES",
     586                 :            :                         "LISTEN_FDS",
     587                 :            :                         "LISTEN_PID",
     588                 :            :                         "MAINPID",
     589                 :            :                         "MANAGERPID",
     590                 :            :                         "NOTIFY_SOCKET",
     591                 :            :                         "PIDFILE",
     592                 :            :                         "REMOTE_ADDR",
     593                 :            :                         "REMOTE_PORT",
     594                 :            :                         "SERVICE_RESULT",
     595                 :            :                         "WATCHDOG_PID",
     596                 :            :                         "WATCHDOG_USEC",
     597                 :            :                         NULL);
     598                 :            : 
     599                 :            :         /* Let's order the environment alphabetically, just to make it pretty */
     600                 :         56 :         strv_sort(l);
     601                 :            : 
     602                 :         56 :         return l;
     603                 :            : }
     604                 :            : 
     605                 :         56 : int manager_default_environment(Manager *m) {
     606         [ -  + ]:         56 :         assert(m);
     607                 :            : 
     608                 :         56 :         m->transient_environment = strv_free(m->transient_environment);
     609                 :            : 
     610         [ -  + ]:         56 :         if (MANAGER_IS_SYSTEM(m)) {
     611                 :            :                 /* The system manager always starts with a clean
     612                 :            :                  * environment for its children. It does not import
     613                 :            :                  * the kernel's or the parents' exported variables.
     614                 :            :                  *
     615                 :            :                  * The initial passed environment is untouched to keep
     616                 :            :                  * /proc/self/environ valid; it is used for tagging
     617                 :            :                  * the init process inside containers. */
     618                 :          0 :                 m->transient_environment = strv_new("PATH=" DEFAULT_PATH);
     619                 :            : 
     620                 :            :                 /* Import locale variables LC_*= from configuration */
     621                 :          0 :                 (void) locale_setup(&m->transient_environment);
     622                 :            :         } else
     623                 :            :                 /* The user manager passes its own environment
     624                 :            :                  * along to its children. */
     625                 :         56 :                 m->transient_environment = strv_copy(environ);
     626                 :            : 
     627         [ -  + ]:         56 :         if (!m->transient_environment)
     628                 :          0 :                 return log_oom();
     629                 :            : 
     630                 :         56 :         sanitize_environment(m->transient_environment);
     631                 :            : 
     632                 :         56 :         return 0;
     633                 :            : }
     634                 :            : 
     635                 :         56 : static int manager_setup_prefix(Manager *m) {
     636                 :            :         struct table_entry {
     637                 :            :                 uint64_t type;
     638                 :            :                 const char *suffix;
     639                 :            :         };
     640                 :            : 
     641                 :            :         static const struct table_entry paths_system[_EXEC_DIRECTORY_TYPE_MAX] = {
     642                 :            :                 [EXEC_DIRECTORY_RUNTIME] = { SD_PATH_SYSTEM_RUNTIME, NULL },
     643                 :            :                 [EXEC_DIRECTORY_STATE] = { SD_PATH_SYSTEM_STATE_PRIVATE, NULL },
     644                 :            :                 [EXEC_DIRECTORY_CACHE] = { SD_PATH_SYSTEM_STATE_CACHE, NULL },
     645                 :            :                 [EXEC_DIRECTORY_LOGS] = { SD_PATH_SYSTEM_STATE_LOGS, NULL },
     646                 :            :                 [EXEC_DIRECTORY_CONFIGURATION] = { SD_PATH_SYSTEM_CONFIGURATION, NULL },
     647                 :            :         };
     648                 :            : 
     649                 :            :         static const struct table_entry paths_user[_EXEC_DIRECTORY_TYPE_MAX] = {
     650                 :            :                 [EXEC_DIRECTORY_RUNTIME] = { SD_PATH_USER_RUNTIME, NULL },
     651                 :            :                 [EXEC_DIRECTORY_STATE] = { SD_PATH_USER_CONFIGURATION, NULL },
     652                 :            :                 [EXEC_DIRECTORY_CACHE] = { SD_PATH_USER_STATE_CACHE, NULL },
     653                 :            :                 [EXEC_DIRECTORY_LOGS] = { SD_PATH_USER_CONFIGURATION, "log" },
     654                 :            :                 [EXEC_DIRECTORY_CONFIGURATION] = { SD_PATH_USER_CONFIGURATION, NULL },
     655                 :            :         };
     656                 :            : 
     657                 :            :         const struct table_entry *p;
     658                 :            :         ExecDirectoryType i;
     659                 :            :         int r;
     660                 :            : 
     661         [ -  + ]:         56 :         assert(m);
     662                 :            : 
     663         [ -  + ]:         56 :         if (MANAGER_IS_SYSTEM(m))
     664                 :          0 :                 p = paths_system;
     665                 :            :         else
     666                 :         56 :                 p = paths_user;
     667                 :            : 
     668         [ +  + ]:        336 :         for (i = 0; i < _EXEC_DIRECTORY_TYPE_MAX; i++) {
     669                 :        280 :                 r = sd_path_home(p[i].type, p[i].suffix, &m->prefix[i]);
     670         [ -  + ]:        280 :                 if (r < 0)
     671                 :          0 :                         return r;
     672                 :            :         }
     673                 :            : 
     674                 :         56 :         return 0;
     675                 :            : }
     676                 :            : 
     677                 :         56 : static void manager_free_unit_name_maps(Manager *m) {
     678                 :         56 :         m->unit_id_map = hashmap_free(m->unit_id_map);
     679                 :         56 :         m->unit_name_map = hashmap_free(m->unit_name_map);
     680                 :         56 :         m->unit_path_cache = set_free_free(m->unit_path_cache);
     681                 :         56 :         m->unit_cache_mtime =  0;
     682                 :         56 : }
     683                 :            : 
     684                 :         56 : static int manager_setup_run_queue(Manager *m) {
     685                 :            :         int r;
     686                 :            : 
     687         [ -  + ]:         56 :         assert(m);
     688         [ -  + ]:         56 :         assert(!m->run_queue_event_source);
     689                 :            : 
     690                 :         56 :         r = sd_event_add_defer(m->event, &m->run_queue_event_source, manager_dispatch_run_queue, m);
     691         [ -  + ]:         56 :         if (r < 0)
     692                 :          0 :                 return r;
     693                 :            : 
     694                 :         56 :         r = sd_event_source_set_priority(m->run_queue_event_source, SD_EVENT_PRIORITY_IDLE);
     695         [ -  + ]:         56 :         if (r < 0)
     696                 :          0 :                 return r;
     697                 :            : 
     698                 :         56 :         r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_OFF);
     699         [ -  + ]:         56 :         if (r < 0)
     700                 :          0 :                 return r;
     701                 :            : 
     702                 :         56 :         (void) sd_event_source_set_description(m->run_queue_event_source, "manager-run-queue");
     703                 :            : 
     704                 :         56 :         return 0;
     705                 :            : }
     706                 :            : 
     707                 :         44 : static int manager_setup_sigchld_event_source(Manager *m) {
     708                 :            :         int r;
     709                 :            : 
     710         [ -  + ]:         44 :         assert(m);
     711         [ -  + ]:         44 :         assert(!m->sigchld_event_source);
     712                 :            : 
     713                 :         44 :         r = sd_event_add_defer(m->event, &m->sigchld_event_source, manager_dispatch_sigchld, m);
     714         [ -  + ]:         44 :         if (r < 0)
     715                 :          0 :                 return r;
     716                 :            : 
     717                 :         44 :         r = sd_event_source_set_priority(m->sigchld_event_source, SD_EVENT_PRIORITY_NORMAL-7);
     718         [ -  + ]:         44 :         if (r < 0)
     719                 :          0 :                 return r;
     720                 :            : 
     721                 :         44 :         r = sd_event_source_set_enabled(m->sigchld_event_source, SD_EVENT_OFF);
     722         [ -  + ]:         44 :         if (r < 0)
     723                 :          0 :                 return r;
     724                 :            : 
     725                 :         44 :         (void) sd_event_source_set_description(m->sigchld_event_source, "manager-sigchld");
     726                 :            : 
     727                 :         44 :         return 0;
     728                 :            : }
     729                 :            : 
     730                 :         56 : int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager **_m) {
     731                 :         56 :         _cleanup_(manager_freep) Manager *m = NULL;
     732                 :            :         int r;
     733                 :            : 
     734         [ -  + ]:         56 :         assert(_m);
     735   [ +  -  -  + ]:         56 :         assert(IN_SET(scope, UNIT_FILE_SYSTEM, UNIT_FILE_USER));
     736                 :            : 
     737                 :         56 :         m = new(Manager, 1);
     738         [ -  + ]:         56 :         if (!m)
     739                 :          0 :                 return -ENOMEM;
     740                 :            : 
     741                 :         56 :         *m = (Manager) {
     742                 :            :                 .unit_file_scope = scope,
     743                 :            :                 .objective = _MANAGER_OBJECTIVE_INVALID,
     744                 :            : 
     745                 :            :                 .status_unit_format = STATUS_UNIT_FORMAT_DEFAULT,
     746                 :            : 
     747                 :            :                 .default_timer_accuracy_usec = USEC_PER_MINUTE,
     748                 :            :                 .default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT,
     749                 :            :                 .default_tasks_accounting = true,
     750                 :            :                 .default_tasks_max = UINT64_MAX,
     751                 :            :                 .default_timeout_start_usec = DEFAULT_TIMEOUT_USEC,
     752                 :            :                 .default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC,
     753                 :            :                 .default_restart_usec = DEFAULT_RESTART_USEC,
     754                 :            : 
     755                 :            :                 .original_log_level = -1,
     756                 :            :                 .original_log_target = _LOG_TARGET_INVALID,
     757                 :            : 
     758                 :            :                 .notify_fd = -1,
     759                 :            :                 .cgroups_agent_fd = -1,
     760                 :            :                 .signal_fd = -1,
     761                 :            :                 .time_change_fd = -1,
     762                 :            :                 .user_lookup_fds = { -1, -1 },
     763                 :            :                 .private_listen_fd = -1,
     764                 :            :                 .dev_autofs_fd = -1,
     765                 :            :                 .cgroup_inotify_fd = -1,
     766                 :            :                 .pin_cgroupfs_fd = -1,
     767                 :            :                 .ask_password_inotify_fd = -1,
     768                 :            :                 .idle_pipe = { -1, -1, -1, -1},
     769                 :            : 
     770                 :            :                  /* start as id #1, so that we can leave #0 around as "null-like" value */
     771                 :            :                 .current_job_id = 1,
     772                 :            : 
     773                 :            :                 .have_ask_password = -EINVAL, /* we don't know */
     774                 :            :                 .first_boot = -1,
     775                 :            :                 .test_run_flags = test_run_flags,
     776                 :            : 
     777                 :            :                 .default_oom_policy = OOM_STOP,
     778                 :            :         };
     779                 :            : 
     780                 :            : #if ENABLE_EFI
     781   [ -  +  #  # ]:         56 :         if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0)
     782                 :          0 :                 boot_timestamps(m->timestamps + MANAGER_TIMESTAMP_USERSPACE,
     783                 :          0 :                                 m->timestamps + MANAGER_TIMESTAMP_FIRMWARE,
     784                 :          0 :                                 m->timestamps + MANAGER_TIMESTAMP_LOADER);
     785                 :            : #endif
     786                 :            : 
     787                 :            :         /* Prepare log fields we can use for structured logging */
     788         [ -  + ]:         56 :         if (MANAGER_IS_SYSTEM(m)) {
     789                 :          0 :                 m->unit_log_field = "UNIT=";
     790                 :          0 :                 m->unit_log_format_string = "UNIT=%s";
     791                 :            : 
     792                 :          0 :                 m->invocation_log_field = "INVOCATION_ID=";
     793                 :          0 :                 m->invocation_log_format_string = "INVOCATION_ID=%s";
     794                 :            :         } else {
     795                 :         56 :                 m->unit_log_field = "USER_UNIT=";
     796                 :         56 :                 m->unit_log_format_string = "USER_UNIT=%s";
     797                 :            : 
     798                 :         56 :                 m->invocation_log_field = "USER_INVOCATION_ID=";
     799                 :         56 :                 m->invocation_log_format_string = "USER_INVOCATION_ID=%s";
     800                 :            :         }
     801                 :            : 
     802                 :            :         /* Reboot immediately if the user hits C-A-D more often than 7x per 2s */
     803                 :         56 :         RATELIMIT_INIT(m->ctrl_alt_del_ratelimit, 2 * USEC_PER_SEC, 7);
     804                 :            : 
     805                 :         56 :         r = manager_default_environment(m);
     806         [ -  + ]:         56 :         if (r < 0)
     807                 :          0 :                 return r;
     808                 :            : 
     809                 :         56 :         r = hashmap_ensure_allocated(&m->units, &string_hash_ops);
     810         [ -  + ]:         56 :         if (r < 0)
     811                 :          0 :                 return r;
     812                 :            : 
     813                 :         56 :         r = hashmap_ensure_allocated(&m->jobs, NULL);
     814         [ -  + ]:         56 :         if (r < 0)
     815                 :          0 :                 return r;
     816                 :            : 
     817                 :         56 :         r = hashmap_ensure_allocated(&m->cgroup_unit, &path_hash_ops);
     818         [ -  + ]:         56 :         if (r < 0)
     819                 :          0 :                 return r;
     820                 :            : 
     821                 :         56 :         r = hashmap_ensure_allocated(&m->watch_bus, &string_hash_ops);
     822         [ -  + ]:         56 :         if (r < 0)
     823                 :          0 :                 return r;
     824                 :            : 
     825                 :         56 :         r = prioq_ensure_allocated(&m->run_queue, compare_job_priority);
     826         [ -  + ]:         56 :         if (r < 0)
     827                 :          0 :                 return r;
     828                 :            : 
     829                 :         56 :         r = manager_setup_prefix(m);
     830         [ -  + ]:         56 :         if (r < 0)
     831                 :          0 :                 return r;
     832                 :            : 
     833                 :         56 :         r = sd_event_default(&m->event);
     834         [ -  + ]:         56 :         if (r < 0)
     835                 :          0 :                 return r;
     836                 :            : 
     837                 :         56 :         r = manager_setup_run_queue(m);
     838         [ -  + ]:         56 :         if (r < 0)
     839                 :          0 :                 return r;
     840                 :            : 
     841         [ +  + ]:         56 :         if (test_run_flags == MANAGER_TEST_RUN_MINIMAL) {
     842                 :         12 :                 m->cgroup_root = strdup("");
     843         [ -  + ]:         12 :                 if (!m->cgroup_root)
     844                 :          0 :                         return -ENOMEM;
     845                 :            :         } else {
     846                 :         44 :                 r = manager_setup_signals(m);
     847         [ -  + ]:         44 :                 if (r < 0)
     848                 :          0 :                         return r;
     849                 :            : 
     850                 :         44 :                 r = manager_setup_cgroup(m);
     851         [ -  + ]:         44 :                 if (r < 0)
     852                 :          0 :                         return r;
     853                 :            : 
     854                 :         44 :                 r = manager_setup_time_change(m);
     855         [ -  + ]:         44 :                 if (r < 0)
     856                 :          0 :                         return r;
     857                 :            : 
     858                 :         44 :                 r = manager_read_timezone_stat(m);
     859         [ -  + ]:         44 :                 if (r < 0)
     860                 :          0 :                         return r;
     861                 :            : 
     862                 :         44 :                 (void) manager_setup_timezone_change(m);
     863                 :            : 
     864                 :         44 :                 r = manager_setup_sigchld_event_source(m);
     865         [ -  + ]:         44 :                 if (r < 0)
     866                 :          0 :                         return r;
     867                 :            :         }
     868                 :            : 
     869   [ -  +  #  # ]:         56 :         if (MANAGER_IS_SYSTEM(m) && test_run_flags == 0) {
     870                 :          0 :                 r = mkdir_label("/run/systemd/units", 0755);
     871   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -EEXIST)
     872                 :          0 :                         return r;
     873                 :            :         }
     874                 :            : 
     875                 :        112 :         m->taint_usr =
     876   [ +  -  -  + ]:        112 :                 !in_initrd() &&
     877                 :         56 :                 dir_is_empty("/usr") > 0;
     878                 :            : 
     879                 :            :         /* Note that we do not set up the notify fd here. We do that after deserialization,
     880                 :            :          * since they might have gotten serialized across the reexec. */
     881                 :            : 
     882                 :         56 :         *_m = TAKE_PTR(m);
     883                 :            : 
     884                 :         56 :         return 0;
     885                 :            : }
     886                 :            : 
     887                 :         52 : static int manager_setup_notify(Manager *m) {
     888                 :            :         int r;
     889                 :            : 
     890         [ +  - ]:         52 :         if (MANAGER_IS_TEST_RUN(m))
     891                 :         52 :                 return 0;
     892                 :            : 
     893         [ #  # ]:          0 :         if (m->notify_fd < 0) {
     894         [ #  # ]:          0 :                 _cleanup_close_ int fd = -1;
     895                 :          0 :                 union sockaddr_union sa = {};
     896                 :            :                 int salen;
     897                 :            : 
     898                 :            :                 /* First free all secondary fields */
     899                 :          0 :                 m->notify_socket = mfree(m->notify_socket);
     900                 :          0 :                 m->notify_event_source = sd_event_source_unref(m->notify_event_source);
     901                 :            : 
     902                 :          0 :                 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
     903         [ #  # ]:          0 :                 if (fd < 0)
     904         [ #  # ]:          0 :                         return log_error_errno(errno, "Failed to allocate notification socket: %m");
     905                 :            : 
     906                 :          0 :                 fd_inc_rcvbuf(fd, NOTIFY_RCVBUF_SIZE);
     907                 :            : 
     908                 :          0 :                 m->notify_socket = path_join(m->prefix[EXEC_DIRECTORY_RUNTIME], "systemd/notify");
     909         [ #  # ]:          0 :                 if (!m->notify_socket)
     910                 :          0 :                         return log_oom();
     911                 :            : 
     912                 :          0 :                 salen = sockaddr_un_set_path(&sa.un, m->notify_socket);
     913         [ #  # ]:          0 :                 if (salen < 0)
     914         [ #  # ]:          0 :                         return log_error_errno(salen, "Notify socket '%s' not valid for AF_UNIX socket address, refusing.", m->notify_socket);
     915                 :            : 
     916                 :          0 :                 (void) mkdir_parents_label(m->notify_socket, 0755);
     917                 :          0 :                 (void) sockaddr_un_unlink(&sa.un);
     918                 :            : 
     919                 :          0 :                 r = bind(fd, &sa.sa, salen);
     920         [ #  # ]:          0 :                 if (r < 0)
     921         [ #  # ]:          0 :                         return log_error_errno(errno, "bind(%s) failed: %m", m->notify_socket);
     922                 :            : 
     923                 :          0 :                 r = setsockopt_int(fd, SOL_SOCKET, SO_PASSCRED, true);
     924         [ #  # ]:          0 :                 if (r < 0)
     925         [ #  # ]:          0 :                         return log_error_errno(r, "SO_PASSCRED failed: %m");
     926                 :            : 
     927                 :          0 :                 m->notify_fd = TAKE_FD(fd);
     928                 :            : 
     929         [ #  # ]:          0 :                 log_debug("Using notification socket %s", m->notify_socket);
     930                 :            :         }
     931                 :            : 
     932         [ #  # ]:          0 :         if (!m->notify_event_source) {
     933                 :          0 :                 r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLIN, manager_dispatch_notify_fd, m);
     934         [ #  # ]:          0 :                 if (r < 0)
     935         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to allocate notify event source: %m");
     936                 :            : 
     937                 :            :                 /* Process notification messages a bit earlier than SIGCHLD, so that we can still identify to which
     938                 :            :                  * service an exit message belongs. */
     939                 :          0 :                 r = sd_event_source_set_priority(m->notify_event_source, SD_EVENT_PRIORITY_NORMAL-8);
     940         [ #  # ]:          0 :                 if (r < 0)
     941         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to set priority of notify event source: %m");
     942                 :            : 
     943                 :          0 :                 (void) sd_event_source_set_description(m->notify_event_source, "manager-notify");
     944                 :            :         }
     945                 :            : 
     946                 :          0 :         return 0;
     947                 :            : }
     948                 :            : 
     949                 :         52 : static int manager_setup_cgroups_agent(Manager *m) {
     950                 :            : 
     951                 :            :         static const union sockaddr_union sa = {
     952                 :            :                 .un.sun_family = AF_UNIX,
     953                 :            :                 .un.sun_path = "/run/systemd/cgroups-agent",
     954                 :            :         };
     955                 :            :         int r;
     956                 :            : 
     957                 :            :         /* This creates a listening socket we receive cgroups agent messages on. We do not use D-Bus for delivering
     958                 :            :          * these messages from the cgroups agent binary to PID 1, as the cgroups agent binary is very short-living, and
     959                 :            :          * each instance of it needs a new D-Bus connection. Since D-Bus connections are SOCK_STREAM/AF_UNIX, on
     960                 :            :          * overloaded systems the backlog of the D-Bus socket becomes relevant, as not more than the configured number
     961                 :            :          * of D-Bus connections may be queued until the kernel will start dropping further incoming connections,
     962                 :            :          * possibly resulting in lost cgroups agent messages. To avoid this, we'll use a private SOCK_DGRAM/AF_UNIX
     963                 :            :          * socket, where no backlog is relevant as communication may take place without an actual connect() cycle, and
     964                 :            :          * we thus won't lose messages.
     965                 :            :          *
     966                 :            :          * Note that PID 1 will forward the agent message to system bus, so that the user systemd instance may listen
     967                 :            :          * to it. The system instance hence listens on this special socket, but the user instances listen on the system
     968                 :            :          * bus for these messages. */
     969                 :            : 
     970         [ +  - ]:         52 :         if (MANAGER_IS_TEST_RUN(m))
     971                 :         52 :                 return 0;
     972                 :            : 
     973         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
     974                 :          0 :                 return 0;
     975                 :            : 
     976                 :          0 :         r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
     977         [ #  # ]:          0 :         if (r < 0)
     978         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to determine whether unified cgroups hierarchy is used: %m");
     979         [ #  # ]:          0 :         if (r > 0) /* We don't need this anymore on the unified hierarchy */
     980                 :          0 :                 return 0;
     981                 :            : 
     982         [ #  # ]:          0 :         if (m->cgroups_agent_fd < 0) {
     983         [ #  # ]:          0 :                 _cleanup_close_ int fd = -1;
     984                 :            : 
     985                 :            :                 /* First free all secondary fields */
     986                 :          0 :                 m->cgroups_agent_event_source = sd_event_source_unref(m->cgroups_agent_event_source);
     987                 :            : 
     988                 :          0 :                 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
     989         [ #  # ]:          0 :                 if (fd < 0)
     990         [ #  # ]:          0 :                         return log_error_errno(errno, "Failed to allocate cgroups agent socket: %m");
     991                 :            : 
     992                 :          0 :                 fd_inc_rcvbuf(fd, CGROUPS_AGENT_RCVBUF_SIZE);
     993                 :            : 
     994                 :          0 :                 (void) sockaddr_un_unlink(&sa.un);
     995                 :            : 
     996                 :            :                 /* Only allow root to connect to this socket */
     997         [ #  # ]:          0 :                 RUN_WITH_UMASK(0077)
     998   [ #  #  #  # ]:          0 :                         r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
     999         [ #  # ]:          0 :                 if (r < 0)
    1000         [ #  # ]:          0 :                         return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
    1001                 :            : 
    1002                 :          0 :                 m->cgroups_agent_fd = TAKE_FD(fd);
    1003                 :            :         }
    1004                 :            : 
    1005         [ #  # ]:          0 :         if (!m->cgroups_agent_event_source) {
    1006                 :          0 :                 r = sd_event_add_io(m->event, &m->cgroups_agent_event_source, m->cgroups_agent_fd, EPOLLIN, manager_dispatch_cgroups_agent_fd, m);
    1007         [ #  # ]:          0 :                 if (r < 0)
    1008         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to allocate cgroups agent event source: %m");
    1009                 :            : 
    1010                 :            :                 /* Process cgroups notifications early. Note that when the agent notification is received
    1011                 :            :                  * we'll just enqueue the unit in the cgroup empty queue, hence pick a high priority than
    1012                 :            :                  * that. Also see handling of cgroup inotify for the unified cgroup stuff. */
    1013                 :          0 :                 r = sd_event_source_set_priority(m->cgroups_agent_event_source, SD_EVENT_PRIORITY_NORMAL-9);
    1014         [ #  # ]:          0 :                 if (r < 0)
    1015         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to set priority of cgroups agent event source: %m");
    1016                 :            : 
    1017                 :          0 :                 (void) sd_event_source_set_description(m->cgroups_agent_event_source, "manager-cgroups-agent");
    1018                 :            :         }
    1019                 :            : 
    1020                 :          0 :         return 0;
    1021                 :            : }
    1022                 :            : 
    1023                 :         52 : static int manager_setup_user_lookup_fd(Manager *m) {
    1024                 :            :         int r;
    1025                 :            : 
    1026         [ -  + ]:         52 :         assert(m);
    1027                 :            : 
    1028                 :            :         /* Set up the socket pair used for passing UID/GID resolution results from forked off processes to PID
    1029                 :            :          * 1. Background: we can't do name lookups (NSS) from PID 1, since it might involve IPC and thus activation,
    1030                 :            :          * and we might hence deadlock on ourselves. Hence we do all user/group lookups asynchronously from the forked
    1031                 :            :          * off processes right before executing the binaries to start. In order to be able to clean up any IPC objects
    1032                 :            :          * created by a unit (see RemoveIPC=) we need to know in PID 1 the used UID/GID of the executed processes,
    1033                 :            :          * hence we establish this communication channel so that forked off processes can pass their UID/GID
    1034                 :            :          * information back to PID 1. The forked off processes send their resolved UID/GID to PID 1 in a simple
    1035                 :            :          * datagram, along with their unit name, so that we can share one communication socket pair among all units for
    1036                 :            :          * this purpose.
    1037                 :            :          *
    1038                 :            :          * You might wonder why we need a communication channel for this that is independent of the usual notification
    1039                 :            :          * socket scheme (i.e. $NOTIFY_SOCKET). The primary difference is about trust: data sent via the $NOTIFY_SOCKET
    1040                 :            :          * channel is only accepted if it originates from the right unit and if reception was enabled for it. The user
    1041                 :            :          * lookup socket OTOH is only accessible by PID 1 and its children until they exec(), and always available.
    1042                 :            :          *
    1043                 :            :          * Note that this function is called under two circumstances: when we first initialize (in which case we
    1044                 :            :          * allocate both the socket pair and the event source to listen on it), and when we deserialize after a reload
    1045                 :            :          * (in which case the socket pair already exists but we still need to allocate the event source for it). */
    1046                 :            : 
    1047         [ +  - ]:         52 :         if (m->user_lookup_fds[0] < 0) {
    1048                 :            : 
    1049                 :            :                 /* Free all secondary fields */
    1050                 :         52 :                 safe_close_pair(m->user_lookup_fds);
    1051                 :         52 :                 m->user_lookup_event_source = sd_event_source_unref(m->user_lookup_event_source);
    1052                 :            : 
    1053         [ -  + ]:         52 :                 if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, m->user_lookup_fds) < 0)
    1054         [ #  # ]:          0 :                         return log_error_errno(errno, "Failed to allocate user lookup socket: %m");
    1055                 :            : 
    1056                 :         52 :                 (void) fd_inc_rcvbuf(m->user_lookup_fds[0], NOTIFY_RCVBUF_SIZE);
    1057                 :            :         }
    1058                 :            : 
    1059         [ +  - ]:         52 :         if (!m->user_lookup_event_source) {
    1060                 :         52 :                 r = sd_event_add_io(m->event, &m->user_lookup_event_source, m->user_lookup_fds[0], EPOLLIN, manager_dispatch_user_lookup_fd, m);
    1061         [ -  + ]:         52 :                 if (r < 0)
    1062         [ #  # ]:          0 :                         return log_error_errno(errno, "Failed to allocate user lookup event source: %m");
    1063                 :            : 
    1064                 :            :                 /* Process even earlier than the notify event source, so that we always know first about valid UID/GID
    1065                 :            :                  * resolutions */
    1066                 :         52 :                 r = sd_event_source_set_priority(m->user_lookup_event_source, SD_EVENT_PRIORITY_NORMAL-11);
    1067         [ -  + ]:         52 :                 if (r < 0)
    1068         [ #  # ]:          0 :                         return log_error_errno(errno, "Failed to set priority of user lookup event source: %m");
    1069                 :            : 
    1070                 :         52 :                 (void) sd_event_source_set_description(m->user_lookup_event_source, "user-lookup");
    1071                 :            :         }
    1072                 :            : 
    1073                 :         52 :         return 0;
    1074                 :            : }
    1075                 :            : 
    1076                 :         56 : static unsigned manager_dispatch_cleanup_queue(Manager *m) {
    1077                 :            :         Unit *u;
    1078                 :         56 :         unsigned n = 0;
    1079                 :            : 
    1080         [ -  + ]:         56 :         assert(m);
    1081                 :            : 
    1082         [ -  + ]:         56 :         while ((u = m->cleanup_queue)) {
    1083         [ #  # ]:          0 :                 assert(u->in_cleanup_queue);
    1084                 :            : 
    1085                 :          0 :                 unit_free(u);
    1086                 :          0 :                 n++;
    1087                 :            :         }
    1088                 :            : 
    1089                 :         56 :         return n;
    1090                 :            : }
    1091                 :            : 
    1092                 :            : enum {
    1093                 :            :         GC_OFFSET_IN_PATH,  /* This one is on the path we were traveling */
    1094                 :            :         GC_OFFSET_UNSURE,   /* No clue */
    1095                 :            :         GC_OFFSET_GOOD,     /* We still need this unit */
    1096                 :            :         GC_OFFSET_BAD,      /* We don't need this unit anymore */
    1097                 :            :         _GC_OFFSET_MAX
    1098                 :            : };
    1099                 :            : 
    1100                 :          0 : static void unit_gc_mark_good(Unit *u, unsigned gc_marker) {
    1101                 :            :         Unit *other;
    1102                 :            :         Iterator i;
    1103                 :            :         void *v;
    1104                 :            : 
    1105                 :          0 :         u->gc_marker = gc_marker + GC_OFFSET_GOOD;
    1106                 :            : 
    1107                 :            :         /* Recursively mark referenced units as GOOD as well */
    1108         [ #  # ]:          0 :         HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REFERENCES], i)
    1109         [ #  # ]:          0 :                 if (other->gc_marker == gc_marker + GC_OFFSET_UNSURE)
    1110                 :          0 :                         unit_gc_mark_good(other, gc_marker);
    1111                 :          0 : }
    1112                 :            : 
    1113                 :          0 : static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
    1114                 :            :         Unit *other;
    1115                 :            :         bool is_bad;
    1116                 :            :         Iterator i;
    1117                 :            :         void *v;
    1118                 :            : 
    1119         [ #  # ]:          0 :         assert(u);
    1120                 :            : 
    1121   [ #  #  #  # ]:          0 :         if (IN_SET(u->gc_marker - gc_marker,
    1122                 :            :                    GC_OFFSET_GOOD, GC_OFFSET_BAD, GC_OFFSET_UNSURE, GC_OFFSET_IN_PATH))
    1123                 :          0 :                 return;
    1124                 :            : 
    1125         [ #  # ]:          0 :         if (u->in_cleanup_queue)
    1126                 :          0 :                 goto bad;
    1127                 :            : 
    1128         [ #  # ]:          0 :         if (!unit_may_gc(u))
    1129                 :          0 :                 goto good;
    1130                 :            : 
    1131                 :          0 :         u->gc_marker = gc_marker + GC_OFFSET_IN_PATH;
    1132                 :            : 
    1133                 :          0 :         is_bad = true;
    1134                 :            : 
    1135         [ #  # ]:          0 :         HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REFERENCED_BY], i) {
    1136                 :          0 :                 unit_gc_sweep(other, gc_marker);
    1137                 :            : 
    1138         [ #  # ]:          0 :                 if (other->gc_marker == gc_marker + GC_OFFSET_GOOD)
    1139                 :          0 :                         goto good;
    1140                 :            : 
    1141         [ #  # ]:          0 :                 if (other->gc_marker != gc_marker + GC_OFFSET_BAD)
    1142                 :          0 :                         is_bad = false;
    1143                 :            :         }
    1144                 :            : 
    1145         [ #  # ]:          0 :         if (u->refs_by_target) {
    1146                 :            :                 const UnitRef *ref;
    1147                 :            : 
    1148         [ #  # ]:          0 :                 LIST_FOREACH(refs_by_target, ref, u->refs_by_target) {
    1149                 :          0 :                         unit_gc_sweep(ref->source, gc_marker);
    1150                 :            : 
    1151         [ #  # ]:          0 :                         if (ref->source->gc_marker == gc_marker + GC_OFFSET_GOOD)
    1152                 :          0 :                                 goto good;
    1153                 :            : 
    1154         [ #  # ]:          0 :                         if (ref->source->gc_marker != gc_marker + GC_OFFSET_BAD)
    1155                 :          0 :                                 is_bad = false;
    1156                 :            :                 }
    1157                 :            :         }
    1158                 :            : 
    1159         [ #  # ]:          0 :         if (is_bad)
    1160                 :          0 :                 goto bad;
    1161                 :            : 
    1162                 :            :         /* We were unable to find anything out about this entry, so
    1163                 :            :          * let's investigate it later */
    1164                 :          0 :         u->gc_marker = gc_marker + GC_OFFSET_UNSURE;
    1165                 :          0 :         unit_add_to_gc_queue(u);
    1166                 :          0 :         return;
    1167                 :            : 
    1168                 :          0 : bad:
    1169                 :            :         /* We definitely know that this one is not useful anymore, so
    1170                 :            :          * let's mark it for deletion */
    1171                 :          0 :         u->gc_marker = gc_marker + GC_OFFSET_BAD;
    1172                 :          0 :         unit_add_to_cleanup_queue(u);
    1173                 :          0 :         return;
    1174                 :            : 
    1175                 :          0 : good:
    1176                 :          0 :         unit_gc_mark_good(u, gc_marker);
    1177                 :            : }
    1178                 :            : 
    1179                 :          0 : static unsigned manager_dispatch_gc_unit_queue(Manager *m) {
    1180                 :          0 :         unsigned n = 0, gc_marker;
    1181                 :            :         Unit *u;
    1182                 :            : 
    1183         [ #  # ]:          0 :         assert(m);
    1184                 :            : 
    1185                 :            :         /* log_debug("Running GC..."); */
    1186                 :            : 
    1187                 :          0 :         m->gc_marker += _GC_OFFSET_MAX;
    1188         [ #  # ]:          0 :         if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX)
    1189                 :          0 :                 m->gc_marker = 1;
    1190                 :            : 
    1191                 :          0 :         gc_marker = m->gc_marker;
    1192                 :            : 
    1193         [ #  # ]:          0 :         while ((u = m->gc_unit_queue)) {
    1194         [ #  # ]:          0 :                 assert(u->in_gc_queue);
    1195                 :            : 
    1196                 :          0 :                 unit_gc_sweep(u, gc_marker);
    1197                 :            : 
    1198   [ #  #  #  #  :          0 :                 LIST_REMOVE(gc_queue, m->gc_unit_queue, u);
             #  #  #  # ]
    1199                 :          0 :                 u->in_gc_queue = false;
    1200                 :            : 
    1201                 :          0 :                 n++;
    1202                 :            : 
    1203   [ #  #  #  # ]:          0 :                 if (IN_SET(u->gc_marker - gc_marker,
    1204                 :            :                            GC_OFFSET_BAD, GC_OFFSET_UNSURE)) {
    1205         [ #  # ]:          0 :                         if (u->id)
    1206         [ #  # ]:          0 :                                 log_unit_debug(u, "Collecting.");
    1207                 :          0 :                         u->gc_marker = gc_marker + GC_OFFSET_BAD;
    1208                 :          0 :                         unit_add_to_cleanup_queue(u);
    1209                 :            :                 }
    1210                 :            :         }
    1211                 :            : 
    1212                 :          0 :         return n;
    1213                 :            : }
    1214                 :            : 
    1215                 :          0 : static unsigned manager_dispatch_gc_job_queue(Manager *m) {
    1216                 :          0 :         unsigned n = 0;
    1217                 :            :         Job *j;
    1218                 :            : 
    1219         [ #  # ]:          0 :         assert(m);
    1220                 :            : 
    1221         [ #  # ]:          0 :         while ((j = m->gc_job_queue)) {
    1222         [ #  # ]:          0 :                 assert(j->in_gc_queue);
    1223                 :            : 
    1224   [ #  #  #  #  :          0 :                 LIST_REMOVE(gc_queue, m->gc_job_queue, j);
             #  #  #  # ]
    1225                 :          0 :                 j->in_gc_queue = false;
    1226                 :            : 
    1227                 :          0 :                 n++;
    1228                 :            : 
    1229         [ #  # ]:          0 :                 if (!job_may_gc(j))
    1230                 :          0 :                         continue;
    1231                 :            : 
    1232         [ #  # ]:          0 :                 log_unit_debug(j->unit, "Collecting job.");
    1233                 :          0 :                 (void) job_finish_and_invalidate(j, JOB_COLLECTED, false, false);
    1234                 :            :         }
    1235                 :            : 
    1236                 :          0 :         return n;
    1237                 :            : }
    1238                 :            : 
    1239                 :          0 : static unsigned manager_dispatch_stop_when_unneeded_queue(Manager *m) {
    1240                 :          0 :         unsigned n = 0;
    1241                 :            :         Unit *u;
    1242                 :            :         int r;
    1243                 :            : 
    1244         [ #  # ]:          0 :         assert(m);
    1245                 :            : 
    1246         [ #  # ]:          0 :         while ((u = m->stop_when_unneeded_queue)) {
    1247         [ #  # ]:          0 :                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
    1248         [ #  # ]:          0 :                 assert(m->stop_when_unneeded_queue);
    1249                 :            : 
    1250         [ #  # ]:          0 :                 assert(u->in_stop_when_unneeded_queue);
    1251   [ #  #  #  #  :          0 :                 LIST_REMOVE(stop_when_unneeded_queue, m->stop_when_unneeded_queue, u);
             #  #  #  # ]
    1252                 :          0 :                 u->in_stop_when_unneeded_queue = false;
    1253                 :            : 
    1254                 :          0 :                 n++;
    1255                 :            : 
    1256         [ #  # ]:          0 :                 if (!unit_is_unneeded(u))
    1257                 :          0 :                         continue;
    1258                 :            : 
    1259         [ #  # ]:          0 :                 log_unit_debug(u, "Unit is not needed anymore.");
    1260                 :            : 
    1261                 :            :                 /* If stopping a unit fails continuously we might enter a stop loop here, hence stop acting on the
    1262                 :            :                  * service being unnecessary after a while. */
    1263                 :            : 
    1264         [ #  # ]:          0 :                 if (!ratelimit_below(&u->auto_stop_ratelimit)) {
    1265         [ #  # ]:          0 :                         log_unit_warning(u, "Unit not needed anymore, but not stopping since we tried this too often recently.");
    1266                 :          0 :                         continue;
    1267                 :            :                 }
    1268                 :            : 
    1269                 :            :                 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
    1270                 :          0 :                 r = manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, NULL, &error, NULL);
    1271         [ #  # ]:          0 :                 if (r < 0)
    1272         [ #  # ]:          0 :                         log_unit_warning_errno(u, r, "Failed to enqueue stop job, ignoring: %s", bus_error_message(&error, r));
    1273                 :            :         }
    1274                 :            : 
    1275                 :          0 :         return n;
    1276                 :            : }
    1277                 :            : 
    1278                 :         56 : static void manager_clear_jobs_and_units(Manager *m) {
    1279                 :            :         Unit *u;
    1280                 :            : 
    1281         [ -  + ]:         56 :         assert(m);
    1282                 :            : 
    1283         [ +  + ]:       8776 :         while ((u = hashmap_first(m->units)))
    1284                 :       8720 :                 unit_free(u);
    1285                 :            : 
    1286                 :         56 :         manager_dispatch_cleanup_queue(m);
    1287                 :            : 
    1288         [ -  + ]:         56 :         assert(!m->load_queue);
    1289         [ -  + ]:         56 :         assert(prioq_isempty(m->run_queue));
    1290         [ -  + ]:         56 :         assert(!m->dbus_unit_queue);
    1291         [ -  + ]:         56 :         assert(!m->dbus_job_queue);
    1292         [ -  + ]:         56 :         assert(!m->cleanup_queue);
    1293         [ -  + ]:         56 :         assert(!m->gc_unit_queue);
    1294         [ -  + ]:         56 :         assert(!m->gc_job_queue);
    1295         [ -  + ]:         56 :         assert(!m->stop_when_unneeded_queue);
    1296                 :            : 
    1297         [ -  + ]:         56 :         assert(hashmap_isempty(m->jobs));
    1298         [ -  + ]:         56 :         assert(hashmap_isempty(m->units));
    1299                 :            : 
    1300                 :         56 :         m->n_on_console = 0;
    1301                 :         56 :         m->n_running_jobs = 0;
    1302                 :         56 :         m->n_installed_jobs = 0;
    1303                 :         56 :         m->n_failed_jobs = 0;
    1304                 :         56 : }
    1305                 :            : 
    1306                 :         56 : Manager* manager_free(Manager *m) {
    1307                 :            :         ExecDirectoryType dt;
    1308                 :            :         UnitType c;
    1309                 :            : 
    1310         [ -  + ]:         56 :         if (!m)
    1311                 :          0 :                 return NULL;
    1312                 :            : 
    1313                 :         56 :         manager_clear_jobs_and_units(m);
    1314                 :            : 
    1315         [ +  + ]:        672 :         for (c = 0; c < _UNIT_TYPE_MAX; c++)
    1316         [ +  + ]:        616 :                 if (unit_vtable[c]->shutdown)
    1317                 :        224 :                         unit_vtable[c]->shutdown(m);
    1318                 :            : 
    1319                 :            :         /* Keep the cgroup hierarchy in place except when we know we are going down for good */
    1320         [ -  + ]:         56 :         manager_shutdown_cgroup(m, IN_SET(m->objective, MANAGER_EXIT, MANAGER_REBOOT, MANAGER_POWEROFF, MANAGER_HALT, MANAGER_KEXEC));
    1321                 :            : 
    1322                 :         56 :         lookup_paths_flush_generator(&m->lookup_paths);
    1323                 :            : 
    1324                 :         56 :         bus_done(m);
    1325                 :            : 
    1326                 :         56 :         exec_runtime_vacuum(m);
    1327                 :         56 :         hashmap_free(m->exec_runtime_by_id);
    1328                 :            : 
    1329                 :         56 :         dynamic_user_vacuum(m, false);
    1330                 :         56 :         hashmap_free(m->dynamic_users);
    1331                 :            : 
    1332                 :         56 :         hashmap_free(m->units);
    1333                 :         56 :         hashmap_free(m->units_by_invocation_id);
    1334                 :         56 :         hashmap_free(m->jobs);
    1335                 :         56 :         hashmap_free(m->watch_pids);
    1336                 :         56 :         hashmap_free(m->watch_bus);
    1337                 :            : 
    1338                 :         56 :         prioq_free(m->run_queue);
    1339                 :            : 
    1340                 :         56 :         set_free(m->startup_units);
    1341                 :         56 :         set_free(m->failed_units);
    1342                 :            : 
    1343                 :         56 :         sd_event_source_unref(m->signal_event_source);
    1344                 :         56 :         sd_event_source_unref(m->sigchld_event_source);
    1345                 :         56 :         sd_event_source_unref(m->notify_event_source);
    1346                 :         56 :         sd_event_source_unref(m->cgroups_agent_event_source);
    1347                 :         56 :         sd_event_source_unref(m->time_change_event_source);
    1348                 :         56 :         sd_event_source_unref(m->timezone_change_event_source);
    1349                 :         56 :         sd_event_source_unref(m->jobs_in_progress_event_source);
    1350                 :         56 :         sd_event_source_unref(m->run_queue_event_source);
    1351                 :         56 :         sd_event_source_unref(m->user_lookup_event_source);
    1352                 :         56 :         sd_event_source_unref(m->sync_bus_names_event_source);
    1353                 :            : 
    1354                 :         56 :         safe_close(m->signal_fd);
    1355                 :         56 :         safe_close(m->notify_fd);
    1356                 :         56 :         safe_close(m->cgroups_agent_fd);
    1357                 :         56 :         safe_close(m->time_change_fd);
    1358                 :         56 :         safe_close_pair(m->user_lookup_fds);
    1359                 :            : 
    1360                 :         56 :         manager_close_ask_password(m);
    1361                 :            : 
    1362                 :         56 :         manager_close_idle_pipe(m);
    1363                 :            : 
    1364                 :         56 :         sd_event_unref(m->event);
    1365                 :            : 
    1366                 :         56 :         free(m->notify_socket);
    1367                 :            : 
    1368                 :         56 :         lookup_paths_free(&m->lookup_paths);
    1369                 :         56 :         strv_free(m->transient_environment);
    1370                 :         56 :         strv_free(m->client_environment);
    1371                 :            : 
    1372                 :         56 :         hashmap_free(m->cgroup_unit);
    1373                 :         56 :         manager_free_unit_name_maps(m);
    1374                 :            : 
    1375                 :         56 :         free(m->switch_root);
    1376                 :         56 :         free(m->switch_root_init);
    1377                 :            : 
    1378                 :         56 :         rlimit_free_all(m->rlimit);
    1379                 :            : 
    1380         [ -  + ]:         56 :         assert(hashmap_isempty(m->units_requiring_mounts_for));
    1381                 :         56 :         hashmap_free(m->units_requiring_mounts_for);
    1382                 :            : 
    1383                 :         56 :         hashmap_free(m->uid_refs);
    1384                 :         56 :         hashmap_free(m->gid_refs);
    1385                 :            : 
    1386         [ +  + ]:        336 :         for (dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++)
    1387                 :        280 :                 m->prefix[dt] = mfree(m->prefix[dt]);
    1388                 :            : 
    1389                 :         56 :         return mfree(m);
    1390                 :            : }
    1391                 :            : 
    1392                 :         52 : static void manager_enumerate_perpetual(Manager *m) {
    1393                 :            :         UnitType c;
    1394                 :            : 
    1395         [ -  + ]:         52 :         assert(m);
    1396                 :            : 
    1397         [ +  + ]:         52 :         if (m->test_run_flags == MANAGER_TEST_RUN_MINIMAL)
    1398                 :          8 :                 return;
    1399                 :            : 
    1400                 :            :         /* Let's ask every type to load all units from disk/kernel that it might know */
    1401         [ +  + ]:        528 :         for (c = 0; c < _UNIT_TYPE_MAX; c++) {
    1402         [ -  + ]:        484 :                 if (!unit_type_supported(c)) {
    1403         [ #  # ]:          0 :                         log_debug("Unit type .%s is not supported on this system.", unit_type_to_string(c));
    1404                 :          0 :                         continue;
    1405                 :            :                 }
    1406                 :            : 
    1407         [ +  + ]:        484 :                 if (unit_vtable[c]->enumerate_perpetual)
    1408                 :        132 :                         unit_vtable[c]->enumerate_perpetual(m);
    1409                 :            :         }
    1410                 :            : }
    1411                 :            : 
    1412                 :         52 : static void manager_enumerate(Manager *m) {
    1413                 :            :         UnitType c;
    1414                 :            : 
    1415         [ -  + ]:         52 :         assert(m);
    1416                 :            : 
    1417         [ +  + ]:         52 :         if (m->test_run_flags == MANAGER_TEST_RUN_MINIMAL)
    1418                 :          8 :                 return;
    1419                 :            : 
    1420                 :            :         /* Let's ask every type to load all units from disk/kernel that it might know */
    1421         [ +  + ]:        528 :         for (c = 0; c < _UNIT_TYPE_MAX; c++) {
    1422         [ -  + ]:        484 :                 if (!unit_type_supported(c)) {
    1423         [ #  # ]:          0 :                         log_debug("Unit type .%s is not supported on this system.", unit_type_to_string(c));
    1424                 :          0 :                         continue;
    1425                 :            :                 }
    1426                 :            : 
    1427         [ +  + ]:        484 :                 if (unit_vtable[c]->enumerate)
    1428                 :        132 :                         unit_vtable[c]->enumerate(m);
    1429                 :            :         }
    1430                 :            : 
    1431                 :         44 :         manager_dispatch_load_queue(m);
    1432                 :            : }
    1433                 :            : 
    1434                 :         52 : static void manager_coldplug(Manager *m) {
    1435                 :            :         Iterator i;
    1436                 :            :         Unit *u;
    1437                 :            :         char *k;
    1438                 :            :         int r;
    1439                 :            : 
    1440         [ -  + ]:         52 :         assert(m);
    1441                 :            : 
    1442         [ +  + ]:         52 :         log_debug("Invoking unit coldplug() handlers…");
    1443                 :            : 
    1444                 :            :         /* Let's place the units back into their deserialized state */
    1445         [ +  + ]:       8016 :         HASHMAP_FOREACH_KEY(u, k, m->units, i) {
    1446                 :            : 
    1447                 :            :                 /* ignore aliases */
    1448         [ -  + ]:       7964 :                 if (u->id != k)
    1449                 :          0 :                         continue;
    1450                 :            : 
    1451                 :       7964 :                 r = unit_coldplug(u);
    1452         [ -  + ]:       7964 :                 if (r < 0)
    1453         [ #  # ]:          0 :                         log_warning_errno(r, "We couldn't coldplug %s, proceeding anyway: %m", u->id);
    1454                 :            :         }
    1455                 :         52 : }
    1456                 :            : 
    1457                 :         52 : static void manager_catchup(Manager *m) {
    1458                 :            :         Iterator i;
    1459                 :            :         Unit *u;
    1460                 :            :         char *k;
    1461                 :            : 
    1462         [ -  + ]:         52 :         assert(m);
    1463                 :            : 
    1464         [ +  + ]:         52 :         log_debug("Invoking unit catchup() handlers…");
    1465                 :            : 
    1466                 :            :         /* Let's catch up on any state changes that happened while we were reloading/reexecing */
    1467         [ +  + ]:       8016 :         HASHMAP_FOREACH_KEY(u, k, m->units, i) {
    1468                 :            : 
    1469                 :            :                 /* ignore aliases */
    1470         [ -  + ]:       7964 :                 if (u->id != k)
    1471                 :          0 :                         continue;
    1472                 :            : 
    1473                 :       7964 :                 unit_catchup(u);
    1474                 :            :         }
    1475                 :         52 : }
    1476                 :            : 
    1477                 :         52 : static void manager_distribute_fds(Manager *m, FDSet *fds) {
    1478                 :            :         Iterator i;
    1479                 :            :         Unit *u;
    1480                 :            : 
    1481         [ -  + ]:         52 :         assert(m);
    1482                 :            : 
    1483         [ +  + ]:         52 :         HASHMAP_FOREACH(u, m->units, i) {
    1484                 :            : 
    1485         [ +  - ]:         44 :                 if (fdset_size(fds) <= 0)
    1486                 :         44 :                         break;
    1487                 :            : 
    1488         [ #  # ]:          0 :                 if (!UNIT_VTABLE(u)->distribute_fds)
    1489                 :          0 :                         continue;
    1490                 :            : 
    1491                 :          0 :                 UNIT_VTABLE(u)->distribute_fds(u, fds);
    1492                 :            :         }
    1493                 :         52 : }
    1494                 :            : 
    1495                 :       7188 : static bool manager_dbus_is_running(Manager *m, bool deserialized) {
    1496                 :            :         Unit *u;
    1497                 :            : 
    1498         [ -  + ]:       7188 :         assert(m);
    1499                 :            : 
    1500                 :            :         /* This checks whether the dbus instance we are supposed to expose our APIs on is up. We check both the socket
    1501                 :            :          * and the service unit. If the 'deserialized' parameter is true we'll check the deserialized state of the unit
    1502                 :            :          * rather than the current one. */
    1503                 :            : 
    1504         [ +  - ]:       7188 :         if (MANAGER_IS_TEST_RUN(m))
    1505                 :       7188 :                 return false;
    1506                 :            : 
    1507                 :          0 :         u = manager_get_unit(m, SPECIAL_DBUS_SOCKET);
    1508         [ #  # ]:          0 :         if (!u)
    1509                 :          0 :                 return false;
    1510   [ #  #  #  # ]:          0 :         if ((deserialized ? SOCKET(u)->deserialized_state : SOCKET(u)->state) != SOCKET_RUNNING)
    1511                 :          0 :                 return false;
    1512                 :            : 
    1513                 :          0 :         u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
    1514         [ #  # ]:          0 :         if (!u)
    1515                 :          0 :                 return false;
    1516   [ #  #  #  #  :          0 :         if (!IN_SET((deserialized ? SERVICE(u)->deserialized_state : SERVICE(u)->state), SERVICE_RUNNING, SERVICE_RELOAD))
                   #  # ]
    1517                 :          0 :                 return false;
    1518                 :            : 
    1519                 :          0 :         return true;
    1520                 :            : }
    1521                 :            : 
    1522                 :         52 : static void manager_setup_bus(Manager *m) {
    1523         [ -  + ]:         52 :         assert(m);
    1524                 :            : 
    1525                 :            :         /* Let's set up our private bus connection now, unconditionally */
    1526                 :         52 :         (void) bus_init_private(m);
    1527                 :            : 
    1528                 :            :         /* If we are in --user mode also connect to the system bus now */
    1529         [ +  - ]:         52 :         if (MANAGER_IS_USER(m))
    1530                 :         52 :                 (void) bus_init_system(m);
    1531                 :            : 
    1532                 :            :         /* Let's connect to the bus now, but only if the unit is supposed to be up */
    1533         [ -  + ]:         52 :         if (manager_dbus_is_running(m, MANAGER_IS_RELOADING(m))) {
    1534                 :          0 :                 (void) bus_init_api(m);
    1535                 :            : 
    1536         [ #  # ]:          0 :                 if (MANAGER_IS_SYSTEM(m))
    1537                 :          0 :                         (void) bus_init_system(m);
    1538                 :            :         }
    1539                 :         52 : }
    1540                 :            : 
    1541                 :         52 : static void manager_preset_all(Manager *m) {
    1542                 :            :         int r;
    1543                 :            : 
    1544         [ -  + ]:         52 :         assert(m);
    1545                 :            : 
    1546         [ +  - ]:         52 :         if (m->first_boot <= 0)
    1547                 :         52 :                 return;
    1548                 :            : 
    1549         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
    1550                 :          0 :                 return;
    1551                 :            : 
    1552         [ #  # ]:          0 :         if (MANAGER_IS_TEST_RUN(m))
    1553                 :          0 :                 return;
    1554                 :            : 
    1555                 :            :         /* If this is the first boot, and we are in the host system, then preset everything */
    1556                 :          0 :         r = unit_file_preset_all(UNIT_FILE_SYSTEM, 0, NULL, UNIT_FILE_PRESET_ENABLE_ONLY, NULL, 0);
    1557         [ #  # ]:          0 :         if (r < 0)
    1558   [ #  #  #  # ]:          0 :                 log_full_errno(r == -EEXIST ? LOG_NOTICE : LOG_WARNING, r,
    1559                 :            :                                "Failed to populate /etc with preset unit settings, ignoring: %m");
    1560                 :            :         else
    1561         [ #  # ]:          0 :                 log_info("Populated /etc with preset unit settings.");
    1562                 :            : }
    1563                 :            : 
    1564                 :         52 : static void manager_vacuum(Manager *m) {
    1565         [ -  + ]:         52 :         assert(m);
    1566                 :            : 
    1567                 :            :         /* Release any dynamic users no longer referenced */
    1568                 :         52 :         dynamic_user_vacuum(m, true);
    1569                 :            : 
    1570                 :            :         /* Release any references to UIDs/GIDs no longer referenced, and destroy any IPC owned by them */
    1571                 :         52 :         manager_vacuum_uid_refs(m);
    1572                 :         52 :         manager_vacuum_gid_refs(m);
    1573                 :            : 
    1574                 :            :         /* Release any runtimes no longer referenced */
    1575                 :         52 :         exec_runtime_vacuum(m);
    1576                 :         52 : }
    1577                 :            : 
    1578                 :         52 : static void manager_ready(Manager *m) {
    1579         [ -  + ]:         52 :         assert(m);
    1580                 :            : 
    1581                 :            :         /* After having loaded everything, do the final round of catching up with what might have changed */
    1582                 :            : 
    1583                 :         52 :         m->objective = MANAGER_OK; /* Tell everyone we are up now */
    1584                 :            : 
    1585                 :            :         /* It might be safe to log to the journal now and connect to dbus */
    1586                 :         52 :         manager_recheck_journal(m);
    1587                 :         52 :         manager_recheck_dbus(m);
    1588                 :            : 
    1589                 :            :         /* Sync current state of bus names with our set of listening units */
    1590                 :         52 :         (void) manager_enqueue_sync_bus_names(m);
    1591                 :            : 
    1592                 :            :         /* Let's finally catch up with any changes that took place while we were reloading/reexecing */
    1593                 :         52 :         manager_catchup(m);
    1594                 :            : 
    1595                 :         52 :         m->honor_device_enumeration = true;
    1596                 :         52 : }
    1597                 :            : 
    1598                 :          0 : static Manager* manager_reloading_start(Manager *m) {
    1599                 :          0 :         m->n_reloading++;
    1600                 :          0 :         return m;
    1601                 :            : }
    1602                 :         52 : static void manager_reloading_stopp(Manager **m) {
    1603         [ -  + ]:         52 :         if (*m) {
    1604         [ #  # ]:          0 :                 assert((*m)->n_reloading > 0);
    1605                 :          0 :                 (*m)->n_reloading--;
    1606                 :            :         }
    1607                 :         52 : }
    1608                 :            : 
    1609                 :         52 : int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
    1610                 :            :         int r;
    1611                 :            : 
    1612         [ -  + ]:         52 :         assert(m);
    1613                 :            : 
    1614                 :            :         /* If we are running in test mode, we still want to run the generators,
    1615                 :            :          * but we should not touch the real generator directories. */
    1616                 :         52 :         r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope,
    1617         [ +  - ]:         52 :                               MANAGER_IS_TEST_RUN(m) ? LOOKUP_PATHS_TEMPORARY_GENERATED : 0,
    1618                 :            :                               NULL);
    1619         [ -  + ]:         52 :         if (r < 0)
    1620         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to initialize path lookup table: %m");
    1621                 :            : 
    1622                 :         52 :         dual_timestamp_get(m->timestamps + manager_timestamp_initrd_mangle(MANAGER_TIMESTAMP_GENERATORS_START));
    1623                 :         52 :         r = manager_run_environment_generators(m);
    1624         [ +  - ]:         52 :         if (r >= 0)
    1625                 :         52 :                 r = manager_run_generators(m);
    1626                 :         52 :         dual_timestamp_get(m->timestamps + manager_timestamp_initrd_mangle(MANAGER_TIMESTAMP_GENERATORS_FINISH));
    1627         [ -  + ]:         52 :         if (r < 0)
    1628                 :          0 :                 return r;
    1629                 :            : 
    1630                 :         52 :         manager_preset_all(m);
    1631                 :            : 
    1632                 :         52 :         r = lookup_paths_reduce(&m->lookup_paths);
    1633         [ -  + ]:         52 :         if (r < 0)
    1634         [ #  # ]:          0 :                 log_warning_errno(r, "Failed to reduce unit file paths, ignoring: %m");
    1635                 :            : 
    1636                 :            :         {
    1637                 :            :                 /* This block is (optionally) done with the reloading counter bumped */
    1638         [ +  - ]:         52 :                 _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
    1639                 :            : 
    1640                 :            :                 /* If we will deserialize make sure that during enumeration this is already known, so we increase the
    1641                 :            :                  * counter here already */
    1642         [ -  + ]:         52 :                 if (serialization)
    1643                 :          0 :                         reloading = manager_reloading_start(m);
    1644                 :            : 
    1645                 :            :                 /* First, enumerate what we can from all config files */
    1646                 :         52 :                 dual_timestamp_get(m->timestamps + manager_timestamp_initrd_mangle(MANAGER_TIMESTAMP_UNITS_LOAD_START));
    1647                 :         52 :                 manager_enumerate_perpetual(m);
    1648                 :         52 :                 manager_enumerate(m);
    1649                 :         52 :                 dual_timestamp_get(m->timestamps + manager_timestamp_initrd_mangle(MANAGER_TIMESTAMP_UNITS_LOAD_FINISH));
    1650                 :            : 
    1651                 :            :                 /* Second, deserialize if there is something to deserialize */
    1652         [ -  + ]:         52 :                 if (serialization) {
    1653                 :          0 :                         r = manager_deserialize(m, serialization, fds);
    1654         [ #  # ]:          0 :                         if (r < 0)
    1655         [ #  # ]:          0 :                                 return log_error_errno(r, "Deserialization failed: %m");
    1656                 :            :                 }
    1657                 :            : 
    1658                 :            :                 /* Any fds left? Find some unit which wants them. This is useful to allow container managers to pass
    1659                 :            :                  * some file descriptors to us pre-initialized. This enables socket-based activation of entire
    1660                 :            :                  * containers. */
    1661                 :         52 :                 manager_distribute_fds(m, fds);
    1662                 :            : 
    1663                 :            :                 /* We might have deserialized the notify fd, but if we didn't then let's create the bus now */
    1664                 :         52 :                 r = manager_setup_notify(m);
    1665         [ -  + ]:         52 :                 if (r < 0)
    1666                 :            :                         /* No sense to continue without notifications, our children would fail anyway. */
    1667                 :          0 :                         return r;
    1668                 :            : 
    1669                 :         52 :                 r = manager_setup_cgroups_agent(m);
    1670         [ -  + ]:         52 :                 if (r < 0)
    1671                 :            :                         /* Likewise, no sense to continue without empty cgroup notifications. */
    1672                 :          0 :                         return r;
    1673                 :            : 
    1674                 :         52 :                 r = manager_setup_user_lookup_fd(m);
    1675         [ -  + ]:         52 :                 if (r < 0)
    1676                 :            :                         /* This shouldn't fail, except if things are really broken. */
    1677                 :          0 :                         return r;
    1678                 :            : 
    1679                 :            :                 /* Connect to the bus if we are good for it */
    1680                 :         52 :                 manager_setup_bus(m);
    1681                 :            : 
    1682                 :            :                 /* Now that we are connected to all possible buses, let's deserialize who is tracking us. */
    1683                 :         52 :                 r = bus_track_coldplug(m, &m->subscribed, false, m->deserialized_subscribed);
    1684         [ -  + ]:         52 :                 if (r < 0)
    1685         [ #  # ]:          0 :                         log_warning_errno(r, "Failed to deserialized tracked clients, ignoring: %m");
    1686                 :         52 :                 m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
    1687                 :            : 
    1688                 :            :                 /* Third, fire things up! */
    1689                 :         52 :                 manager_coldplug(m);
    1690                 :            : 
    1691                 :            :                 /* Clean up runtime objects */
    1692                 :         52 :                 manager_vacuum(m);
    1693                 :            : 
    1694         [ -  + ]:         52 :                 if (serialization)
    1695                 :            :                         /* Let's wait for the UnitNew/JobNew messages being sent, before we notify that the
    1696                 :            :                          * reload is finished */
    1697                 :          0 :                         m->send_reloading_done = true;
    1698                 :            :         }
    1699                 :            : 
    1700                 :         52 :         manager_ready(m);
    1701                 :            : 
    1702                 :         52 :         return 0;
    1703                 :            : }
    1704                 :            : 
    1705                 :         72 : int manager_add_job(
    1706                 :            :                 Manager *m,
    1707                 :            :                 JobType type,
    1708                 :            :                 Unit *unit,
    1709                 :            :                 JobMode mode,
    1710                 :            :                 Set *affected_jobs,
    1711                 :            :                 sd_bus_error *error,
    1712                 :            :                 Job **ret) {
    1713                 :            : 
    1714                 :            :         Transaction *tr;
    1715                 :            :         int r;
    1716                 :            : 
    1717         [ -  + ]:         72 :         assert(m);
    1718         [ -  + ]:         72 :         assert(type < _JOB_TYPE_MAX);
    1719         [ -  + ]:         72 :         assert(unit);
    1720         [ -  + ]:         72 :         assert(mode < _JOB_MODE_MAX);
    1721                 :            : 
    1722   [ -  +  #  # ]:         72 :         if (mode == JOB_ISOLATE && type != JOB_START)
    1723                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Isolate is only valid for start.");
    1724                 :            : 
    1725   [ -  +  #  # ]:         72 :         if (mode == JOB_ISOLATE && !unit->allow_isolate)
    1726                 :          0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
    1727                 :            : 
    1728         [ +  - ]:         72 :         log_unit_debug(unit, "Trying to enqueue job %s/%s/%s", unit->id, job_type_to_string(type), job_mode_to_string(mode));
    1729                 :            : 
    1730                 :         72 :         type = job_type_collapse(type, unit);
    1731                 :            : 
    1732                 :         72 :         tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
    1733         [ -  + ]:         72 :         if (!tr)
    1734                 :          0 :                 return -ENOMEM;
    1735                 :            : 
    1736                 :        144 :         r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, false,
    1737         [ -  + ]:         72 :                                                  IN_SET(mode, JOB_IGNORE_DEPENDENCIES, JOB_IGNORE_REQUIREMENTS),
    1738                 :            :                                                  mode == JOB_IGNORE_DEPENDENCIES, error);
    1739         [ -  + ]:         72 :         if (r < 0)
    1740                 :          0 :                 goto tr_abort;
    1741                 :            : 
    1742         [ -  + ]:         72 :         if (mode == JOB_ISOLATE) {
    1743                 :          0 :                 r = transaction_add_isolate_jobs(tr, m);
    1744         [ #  # ]:          0 :                 if (r < 0)
    1745                 :          0 :                         goto tr_abort;
    1746                 :            :         }
    1747                 :            : 
    1748                 :         72 :         r = transaction_activate(tr, m, mode, affected_jobs, error);
    1749         [ +  + ]:         72 :         if (r < 0)
    1750                 :         16 :                 goto tr_abort;
    1751                 :            : 
    1752         [ +  - ]:         56 :         log_unit_debug(unit,
    1753                 :            :                        "Enqueued job %s/%s as %u", unit->id,
    1754                 :            :                        job_type_to_string(type), (unsigned) tr->anchor_job->id);
    1755                 :            : 
    1756         [ +  + ]:         56 :         if (ret)
    1757                 :         32 :                 *ret = tr->anchor_job;
    1758                 :            : 
    1759                 :         56 :         transaction_free(tr);
    1760                 :         56 :         return 0;
    1761                 :            : 
    1762                 :         16 : tr_abort:
    1763                 :         16 :         transaction_abort(tr);
    1764                 :         16 :         transaction_free(tr);
    1765                 :         16 :         return r;
    1766                 :            : }
    1767                 :            : 
    1768                 :          0 : int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, Set *affected_jobs, sd_bus_error *e, Job **ret) {
    1769                 :          0 :         Unit *unit = NULL;  /* just to appease gcc, initialization is not really necessary */
    1770                 :            :         int r;
    1771                 :            : 
    1772         [ #  # ]:          0 :         assert(m);
    1773         [ #  # ]:          0 :         assert(type < _JOB_TYPE_MAX);
    1774         [ #  # ]:          0 :         assert(name);
    1775         [ #  # ]:          0 :         assert(mode < _JOB_MODE_MAX);
    1776                 :            : 
    1777                 :          0 :         r = manager_load_unit(m, name, NULL, NULL, &unit);
    1778         [ #  # ]:          0 :         if (r < 0)
    1779                 :          0 :                 return r;
    1780         [ #  # ]:          0 :         assert(unit);
    1781                 :            : 
    1782                 :          0 :         return manager_add_job(m, type, unit, mode, affected_jobs, e, ret);
    1783                 :            : }
    1784                 :            : 
    1785                 :          0 : int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name, JobMode mode, Set *affected_jobs, Job **ret) {
    1786                 :          0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
    1787                 :            :         int r;
    1788                 :            : 
    1789         [ #  # ]:          0 :         assert(m);
    1790         [ #  # ]:          0 :         assert(type < _JOB_TYPE_MAX);
    1791         [ #  # ]:          0 :         assert(name);
    1792         [ #  # ]:          0 :         assert(mode < _JOB_MODE_MAX);
    1793                 :            : 
    1794                 :          0 :         r = manager_add_job_by_name(m, type, name, mode, affected_jobs, &error, ret);
    1795         [ #  # ]:          0 :         if (r < 0)
    1796         [ #  # ]:          0 :                 return log_warning_errno(r, "Failed to enqueue %s job for %s: %s", job_mode_to_string(mode), name, bus_error_message(&error, r));
    1797                 :            : 
    1798                 :          0 :         return r;
    1799                 :            : }
    1800                 :            : 
    1801                 :          0 : int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error *e) {
    1802                 :            :         int r;
    1803                 :            :         Transaction *tr;
    1804                 :            : 
    1805         [ #  # ]:          0 :         assert(m);
    1806         [ #  # ]:          0 :         assert(unit);
    1807         [ #  # ]:          0 :         assert(mode < _JOB_MODE_MAX);
    1808         [ #  # ]:          0 :         assert(mode != JOB_ISOLATE); /* Isolate is only valid for start */
    1809                 :            : 
    1810                 :          0 :         tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
    1811         [ #  # ]:          0 :         if (!tr)
    1812                 :          0 :                 return -ENOMEM;
    1813                 :            : 
    1814                 :            :         /* We need an anchor job */
    1815                 :          0 :         r = transaction_add_job_and_dependencies(tr, JOB_NOP, unit, NULL, false, false, true, true, e);
    1816         [ #  # ]:          0 :         if (r < 0)
    1817                 :          0 :                 goto tr_abort;
    1818                 :            : 
    1819                 :            :         /* Failure in adding individual dependencies is ignored, so this always succeeds. */
    1820                 :          0 :         transaction_add_propagate_reload_jobs(tr, unit, tr->anchor_job, mode == JOB_IGNORE_DEPENDENCIES, e);
    1821                 :            : 
    1822                 :          0 :         r = transaction_activate(tr, m, mode, NULL, e);
    1823         [ #  # ]:          0 :         if (r < 0)
    1824                 :          0 :                 goto tr_abort;
    1825                 :            : 
    1826                 :          0 :         transaction_free(tr);
    1827                 :          0 :         return 0;
    1828                 :            : 
    1829                 :          0 : tr_abort:
    1830                 :          0 :         transaction_abort(tr);
    1831                 :          0 :         transaction_free(tr);
    1832                 :          0 :         return r;
    1833                 :            : }
    1834                 :            : 
    1835                 :         96 : Job *manager_get_job(Manager *m, uint32_t id) {
    1836         [ -  + ]:         96 :         assert(m);
    1837                 :            : 
    1838                 :         96 :         return hashmap_get(m->jobs, UINT32_TO_PTR(id));
    1839                 :            : }
    1840                 :            : 
    1841                 :      24192 : Unit *manager_get_unit(Manager *m, const char *name) {
    1842         [ -  + ]:      24192 :         assert(m);
    1843         [ -  + ]:      24192 :         assert(name);
    1844                 :            : 
    1845                 :      24192 :         return hashmap_get(m->units, name);
    1846                 :            : }
    1847                 :            : 
    1848                 :        192 : static int manager_dispatch_target_deps_queue(Manager *m) {
    1849                 :            :         Unit *u;
    1850                 :            :         unsigned k;
    1851                 :        192 :         int r = 0;
    1852                 :            : 
    1853                 :            :         static const UnitDependency deps[] = {
    1854                 :            :                 UNIT_REQUIRED_BY,
    1855                 :            :                 UNIT_REQUISITE_OF,
    1856                 :            :                 UNIT_WANTED_BY,
    1857                 :            :                 UNIT_BOUND_BY
    1858                 :            :         };
    1859                 :            : 
    1860         [ -  + ]:        192 :         assert(m);
    1861                 :            : 
    1862         [ +  + ]:       7452 :         while ((u = m->target_deps_queue)) {
    1863         [ -  + ]:       7260 :                 assert(u->in_target_deps_queue);
    1864                 :            : 
    1865   [ -  +  +  +  :       7260 :                 LIST_REMOVE(target_deps_queue, u->manager->target_deps_queue, u);
             -  +  -  + ]
    1866                 :       7260 :                 u->in_target_deps_queue = false;
    1867                 :            : 
    1868         [ +  + ]:      36300 :                 for (k = 0; k < ELEMENTSOF(deps); k++) {
    1869                 :            :                         Unit *target;
    1870                 :            :                         Iterator i;
    1871                 :            :                         void *v;
    1872                 :            : 
    1873         [ +  + ]:      30308 :                         HASHMAP_FOREACH_KEY(v, target, u->dependencies[deps[k]], i) {
    1874                 :       1268 :                                 r = unit_add_default_target_dependency(u, target);
    1875         [ -  + ]:       1268 :                                 if (r < 0)
    1876                 :          0 :                                         return r;
    1877                 :            :                         }
    1878                 :            :                 }
    1879                 :            :         }
    1880                 :            : 
    1881                 :        192 :         return r;
    1882                 :            : }
    1883                 :            : 
    1884                 :        716 : unsigned manager_dispatch_load_queue(Manager *m) {
    1885                 :            :         Unit *u;
    1886                 :        716 :         unsigned n = 0;
    1887                 :            : 
    1888         [ -  + ]:        716 :         assert(m);
    1889                 :            : 
    1890                 :            :         /* Make sure we are not run recursively */
    1891         [ +  + ]:        716 :         if (m->dispatching_load_queue)
    1892                 :        524 :                 return 0;
    1893                 :            : 
    1894                 :        192 :         m->dispatching_load_queue = true;
    1895                 :            : 
    1896                 :            :         /* Dispatches the load queue. Takes a unit from the queue and
    1897                 :            :          * tries to load its data until the queue is empty */
    1898                 :            : 
    1899         [ +  + ]:       8900 :         while ((u = m->load_queue)) {
    1900         [ -  + ]:       8708 :                 assert(u->in_load_queue);
    1901                 :            : 
    1902                 :       8708 :                 unit_load(u);
    1903                 :       8708 :                 n++;
    1904                 :            :         }
    1905                 :            : 
    1906                 :        192 :         m->dispatching_load_queue = false;
    1907                 :            : 
    1908                 :            :         /* Dispatch the units waiting for their target dependencies to be added now, as all targets that we know about
    1909                 :            :          * should be loaded and have aliases resolved */
    1910                 :        192 :         (void) manager_dispatch_target_deps_queue(m);
    1911                 :            : 
    1912                 :        192 :         return n;
    1913                 :            : }
    1914                 :            : 
    1915                 :       4112 : int manager_load_unit_prepare(
    1916                 :            :                 Manager *m,
    1917                 :            :                 const char *name,
    1918                 :            :                 const char *path,
    1919                 :            :                 sd_bus_error *e,
    1920                 :            :                 Unit **_ret) {
    1921                 :            : 
    1922                 :       4112 :         _cleanup_(unit_freep) Unit *cleanup_ret = NULL;
    1923                 :            :         Unit *ret;
    1924                 :            :         UnitType t;
    1925                 :            :         int r;
    1926                 :            : 
    1927         [ -  + ]:       4112 :         assert(m);
    1928   [ -  +  #  # ]:       4112 :         assert(name || path);
    1929         [ -  + ]:       4112 :         assert(_ret);
    1930                 :            : 
    1931                 :            :         /* This will prepare the unit for loading, but not actually
    1932                 :            :          * load anything from disk. */
    1933                 :            : 
    1934   [ -  +  #  # ]:       4112 :         if (path && !is_path(path))
    1935                 :          0 :                 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
    1936                 :            : 
    1937         [ -  + ]:       4112 :         if (!name)
    1938                 :          0 :                 name = basename(path);
    1939                 :            : 
    1940                 :       4112 :         t = unit_name_to_type(name);
    1941                 :            : 
    1942   [ +  -  -  + ]:       4112 :         if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) {
    1943         [ #  # ]:          0 :                 if (unit_name_is_valid(name, UNIT_NAME_TEMPLATE))
    1944                 :          0 :                         return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is missing the instance name.", name);
    1945                 :            : 
    1946                 :          0 :                 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is not valid.", name);
    1947                 :            :         }
    1948                 :            : 
    1949                 :       4112 :         ret = manager_get_unit(m, name);
    1950         [ +  + ]:       4112 :         if (ret) {
    1951                 :       2312 :                 *_ret = ret;
    1952                 :       2312 :                 return 1;
    1953                 :            :         }
    1954                 :            : 
    1955                 :       1800 :         ret = cleanup_ret = unit_new(m, unit_vtable[t]->object_size);
    1956         [ -  + ]:       1800 :         if (!ret)
    1957                 :          0 :                 return -ENOMEM;
    1958                 :            : 
    1959         [ -  + ]:       1800 :         if (path) {
    1960                 :          0 :                 ret->fragment_path = strdup(path);
    1961         [ #  # ]:          0 :                 if (!ret->fragment_path)
    1962                 :          0 :                         return -ENOMEM;
    1963                 :            :         }
    1964                 :            : 
    1965                 :       1800 :         r = unit_add_name(ret, name);
    1966         [ -  + ]:       1800 :         if (r < 0)
    1967                 :          0 :                 return r;
    1968                 :            : 
    1969                 :       1800 :         unit_add_to_load_queue(ret);
    1970                 :       1800 :         unit_add_to_dbus_queue(ret);
    1971                 :       1800 :         unit_add_to_gc_queue(ret);
    1972                 :            : 
    1973                 :       1800 :         *_ret = ret;
    1974                 :       1800 :         cleanup_ret = NULL;
    1975                 :            : 
    1976                 :       1800 :         return 0;
    1977                 :            : }
    1978                 :            : 
    1979                 :       2984 : int manager_load_unit(
    1980                 :            :                 Manager *m,
    1981                 :            :                 const char *name,
    1982                 :            :                 const char *path,
    1983                 :            :                 sd_bus_error *e,
    1984                 :            :                 Unit **_ret) {
    1985                 :            : 
    1986                 :            :         int r;
    1987                 :            : 
    1988         [ -  + ]:       2984 :         assert(m);
    1989         [ -  + ]:       2984 :         assert(_ret);
    1990                 :            : 
    1991                 :            :         /* This will load the service information files, but not actually
    1992                 :            :          * start any services or anything. */
    1993                 :            : 
    1994                 :       2984 :         r = manager_load_unit_prepare(m, name, path, e, _ret);
    1995         [ +  + ]:       2984 :         if (r != 0)
    1996                 :       2312 :                 return r;
    1997                 :            : 
    1998                 :        672 :         manager_dispatch_load_queue(m);
    1999                 :            : 
    2000                 :        672 :         *_ret = unit_follow_merge(*_ret);
    2001                 :        672 :         return 0;
    2002                 :            : }
    2003                 :            : 
    2004                 :        152 : int manager_load_startable_unit_or_warn(
    2005                 :            :                 Manager *m,
    2006                 :            :                 const char *name,
    2007                 :            :                 const char *path,
    2008                 :            :                 Unit **ret) {
    2009                 :            : 
    2010                 :            :         /* Load a unit, make sure it loaded fully and is not masked. */
    2011                 :            : 
    2012                 :        152 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
    2013                 :            :         Unit *unit;
    2014                 :            :         int r;
    2015                 :            : 
    2016                 :        152 :         r = manager_load_unit(m, name, path, &error, &unit);
    2017         [ -  + ]:        152 :         if (r < 0)
    2018   [ #  #  #  #  :          0 :                 return log_error_errno(r, "Failed to load %s %s: %s",
                   #  # ]
    2019                 :            :                                        name ? "unit" : "unit file", name ?: path,
    2020                 :            :                                        bus_error_message(&error, r));
    2021                 :            : 
    2022                 :        152 :         r = bus_unit_validate_load_state(unit, &error);
    2023         [ -  + ]:        152 :         if (r < 0)
    2024         [ #  # ]:          0 :                 return log_error_errno(r, "%s", bus_error_message(&error, r));
    2025                 :            : 
    2026                 :        152 :         *ret = unit;
    2027                 :        152 :         return 0;
    2028                 :            : }
    2029                 :            : 
    2030                 :         40 : void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
    2031                 :            :         Iterator i;
    2032                 :            :         Job *j;
    2033                 :            : 
    2034         [ -  + ]:         40 :         assert(s);
    2035         [ -  + ]:         40 :         assert(f);
    2036                 :            : 
    2037         [ +  + ]:        248 :         HASHMAP_FOREACH(j, s->jobs, i)
    2038                 :        208 :                 job_dump(j, f, prefix);
    2039                 :         40 : }
    2040                 :            : 
    2041                 :         24 : void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
    2042                 :            :         Iterator i;
    2043                 :            :         Unit *u;
    2044                 :            :         const char *t;
    2045                 :            : 
    2046         [ -  + ]:         24 :         assert(s);
    2047         [ -  + ]:         24 :         assert(f);
    2048                 :            : 
    2049         [ +  + ]:       4832 :         HASHMAP_FOREACH_KEY(u, t, s->units, i)
    2050         [ +  - ]:       4808 :                 if (u->id == t)
    2051                 :       4808 :                         unit_dump(u, f, prefix);
    2052                 :         24 : }
    2053                 :            : 
    2054                 :          0 : void manager_dump(Manager *m, FILE *f, const char *prefix) {
    2055                 :            :         ManagerTimestamp q;
    2056                 :            : 
    2057         [ #  # ]:          0 :         assert(m);
    2058         [ #  # ]:          0 :         assert(f);
    2059                 :            : 
    2060         [ #  # ]:          0 :         for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
    2061                 :          0 :                 const dual_timestamp *t = m->timestamps + q;
    2062                 :            :                 char buf[CONST_MAX(FORMAT_TIMESPAN_MAX, FORMAT_TIMESTAMP_MAX)];
    2063                 :            : 
    2064         [ #  # ]:          0 :                 if (dual_timestamp_is_set(t))
    2065         [ #  # ]:          0 :                         fprintf(f, "%sTimestamp %s: %s\n",
    2066                 :            :                                 strempty(prefix),
    2067                 :            :                                 manager_timestamp_to_string(q),
    2068                 :          0 :                                 timestamp_is_set(t->realtime) ? format_timestamp(buf, sizeof buf, t->realtime) :
    2069                 :          0 :                                                                 format_timespan(buf, sizeof buf, t->monotonic, 1));
    2070                 :            :         }
    2071                 :            : 
    2072                 :          0 :         manager_dump_units(m, f, prefix);
    2073                 :          0 :         manager_dump_jobs(m, f, prefix);
    2074                 :          0 : }
    2075                 :            : 
    2076                 :          0 : int manager_get_dump_string(Manager *m, char **ret) {
    2077                 :          0 :         _cleanup_free_ char *dump = NULL;
    2078                 :          0 :         _cleanup_fclose_ FILE *f = NULL;
    2079                 :            :         size_t size;
    2080                 :            :         int r;
    2081                 :            : 
    2082         [ #  # ]:          0 :         assert(m);
    2083         [ #  # ]:          0 :         assert(ret);
    2084                 :            : 
    2085                 :          0 :         f = open_memstream_unlocked(&dump, &size);
    2086         [ #  # ]:          0 :         if (!f)
    2087                 :          0 :                 return -errno;
    2088                 :            : 
    2089                 :          0 :         manager_dump(m, f, NULL);
    2090                 :            : 
    2091                 :          0 :         r = fflush_and_check(f);
    2092         [ #  # ]:          0 :         if (r < 0)
    2093                 :          0 :                 return r;
    2094                 :            : 
    2095                 :          0 :         f = safe_fclose(f);
    2096                 :            : 
    2097                 :          0 :         *ret = TAKE_PTR(dump);
    2098                 :            : 
    2099                 :          0 :         return 0;
    2100                 :            : }
    2101                 :            : 
    2102                 :         12 : void manager_clear_jobs(Manager *m) {
    2103                 :            :         Job *j;
    2104                 :            : 
    2105         [ -  + ]:         12 :         assert(m);
    2106                 :            : 
    2107         [ +  + ]:        108 :         while ((j = hashmap_first(m->jobs)))
    2108                 :            :                 /* No need to recurse. We're cancelling all jobs. */
    2109                 :         96 :                 job_finish_and_invalidate(j, JOB_CANCELED, false, false);
    2110                 :         12 : }
    2111                 :            : 
    2112                 :         24 : void manager_unwatch_pid(Manager *m, pid_t pid) {
    2113         [ -  + ]:         24 :         assert(m);
    2114                 :            : 
    2115                 :            :         /* First let's drop the unit keyed as "pid". */
    2116                 :         24 :         (void) hashmap_remove(m->watch_pids, PID_TO_PTR(pid));
    2117                 :            : 
    2118                 :            :         /* Then, let's also drop the array keyed by -pid. */
    2119                 :         24 :         free(hashmap_remove(m->watch_pids, PID_TO_PTR(-pid)));
    2120                 :         24 : }
    2121                 :            : 
    2122                 :         24 : static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) {
    2123                 :         24 :         Manager *m = userdata;
    2124                 :            :         Job *j;
    2125                 :            : 
    2126         [ -  + ]:         24 :         assert(source);
    2127         [ -  + ]:         24 :         assert(m);
    2128                 :            : 
    2129         [ +  + ]:        168 :         while ((j = prioq_peek(m->run_queue))) {
    2130         [ -  + ]:        144 :                 assert(j->installed);
    2131         [ -  + ]:        144 :                 assert(j->in_run_queue);
    2132                 :            : 
    2133                 :        144 :                 (void) job_run_and_invalidate(j);
    2134                 :            :         }
    2135                 :            : 
    2136         [ +  - ]:         24 :         if (m->n_running_jobs > 0)
    2137                 :         24 :                 manager_watch_jobs_in_progress(m);
    2138                 :            : 
    2139         [ -  + ]:         24 :         if (m->n_on_console > 0)
    2140                 :          0 :                 manager_watch_idle_pipe(m);
    2141                 :            : 
    2142                 :         24 :         return 1;
    2143                 :            : }
    2144                 :            : 
    2145                 :          0 : static unsigned manager_dispatch_dbus_queue(Manager *m) {
    2146                 :          0 :         unsigned n = 0, budget;
    2147                 :            :         Unit *u;
    2148                 :            :         Job *j;
    2149                 :            : 
    2150         [ #  # ]:          0 :         assert(m);
    2151                 :            : 
    2152                 :            :         /* When we are reloading, let's not wait with generating signals, since we need to exit the manager as quickly
    2153                 :            :          * as we can. There's no point in throttling generation of signals in that case. */
    2154   [ #  #  #  #  :          0 :         if (MANAGER_IS_RELOADING(m) || m->send_reloading_done || m->pending_reload_message)
                   #  # ]
    2155                 :          0 :                 budget = (unsigned) -1; /* infinite budget in this case */
    2156                 :            :         else {
    2157                 :            :                 /* Anything to do at all? */
    2158   [ #  #  #  # ]:          0 :                 if (!m->dbus_unit_queue && !m->dbus_job_queue)
    2159                 :          0 :                         return 0;
    2160                 :            : 
    2161                 :            :                 /* Do we have overly many messages queued at the moment? If so, let's not enqueue more on top, let's
    2162                 :            :                  * sit this cycle out, and process things in a later cycle when the queues got a bit emptier. */
    2163         [ #  # ]:          0 :                 if (manager_bus_n_queued_write(m) > MANAGER_BUS_BUSY_THRESHOLD)
    2164                 :          0 :                         return 0;
    2165                 :            : 
    2166                 :            :                 /* Only process a certain number of units/jobs per event loop iteration. Even if the bus queue wasn't
    2167                 :            :                  * overly full before this call we shouldn't increase it in size too wildly in one step, and we
    2168                 :            :                  * shouldn't monopolize CPU time with generating these messages. Note the difference in counting of
    2169                 :            :                  * this "budget" and the "threshold" above: the "budget" is decreased only once per generated message,
    2170                 :            :                  * regardless how many buses/direct connections it is enqueued on, while the "threshold" is applied to
    2171                 :            :                  * each queued instance of bus message, i.e. if the same message is enqueued to five buses/direct
    2172                 :            :                  * connections it will be counted five times. This difference in counting ("references"
    2173                 :            :                  * vs. "instances") is primarily a result of the fact that it's easier to implement it this way,
    2174                 :            :                  * however it also reflects the thinking that the "threshold" should put a limit on used queue memory,
    2175                 :            :                  * i.e. space, while the "budget" should put a limit on time. Also note that the "threshold" is
    2176                 :            :                  * currently chosen much higher than the "budget". */
    2177                 :          0 :                 budget = MANAGER_BUS_MESSAGE_BUDGET;
    2178                 :            :         }
    2179                 :            : 
    2180   [ #  #  #  # ]:          0 :         while (budget != 0 && (u = m->dbus_unit_queue)) {
    2181                 :            : 
    2182         [ #  # ]:          0 :                 assert(u->in_dbus_queue);
    2183                 :            : 
    2184                 :          0 :                 bus_unit_send_change_signal(u);
    2185                 :          0 :                 n++;
    2186                 :            : 
    2187         [ #  # ]:          0 :                 if (budget != (unsigned) -1)
    2188                 :          0 :                         budget--;
    2189                 :            :         }
    2190                 :            : 
    2191   [ #  #  #  # ]:          0 :         while (budget != 0 && (j = m->dbus_job_queue)) {
    2192         [ #  # ]:          0 :                 assert(j->in_dbus_queue);
    2193                 :            : 
    2194                 :          0 :                 bus_job_send_change_signal(j);
    2195                 :          0 :                 n++;
    2196                 :            : 
    2197         [ #  # ]:          0 :                 if (budget != (unsigned) -1)
    2198                 :          0 :                         budget--;
    2199                 :            :         }
    2200                 :            : 
    2201         [ #  # ]:          0 :         if (m->send_reloading_done) {
    2202                 :          0 :                 m->send_reloading_done = false;
    2203                 :          0 :                 bus_manager_send_reloading(m, false);
    2204                 :          0 :                 n++;
    2205                 :            :         }
    2206                 :            : 
    2207         [ #  # ]:          0 :         if (m->pending_reload_message) {
    2208                 :          0 :                 bus_send_pending_reload_message(m);
    2209                 :          0 :                 n++;
    2210                 :            :         }
    2211                 :            : 
    2212                 :          0 :         return n;
    2213                 :            : }
    2214                 :            : 
    2215                 :          0 : static int manager_dispatch_cgroups_agent_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
    2216                 :          0 :         Manager *m = userdata;
    2217                 :            :         char buf[PATH_MAX];
    2218                 :            :         ssize_t n;
    2219                 :            : 
    2220                 :          0 :         n = recv(fd, buf, sizeof(buf), 0);
    2221         [ #  # ]:          0 :         if (n < 0)
    2222         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to read cgroups agent message: %m");
    2223         [ #  # ]:          0 :         if (n == 0) {
    2224         [ #  # ]:          0 :                 log_error("Got zero-length cgroups agent message, ignoring.");
    2225                 :          0 :                 return 0;
    2226                 :            :         }
    2227         [ #  # ]:          0 :         if ((size_t) n >= sizeof(buf)) {
    2228         [ #  # ]:          0 :                 log_error("Got overly long cgroups agent message, ignoring.");
    2229                 :          0 :                 return 0;
    2230                 :            :         }
    2231                 :            : 
    2232         [ #  # ]:          0 :         if (memchr(buf, 0, n)) {
    2233         [ #  # ]:          0 :                 log_error("Got cgroups agent message with embedded NUL byte, ignoring.");
    2234                 :          0 :                 return 0;
    2235                 :            :         }
    2236                 :          0 :         buf[n] = 0;
    2237                 :            : 
    2238                 :          0 :         manager_notify_cgroup_empty(m, buf);
    2239                 :          0 :         (void) bus_forward_agent_released(m, buf);
    2240                 :            : 
    2241                 :          0 :         return 0;
    2242                 :            : }
    2243                 :            : 
    2244                 :          0 : static void manager_invoke_notify_message(
    2245                 :            :                 Manager *m,
    2246                 :            :                 Unit *u,
    2247                 :            :                 const struct ucred *ucred,
    2248                 :            :                 const char *buf,
    2249                 :            :                 FDSet *fds) {
    2250                 :            : 
    2251         [ #  # ]:          0 :         assert(m);
    2252         [ #  # ]:          0 :         assert(u);
    2253         [ #  # ]:          0 :         assert(ucred);
    2254         [ #  # ]:          0 :         assert(buf);
    2255                 :            : 
    2256         [ #  # ]:          0 :         if (u->notifygen == m->notifygen) /* Already invoked on this same unit in this same iteration? */
    2257                 :          0 :                 return;
    2258                 :          0 :         u->notifygen = m->notifygen;
    2259                 :            : 
    2260         [ #  # ]:          0 :         if (UNIT_VTABLE(u)->notify_message) {
    2261         [ #  # ]:          0 :                 _cleanup_strv_free_ char **tags = NULL;
    2262                 :            : 
    2263                 :          0 :                 tags = strv_split(buf, NEWLINE);
    2264         [ #  # ]:          0 :                 if (!tags) {
    2265                 :          0 :                         log_oom();
    2266                 :          0 :                         return;
    2267                 :            :                 }
    2268                 :            : 
    2269                 :          0 :                 UNIT_VTABLE(u)->notify_message(u, ucred, tags, fds);
    2270                 :            : 
    2271         [ #  # ]:          0 :         } else if (DEBUG_LOGGING) {
    2272                 :          0 :                 _cleanup_free_ char *x = NULL, *y = NULL;
    2273                 :            : 
    2274                 :          0 :                 x = ellipsize(buf, 20, 90);
    2275         [ #  # ]:          0 :                 if (x)
    2276                 :          0 :                         y = cescape(x);
    2277                 :            : 
    2278         [ #  # ]:          0 :                 log_unit_debug(u, "Got notification message \"%s\", ignoring.", strnull(y));
    2279                 :            :         }
    2280                 :            : }
    2281                 :            : 
    2282                 :          0 : static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
    2283                 :            : 
    2284                 :          0 :         _cleanup_fdset_free_ FDSet *fds = NULL;
    2285                 :          0 :         Manager *m = userdata;
    2286                 :            :         char buf[NOTIFY_BUFFER_MAX+1];
    2287                 :          0 :         struct iovec iovec = {
    2288                 :            :                 .iov_base = buf,
    2289                 :            :                 .iov_len = sizeof(buf)-1,
    2290                 :            :         };
    2291                 :            :         union {
    2292                 :            :                 struct cmsghdr cmsghdr;
    2293                 :            :                 uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
    2294                 :            :                             CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)];
    2295                 :          0 :         } control = {};
    2296                 :          0 :         struct msghdr msghdr = {
    2297                 :            :                 .msg_iov = &iovec,
    2298                 :            :                 .msg_iovlen = 1,
    2299                 :            :                 .msg_control = &control,
    2300                 :            :                 .msg_controllen = sizeof(control),
    2301                 :            :         };
    2302                 :            : 
    2303                 :            :         struct cmsghdr *cmsg;
    2304                 :          0 :         struct ucred *ucred = NULL;
    2305                 :          0 :         _cleanup_free_ Unit **array_copy = NULL;
    2306                 :            :         Unit *u1, *u2, **array;
    2307                 :          0 :         int r, *fd_array = NULL;
    2308                 :          0 :         size_t n_fds = 0;
    2309                 :          0 :         bool found = false;
    2310                 :            :         ssize_t n;
    2311                 :            : 
    2312         [ #  # ]:          0 :         assert(m);
    2313         [ #  # ]:          0 :         assert(m->notify_fd == fd);
    2314                 :            : 
    2315         [ #  # ]:          0 :         if (revents != EPOLLIN) {
    2316         [ #  # ]:          0 :                 log_warning("Got unexpected poll event for notify fd.");
    2317                 :          0 :                 return 0;
    2318                 :            :         }
    2319                 :            : 
    2320                 :          0 :         n = recvmsg(m->notify_fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC|MSG_TRUNC);
    2321         [ #  # ]:          0 :         if (n < 0) {
    2322   [ #  #  #  # ]:          0 :                 if (IN_SET(errno, EAGAIN, EINTR))
    2323                 :          0 :                         return 0; /* Spurious wakeup, try again */
    2324                 :            : 
    2325                 :            :                 /* If this is any other, real error, then let's stop processing this socket. This of course means we
    2326                 :            :                  * won't take notification messages anymore, but that's still better than busy looping around this:
    2327                 :            :                  * being woken up over and over again but being unable to actually read the message off the socket. */
    2328         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to receive notification message: %m");
    2329                 :            :         }
    2330                 :            : 
    2331   [ #  #  #  # ]:          0 :         CMSG_FOREACH(cmsg, &msghdr) {
    2332   [ #  #  #  # ]:          0 :                 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
    2333                 :            : 
    2334                 :          0 :                         fd_array = (int*) CMSG_DATA(cmsg);
    2335                 :          0 :                         n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
    2336                 :            : 
    2337         [ #  # ]:          0 :                 } else if (cmsg->cmsg_level == SOL_SOCKET &&
    2338         [ #  # ]:          0 :                            cmsg->cmsg_type == SCM_CREDENTIALS &&
    2339         [ #  # ]:          0 :                            cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
    2340                 :            : 
    2341                 :          0 :                         ucred = (struct ucred*) CMSG_DATA(cmsg);
    2342                 :            :                 }
    2343                 :            :         }
    2344                 :            : 
    2345         [ #  # ]:          0 :         if (n_fds > 0) {
    2346         [ #  # ]:          0 :                 assert(fd_array);
    2347                 :            : 
    2348                 :          0 :                 r = fdset_new_array(&fds, fd_array, n_fds);
    2349         [ #  # ]:          0 :                 if (r < 0) {
    2350                 :          0 :                         close_many(fd_array, n_fds);
    2351                 :          0 :                         log_oom();
    2352                 :          0 :                         return 0;
    2353                 :            :                 }
    2354                 :            :         }
    2355                 :            : 
    2356   [ #  #  #  # ]:          0 :         if (!ucred || !pid_is_valid(ucred->pid)) {
    2357         [ #  # ]:          0 :                 log_warning("Received notify message without valid credentials. Ignoring.");
    2358                 :          0 :                 return 0;
    2359                 :            :         }
    2360                 :            : 
    2361   [ #  #  #  # ]:          0 :         if ((size_t) n >= sizeof(buf) || (msghdr.msg_flags & MSG_TRUNC)) {
    2362         [ #  # ]:          0 :                 log_warning("Received notify message exceeded maximum size. Ignoring.");
    2363                 :          0 :                 return 0;
    2364                 :            :         }
    2365                 :            : 
    2366                 :            :         /* As extra safety check, let's make sure the string we get doesn't contain embedded NUL bytes. We permit one
    2367                 :            :          * trailing NUL byte in the message, but don't expect it. */
    2368   [ #  #  #  # ]:          0 :         if (n > 1 && memchr(buf, 0, n-1)) {
    2369         [ #  # ]:          0 :                 log_warning("Received notify message with embedded NUL bytes. Ignoring.");
    2370                 :          0 :                 return 0;
    2371                 :            :         }
    2372                 :            : 
    2373                 :            :         /* Make sure it's NUL-terminated. */
    2374                 :          0 :         buf[n] = 0;
    2375                 :            : 
    2376                 :            :         /* Increase the generation counter used for filtering out duplicate unit invocations. */
    2377                 :          0 :         m->notifygen++;
    2378                 :            : 
    2379                 :            :         /* Notify every unit that might be interested, which might be multiple. */
    2380                 :          0 :         u1 = manager_get_unit_by_pid_cgroup(m, ucred->pid);
    2381                 :          0 :         u2 = hashmap_get(m->watch_pids, PID_TO_PTR(ucred->pid));
    2382                 :          0 :         array = hashmap_get(m->watch_pids, PID_TO_PTR(-ucred->pid));
    2383         [ #  # ]:          0 :         if (array) {
    2384                 :          0 :                 size_t k = 0;
    2385                 :            : 
    2386         [ #  # ]:          0 :                 while (array[k])
    2387                 :          0 :                         k++;
    2388                 :            : 
    2389                 :          0 :                 array_copy = newdup(Unit*, array, k+1);
    2390         [ #  # ]:          0 :                 if (!array_copy)
    2391                 :          0 :                         log_oom();
    2392                 :            :         }
    2393                 :            :         /* And now invoke the per-unit callbacks. Note that manager_invoke_notify_message() will handle duplicate units
    2394                 :            :          * make sure we only invoke each unit's handler once. */
    2395         [ #  # ]:          0 :         if (u1) {
    2396                 :          0 :                 manager_invoke_notify_message(m, u1, ucred, buf, fds);
    2397                 :          0 :                 found = true;
    2398                 :            :         }
    2399         [ #  # ]:          0 :         if (u2) {
    2400                 :          0 :                 manager_invoke_notify_message(m, u2, ucred, buf, fds);
    2401                 :          0 :                 found = true;
    2402                 :            :         }
    2403         [ #  # ]:          0 :         if (array_copy)
    2404         [ #  # ]:          0 :                 for (size_t i = 0; array_copy[i]; i++) {
    2405                 :          0 :                         manager_invoke_notify_message(m, array_copy[i], ucred, buf, fds);
    2406                 :          0 :                         found = true;
    2407                 :            :                 }
    2408                 :            : 
    2409         [ #  # ]:          0 :         if (!found)
    2410         [ #  # ]:          0 :                 log_warning("Cannot find unit for notify message of PID "PID_FMT", ignoring.", ucred->pid);
    2411                 :            : 
    2412         [ #  # ]:          0 :         if (fdset_size(fds) > 0)
    2413         [ #  # ]:          0 :                 log_warning("Got extra auxiliary fds with notification message, closing them.");
    2414                 :            : 
    2415                 :          0 :         return 0;
    2416                 :            : }
    2417                 :            : 
    2418                 :          0 : static void manager_invoke_sigchld_event(
    2419                 :            :                 Manager *m,
    2420                 :            :                 Unit *u,
    2421                 :            :                 const siginfo_t *si) {
    2422                 :            : 
    2423         [ #  # ]:          0 :         assert(m);
    2424         [ #  # ]:          0 :         assert(u);
    2425         [ #  # ]:          0 :         assert(si);
    2426                 :            : 
    2427                 :            :         /* Already invoked the handler of this unit in this iteration? Then don't process this again */
    2428         [ #  # ]:          0 :         if (u->sigchldgen == m->sigchldgen)
    2429                 :          0 :                 return;
    2430                 :          0 :         u->sigchldgen = m->sigchldgen;
    2431                 :            : 
    2432         [ #  # ]:          0 :         log_unit_debug(u, "Child "PID_FMT" belongs to %s.", si->si_pid, u->id);
    2433                 :          0 :         unit_unwatch_pid(u, si->si_pid);
    2434                 :            : 
    2435         [ #  # ]:          0 :         if (UNIT_VTABLE(u)->sigchld_event)
    2436                 :          0 :                 UNIT_VTABLE(u)->sigchld_event(u, si->si_pid, si->si_code, si->si_status);
    2437                 :            : }
    2438                 :            : 
    2439                 :         11 : static int manager_dispatch_sigchld(sd_event_source *source, void *userdata) {
    2440                 :         11 :         Manager *m = userdata;
    2441                 :         11 :         siginfo_t si = {};
    2442                 :            :         int r;
    2443                 :            : 
    2444         [ -  + ]:         11 :         assert(source);
    2445         [ -  + ]:         11 :         assert(m);
    2446                 :            : 
    2447                 :            :         /* First we call waitid() for a PID and do not reap the zombie. That way we can still access /proc/$PID for it
    2448                 :            :          * while it is a zombie. */
    2449                 :            : 
    2450         [ +  + ]:         11 :         if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
    2451                 :            : 
    2452         [ -  + ]:          3 :                 if (errno != ECHILD)
    2453         [ #  # ]:          0 :                         log_error_errno(errno, "Failed to peek for child with waitid(), ignoring: %m");
    2454                 :            : 
    2455                 :          3 :                 goto turn_off;
    2456                 :            :         }
    2457                 :            : 
    2458         [ -  + ]:          8 :         if (si.si_pid <= 0)
    2459                 :          0 :                 goto turn_off;
    2460                 :            : 
    2461   [ +  -  +  - ]:          8 :         if (IN_SET(si.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED)) {
    2462                 :          8 :                 _cleanup_free_ Unit **array_copy = NULL;
    2463                 :          8 :                 _cleanup_free_ char *name = NULL;
    2464                 :            :                 Unit *u1, *u2, **array;
    2465                 :            : 
    2466                 :          8 :                 (void) get_process_comm(si.si_pid, &name);
    2467                 :            : 
    2468   [ -  +  #  # ]:          8 :                 log_debug("Child "PID_FMT" (%s) died (code=%s, status=%i/%s)",
    2469                 :            :                           si.si_pid, strna(name),
    2470                 :            :                           sigchld_code_to_string(si.si_code),
    2471                 :            :                           si.si_status,
    2472                 :            :                           strna(si.si_code == CLD_EXITED
    2473                 :            :                                 ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL)
    2474                 :            :                                 : signal_to_string(si.si_status)));
    2475                 :            : 
    2476                 :            :                 /* Increase the generation counter used for filtering out duplicate unit invocations */
    2477                 :          8 :                 m->sigchldgen++;
    2478                 :            : 
    2479                 :            :                 /* And now figure out the unit this belongs to, it might be multiple... */
    2480                 :          8 :                 u1 = manager_get_unit_by_pid_cgroup(m, si.si_pid);
    2481                 :          8 :                 u2 = hashmap_get(m->watch_pids, PID_TO_PTR(si.si_pid));
    2482                 :          8 :                 array = hashmap_get(m->watch_pids, PID_TO_PTR(-si.si_pid));
    2483         [ -  + ]:          8 :                 if (array) {
    2484                 :          0 :                         size_t n = 0;
    2485                 :            : 
    2486                 :            :                         /* Count how many entries the array has */
    2487         [ #  # ]:          0 :                         while (array[n])
    2488                 :          0 :                                 n++;
    2489                 :            : 
    2490                 :            :                         /* Make a copy of the array so that we don't trip up on the array changing beneath us */
    2491                 :          0 :                         array_copy = newdup(Unit*, array, n+1);
    2492         [ #  # ]:          0 :                         if (!array_copy)
    2493                 :          0 :                                 log_oom();
    2494                 :            :                 }
    2495                 :            : 
    2496                 :            :                 /* Finally, execute them all. Note that u1, u2 and the array might contain duplicates, but
    2497                 :            :                  * that's fine, manager_invoke_sigchld_event() will ensure we only invoke the handlers once for
    2498                 :            :                  * each iteration. */
    2499         [ -  + ]:          8 :                 if (u1) {
    2500                 :            :                         /* We check for oom condition, in case we got SIGCHLD before the oom notification.
    2501                 :            :                          * We only do this for the cgroup the PID belonged to. */
    2502                 :          0 :                         (void) unit_check_oom(u1);
    2503                 :            : 
    2504                 :          0 :                         manager_invoke_sigchld_event(m, u1, &si);
    2505                 :            :                 }
    2506         [ -  + ]:          8 :                 if (u2)
    2507                 :          0 :                         manager_invoke_sigchld_event(m, u2, &si);
    2508         [ -  + ]:          8 :                 if (array_copy)
    2509         [ #  # ]:          0 :                         for (size_t i = 0; array_copy[i]; i++)
    2510                 :          0 :                                 manager_invoke_sigchld_event(m, array_copy[i], &si);
    2511                 :            :         }
    2512                 :            : 
    2513                 :            :         /* And now, we actually reap the zombie. */
    2514         [ -  + ]:          8 :         if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
    2515         [ #  # ]:          0 :                 log_error_errno(errno, "Failed to dequeue child, ignoring: %m");
    2516                 :          0 :                 return 0;
    2517                 :            :         }
    2518                 :            : 
    2519                 :          8 :         return 0;
    2520                 :            : 
    2521                 :          3 : turn_off:
    2522                 :            :         /* All children processed for now, turn off event source */
    2523                 :            : 
    2524                 :          3 :         r = sd_event_source_set_enabled(m->sigchld_event_source, SD_EVENT_OFF);
    2525         [ -  + ]:          3 :         if (r < 0)
    2526         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to disable SIGCHLD event source: %m");
    2527                 :            : 
    2528                 :          3 :         return 0;
    2529                 :            : }
    2530                 :            : 
    2531                 :          0 : static void manager_start_target(Manager *m, const char *name, JobMode mode) {
    2532                 :          0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
    2533                 :            :         int r;
    2534                 :            : 
    2535         [ #  # ]:          0 :         log_debug("Activating special unit %s", name);
    2536                 :            : 
    2537                 :          0 :         r = manager_add_job_by_name(m, JOB_START, name, mode, NULL, &error, NULL);
    2538         [ #  # ]:          0 :         if (r < 0)
    2539         [ #  # ]:          0 :                 log_error("Failed to enqueue %s job: %s", name, bus_error_message(&error, r));
    2540                 :          0 : }
    2541                 :            : 
    2542                 :          0 : static void manager_handle_ctrl_alt_del(Manager *m) {
    2543                 :            :         /* If the user presses C-A-D more than
    2544                 :            :          * 7 times within 2s, we reboot/shutdown immediately,
    2545                 :            :          * unless it was disabled in system.conf */
    2546                 :            : 
    2547   [ #  #  #  # ]:          0 :         if (ratelimit_below(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == EMERGENCY_ACTION_NONE)
    2548                 :          0 :                 manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
    2549                 :            :         else
    2550                 :          0 :                 emergency_action(m, m->cad_burst_action, EMERGENCY_ACTION_WARN, NULL, -1,
    2551                 :            :                                 "Ctrl-Alt-Del was pressed more than 7 times within 2s");
    2552                 :          0 : }
    2553                 :            : 
    2554                 :          3 : static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
    2555                 :          3 :         Manager *m = userdata;
    2556                 :            :         ssize_t n;
    2557                 :            :         struct signalfd_siginfo sfsi;
    2558                 :            :         int r;
    2559                 :            : 
    2560         [ -  + ]:          3 :         assert(m);
    2561         [ -  + ]:          3 :         assert(m->signal_fd == fd);
    2562                 :            : 
    2563         [ -  + ]:          3 :         if (revents != EPOLLIN) {
    2564         [ #  # ]:          0 :                 log_warning("Got unexpected events from signal file descriptor.");
    2565                 :          0 :                 return 0;
    2566                 :            :         }
    2567                 :            : 
    2568                 :          3 :         n = read(m->signal_fd, &sfsi, sizeof(sfsi));
    2569         [ -  + ]:          3 :         if (n != sizeof(sfsi)) {
    2570         [ #  # ]:          0 :                 if (n >= 0) {
    2571         [ #  # ]:          0 :                         log_warning("Truncated read from signal fd (%zu bytes), ignoring!", n);
    2572                 :          0 :                         return 0;
    2573                 :            :                 }
    2574                 :            : 
    2575   [ #  #  #  # ]:          0 :                 if (IN_SET(errno, EINTR, EAGAIN))
    2576                 :          0 :                         return 0;
    2577                 :            : 
    2578                 :            :                 /* We return an error here, which will kill this handler,
    2579                 :            :                  * to avoid a busy loop on read error. */
    2580         [ #  # ]:          0 :                 return log_error_errno(errno, "Reading from signal fd failed: %m");
    2581                 :            :         }
    2582                 :            : 
    2583         [ -  + ]:          3 :         log_received_signal(sfsi.ssi_signo == SIGCHLD ||
    2584   [ #  #  #  # ]:          0 :                             (sfsi.ssi_signo == SIGTERM && MANAGER_IS_USER(m))
    2585                 :            :                             ? LOG_DEBUG : LOG_INFO,
    2586                 :            :                             &sfsi);
    2587                 :            : 
    2588   [ +  -  -  -  :          3 :         switch (sfsi.ssi_signo) {
             -  -  -  -  
                      - ]
    2589                 :            : 
    2590                 :          3 :         case SIGCHLD:
    2591                 :          3 :                 r = sd_event_source_set_enabled(m->sigchld_event_source, SD_EVENT_ON);
    2592         [ -  + ]:          3 :                 if (r < 0)
    2593         [ #  # ]:          0 :                         log_warning_errno(r, "Failed to enable SIGCHLD event source, ignoring: %m");
    2594                 :            : 
    2595                 :          3 :                 break;
    2596                 :            : 
    2597                 :          0 :         case SIGTERM:
    2598         [ #  # ]:          0 :                 if (MANAGER_IS_SYSTEM(m)) {
    2599                 :            :                         /* This is for compatibility with the original sysvinit */
    2600         [ #  # ]:          0 :                         if (verify_run_space_and_log("Refusing to reexecute") < 0)
    2601                 :          0 :                                 break;
    2602                 :            : 
    2603                 :          0 :                         m->objective = MANAGER_REEXECUTE;
    2604                 :          0 :                         break;
    2605                 :            :                 }
    2606                 :            : 
    2607                 :            :                 _fallthrough_;
    2608                 :            :         case SIGINT:
    2609         [ #  # ]:          0 :                 if (MANAGER_IS_SYSTEM(m))
    2610                 :          0 :                         manager_handle_ctrl_alt_del(m);
    2611                 :            :                 else
    2612                 :          0 :                         manager_start_target(m, SPECIAL_EXIT_TARGET,
    2613                 :            :                                              JOB_REPLACE_IRREVERSIBLY);
    2614                 :          0 :                 break;
    2615                 :            : 
    2616                 :          0 :         case SIGWINCH:
    2617                 :            :                 /* This is a nop on non-init */
    2618         [ #  # ]:          0 :                 if (MANAGER_IS_SYSTEM(m))
    2619                 :          0 :                         manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
    2620                 :            : 
    2621                 :          0 :                 break;
    2622                 :            : 
    2623                 :          0 :         case SIGPWR:
    2624                 :            :                 /* This is a nop on non-init */
    2625         [ #  # ]:          0 :                 if (MANAGER_IS_SYSTEM(m))
    2626                 :          0 :                         manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
    2627                 :            : 
    2628                 :          0 :                 break;
    2629                 :            : 
    2630                 :          0 :         case SIGUSR1:
    2631         [ #  # ]:          0 :                 if (manager_dbus_is_running(m, false)) {
    2632         [ #  # ]:          0 :                         log_info("Trying to reconnect to bus...");
    2633                 :            : 
    2634                 :          0 :                         (void) bus_init_api(m);
    2635                 :            : 
    2636         [ #  # ]:          0 :                         if (MANAGER_IS_SYSTEM(m))
    2637                 :          0 :                                 (void) bus_init_system(m);
    2638                 :            :                 } else {
    2639         [ #  # ]:          0 :                         log_info("Starting D-Bus service...");
    2640                 :          0 :                         manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
    2641                 :            :                 }
    2642                 :            : 
    2643                 :          0 :                 break;
    2644                 :            : 
    2645                 :          0 :         case SIGUSR2: {
    2646                 :          0 :                 _cleanup_free_ char *dump = NULL;
    2647                 :            : 
    2648                 :          0 :                 r = manager_get_dump_string(m, &dump);
    2649         [ #  # ]:          0 :                 if (r < 0) {
    2650         [ #  # ]:          0 :                         log_warning_errno(errno, "Failed to acquire manager dump: %m");
    2651                 :          0 :                         break;
    2652                 :            :                 }
    2653                 :            : 
    2654                 :          0 :                 log_dump(LOG_INFO, dump);
    2655                 :          0 :                 break;
    2656                 :            :         }
    2657                 :            : 
    2658                 :          0 :         case SIGHUP:
    2659         [ #  # ]:          0 :                 if (verify_run_space_and_log("Refusing to reload") < 0)
    2660                 :          0 :                         break;
    2661                 :            : 
    2662                 :          0 :                 m->objective = MANAGER_RELOAD;
    2663                 :          0 :                 break;
    2664                 :            : 
    2665                 :          0 :         default: {
    2666                 :            : 
    2667                 :            :                 /* Starting SIGRTMIN+0 */
    2668                 :            :                 static const struct {
    2669                 :            :                         const char *target;
    2670                 :            :                         JobMode mode;
    2671                 :            :                 } target_table[] = {
    2672                 :            :                         [0] = { SPECIAL_DEFAULT_TARGET,   JOB_ISOLATE },
    2673                 :            :                         [1] = { SPECIAL_RESCUE_TARGET,    JOB_ISOLATE },
    2674                 :            :                         [2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE },
    2675                 :            :                         [3] = { SPECIAL_HALT_TARGET,      JOB_REPLACE_IRREVERSIBLY },
    2676                 :            :                         [4] = { SPECIAL_POWEROFF_TARGET,  JOB_REPLACE_IRREVERSIBLY },
    2677                 :            :                         [5] = { SPECIAL_REBOOT_TARGET,    JOB_REPLACE_IRREVERSIBLY },
    2678                 :            :                         [6] = { SPECIAL_KEXEC_TARGET,     JOB_REPLACE_IRREVERSIBLY },
    2679                 :            :                 };
    2680                 :            : 
    2681                 :            :                 /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
    2682                 :            :                 static const ManagerObjective objective_table[] = {
    2683                 :            :                         [0] = MANAGER_HALT,
    2684                 :            :                         [1] = MANAGER_POWEROFF,
    2685                 :            :                         [2] = MANAGER_REBOOT,
    2686                 :            :                         [3] = MANAGER_KEXEC,
    2687                 :            :                 };
    2688                 :            : 
    2689         [ #  # ]:          0 :                 if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
    2690         [ #  # ]:          0 :                     (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
    2691                 :          0 :                         int idx = (int) sfsi.ssi_signo - SIGRTMIN;
    2692                 :          0 :                         manager_start_target(m, target_table[idx].target,
    2693                 :            :                                              target_table[idx].mode);
    2694                 :          0 :                         break;
    2695                 :            :                 }
    2696                 :            : 
    2697         [ #  # ]:          0 :                 if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
    2698         [ #  # ]:          0 :                     (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(objective_table)) {
    2699                 :          0 :                         m->objective = objective_table[sfsi.ssi_signo - SIGRTMIN - 13];
    2700                 :          0 :                         break;
    2701                 :            :                 }
    2702                 :            : 
    2703   [ #  #  #  #  :          0 :                 switch (sfsi.ssi_signo - SIGRTMIN) {
             #  #  #  #  
                      # ]
    2704                 :            : 
    2705                 :          0 :                 case 20:
    2706                 :          0 :                         manager_set_show_status(m, SHOW_STATUS_YES);
    2707                 :          0 :                         break;
    2708                 :            : 
    2709                 :          0 :                 case 21:
    2710                 :          0 :                         manager_set_show_status(m, SHOW_STATUS_NO);
    2711                 :          0 :                         break;
    2712                 :            : 
    2713                 :          0 :                 case 22:
    2714                 :          0 :                         manager_override_log_level(m, LOG_DEBUG);
    2715                 :          0 :                         break;
    2716                 :            : 
    2717                 :          0 :                 case 23:
    2718                 :          0 :                         manager_restore_original_log_level(m);
    2719                 :          0 :                         break;
    2720                 :            : 
    2721                 :          0 :                 case 24:
    2722         [ #  # ]:          0 :                         if (MANAGER_IS_USER(m)) {
    2723                 :          0 :                                 m->objective = MANAGER_EXIT;
    2724                 :          0 :                                 return 0;
    2725                 :            :                         }
    2726                 :            : 
    2727                 :            :                         /* This is a nop on init */
    2728                 :          0 :                         break;
    2729                 :            : 
    2730                 :          0 :                 case 26:
    2731                 :            :                 case 29: /* compatibility: used to be mapped to LOG_TARGET_SYSLOG_OR_KMSG */
    2732                 :          0 :                         manager_restore_original_log_target(m);
    2733                 :          0 :                         break;
    2734                 :            : 
    2735                 :          0 :                 case 27:
    2736                 :          0 :                         manager_override_log_target(m, LOG_TARGET_CONSOLE);
    2737                 :          0 :                         break;
    2738                 :            : 
    2739                 :          0 :                 case 28:
    2740                 :          0 :                         manager_override_log_target(m, LOG_TARGET_KMSG);
    2741                 :          0 :                         break;
    2742                 :            : 
    2743                 :          0 :                 default:
    2744         [ #  # ]:          0 :                         log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo));
    2745                 :            :                 }
    2746                 :            :         }}
    2747                 :            : 
    2748                 :          3 :         return 0;
    2749                 :            : }
    2750                 :            : 
    2751                 :          0 : static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
    2752                 :          0 :         Manager *m = userdata;
    2753                 :            :         Iterator i;
    2754                 :            :         Unit *u;
    2755                 :            : 
    2756         [ #  # ]:          0 :         assert(m);
    2757         [ #  # ]:          0 :         assert(m->time_change_fd == fd);
    2758                 :            : 
    2759                 :          0 :         log_struct(LOG_DEBUG,
    2760                 :            :                    "MESSAGE_ID=" SD_MESSAGE_TIME_CHANGE_STR,
    2761                 :            :                    LOG_MESSAGE("Time has been changed"));
    2762                 :            : 
    2763                 :            :         /* Restart the watch */
    2764                 :          0 :         (void) manager_setup_time_change(m);
    2765                 :            : 
    2766         [ #  # ]:          0 :         HASHMAP_FOREACH(u, m->units, i)
    2767         [ #  # ]:          0 :                 if (UNIT_VTABLE(u)->time_change)
    2768                 :          0 :                         UNIT_VTABLE(u)->time_change(u);
    2769                 :            : 
    2770                 :          0 :         return 0;
    2771                 :            : }
    2772                 :            : 
    2773                 :          0 : static int manager_dispatch_timezone_change(
    2774                 :            :                 sd_event_source *source,
    2775                 :            :                 const struct inotify_event *e,
    2776                 :            :                 void *userdata) {
    2777                 :            : 
    2778                 :          0 :         Manager *m = userdata;
    2779                 :            :         int changed;
    2780                 :            :         Iterator i;
    2781                 :            :         Unit *u;
    2782                 :            : 
    2783         [ #  # ]:          0 :         assert(m);
    2784                 :            : 
    2785         [ #  # ]:          0 :         log_debug("inotify event for /etc/localtime");
    2786                 :            : 
    2787                 :          0 :         changed = manager_read_timezone_stat(m);
    2788         [ #  # ]:          0 :         if (changed <= 0)
    2789                 :          0 :                 return changed;
    2790                 :            : 
    2791                 :            :         /* Something changed, restart the watch, to ensure we watch the new /etc/localtime if it changed */
    2792                 :          0 :         (void) manager_setup_timezone_change(m);
    2793                 :            : 
    2794                 :            :         /* Read the new timezone */
    2795                 :          0 :         tzset();
    2796                 :            : 
    2797         [ #  # ]:          0 :         log_debug("Timezone has been changed (now: %s).", tzname[daylight]);
    2798                 :            : 
    2799         [ #  # ]:          0 :         HASHMAP_FOREACH(u, m->units, i)
    2800         [ #  # ]:          0 :                 if (UNIT_VTABLE(u)->timezone_change)
    2801                 :          0 :                         UNIT_VTABLE(u)->timezone_change(u);
    2802                 :            : 
    2803                 :          0 :         return 0;
    2804                 :            : }
    2805                 :            : 
    2806                 :          0 : static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
    2807                 :          0 :         Manager *m = userdata;
    2808                 :            : 
    2809         [ #  # ]:          0 :         assert(m);
    2810         [ #  # ]:          0 :         assert(m->idle_pipe[2] == fd);
    2811                 :            : 
    2812                 :            :         /* There's at least one Type=idle child that just gave up on us waiting for the boot process to complete. Let's
    2813                 :            :          * now turn off any further console output if there's at least one service that needs console access, so that
    2814                 :            :          * from now on our own output should not spill into that service's output anymore. After all, we support
    2815                 :            :          * Type=idle only to beautify console output and it generally is set on services that want to own the console
    2816                 :            :          * exclusively without our interference. */
    2817                 :          0 :         m->no_console_output = m->n_on_console > 0;
    2818                 :            : 
    2819                 :            :         /* Acknowledge the child's request, and let all all other children know too that they shouldn't wait any longer
    2820                 :            :          * by closing the pipes towards them, which is what they are waiting for. */
    2821                 :          0 :         manager_close_idle_pipe(m);
    2822                 :            : 
    2823                 :          0 :         return 0;
    2824                 :            : }
    2825                 :            : 
    2826                 :          0 : static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata) {
    2827                 :          0 :         Manager *m = userdata;
    2828                 :            :         int r;
    2829                 :            :         uint64_t next;
    2830                 :            : 
    2831         [ #  # ]:          0 :         assert(m);
    2832         [ #  # ]:          0 :         assert(source);
    2833                 :            : 
    2834                 :          0 :         manager_print_jobs_in_progress(m);
    2835                 :            : 
    2836                 :          0 :         next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_PERIOD_USEC;
    2837                 :          0 :         r = sd_event_source_set_time(source, next);
    2838         [ #  # ]:          0 :         if (r < 0)
    2839                 :          0 :                 return r;
    2840                 :            : 
    2841                 :          0 :         return sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);
    2842                 :            : }
    2843                 :            : 
    2844                 :          0 : int manager_loop(Manager *m) {
    2845                 :            :         int r;
    2846                 :            : 
    2847                 :          0 :         RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
    2848                 :            : 
    2849         [ #  # ]:          0 :         assert(m);
    2850         [ #  # ]:          0 :         assert(m->objective == MANAGER_OK); /* Ensure manager_startup() has been called */
    2851                 :            : 
    2852                 :          0 :         manager_check_finished(m);
    2853                 :            : 
    2854                 :            :         /* There might still be some zombies hanging around from before we were exec()'ed. Let's reap them. */
    2855                 :          0 :         r = sd_event_source_set_enabled(m->sigchld_event_source, SD_EVENT_ON);
    2856         [ #  # ]:          0 :         if (r < 0)
    2857         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to enable SIGCHLD event source: %m");
    2858                 :            : 
    2859         [ #  # ]:          0 :         while (m->objective == MANAGER_OK) {
    2860                 :            :                 usec_t wait_usec;
    2861                 :            : 
    2862   [ #  #  #  # ]:          0 :                 if (timestamp_is_set(m->runtime_watchdog) && MANAGER_IS_SYSTEM(m))
    2863                 :          0 :                         watchdog_ping();
    2864                 :            : 
    2865         [ #  # ]:          0 :                 if (!ratelimit_below(&rl)) {
    2866                 :            :                         /* Yay, something is going seriously wrong, pause a little */
    2867         [ #  # ]:          0 :                         log_warning("Looping too fast. Throttling execution a little.");
    2868                 :          0 :                         sleep(1);
    2869                 :            :                 }
    2870                 :            : 
    2871         [ #  # ]:          0 :                 if (manager_dispatch_load_queue(m) > 0)
    2872                 :          0 :                         continue;
    2873                 :            : 
    2874         [ #  # ]:          0 :                 if (manager_dispatch_gc_job_queue(m) > 0)
    2875                 :          0 :                         continue;
    2876                 :            : 
    2877         [ #  # ]:          0 :                 if (manager_dispatch_gc_unit_queue(m) > 0)
    2878                 :          0 :                         continue;
    2879                 :            : 
    2880         [ #  # ]:          0 :                 if (manager_dispatch_cleanup_queue(m) > 0)
    2881                 :          0 :                         continue;
    2882                 :            : 
    2883         [ #  # ]:          0 :                 if (manager_dispatch_cgroup_realize_queue(m) > 0)
    2884                 :          0 :                         continue;
    2885                 :            : 
    2886         [ #  # ]:          0 :                 if (manager_dispatch_stop_when_unneeded_queue(m) > 0)
    2887                 :          0 :                         continue;
    2888                 :            : 
    2889         [ #  # ]:          0 :                 if (manager_dispatch_dbus_queue(m) > 0)
    2890                 :          0 :                         continue;
    2891                 :            : 
    2892                 :            :                 /* Sleep for half the watchdog time */
    2893   [ #  #  #  # ]:          0 :                 if (timestamp_is_set(m->runtime_watchdog) && MANAGER_IS_SYSTEM(m)) {
    2894                 :          0 :                         wait_usec = m->runtime_watchdog / 2;
    2895         [ #  # ]:          0 :                         if (wait_usec <= 0)
    2896                 :          0 :                                 wait_usec = 1;
    2897                 :            :                 } else
    2898                 :          0 :                         wait_usec = USEC_INFINITY;
    2899                 :            : 
    2900                 :          0 :                 r = sd_event_run(m->event, wait_usec);
    2901         [ #  # ]:          0 :                 if (r < 0)
    2902         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to run event loop: %m");
    2903                 :            :         }
    2904                 :            : 
    2905                 :          0 :         return m->objective;
    2906                 :            : }
    2907                 :            : 
    2908                 :          0 : int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, Unit **_u) {
    2909                 :          0 :         _cleanup_free_ char *n = NULL;
    2910                 :            :         sd_id128_t invocation_id;
    2911                 :            :         Unit *u;
    2912                 :            :         int r;
    2913                 :            : 
    2914         [ #  # ]:          0 :         assert(m);
    2915         [ #  # ]:          0 :         assert(s);
    2916         [ #  # ]:          0 :         assert(_u);
    2917                 :            : 
    2918                 :          0 :         r = unit_name_from_dbus_path(s, &n);
    2919         [ #  # ]:          0 :         if (r < 0)
    2920                 :          0 :                 return r;
    2921                 :            : 
    2922                 :            :         /* Permit addressing units by invocation ID: if the passed bus path is suffixed by a 128bit ID then we use it
    2923                 :            :          * as invocation ID. */
    2924                 :          0 :         r = sd_id128_from_string(n, &invocation_id);
    2925         [ #  # ]:          0 :         if (r >= 0) {
    2926                 :          0 :                 u = hashmap_get(m->units_by_invocation_id, &invocation_id);
    2927         [ #  # ]:          0 :                 if (u) {
    2928                 :          0 :                         *_u = u;
    2929                 :          0 :                         return 0;
    2930                 :            :                 }
    2931                 :            : 
    2932                 :          0 :                 return sd_bus_error_setf(e, BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID,
    2933                 :            :                                          "No unit with the specified invocation ID " SD_ID128_FORMAT_STR " known.",
    2934                 :          0 :                                          SD_ID128_FORMAT_VAL(invocation_id));
    2935                 :            :         }
    2936                 :            : 
    2937                 :            :         /* If this didn't work, we check if this is a unit name */
    2938         [ #  # ]:          0 :         if (!unit_name_is_valid(n, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) {
    2939                 :          0 :                 _cleanup_free_ char *nn = NULL;
    2940                 :            : 
    2941                 :          0 :                 nn = cescape(n);
    2942                 :          0 :                 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS,
    2943                 :            :                                          "Unit name %s is neither a valid invocation ID nor unit name.", strnull(nn));
    2944                 :            :         }
    2945                 :            : 
    2946                 :          0 :         r = manager_load_unit(m, n, NULL, e, &u);
    2947         [ #  # ]:          0 :         if (r < 0)
    2948                 :          0 :                 return r;
    2949                 :            : 
    2950                 :          0 :         *_u = u;
    2951                 :          0 :         return 0;
    2952                 :            : }
    2953                 :            : 
    2954                 :          0 : int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
    2955                 :            :         const char *p;
    2956                 :            :         unsigned id;
    2957                 :            :         Job *j;
    2958                 :            :         int r;
    2959                 :            : 
    2960         [ #  # ]:          0 :         assert(m);
    2961         [ #  # ]:          0 :         assert(s);
    2962         [ #  # ]:          0 :         assert(_j);
    2963                 :            : 
    2964                 :          0 :         p = startswith(s, "/org/freedesktop/systemd1/job/");
    2965         [ #  # ]:          0 :         if (!p)
    2966                 :          0 :                 return -EINVAL;
    2967                 :            : 
    2968                 :          0 :         r = safe_atou(p, &id);
    2969         [ #  # ]:          0 :         if (r < 0)
    2970                 :          0 :                 return r;
    2971                 :            : 
    2972                 :          0 :         j = manager_get_job(m, id);
    2973         [ #  # ]:          0 :         if (!j)
    2974                 :          0 :                 return -ENOENT;
    2975                 :            : 
    2976                 :          0 :         *_j = j;
    2977                 :            : 
    2978                 :          0 :         return 0;
    2979                 :            : }
    2980                 :            : 
    2981                 :          0 : void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
    2982                 :            : 
    2983                 :            : #if HAVE_AUDIT
    2984         [ #  # ]:          0 :         _cleanup_free_ char *p = NULL;
    2985                 :            :         const char *msg;
    2986                 :            :         int audit_fd, r;
    2987                 :            : 
    2988         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
    2989                 :          0 :                 return;
    2990                 :            : 
    2991                 :          0 :         audit_fd = get_audit_fd();
    2992         [ #  # ]:          0 :         if (audit_fd < 0)
    2993                 :          0 :                 return;
    2994                 :            : 
    2995                 :            :         /* Don't generate audit events if the service was already
    2996                 :            :          * started and we're just deserializing */
    2997         [ #  # ]:          0 :         if (MANAGER_IS_RELOADING(m))
    2998                 :          0 :                 return;
    2999                 :            : 
    3000         [ #  # ]:          0 :         if (u->type != UNIT_SERVICE)
    3001                 :          0 :                 return;
    3002                 :            : 
    3003                 :          0 :         r = unit_name_to_prefix_and_instance(u->id, &p);
    3004         [ #  # ]:          0 :         if (r < 0) {
    3005         [ #  # ]:          0 :                 log_error_errno(r, "Failed to extract prefix and instance of unit name: %m");
    3006                 :          0 :                 return;
    3007                 :            :         }
    3008                 :            : 
    3009   [ #  #  #  #  :          0 :         msg = strjoina("unit=", p);
          #  #  #  #  #  
                #  #  # ]
    3010         [ #  # ]:          0 :         if (audit_log_user_comm_message(audit_fd, type, msg, "systemd", NULL, NULL, NULL, success) < 0) {
    3011         [ #  # ]:          0 :                 if (errno == EPERM)
    3012                 :            :                         /* We aren't allowed to send audit messages?
    3013                 :            :                          * Then let's not retry again. */
    3014                 :          0 :                         close_audit_fd();
    3015                 :            :                 else
    3016         [ #  # ]:          0 :                         log_warning_errno(errno, "Failed to send audit message: %m");
    3017                 :            :         }
    3018                 :            : #endif
    3019                 :            : 
    3020                 :            : }
    3021                 :            : 
    3022                 :       6964 : void manager_send_unit_plymouth(Manager *m, Unit *u) {
    3023                 :            :         static const union sockaddr_union sa = PLYMOUTH_SOCKET;
    3024         [ -  + ]:       6964 :         _cleanup_free_ char *message = NULL;
    3025         [ -  + ]:       6964 :         _cleanup_close_ int fd = -1;
    3026                 :       6964 :         int n = 0;
    3027                 :            : 
    3028                 :            :         /* Don't generate plymouth events if the service was already
    3029                 :            :          * started and we're just deserializing */
    3030         [ -  + ]:       6964 :         if (MANAGER_IS_RELOADING(m))
    3031                 :          0 :                 return;
    3032                 :            : 
    3033         [ +  - ]:       6964 :         if (!MANAGER_IS_SYSTEM(m))
    3034                 :       6964 :                 return;
    3035                 :            : 
    3036         [ #  # ]:          0 :         if (detect_container() > 0)
    3037                 :          0 :                 return;
    3038                 :            : 
    3039   [ #  #  #  # ]:          0 :         if (!IN_SET(u->type, UNIT_SERVICE, UNIT_MOUNT, UNIT_SWAP))
    3040                 :          0 :                 return;
    3041                 :            : 
    3042                 :            :         /* We set SOCK_NONBLOCK here so that we rather drop the
    3043                 :            :          * message then wait for plymouth */
    3044                 :          0 :         fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
    3045         [ #  # ]:          0 :         if (fd < 0) {
    3046         [ #  # ]:          0 :                 log_error_errno(errno, "socket() failed: %m");
    3047                 :          0 :                 return;
    3048                 :            :         }
    3049                 :            : 
    3050   [ #  #  #  #  :          0 :         if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
                   #  # ]
    3051   [ #  #  #  #  :          0 :                 if (!IN_SET(errno, EAGAIN, ENOENT) && !ERRNO_IS_DISCONNECT(errno))
                   #  # ]
    3052         [ #  # ]:          0 :                         log_error_errno(errno, "connect() failed: %m");
    3053                 :          0 :                 return;
    3054                 :            :         }
    3055                 :            : 
    3056         [ #  # ]:          0 :         if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) {
    3057                 :          0 :                 log_oom();
    3058                 :          0 :                 return;
    3059                 :            :         }
    3060                 :            : 
    3061                 :          0 :         errno = 0;
    3062         [ #  # ]:          0 :         if (write(fd, message, n + 1) != n + 1)
    3063   [ #  #  #  #  :          0 :                 if (!IN_SET(errno, EAGAIN, ENOENT) && !ERRNO_IS_DISCONNECT(errno))
                   #  # ]
    3064         [ #  # ]:          0 :                         log_error_errno(errno, "Failed to write Plymouth message: %m");
    3065                 :            : }
    3066                 :            : 
    3067                 :          0 : int manager_open_serialization(Manager *m, FILE **_f) {
    3068                 :            :         int fd;
    3069                 :            :         FILE *f;
    3070                 :            : 
    3071         [ #  # ]:          0 :         assert(_f);
    3072                 :            : 
    3073                 :          0 :         fd = open_serialization_fd("systemd-state");
    3074         [ #  # ]:          0 :         if (fd < 0)
    3075                 :          0 :                 return fd;
    3076                 :            : 
    3077                 :          0 :         f = fdopen(fd, "w+");
    3078         [ #  # ]:          0 :         if (!f) {
    3079                 :          0 :                 safe_close(fd);
    3080                 :          0 :                 return -errno;
    3081                 :            :         }
    3082                 :            : 
    3083                 :          0 :         *_f = f;
    3084                 :          0 :         return 0;
    3085                 :            : }
    3086                 :            : 
    3087                 :          0 : static bool manager_timestamp_shall_serialize(ManagerTimestamp t) {
    3088                 :            : 
    3089         [ #  # ]:          0 :         if (!in_initrd())
    3090                 :          0 :                 return true;
    3091                 :            : 
    3092                 :            :         /* The following timestamps only apply to the host system, hence only serialize them there */
    3093         [ #  # ]:          0 :         return !IN_SET(t,
    3094                 :            :                        MANAGER_TIMESTAMP_USERSPACE, MANAGER_TIMESTAMP_FINISH,
    3095                 :            :                        MANAGER_TIMESTAMP_SECURITY_START, MANAGER_TIMESTAMP_SECURITY_FINISH,
    3096                 :            :                        MANAGER_TIMESTAMP_GENERATORS_START, MANAGER_TIMESTAMP_GENERATORS_FINISH,
    3097                 :            :                        MANAGER_TIMESTAMP_UNITS_LOAD_START, MANAGER_TIMESTAMP_UNITS_LOAD_FINISH);
    3098                 :            : }
    3099                 :            : 
    3100                 :          0 : int manager_serialize(
    3101                 :            :                 Manager *m,
    3102                 :            :                 FILE *f,
    3103                 :            :                 FDSet *fds,
    3104                 :            :                 bool switching_root) {
    3105                 :            : 
    3106                 :            :         ManagerTimestamp q;
    3107                 :            :         const char *t;
    3108                 :            :         Iterator i;
    3109                 :            :         Unit *u;
    3110                 :            :         int r;
    3111                 :            : 
    3112         [ #  # ]:          0 :         assert(m);
    3113         [ #  # ]:          0 :         assert(f);
    3114         [ #  # ]:          0 :         assert(fds);
    3115                 :            : 
    3116                 :          0 :         _cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
    3117                 :            : 
    3118                 :          0 :         (void) serialize_item_format(f, "current-job-id", "%" PRIu32, m->current_job_id);
    3119                 :          0 :         (void) serialize_item_format(f, "n-installed-jobs", "%u", m->n_installed_jobs);
    3120                 :          0 :         (void) serialize_item_format(f, "n-failed-jobs", "%u", m->n_failed_jobs);
    3121                 :          0 :         (void) serialize_bool(f, "taint-usr", m->taint_usr);
    3122                 :          0 :         (void) serialize_bool(f, "ready-sent", m->ready_sent);
    3123                 :          0 :         (void) serialize_bool(f, "taint-logged", m->taint_logged);
    3124                 :          0 :         (void) serialize_bool(f, "service-watchdogs", m->service_watchdogs);
    3125                 :            : 
    3126                 :            :         /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
    3127                 :          0 :         (void) serialize_bool(f, "honor-device-enumeration", !switching_root);
    3128                 :            : 
    3129                 :          0 :         t = show_status_to_string(m->show_status);
    3130         [ #  # ]:          0 :         if (t)
    3131                 :          0 :                 (void) serialize_item(f, "show-status", t);
    3132                 :            : 
    3133         [ #  # ]:          0 :         if (m->log_level_overridden)
    3134                 :          0 :                 (void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level());
    3135         [ #  # ]:          0 :         if (m->log_target_overridden)
    3136                 :          0 :                 (void) serialize_item(f, "log-target-override", log_target_to_string(log_get_target()));
    3137                 :            : 
    3138         [ #  # ]:          0 :         for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
    3139      [ #  #  # ]:          0 :                 _cleanup_free_ char *joined = NULL;
    3140                 :            : 
    3141         [ #  # ]:          0 :                 if (!manager_timestamp_shall_serialize(q))
    3142                 :          0 :                         continue;
    3143                 :            : 
    3144                 :          0 :                 joined = strjoin(manager_timestamp_to_string(q), "-timestamp");
    3145         [ #  # ]:          0 :                 if (!joined)
    3146                 :          0 :                         return log_oom();
    3147                 :            : 
    3148                 :          0 :                 (void) serialize_dual_timestamp(f, joined, m->timestamps + q);
    3149                 :            :         }
    3150                 :            : 
    3151         [ #  # ]:          0 :         if (!switching_root)
    3152                 :          0 :                 (void) serialize_strv(f, "env", m->client_environment);
    3153                 :            : 
    3154         [ #  # ]:          0 :         if (m->notify_fd >= 0) {
    3155                 :          0 :                 r = serialize_fd(f, fds, "notify-fd", m->notify_fd);
    3156         [ #  # ]:          0 :                 if (r < 0)
    3157                 :          0 :                         return r;
    3158                 :            : 
    3159                 :          0 :                 (void) serialize_item(f, "notify-socket", m->notify_socket);
    3160                 :            :         }
    3161                 :            : 
    3162         [ #  # ]:          0 :         if (m->cgroups_agent_fd >= 0) {
    3163                 :          0 :                 r = serialize_fd(f, fds, "cgroups-agent-fd", m->cgroups_agent_fd);
    3164         [ #  # ]:          0 :                 if (r < 0)
    3165                 :          0 :                         return r;
    3166                 :            :         }
    3167                 :            : 
    3168         [ #  # ]:          0 :         if (m->user_lookup_fds[0] >= 0) {
    3169                 :            :                 int copy0, copy1;
    3170                 :            : 
    3171                 :          0 :                 copy0 = fdset_put_dup(fds, m->user_lookup_fds[0]);
    3172         [ #  # ]:          0 :                 if (copy0 < 0)
    3173         [ #  # ]:          0 :                         return log_error_errno(copy0, "Failed to add user lookup fd to serialization: %m");
    3174                 :            : 
    3175                 :          0 :                 copy1 = fdset_put_dup(fds, m->user_lookup_fds[1]);
    3176         [ #  # ]:          0 :                 if (copy1 < 0)
    3177         [ #  # ]:          0 :                         return log_error_errno(copy1, "Failed to add user lookup fd to serialization: %m");
    3178                 :            : 
    3179                 :          0 :                 (void) serialize_item_format(f, "user-lookup", "%i %i", copy0, copy1);
    3180                 :            :         }
    3181                 :            : 
    3182                 :          0 :         bus_track_serialize(m->subscribed, f, "subscribed");
    3183                 :            : 
    3184                 :          0 :         r = dynamic_user_serialize(m, f, fds);
    3185         [ #  # ]:          0 :         if (r < 0)
    3186                 :          0 :                 return r;
    3187                 :            : 
    3188                 :          0 :         manager_serialize_uid_refs(m, f);
    3189                 :          0 :         manager_serialize_gid_refs(m, f);
    3190                 :            : 
    3191                 :          0 :         r = exec_runtime_serialize(m, f, fds);
    3192         [ #  # ]:          0 :         if (r < 0)
    3193                 :          0 :                 return r;
    3194                 :            : 
    3195                 :          0 :         (void) fputc('\n', f);
    3196                 :            : 
    3197         [ #  # ]:          0 :         HASHMAP_FOREACH_KEY(u, t, m->units, i) {
    3198         [ #  # ]:          0 :                 if (u->id != t)
    3199                 :          0 :                         continue;
    3200                 :            : 
    3201                 :            :                 /* Start marker */
    3202                 :          0 :                 fputs(u->id, f);
    3203                 :          0 :                 fputc('\n', f);
    3204                 :            : 
    3205                 :          0 :                 r = unit_serialize(u, f, fds, !switching_root);
    3206         [ #  # ]:          0 :                 if (r < 0)
    3207                 :          0 :                         return r;
    3208                 :            :         }
    3209                 :            : 
    3210                 :          0 :         r = fflush_and_check(f);
    3211         [ #  # ]:          0 :         if (r < 0)
    3212         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to flush serialization: %m");
    3213                 :            : 
    3214                 :          0 :         r = bus_fdset_add_all(m, fds);
    3215         [ #  # ]:          0 :         if (r < 0)
    3216         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to add bus sockets to serialization: %m");
    3217                 :            : 
    3218                 :          0 :         return 0;
    3219                 :            : }
    3220                 :            : 
    3221                 :          0 : static int manager_deserialize_one_unit(Manager *m, const char *name, FILE *f, FDSet *fds) {
    3222                 :            :         Unit *u;
    3223                 :            :         int r;
    3224                 :            : 
    3225                 :          0 :         r = manager_load_unit(m, name, NULL, NULL, &u);
    3226         [ #  # ]:          0 :         if (r < 0) {
    3227         [ #  # ]:          0 :                 if (r == -ENOMEM)
    3228                 :          0 :                         return r;
    3229         [ #  # ]:          0 :                 return log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", name);
    3230                 :            :         }
    3231                 :            : 
    3232                 :          0 :         r = unit_deserialize(u, f, fds);
    3233         [ #  # ]:          0 :         if (r < 0) {
    3234         [ #  # ]:          0 :                 if (r == -ENOMEM)
    3235                 :          0 :                         return r;
    3236         [ #  # ]:          0 :                 return log_notice_errno(r, "Failed to deserialize unit \"%s\", skipping: %m", name);
    3237                 :            :         }
    3238                 :            : 
    3239                 :          0 :         return 0;
    3240                 :            : }
    3241                 :            : 
    3242                 :          0 : static int manager_deserialize_units(Manager *m, FILE *f, FDSet *fds) {
    3243                 :            :         const char *unit_name;
    3244                 :            :         int r;
    3245                 :            : 
    3246                 :          0 :         for (;;) {
    3247      [ #  #  # ]:          0 :                 _cleanup_free_ char *line = NULL;
    3248                 :            :                 /* Start marker */
    3249                 :          0 :                 r = read_line(f, LONG_LINE_MAX, &line);
    3250         [ #  # ]:          0 :                 if (r < 0)
    3251         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to read serialization line: %m");
    3252         [ #  # ]:          0 :                 if (r == 0)
    3253                 :          0 :                         break;
    3254                 :            : 
    3255                 :          0 :                 unit_name = strstrip(line);
    3256                 :            : 
    3257                 :          0 :                 r = manager_deserialize_one_unit(m, unit_name, f, fds);
    3258         [ #  # ]:          0 :                 if (r == -ENOMEM)
    3259                 :          0 :                         return r;
    3260         [ #  # ]:          0 :                 if (r < 0) {
    3261                 :          0 :                         r = unit_deserialize_skip(f);
    3262         [ #  # ]:          0 :                         if (r < 0)
    3263                 :          0 :                                 return r;
    3264                 :            :                 }
    3265                 :            :         }
    3266                 :            : 
    3267                 :          0 :         return 0;
    3268                 :            : }
    3269                 :            : 
    3270                 :          0 : int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
    3271                 :          0 :         int r = 0;
    3272                 :            : 
    3273         [ #  # ]:          0 :         assert(m);
    3274         [ #  # ]:          0 :         assert(f);
    3275                 :            : 
    3276         [ #  # ]:          0 :         log_debug("Deserializing state...");
    3277                 :            : 
    3278                 :            :         /* If we are not in reload mode yet, enter it now. Not that this is recursive, a caller might already have
    3279                 :            :          * increased it to non-zero, which is why we just increase it by one here and down again at the end of this
    3280                 :            :          * call. */
    3281                 :          0 :         _cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
    3282                 :            : 
    3283                 :          0 :         for (;;) {
    3284      [ #  #  # ]:          0 :                 _cleanup_free_ char *line = NULL;
    3285                 :            :                 const char *val, *l;
    3286                 :            : 
    3287                 :          0 :                 r = read_line(f, LONG_LINE_MAX, &line);
    3288         [ #  # ]:          0 :                 if (r < 0)
    3289         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to read serialization line: %m");
    3290         [ #  # ]:          0 :                 if (r == 0)
    3291                 :          0 :                         break;
    3292                 :            : 
    3293                 :          0 :                 l = strstrip(line);
    3294         [ #  # ]:          0 :                 if (isempty(l)) /* end marker */
    3295                 :          0 :                         break;
    3296                 :            : 
    3297         [ #  # ]:          0 :                 if ((val = startswith(l, "current-job-id="))) {
    3298                 :            :                         uint32_t id;
    3299                 :            : 
    3300         [ #  # ]:          0 :                         if (safe_atou32(val, &id) < 0)
    3301         [ #  # ]:          0 :                                 log_notice("Failed to parse current job id value '%s', ignoring.", val);
    3302                 :            :                         else
    3303                 :          0 :                                 m->current_job_id = MAX(m->current_job_id, id);
    3304                 :            : 
    3305         [ #  # ]:          0 :                 } else if ((val = startswith(l, "n-installed-jobs="))) {
    3306                 :            :                         uint32_t n;
    3307                 :            : 
    3308         [ #  # ]:          0 :                         if (safe_atou32(val, &n) < 0)
    3309         [ #  # ]:          0 :                                 log_notice("Failed to parse installed jobs counter '%s', ignoring.", val);
    3310                 :            :                         else
    3311                 :          0 :                                 m->n_installed_jobs += n;
    3312                 :            : 
    3313         [ #  # ]:          0 :                 } else if ((val = startswith(l, "n-failed-jobs="))) {
    3314                 :            :                         uint32_t n;
    3315                 :            : 
    3316         [ #  # ]:          0 :                         if (safe_atou32(val, &n) < 0)
    3317         [ #  # ]:          0 :                                 log_notice("Failed to parse failed jobs counter '%s', ignoring.", val);
    3318                 :            :                         else
    3319                 :          0 :                                 m->n_failed_jobs += n;
    3320                 :            : 
    3321         [ #  # ]:          0 :                 } else if ((val = startswith(l, "taint-usr="))) {
    3322                 :            :                         int b;
    3323                 :            : 
    3324                 :          0 :                         b = parse_boolean(val);
    3325         [ #  # ]:          0 :                         if (b < 0)
    3326         [ #  # ]:          0 :                                 log_notice("Failed to parse taint /usr flag '%s', ignoring.", val);
    3327                 :            :                         else
    3328   [ #  #  #  # ]:          0 :                                 m->taint_usr = m->taint_usr || b;
    3329                 :            : 
    3330         [ #  # ]:          0 :                 } else if ((val = startswith(l, "ready-sent="))) {
    3331                 :            :                         int b;
    3332                 :            : 
    3333                 :          0 :                         b = parse_boolean(val);
    3334         [ #  # ]:          0 :                         if (b < 0)
    3335         [ #  # ]:          0 :                                 log_notice("Failed to parse ready-sent flag '%s', ignoring.", val);
    3336                 :            :                         else
    3337   [ #  #  #  # ]:          0 :                                 m->ready_sent = m->ready_sent || b;
    3338                 :            : 
    3339         [ #  # ]:          0 :                 } else if ((val = startswith(l, "taint-logged="))) {
    3340                 :            :                         int b;
    3341                 :            : 
    3342                 :          0 :                         b = parse_boolean(val);
    3343         [ #  # ]:          0 :                         if (b < 0)
    3344         [ #  # ]:          0 :                                 log_notice("Failed to parse taint-logged flag '%s', ignoring.", val);
    3345                 :            :                         else
    3346   [ #  #  #  # ]:          0 :                                 m->taint_logged = m->taint_logged || b;
    3347                 :            : 
    3348         [ #  # ]:          0 :                 } else if ((val = startswith(l, "service-watchdogs="))) {
    3349                 :            :                         int b;
    3350                 :            : 
    3351                 :          0 :                         b = parse_boolean(val);
    3352         [ #  # ]:          0 :                         if (b < 0)
    3353         [ #  # ]:          0 :                                 log_notice("Failed to parse service-watchdogs flag '%s', ignoring.", val);
    3354                 :            :                         else
    3355                 :          0 :                                 m->service_watchdogs = b;
    3356                 :            : 
    3357         [ #  # ]:          0 :                 } else if ((val = startswith(l, "honor-device-enumeration="))) {
    3358                 :            :                         int b;
    3359                 :            : 
    3360                 :          0 :                         b = parse_boolean(val);
    3361         [ #  # ]:          0 :                         if (b < 0)
    3362         [ #  # ]:          0 :                                 log_notice("Failed to parse honor-device-enumeration flag '%s', ignoring.", val);
    3363                 :            :                         else
    3364                 :          0 :                                 m->honor_device_enumeration = b;
    3365                 :            : 
    3366         [ #  # ]:          0 :                 } else if ((val = startswith(l, "show-status="))) {
    3367                 :            :                         ShowStatus s;
    3368                 :            : 
    3369                 :          0 :                         s = show_status_from_string(val);
    3370         [ #  # ]:          0 :                         if (s < 0)
    3371         [ #  # ]:          0 :                                 log_notice("Failed to parse show-status flag '%s', ignoring.", val);
    3372                 :            :                         else
    3373                 :          0 :                                 manager_set_show_status(m, s);
    3374                 :            : 
    3375         [ #  # ]:          0 :                 } else if ((val = startswith(l, "log-level-override="))) {
    3376                 :            :                         int level;
    3377                 :            : 
    3378                 :          0 :                         level = log_level_from_string(val);
    3379         [ #  # ]:          0 :                         if (level < 0)
    3380         [ #  # ]:          0 :                                 log_notice("Failed to parse log-level-override value '%s', ignoring.", val);
    3381                 :            :                         else
    3382                 :          0 :                                 manager_override_log_level(m, level);
    3383                 :            : 
    3384         [ #  # ]:          0 :                 } else if ((val = startswith(l, "log-target-override="))) {
    3385                 :            :                         LogTarget target;
    3386                 :            : 
    3387                 :          0 :                         target = log_target_from_string(val);
    3388         [ #  # ]:          0 :                         if (target < 0)
    3389         [ #  # ]:          0 :                                 log_notice("Failed to parse log-target-override value '%s', ignoring.", val);
    3390                 :            :                         else
    3391                 :          0 :                                 manager_override_log_target(m, target);
    3392                 :            : 
    3393         [ #  # ]:          0 :                 } else if (startswith(l, "env=")) {
    3394                 :          0 :                         r = deserialize_environment(l + 4, &m->client_environment);
    3395         [ #  # ]:          0 :                         if (r < 0)
    3396         [ #  # ]:          0 :                                 log_notice_errno(r, "Failed to parse environment entry: \"%s\", ignoring: %m", l);
    3397                 :            : 
    3398         [ #  # ]:          0 :                 } else if ((val = startswith(l, "notify-fd="))) {
    3399                 :            :                         int fd;
    3400                 :            : 
    3401   [ #  #  #  #  :          0 :                         if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
                   #  # ]
    3402         [ #  # ]:          0 :                                 log_notice("Failed to parse notify fd, ignoring: \"%s\"", val);
    3403                 :            :                         else {
    3404                 :          0 :                                 m->notify_event_source = sd_event_source_unref(m->notify_event_source);
    3405                 :          0 :                                 safe_close(m->notify_fd);
    3406                 :          0 :                                 m->notify_fd = fdset_remove(fds, fd);
    3407                 :            :                         }
    3408                 :            : 
    3409         [ #  # ]:          0 :                 } else if ((val = startswith(l, "notify-socket="))) {
    3410                 :          0 :                         r = free_and_strdup(&m->notify_socket, val);
    3411         [ #  # ]:          0 :                         if (r < 0)
    3412                 :          0 :                                 return r;
    3413                 :            : 
    3414         [ #  # ]:          0 :                 } else if ((val = startswith(l, "cgroups-agent-fd="))) {
    3415                 :            :                         int fd;
    3416                 :            : 
    3417   [ #  #  #  #  :          0 :                         if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
                   #  # ]
    3418         [ #  # ]:          0 :                                 log_notice("Failed to parse cgroups agent fd, ignoring.: %s", val);
    3419                 :            :                         else {
    3420                 :          0 :                                 m->cgroups_agent_event_source = sd_event_source_unref(m->cgroups_agent_event_source);
    3421                 :          0 :                                 safe_close(m->cgroups_agent_fd);
    3422                 :          0 :                                 m->cgroups_agent_fd = fdset_remove(fds, fd);
    3423                 :            :                         }
    3424                 :            : 
    3425         [ #  # ]:          0 :                 } else if ((val = startswith(l, "user-lookup="))) {
    3426                 :            :                         int fd0, fd1;
    3427                 :            : 
    3428   [ #  #  #  #  :          0 :                         if (sscanf(val, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1))
          #  #  #  #  #  
                #  #  # ]
    3429         [ #  # ]:          0 :                                 log_notice("Failed to parse user lookup fd, ignoring: %s", val);
    3430                 :            :                         else {
    3431                 :          0 :                                 m->user_lookup_event_source = sd_event_source_unref(m->user_lookup_event_source);
    3432                 :          0 :                                 safe_close_pair(m->user_lookup_fds);
    3433                 :          0 :                                 m->user_lookup_fds[0] = fdset_remove(fds, fd0);
    3434                 :          0 :                                 m->user_lookup_fds[1] = fdset_remove(fds, fd1);
    3435                 :            :                         }
    3436                 :            : 
    3437         [ #  # ]:          0 :                 } else if ((val = startswith(l, "dynamic-user=")))
    3438                 :          0 :                         dynamic_user_deserialize_one(m, val, fds);
    3439         [ #  # ]:          0 :                 else if ((val = startswith(l, "destroy-ipc-uid=")))
    3440                 :          0 :                         manager_deserialize_uid_refs_one(m, val);
    3441         [ #  # ]:          0 :                 else if ((val = startswith(l, "destroy-ipc-gid=")))
    3442                 :          0 :                         manager_deserialize_gid_refs_one(m, val);
    3443         [ #  # ]:          0 :                 else if ((val = startswith(l, "exec-runtime=")))
    3444                 :          0 :                         exec_runtime_deserialize_one(m, val, fds);
    3445         [ #  # ]:          0 :                 else if ((val = startswith(l, "subscribed="))) {
    3446                 :            : 
    3447         [ #  # ]:          0 :                         if (strv_extend(&m->deserialized_subscribed, val) < 0)
    3448                 :          0 :                                 return -ENOMEM;
    3449                 :            : 
    3450                 :            :                 } else {
    3451                 :            :                         ManagerTimestamp q;
    3452                 :            : 
    3453         [ #  # ]:          0 :                         for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
    3454                 :          0 :                                 val = startswith(l, manager_timestamp_to_string(q));
    3455         [ #  # ]:          0 :                                 if (!val)
    3456                 :          0 :                                         continue;
    3457                 :            : 
    3458                 :          0 :                                 val = startswith(val, "-timestamp=");
    3459         [ #  # ]:          0 :                                 if (val)
    3460                 :          0 :                                         break;
    3461                 :            :                         }
    3462                 :            : 
    3463         [ #  # ]:          0 :                         if (q < _MANAGER_TIMESTAMP_MAX) /* found it */
    3464                 :          0 :                                 (void) deserialize_dual_timestamp(val, m->timestamps + q);
    3465         [ #  # ]:          0 :                         else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */
    3466         [ #  # ]:          0 :                                 log_notice("Unknown serialization item '%s', ignoring.", l);
    3467                 :            :                 }
    3468                 :            :         }
    3469                 :            : 
    3470                 :          0 :         return manager_deserialize_units(m, f, fds);
    3471                 :            : }
    3472                 :            : 
    3473                 :          0 : int manager_reload(Manager *m) {
    3474                 :          0 :         _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
    3475                 :          0 :         _cleanup_fdset_free_ FDSet *fds = NULL;
    3476                 :          0 :         _cleanup_fclose_ FILE *f = NULL;
    3477                 :            :         int r;
    3478                 :            : 
    3479         [ #  # ]:          0 :         assert(m);
    3480                 :            : 
    3481                 :          0 :         r = manager_open_serialization(m, &f);
    3482         [ #  # ]:          0 :         if (r < 0)
    3483         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to create serialization file: %m");
    3484                 :            : 
    3485                 :          0 :         fds = fdset_new();
    3486         [ #  # ]:          0 :         if (!fds)
    3487                 :          0 :                 return log_oom();
    3488                 :            : 
    3489                 :            :         /* We are officially in reload mode from here on. */
    3490                 :          0 :         reloading = manager_reloading_start(m);
    3491                 :            : 
    3492                 :          0 :         r = manager_serialize(m, f, fds, false);
    3493         [ #  # ]:          0 :         if (r < 0)
    3494                 :          0 :                 return r;
    3495                 :            : 
    3496         [ #  # ]:          0 :         if (fseeko(f, 0, SEEK_SET) < 0)
    3497         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to seek to beginning of serialization: %m");
    3498                 :            : 
    3499                 :            :         /* 💀 This is the point of no return, from here on there is no way back. 💀 */
    3500                 :          0 :         reloading = NULL;
    3501                 :            : 
    3502                 :          0 :         bus_manager_send_reloading(m, true);
    3503                 :            : 
    3504                 :            :         /* Start by flushing out all jobs and units, all generated units, all runtime environments, all dynamic users
    3505                 :            :          * and everything else that is worth flushing out. We'll get it all back from the serialization — if we need
    3506                 :            :          * it.*/
    3507                 :            : 
    3508                 :          0 :         manager_clear_jobs_and_units(m);
    3509                 :          0 :         lookup_paths_flush_generator(&m->lookup_paths);
    3510                 :          0 :         lookup_paths_free(&m->lookup_paths);
    3511                 :          0 :         exec_runtime_vacuum(m);
    3512                 :          0 :         dynamic_user_vacuum(m, false);
    3513                 :          0 :         m->uid_refs = hashmap_free(m->uid_refs);
    3514                 :          0 :         m->gid_refs = hashmap_free(m->gid_refs);
    3515                 :            : 
    3516                 :          0 :         r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, 0, NULL);
    3517         [ #  # ]:          0 :         if (r < 0)
    3518         [ #  # ]:          0 :                 log_warning_errno(r, "Failed to initialize path lookup table, ignoring: %m");
    3519                 :            : 
    3520                 :          0 :         (void) manager_run_environment_generators(m);
    3521                 :          0 :         (void) manager_run_generators(m);
    3522                 :            : 
    3523                 :          0 :         r = lookup_paths_reduce(&m->lookup_paths);
    3524         [ #  # ]:          0 :         if (r < 0)
    3525         [ #  # ]:          0 :                 log_warning_errno(r, "Failed to reduce unit file paths, ignoring: %m");
    3526                 :            : 
    3527                 :            :         /* We flushed out generated files, for which we don't watch mtime, so we should flush the old map. */
    3528                 :          0 :         manager_free_unit_name_maps(m);
    3529                 :            : 
    3530                 :            :         /* First, enumerate what we can from kernel and suchlike */
    3531                 :          0 :         manager_enumerate_perpetual(m);
    3532                 :          0 :         manager_enumerate(m);
    3533                 :            : 
    3534                 :            :         /* Second, deserialize our stored data */
    3535                 :          0 :         r = manager_deserialize(m, f, fds);
    3536         [ #  # ]:          0 :         if (r < 0)
    3537         [ #  # ]:          0 :                 log_warning_errno(r, "Deserialization failed, proceeding anyway: %m");
    3538                 :            : 
    3539                 :            :         /* We don't need the serialization anymore */
    3540                 :          0 :         f = safe_fclose(f);
    3541                 :            : 
    3542                 :            :         /* Re-register notify_fd as event source, and set up other sockets/communication channels we might need */
    3543                 :          0 :         (void) manager_setup_notify(m);
    3544                 :          0 :         (void) manager_setup_cgroups_agent(m);
    3545                 :          0 :         (void) manager_setup_user_lookup_fd(m);
    3546                 :            : 
    3547                 :            :         /* Third, fire things up! */
    3548                 :          0 :         manager_coldplug(m);
    3549                 :            : 
    3550                 :            :         /* Clean up runtime objects no longer referenced */
    3551                 :          0 :         manager_vacuum(m);
    3552                 :            : 
    3553                 :            :         /* Consider the reload process complete now. */
    3554         [ #  # ]:          0 :         assert(m->n_reloading > 0);
    3555                 :          0 :         m->n_reloading--;
    3556                 :            : 
    3557                 :            :         /* On manager reloading, device tag data should exists, thus, we should honor the results of device
    3558                 :            :          * enumeration. The flag should be always set correctly by the serialized data, but it may fail. So,
    3559                 :            :          * let's always set the flag here for safety. */
    3560                 :          0 :         m->honor_device_enumeration = true;
    3561                 :            : 
    3562                 :          0 :         manager_ready(m);
    3563                 :            : 
    3564                 :          0 :         m->send_reloading_done = true;
    3565                 :          0 :         return 0;
    3566                 :            : }
    3567                 :            : 
    3568                 :          0 : void manager_reset_failed(Manager *m) {
    3569                 :            :         Unit *u;
    3570                 :            :         Iterator i;
    3571                 :            : 
    3572         [ #  # ]:          0 :         assert(m);
    3573                 :            : 
    3574         [ #  # ]:          0 :         HASHMAP_FOREACH(u, m->units, i)
    3575                 :          0 :                 unit_reset_failed(u);
    3576                 :          0 : }
    3577                 :            : 
    3578                 :          0 : bool manager_unit_inactive_or_pending(Manager *m, const char *name) {
    3579                 :            :         Unit *u;
    3580                 :            : 
    3581         [ #  # ]:          0 :         assert(m);
    3582         [ #  # ]:          0 :         assert(name);
    3583                 :            : 
    3584                 :            :         /* Returns true if the unit is inactive or going down */
    3585                 :          0 :         u = manager_get_unit(m, name);
    3586         [ #  # ]:          0 :         if (!u)
    3587                 :          0 :                 return true;
    3588                 :            : 
    3589                 :          0 :         return unit_inactive_or_pending(u);
    3590                 :            : }
    3591                 :            : 
    3592                 :         24 : static void log_taint_string(Manager *m) {
    3593         [ -  + ]:         24 :         _cleanup_free_ char *taint = NULL;
    3594                 :            : 
    3595         [ -  + ]:         24 :         assert(m);
    3596                 :            : 
    3597   [ -  +  #  # ]:         24 :         if (MANAGER_IS_USER(m) || m->taint_logged)
    3598                 :         24 :                 return;
    3599                 :            : 
    3600                 :          0 :         m->taint_logged = true; /* only check for taint once */
    3601                 :            : 
    3602                 :          0 :         taint = manager_taint_string(m);
    3603         [ #  # ]:          0 :         if (isempty(taint))
    3604                 :          0 :                 return;
    3605                 :            : 
    3606                 :          0 :         log_struct(LOG_NOTICE,
    3607                 :            :                    LOG_MESSAGE("System is tainted: %s", taint),
    3608                 :            :                    "TAINT=%s", taint,
    3609                 :            :                    "MESSAGE_ID=" SD_MESSAGE_TAINTED_STR);
    3610                 :            : }
    3611                 :            : 
    3612                 :          4 : static void manager_notify_finished(Manager *m) {
    3613                 :            :         char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
    3614                 :            :         usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec;
    3615                 :            : 
    3616         [ +  - ]:          4 :         if (MANAGER_IS_TEST_RUN(m))
    3617                 :          4 :                 return;
    3618                 :            : 
    3619   [ #  #  #  # ]:          0 :         if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) {
    3620                 :            :                 char ts[FORMAT_TIMESPAN_MAX];
    3621                 :          0 :                 char buf[FORMAT_TIMESPAN_MAX + STRLEN(" (firmware) + ") + FORMAT_TIMESPAN_MAX + STRLEN(" (loader) + ")]
    3622                 :            :                         = {};
    3623                 :          0 :                 char *p = buf;
    3624                 :          0 :                 size_t size = sizeof buf;
    3625                 :            : 
    3626                 :            :                 /* Note that MANAGER_TIMESTAMP_KERNEL's monotonic value is always at 0, and
    3627                 :            :                  * MANAGER_TIMESTAMP_FIRMWARE's and MANAGER_TIMESTAMP_LOADER's monotonic value should be considered
    3628                 :            :                  * negative values. */
    3629                 :            : 
    3630                 :          0 :                 firmware_usec = m->timestamps[MANAGER_TIMESTAMP_FIRMWARE].monotonic - m->timestamps[MANAGER_TIMESTAMP_LOADER].monotonic;
    3631                 :          0 :                 loader_usec = m->timestamps[MANAGER_TIMESTAMP_LOADER].monotonic - m->timestamps[MANAGER_TIMESTAMP_KERNEL].monotonic;
    3632                 :          0 :                 userspace_usec = m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic - m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic;
    3633                 :          0 :                 total_usec = m->timestamps[MANAGER_TIMESTAMP_FIRMWARE].monotonic + m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic;
    3634                 :            : 
    3635         [ #  # ]:          0 :                 if (firmware_usec > 0)
    3636                 :          0 :                         size = strpcpyf(&p, size, "%s (firmware) + ", format_timespan(ts, sizeof(ts), firmware_usec, USEC_PER_MSEC));
    3637         [ #  # ]:          0 :                 if (loader_usec > 0)
    3638                 :          0 :                         size = strpcpyf(&p, size, "%s (loader) + ", format_timespan(ts, sizeof(ts), loader_usec, USEC_PER_MSEC));
    3639                 :            : 
    3640         [ #  # ]:          0 :                 if (dual_timestamp_is_set(&m->timestamps[MANAGER_TIMESTAMP_INITRD])) {
    3641                 :            : 
    3642                 :            :                         /* The initrd case on bare-metal*/
    3643                 :          0 :                         kernel_usec = m->timestamps[MANAGER_TIMESTAMP_INITRD].monotonic - m->timestamps[MANAGER_TIMESTAMP_KERNEL].monotonic;
    3644                 :          0 :                         initrd_usec = m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic - m->timestamps[MANAGER_TIMESTAMP_INITRD].monotonic;
    3645                 :            : 
    3646                 :          0 :                         log_struct(LOG_INFO,
    3647                 :            :                                    "MESSAGE_ID=" SD_MESSAGE_STARTUP_FINISHED_STR,
    3648                 :            :                                    "KERNEL_USEC="USEC_FMT, kernel_usec,
    3649                 :            :                                    "INITRD_USEC="USEC_FMT, initrd_usec,
    3650                 :            :                                    "USERSPACE_USEC="USEC_FMT, userspace_usec,
    3651                 :            :                                    LOG_MESSAGE("Startup finished in %s%s (kernel) + %s (initrd) + %s (userspace) = %s.",
    3652                 :            :                                                buf,
    3653                 :            :                                                format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
    3654                 :            :                                                format_timespan(initrd, sizeof(initrd), initrd_usec, USEC_PER_MSEC),
    3655                 :            :                                                format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
    3656                 :            :                                                format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)));
    3657                 :            :                 } else {
    3658                 :            :                         /* The initrd-less case on bare-metal*/
    3659                 :            : 
    3660                 :          0 :                         kernel_usec = m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic - m->timestamps[MANAGER_TIMESTAMP_KERNEL].monotonic;
    3661                 :          0 :                         initrd_usec = 0;
    3662                 :            : 
    3663                 :          0 :                         log_struct(LOG_INFO,
    3664                 :            :                                    "MESSAGE_ID=" SD_MESSAGE_STARTUP_FINISHED_STR,
    3665                 :            :                                    "KERNEL_USEC="USEC_FMT, kernel_usec,
    3666                 :            :                                    "USERSPACE_USEC="USEC_FMT, userspace_usec,
    3667                 :            :                                    LOG_MESSAGE("Startup finished in %s%s (kernel) + %s (userspace) = %s.",
    3668                 :            :                                                buf,
    3669                 :            :                                                format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
    3670                 :            :                                                format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
    3671                 :            :                                                format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)));
    3672                 :            :                 }
    3673                 :            :         } else {
    3674                 :            :                 /* The container and --user case */
    3675                 :          0 :                 firmware_usec = loader_usec = initrd_usec = kernel_usec = 0;
    3676                 :          0 :                 total_usec = userspace_usec = m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic - m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic;
    3677                 :            : 
    3678                 :          0 :                 log_struct(LOG_INFO,
    3679                 :            :                            "MESSAGE_ID=" SD_MESSAGE_USER_STARTUP_FINISHED_STR,
    3680                 :            :                            "USERSPACE_USEC="USEC_FMT, userspace_usec,
    3681                 :            :                            LOG_MESSAGE("Startup finished in %s.",
    3682                 :            :                                        format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)));
    3683                 :            :         }
    3684                 :            : 
    3685                 :          0 :         bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
    3686                 :            : 
    3687                 :          0 :         sd_notifyf(false,
    3688         [ #  # ]:          0 :                    m->ready_sent ? "STATUS=Startup finished in %s."
    3689                 :            :                                  : "READY=1\n"
    3690                 :            :                                    "STATUS=Startup finished in %s.",
    3691                 :            :                    format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC));
    3692                 :          0 :         m->ready_sent = true;
    3693                 :            : 
    3694                 :          0 :         log_taint_string(m);
    3695                 :            : }
    3696                 :            : 
    3697                 :         24 : static void manager_send_ready(Manager *m) {
    3698         [ -  + ]:         24 :         assert(m);
    3699                 :            : 
    3700                 :            :         /* We send READY=1 on reaching basic.target only when running in --user mode. */
    3701   [ +  -  -  + ]:         24 :         if (!MANAGER_IS_USER(m) || m->ready_sent)
    3702                 :          0 :                 return;
    3703                 :            : 
    3704                 :         24 :         m->ready_sent = true;
    3705                 :            : 
    3706                 :         24 :         sd_notifyf(false,
    3707                 :            :                    "READY=1\n"
    3708                 :            :                    "STATUS=Reached " SPECIAL_BASIC_TARGET ".");
    3709                 :            : }
    3710                 :            : 
    3711                 :        176 : static void manager_check_basic_target(Manager *m) {
    3712                 :            :         Unit *u;
    3713                 :            : 
    3714         [ -  + ]:        176 :         assert(m);
    3715                 :            : 
    3716                 :            :         /* Small shortcut */
    3717   [ -  +  #  # ]:        176 :         if (m->ready_sent && m->taint_logged)
    3718                 :          0 :                 return;
    3719                 :            : 
    3720                 :        176 :         u = manager_get_unit(m, SPECIAL_BASIC_TARGET);
    3721   [ +  -  +  + ]:        176 :         if (!u || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u)))
    3722                 :        152 :                 return;
    3723                 :            : 
    3724                 :            :         /* For user managers, send out READY=1 as soon as we reach basic.target */
    3725                 :         24 :         manager_send_ready(m);
    3726                 :            : 
    3727                 :            :         /* Log the taint string as soon as we reach basic.target */
    3728                 :         24 :         log_taint_string(m);
    3729                 :            : }
    3730                 :            : 
    3731                 :        176 : void manager_check_finished(Manager *m) {
    3732         [ -  + ]:        176 :         assert(m);
    3733                 :            : 
    3734         [ -  + ]:        176 :         if (MANAGER_IS_RELOADING(m))
    3735                 :          0 :                 return;
    3736                 :            : 
    3737                 :            :         /* Verify that we have entered the event loop already, and not left it again. */
    3738         [ -  + ]:        176 :         if (!MANAGER_IS_RUNNING(m))
    3739                 :          0 :                 return;
    3740                 :            : 
    3741                 :        176 :         manager_check_basic_target(m);
    3742                 :            : 
    3743         [ +  + ]:        176 :         if (hashmap_size(m->jobs) > 0) {
    3744         [ -  + ]:        164 :                 if (m->jobs_in_progress_event_source)
    3745                 :            :                         /* Ignore any failure, this is only for feedback */
    3746                 :          0 :                         (void) sd_event_source_set_time(m->jobs_in_progress_event_source, now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC);
    3747                 :            : 
    3748                 :        164 :                 return;
    3749                 :            :         }
    3750                 :            : 
    3751                 :         12 :         manager_flip_auto_status(m, false);
    3752                 :            : 
    3753                 :            :         /* Notify Type=idle units that we are done now */
    3754                 :         12 :         manager_close_idle_pipe(m);
    3755                 :            : 
    3756                 :            :         /* Turn off confirm spawn now */
    3757                 :         12 :         m->confirm_spawn = NULL;
    3758                 :            : 
    3759                 :            :         /* No need to update ask password status when we're going non-interactive */
    3760                 :         12 :         manager_close_ask_password(m);
    3761                 :            : 
    3762                 :            :         /* This is no longer the first boot */
    3763                 :         12 :         manager_set_first_boot(m, false);
    3764                 :            : 
    3765         [ +  + ]:         12 :         if (MANAGER_IS_FINISHED(m))
    3766                 :          8 :                 return;
    3767                 :            : 
    3768                 :          4 :         dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_FINISH);
    3769                 :            : 
    3770                 :          4 :         manager_notify_finished(m);
    3771                 :            : 
    3772                 :          4 :         manager_invalidate_startup_units(m);
    3773                 :            : }
    3774                 :            : 
    3775                 :          0 : static bool generator_path_any(const char* const* paths) {
    3776                 :            :         char **path;
    3777                 :          0 :         bool found = false;
    3778                 :            : 
    3779                 :            :         /* Optimize by skipping the whole process by not creating output directories
    3780                 :            :          * if no generators are found. */
    3781   [ #  #  #  # ]:          0 :         STRV_FOREACH(path, (char**) paths)
    3782         [ #  # ]:          0 :                 if (access(*path, F_OK) == 0)
    3783                 :          0 :                         found = true;
    3784         [ #  # ]:          0 :                 else if (errno != ENOENT)
    3785         [ #  # ]:          0 :                         log_warning_errno(errno, "Failed to open generator directory %s: %m", *path);
    3786                 :            : 
    3787                 :          0 :         return found;
    3788                 :            : }
    3789                 :            : 
    3790                 :            : static const char *const system_env_generator_binary_paths[] = {
    3791                 :            :         "/run/systemd/system-environment-generators",
    3792                 :            :         "/etc/systemd/system-environment-generators",
    3793                 :            :         "/usr/local/lib/systemd/system-environment-generators",
    3794                 :            :         SYSTEM_ENV_GENERATOR_PATH,
    3795                 :            :         NULL
    3796                 :            : };
    3797                 :            : 
    3798                 :            : static const char *const user_env_generator_binary_paths[] = {
    3799                 :            :         "/run/systemd/user-environment-generators",
    3800                 :            :         "/etc/systemd/user-environment-generators",
    3801                 :            :         "/usr/local/lib/systemd/user-environment-generators",
    3802                 :            :         USER_ENV_GENERATOR_PATH,
    3803                 :            :         NULL
    3804                 :            : };
    3805                 :            : 
    3806                 :         52 : static int manager_run_environment_generators(Manager *m) {
    3807                 :         52 :         char **tmp = NULL; /* this is only used in the forked process, no cleanup here */
    3808                 :            :         const char *const *paths;
    3809                 :        104 :         void* args[] = {
    3810                 :            :                 [STDOUT_GENERATE] = &tmp,
    3811                 :            :                 [STDOUT_COLLECT] = &tmp,
    3812                 :         52 :                 [STDOUT_CONSUME] = &m->transient_environment,
    3813                 :            :         };
    3814                 :            :         int r;
    3815                 :            : 
    3816   [ +  -  +  - ]:         52 :         if (MANAGER_IS_TEST_RUN(m) && !(m->test_run_flags & MANAGER_TEST_RUN_ENV_GENERATORS))
    3817                 :         52 :                 return 0;
    3818                 :            : 
    3819         [ #  # ]:          0 :         paths = MANAGER_IS_SYSTEM(m) ? system_env_generator_binary_paths : user_env_generator_binary_paths;
    3820                 :            : 
    3821         [ #  # ]:          0 :         if (!generator_path_any(paths))
    3822                 :          0 :                 return 0;
    3823                 :            : 
    3824         [ #  # ]:          0 :         RUN_WITH_UMASK(0022)
    3825                 :          0 :                 r = execute_directories(paths, DEFAULT_TIMEOUT_USEC, gather_environment,
    3826                 :            :                                         args, NULL, m->transient_environment, EXEC_DIR_PARALLEL | EXEC_DIR_IGNORE_ERRORS);
    3827                 :          0 :         return r;
    3828                 :            : }
    3829                 :            : 
    3830                 :         52 : static int manager_run_generators(Manager *m) {
    3831                 :         52 :         _cleanup_strv_free_ char **paths = NULL;
    3832                 :            :         const char *argv[5];
    3833                 :            :         int r;
    3834                 :            : 
    3835         [ -  + ]:         52 :         assert(m);
    3836                 :            : 
    3837   [ +  -  +  - ]:         52 :         if (MANAGER_IS_TEST_RUN(m) && !(m->test_run_flags & MANAGER_TEST_RUN_GENERATORS))
    3838                 :         52 :                 return 0;
    3839                 :            : 
    3840                 :          0 :         paths = generator_binary_paths(m->unit_file_scope);
    3841         [ #  # ]:          0 :         if (!paths)
    3842                 :          0 :                 return log_oom();
    3843                 :            : 
    3844         [ #  # ]:          0 :         if (!generator_path_any((const char* const*) paths))
    3845                 :          0 :                 return 0;
    3846                 :            : 
    3847                 :          0 :         r = lookup_paths_mkdir_generator(&m->lookup_paths);
    3848         [ #  # ]:          0 :         if (r < 0) {
    3849         [ #  # ]:          0 :                 log_error_errno(r, "Failed to create generator directories: %m");
    3850                 :          0 :                 goto finish;
    3851                 :            :         }
    3852                 :            : 
    3853                 :          0 :         argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
    3854                 :          0 :         argv[1] = m->lookup_paths.generator;
    3855                 :          0 :         argv[2] = m->lookup_paths.generator_early;
    3856                 :          0 :         argv[3] = m->lookup_paths.generator_late;
    3857                 :          0 :         argv[4] = NULL;
    3858                 :            : 
    3859         [ #  # ]:          0 :         RUN_WITH_UMASK(0022)
    3860                 :          0 :                 (void) execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC, NULL, NULL,
    3861                 :            :                                            (char**) argv, m->transient_environment, EXEC_DIR_PARALLEL | EXEC_DIR_IGNORE_ERRORS);
    3862                 :            : 
    3863                 :          0 :         r = 0;
    3864                 :            : 
    3865                 :          0 : finish:
    3866                 :          0 :         lookup_paths_trim_generator(&m->lookup_paths);
    3867                 :          0 :         return r;
    3868                 :            : }
    3869                 :            : 
    3870                 :          0 : int manager_transient_environment_add(Manager *m, char **plus) {
    3871                 :            :         char **a;
    3872                 :            : 
    3873         [ #  # ]:          0 :         assert(m);
    3874                 :            : 
    3875         [ #  # ]:          0 :         if (strv_isempty(plus))
    3876                 :          0 :                 return 0;
    3877                 :            : 
    3878                 :          0 :         a = strv_env_merge(2, m->transient_environment, plus);
    3879         [ #  # ]:          0 :         if (!a)
    3880                 :          0 :                 return log_oom();
    3881                 :            : 
    3882                 :          0 :         sanitize_environment(a);
    3883                 :            : 
    3884                 :          0 :         return strv_free_and_replace(m->transient_environment, a);
    3885                 :            : }
    3886                 :            : 
    3887                 :          0 : int manager_client_environment_modify(
    3888                 :            :                 Manager *m,
    3889                 :            :                 char **minus,
    3890                 :            :                 char **plus) {
    3891                 :            : 
    3892                 :          0 :         char **a = NULL, **b = NULL, **l;
    3893                 :            : 
    3894         [ #  # ]:          0 :         assert(m);
    3895                 :            : 
    3896   [ #  #  #  # ]:          0 :         if (strv_isempty(minus) && strv_isempty(plus))
    3897                 :          0 :                 return 0;
    3898                 :            : 
    3899                 :          0 :         l = m->client_environment;
    3900                 :            : 
    3901         [ #  # ]:          0 :         if (!strv_isempty(minus)) {
    3902                 :          0 :                 a = strv_env_delete(l, 1, minus);
    3903         [ #  # ]:          0 :                 if (!a)
    3904                 :          0 :                         return -ENOMEM;
    3905                 :            : 
    3906                 :          0 :                 l = a;
    3907                 :            :         }
    3908                 :            : 
    3909         [ #  # ]:          0 :         if (!strv_isempty(plus)) {
    3910                 :          0 :                 b = strv_env_merge(2, l, plus);
    3911         [ #  # ]:          0 :                 if (!b) {
    3912                 :          0 :                         strv_free(a);
    3913                 :          0 :                         return -ENOMEM;
    3914                 :            :                 }
    3915                 :            : 
    3916                 :          0 :                 l = b;
    3917                 :            :         }
    3918                 :            : 
    3919         [ #  # ]:          0 :         if (m->client_environment != l)
    3920                 :          0 :                 strv_free(m->client_environment);
    3921                 :            : 
    3922         [ #  # ]:          0 :         if (a != l)
    3923                 :          0 :                 strv_free(a);
    3924         [ #  # ]:          0 :         if (b != l)
    3925                 :          0 :                 strv_free(b);
    3926                 :            : 
    3927                 :          0 :         m->client_environment = sanitize_environment(l);
    3928                 :          0 :         return 0;
    3929                 :            : }
    3930                 :            : 
    3931                 :         24 : int manager_get_effective_environment(Manager *m, char ***ret) {
    3932                 :            :         char **l;
    3933                 :            : 
    3934         [ -  + ]:         24 :         assert(m);
    3935         [ -  + ]:         24 :         assert(ret);
    3936                 :            : 
    3937                 :         24 :         l = strv_env_merge(2, m->transient_environment, m->client_environment);
    3938         [ -  + ]:         24 :         if (!l)
    3939                 :          0 :                 return -ENOMEM;
    3940                 :            : 
    3941                 :         24 :         *ret = l;
    3942                 :         24 :         return 0;
    3943                 :            : }
    3944                 :            : 
    3945                 :          0 : int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) {
    3946                 :            :         int i;
    3947                 :            : 
    3948         [ #  # ]:          0 :         assert(m);
    3949                 :            : 
    3950         [ #  # ]:          0 :         for (i = 0; i < _RLIMIT_MAX; i++) {
    3951                 :          0 :                 m->rlimit[i] = mfree(m->rlimit[i]);
    3952                 :            : 
    3953         [ #  # ]:          0 :                 if (!default_rlimit[i])
    3954                 :          0 :                         continue;
    3955                 :            : 
    3956                 :          0 :                 m->rlimit[i] = newdup(struct rlimit, default_rlimit[i], 1);
    3957         [ #  # ]:          0 :                 if (!m->rlimit[i])
    3958                 :          0 :                         return log_oom();
    3959                 :            :         }
    3960                 :            : 
    3961                 :          0 :         return 0;
    3962                 :            : }
    3963                 :            : 
    3964                 :       7136 : void manager_recheck_dbus(Manager *m) {
    3965         [ -  + ]:       7136 :         assert(m);
    3966                 :            : 
    3967                 :            :         /* Connects to the bus if the dbus service and socket are running. If we are running in user mode this is all
    3968                 :            :          * it does. In system mode we'll also connect to the system bus (which will most likely just reuse the
    3969                 :            :          * connection of the API bus). That's because the system bus after all runs as service of the system instance,
    3970                 :            :          * while in the user instance we can assume it's already there. */
    3971                 :            : 
    3972         [ -  + ]:       7136 :         if (MANAGER_IS_RELOADING(m))
    3973                 :          0 :                 return; /* don't check while we are reloading… */
    3974                 :            : 
    3975         [ -  + ]:       7136 :         if (manager_dbus_is_running(m, false)) {
    3976                 :          0 :                 (void) bus_init_api(m);
    3977                 :            : 
    3978         [ #  # ]:          0 :                 if (MANAGER_IS_SYSTEM(m))
    3979                 :          0 :                         (void) bus_init_system(m);
    3980                 :            :         } else {
    3981                 :       7136 :                 (void) bus_done_api(m);
    3982                 :            : 
    3983         [ -  + ]:       7136 :                 if (MANAGER_IS_SYSTEM(m))
    3984                 :          0 :                         (void) bus_done_system(m);
    3985                 :            :         }
    3986                 :            : }
    3987                 :            : 
    3988                 :          0 : static bool manager_journal_is_running(Manager *m) {
    3989                 :            :         Unit *u;
    3990                 :            : 
    3991         [ #  # ]:          0 :         assert(m);
    3992                 :            : 
    3993         [ #  # ]:          0 :         if (MANAGER_IS_TEST_RUN(m))
    3994                 :          0 :                 return false;
    3995                 :            : 
    3996                 :            :         /* If we are the user manager we can safely assume that the journal is up */
    3997         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
    3998                 :          0 :                 return true;
    3999                 :            : 
    4000                 :            :         /* Check that the socket is not only up, but in RUNNING state */
    4001                 :          0 :         u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
    4002         [ #  # ]:          0 :         if (!u)
    4003                 :          0 :                 return false;
    4004         [ #  # ]:          0 :         if (SOCKET(u)->state != SOCKET_RUNNING)
    4005                 :          0 :                 return false;
    4006                 :            : 
    4007                 :            :         /* Similar, check if the daemon itself is fully up, too */
    4008                 :          0 :         u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE);
    4009         [ #  # ]:          0 :         if (!u)
    4010                 :          0 :                 return false;
    4011   [ #  #  #  # ]:          0 :         if (!IN_SET(SERVICE(u)->state, SERVICE_RELOAD, SERVICE_RUNNING))
    4012                 :          0 :                 return false;
    4013                 :            : 
    4014                 :          0 :         return true;
    4015                 :            : }
    4016                 :            : 
    4017                 :       7136 : void manager_recheck_journal(Manager *m) {
    4018                 :            : 
    4019         [ -  + ]:       7136 :         assert(m);
    4020                 :            : 
    4021                 :            :         /* Don't bother with this unless we are in the special situation of being PID 1 */
    4022         [ +  - ]:       7136 :         if (getpid_cached() != 1)
    4023                 :       7136 :                 return;
    4024                 :            : 
    4025                 :            :         /* Don't check this while we are reloading, things might still change */
    4026         [ #  # ]:          0 :         if (MANAGER_IS_RELOADING(m))
    4027                 :          0 :                 return;
    4028                 :            : 
    4029                 :            :         /* The journal is fully and entirely up? If so, let's permit logging to it, if that's configured. If the
    4030                 :            :          * journal is down, don't ever log to it, otherwise we might end up deadlocking ourselves as we might trigger
    4031                 :            :          * an activation ourselves we can't fulfill. */
    4032                 :          0 :         log_set_prohibit_ipc(!manager_journal_is_running(m));
    4033                 :          0 :         log_open();
    4034                 :            : }
    4035                 :            : 
    4036                 :          0 : void manager_set_show_status(Manager *m, ShowStatus mode) {
    4037         [ #  # ]:          0 :         assert(m);
    4038   [ #  #  #  # ]:          0 :         assert(IN_SET(mode, SHOW_STATUS_AUTO, SHOW_STATUS_NO, SHOW_STATUS_YES, SHOW_STATUS_TEMPORARY));
    4039                 :            : 
    4040         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
    4041                 :          0 :                 return;
    4042                 :            : 
    4043         [ #  # ]:          0 :         if (m->show_status != mode)
    4044   [ #  #  #  # ]:          0 :                 log_debug("%s showing of status.",
    4045                 :            :                           mode == SHOW_STATUS_NO ? "Disabling" : "Enabling");
    4046                 :          0 :         m->show_status = mode;
    4047                 :            : 
    4048   [ #  #  #  # ]:          0 :         if (IN_SET(mode, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES))
    4049                 :          0 :                 (void) touch("/run/systemd/show-status");
    4050                 :            :         else
    4051                 :          0 :                 (void) unlink("/run/systemd/show-status");
    4052                 :            : }
    4053                 :            : 
    4054                 :        104 : static bool manager_get_show_status(Manager *m, StatusType type) {
    4055         [ -  + ]:        104 :         assert(m);
    4056                 :            : 
    4057         [ +  - ]:        104 :         if (!MANAGER_IS_SYSTEM(m))
    4058                 :        104 :                 return false;
    4059                 :            : 
    4060         [ #  # ]:          0 :         if (m->no_console_output)
    4061                 :          0 :                 return false;
    4062                 :            : 
    4063   [ #  #  #  # ]:          0 :         if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
    4064                 :          0 :                 return false;
    4065                 :            : 
    4066                 :            :         /* If we cannot find out the status properly, just proceed. */
    4067   [ #  #  #  # ]:          0 :         if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0)
    4068                 :          0 :                 return false;
    4069                 :            : 
    4070         [ #  # ]:          0 :         return IN_SET(m->show_status, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES);
    4071                 :            : }
    4072                 :            : 
    4073                 :         24 : const char *manager_get_confirm_spawn(Manager *m) {
    4074                 :            :         static int last_errno = 0;
    4075                 :            :         struct stat st;
    4076                 :            :         int r;
    4077                 :            : 
    4078         [ -  + ]:         24 :         assert(m);
    4079                 :            : 
    4080                 :            :         /* Here's the deal: we want to test the validity of the console but don't want
    4081                 :            :          * PID1 to go through the whole console process which might block. But we also
    4082                 :            :          * want to warn the user only once if something is wrong with the console so we
    4083                 :            :          * cannot do the sanity checks after spawning our children. So here we simply do
    4084                 :            :          * really basic tests to hopefully trap common errors.
    4085                 :            :          *
    4086                 :            :          * If the console suddenly disappear at the time our children will really it
    4087                 :            :          * then they will simply fail to acquire it and a positive answer will be
    4088                 :            :          * assumed. New children will fallback to /dev/console though.
    4089                 :            :          *
    4090                 :            :          * Note: TTYs are devices that can come and go any time, and frequently aren't
    4091                 :            :          * available yet during early boot (consider a USB rs232 dongle...). If for any
    4092                 :            :          * reason the configured console is not ready, we fallback to the default
    4093                 :            :          * console. */
    4094                 :            : 
    4095   [ -  +  #  # ]:         24 :         if (!m->confirm_spawn || path_equal(m->confirm_spawn, "/dev/console"))
    4096                 :         24 :                 return m->confirm_spawn;
    4097                 :            : 
    4098         [ #  # ]:          0 :         if (stat(m->confirm_spawn, &st) < 0) {
    4099                 :          0 :                 r = -errno;
    4100                 :          0 :                 goto fail;
    4101                 :            :         }
    4102                 :            : 
    4103         [ #  # ]:          0 :         if (!S_ISCHR(st.st_mode)) {
    4104                 :          0 :                 r = -ENOTTY;
    4105                 :          0 :                 goto fail;
    4106                 :            :         }
    4107                 :            : 
    4108                 :          0 :         last_errno = 0;
    4109                 :          0 :         return m->confirm_spawn;
    4110                 :            : 
    4111                 :          0 : fail:
    4112         [ #  # ]:          0 :         if (last_errno != r)
    4113         [ #  # ]:          0 :                 last_errno = log_warning_errno(r, "Failed to open %s, using default console: %m", m->confirm_spawn);
    4114                 :            : 
    4115                 :          0 :         return "/dev/console";
    4116                 :            : }
    4117                 :            : 
    4118                 :         12 : void manager_set_first_boot(Manager *m, bool b) {
    4119         [ -  + ]:         12 :         assert(m);
    4120                 :            : 
    4121         [ +  - ]:         12 :         if (!MANAGER_IS_SYSTEM(m))
    4122                 :         12 :                 return;
    4123                 :            : 
    4124         [ #  # ]:          0 :         if (m->first_boot != (int) b) {
    4125         [ #  # ]:          0 :                 if (b)
    4126                 :          0 :                         (void) touch("/run/systemd/first-boot");
    4127                 :            :                 else
    4128                 :          0 :                         (void) unlink("/run/systemd/first-boot");
    4129                 :            :         }
    4130                 :            : 
    4131                 :          0 :         m->first_boot = b;
    4132                 :            : }
    4133                 :            : 
    4134                 :          0 : void manager_disable_confirm_spawn(void) {
    4135                 :          0 :         (void) touch("/run/systemd/confirm_spawn_disabled");
    4136                 :          0 : }
    4137                 :            : 
    4138                 :         24 : bool manager_is_confirm_spawn_disabled(Manager *m) {
    4139         [ +  - ]:         24 :         if (!m->confirm_spawn)
    4140                 :         24 :                 return true;
    4141                 :            : 
    4142                 :          0 :         return access("/run/systemd/confirm_spawn_disabled", F_OK) >= 0;
    4143                 :            : }
    4144                 :            : 
    4145                 :        104 : void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) {
    4146                 :            :         va_list ap;
    4147                 :            : 
    4148                 :            :         /* If m is NULL, assume we're after shutdown and let the messages through. */
    4149                 :            : 
    4150   [ +  -  +  - ]:        104 :         if (m && !manager_get_show_status(m, type))
    4151                 :        104 :                 return;
    4152                 :            : 
    4153                 :            :         /* XXX We should totally drop the check for ephemeral here
    4154                 :            :          * and thus effectively make 'Type=idle' pointless. */
    4155   [ #  #  #  #  :          0 :         if (type == STATUS_TYPE_EPHEMERAL && m && m->n_on_console > 0)
                   #  # ]
    4156                 :          0 :                 return;
    4157                 :            : 
    4158                 :          0 :         va_start(ap, format);
    4159         [ #  # ]:          0 :         status_vprintf(status, SHOW_STATUS_ELLIPSIZE|(type == STATUS_TYPE_EPHEMERAL ? SHOW_STATUS_EPHEMERAL : 0), format, ap);
    4160                 :          0 :         va_end(ap);
    4161                 :            : }
    4162                 :            : 
    4163                 :        704 : Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
    4164                 :        704 :         char p[strlen(path)+1];
    4165                 :            : 
    4166         [ -  + ]:        704 :         assert(m);
    4167         [ -  + ]:        704 :         assert(path);
    4168                 :            : 
    4169                 :        704 :         strcpy(p, path);
    4170                 :        704 :         path_simplify(p, false);
    4171                 :            : 
    4172         [ +  + ]:        704 :         return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p);
    4173                 :            : }
    4174                 :            : 
    4175                 :      15812 : int manager_update_failed_units(Manager *m, Unit *u, bool failed) {
    4176                 :            :         unsigned size;
    4177                 :            :         int r;
    4178                 :            : 
    4179         [ -  + ]:      15812 :         assert(m);
    4180         [ -  + ]:      15812 :         assert(u->manager == m);
    4181                 :            : 
    4182                 :      15812 :         size = set_size(m->failed_units);
    4183                 :            : 
    4184         [ -  + ]:      15812 :         if (failed) {
    4185                 :          0 :                 r = set_ensure_allocated(&m->failed_units, NULL);
    4186         [ #  # ]:          0 :                 if (r < 0)
    4187                 :          0 :                         return log_oom();
    4188                 :            : 
    4189         [ #  # ]:          0 :                 if (set_put(m->failed_units, u) < 0)
    4190                 :          0 :                         return log_oom();
    4191                 :            :         } else
    4192                 :      15812 :                 (void) set_remove(m->failed_units, u);
    4193                 :            : 
    4194         [ -  + ]:      15812 :         if (set_size(m->failed_units) != size)
    4195                 :          0 :                 bus_manager_send_change_signal(m);
    4196                 :            : 
    4197                 :      15812 :         return 0;
    4198                 :            : }
    4199                 :            : 
    4200                 :        472 : ManagerState manager_state(Manager *m) {
    4201                 :            :         Unit *u;
    4202                 :            : 
    4203         [ -  + ]:        472 :         assert(m);
    4204                 :            : 
    4205                 :            :         /* Did we ever finish booting? If not then we are still starting up */
    4206         [ +  + ]:        472 :         if (!MANAGER_IS_FINISHED(m)) {
    4207                 :            : 
    4208                 :        326 :                 u = manager_get_unit(m, SPECIAL_BASIC_TARGET);
    4209   [ +  -  +  + ]:        326 :                 if (!u || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u)))
    4210                 :        302 :                         return MANAGER_INITIALIZING;
    4211                 :            : 
    4212                 :         24 :                 return MANAGER_STARTING;
    4213                 :            :         }
    4214                 :            : 
    4215                 :            :         /* Is the special shutdown target active or queued? If so, we are in shutdown state */
    4216                 :        146 :         u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
    4217   [ +  -  -  + ]:        146 :         if (u && unit_active_or_pending(u))
    4218                 :          0 :                 return MANAGER_STOPPING;
    4219                 :            : 
    4220         [ -  + ]:        146 :         if (MANAGER_IS_SYSTEM(m)) {
    4221                 :            :                 /* Are the rescue or emergency targets active or queued? If so we are in maintenance state */
    4222                 :          0 :                 u = manager_get_unit(m, SPECIAL_RESCUE_TARGET);
    4223   [ #  #  #  # ]:          0 :                 if (u && unit_active_or_pending(u))
    4224                 :          0 :                         return MANAGER_MAINTENANCE;
    4225                 :            : 
    4226                 :          0 :                 u = manager_get_unit(m, SPECIAL_EMERGENCY_TARGET);
    4227   [ #  #  #  # ]:          0 :                 if (u && unit_active_or_pending(u))
    4228                 :          0 :                         return MANAGER_MAINTENANCE;
    4229                 :            :         }
    4230                 :            : 
    4231                 :            :         /* Are there any failed units? If so, we are in degraded mode */
    4232         [ -  + ]:        146 :         if (set_size(m->failed_units) > 0)
    4233                 :          0 :                 return MANAGER_DEGRADED;
    4234                 :            : 
    4235                 :        146 :         return MANAGER_RUNNING;
    4236                 :            : }
    4237                 :            : 
    4238                 :            : #define DESTROY_IPC_FLAG (UINT32_C(1) << 31)
    4239                 :            : 
    4240                 :          0 : static void manager_unref_uid_internal(
    4241                 :            :                 Manager *m,
    4242                 :            :                 Hashmap **uid_refs,
    4243                 :            :                 uid_t uid,
    4244                 :            :                 bool destroy_now,
    4245                 :            :                 int (*_clean_ipc)(uid_t uid)) {
    4246                 :            : 
    4247                 :            :         uint32_t c, n;
    4248                 :            : 
    4249         [ #  # ]:          0 :         assert(m);
    4250         [ #  # ]:          0 :         assert(uid_refs);
    4251         [ #  # ]:          0 :         assert(uid_is_valid(uid));
    4252         [ #  # ]:          0 :         assert(_clean_ipc);
    4253                 :            : 
    4254                 :            :         /* A generic implementation, covering both manager_unref_uid() and manager_unref_gid(), under the assumption
    4255                 :            :          * that uid_t and gid_t are actually defined the same way, with the same validity rules.
    4256                 :            :          *
    4257                 :            :          * We store a hashmap where the UID/GID is they key and the value is a 32bit reference counter, whose highest
    4258                 :            :          * bit is used as flag for marking UIDs/GIDs whose IPC objects to remove when the last reference to the UID/GID
    4259                 :            :          * is dropped. The flag is set to on, once at least one reference from a unit where RemoveIPC= is set is added
    4260                 :            :          * on a UID/GID. It is reset when the UID's/GID's reference counter drops to 0 again. */
    4261                 :            : 
    4262                 :            :         assert_cc(sizeof(uid_t) == sizeof(gid_t));
    4263                 :            :         assert_cc(UID_INVALID == (uid_t) GID_INVALID);
    4264                 :            : 
    4265         [ #  # ]:          0 :         if (uid == 0) /* We don't keep track of root, and will never destroy it */
    4266                 :          0 :                 return;
    4267                 :            : 
    4268                 :          0 :         c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid)));
    4269                 :            : 
    4270                 :          0 :         n = c & ~DESTROY_IPC_FLAG;
    4271         [ #  # ]:          0 :         assert(n > 0);
    4272                 :          0 :         n--;
    4273                 :            : 
    4274   [ #  #  #  # ]:          0 :         if (destroy_now && n == 0) {
    4275                 :          0 :                 hashmap_remove(*uid_refs, UID_TO_PTR(uid));
    4276                 :            : 
    4277         [ #  # ]:          0 :                 if (c & DESTROY_IPC_FLAG) {
    4278   [ #  #  #  # ]:          0 :                         log_debug("%s " UID_FMT " is no longer referenced, cleaning up its IPC.",
    4279                 :            :                                   _clean_ipc == clean_ipc_by_uid ? "UID" : "GID",
    4280                 :            :                                   uid);
    4281                 :          0 :                         (void) _clean_ipc(uid);
    4282                 :            :                 }
    4283                 :            :         } else {
    4284                 :          0 :                 c = n | (c & DESTROY_IPC_FLAG);
    4285         [ #  # ]:          0 :                 assert_se(hashmap_update(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c)) >= 0);
    4286                 :            :         }
    4287                 :            : }
    4288                 :            : 
    4289                 :          0 : void manager_unref_uid(Manager *m, uid_t uid, bool destroy_now) {
    4290                 :          0 :         manager_unref_uid_internal(m, &m->uid_refs, uid, destroy_now, clean_ipc_by_uid);
    4291                 :          0 : }
    4292                 :            : 
    4293                 :          0 : void manager_unref_gid(Manager *m, gid_t gid, bool destroy_now) {
    4294                 :          0 :         manager_unref_uid_internal(m, &m->gid_refs, (uid_t) gid, destroy_now, clean_ipc_by_gid);
    4295                 :          0 : }
    4296                 :            : 
    4297                 :          0 : static int manager_ref_uid_internal(
    4298                 :            :                 Manager *m,
    4299                 :            :                 Hashmap **uid_refs,
    4300                 :            :                 uid_t uid,
    4301                 :            :                 bool clean_ipc) {
    4302                 :            : 
    4303                 :            :         uint32_t c, n;
    4304                 :            :         int r;
    4305                 :            : 
    4306         [ #  # ]:          0 :         assert(m);
    4307         [ #  # ]:          0 :         assert(uid_refs);
    4308         [ #  # ]:          0 :         assert(uid_is_valid(uid));
    4309                 :            : 
    4310                 :            :         /* A generic implementation, covering both manager_ref_uid() and manager_ref_gid(), under the assumption
    4311                 :            :          * that uid_t and gid_t are actually defined the same way, with the same validity rules. */
    4312                 :            : 
    4313                 :            :         assert_cc(sizeof(uid_t) == sizeof(gid_t));
    4314                 :            :         assert_cc(UID_INVALID == (uid_t) GID_INVALID);
    4315                 :            : 
    4316         [ #  # ]:          0 :         if (uid == 0) /* We don't keep track of root, and will never destroy it */
    4317                 :          0 :                 return 0;
    4318                 :            : 
    4319                 :          0 :         r = hashmap_ensure_allocated(uid_refs, &trivial_hash_ops);
    4320         [ #  # ]:          0 :         if (r < 0)
    4321                 :          0 :                 return r;
    4322                 :            : 
    4323                 :          0 :         c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid)));
    4324                 :            : 
    4325                 :          0 :         n = c & ~DESTROY_IPC_FLAG;
    4326                 :          0 :         n++;
    4327                 :            : 
    4328         [ #  # ]:          0 :         if (n & DESTROY_IPC_FLAG) /* check for overflow */
    4329                 :          0 :                 return -EOVERFLOW;
    4330                 :            : 
    4331         [ #  # ]:          0 :         c = n | (c & DESTROY_IPC_FLAG) | (clean_ipc ? DESTROY_IPC_FLAG : 0);
    4332                 :            : 
    4333                 :          0 :         return hashmap_replace(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c));
    4334                 :            : }
    4335                 :            : 
    4336                 :          0 : int manager_ref_uid(Manager *m, uid_t uid, bool clean_ipc) {
    4337                 :          0 :         return manager_ref_uid_internal(m, &m->uid_refs, uid, clean_ipc);
    4338                 :            : }
    4339                 :            : 
    4340                 :          0 : int manager_ref_gid(Manager *m, gid_t gid, bool clean_ipc) {
    4341                 :          0 :         return manager_ref_uid_internal(m, &m->gid_refs, (uid_t) gid, clean_ipc);
    4342                 :            : }
    4343                 :            : 
    4344                 :        104 : static void manager_vacuum_uid_refs_internal(
    4345                 :            :                 Manager *m,
    4346                 :            :                 Hashmap **uid_refs,
    4347                 :            :                 int (*_clean_ipc)(uid_t uid)) {
    4348                 :            : 
    4349                 :            :         Iterator i;
    4350                 :            :         void *p, *k;
    4351                 :            : 
    4352         [ -  + ]:        104 :         assert(m);
    4353         [ -  + ]:        104 :         assert(uid_refs);
    4354         [ -  + ]:        104 :         assert(_clean_ipc);
    4355                 :            : 
    4356         [ -  + ]:        104 :         HASHMAP_FOREACH_KEY(p, k, *uid_refs, i) {
    4357                 :            :                 uint32_t c, n;
    4358                 :            :                 uid_t uid;
    4359                 :            : 
    4360                 :          0 :                 uid = PTR_TO_UID(k);
    4361                 :          0 :                 c = PTR_TO_UINT32(p);
    4362                 :            : 
    4363                 :          0 :                 n = c & ~DESTROY_IPC_FLAG;
    4364         [ #  # ]:          0 :                 if (n > 0)
    4365                 :          0 :                         continue;
    4366                 :            : 
    4367         [ #  # ]:          0 :                 if (c & DESTROY_IPC_FLAG) {
    4368   [ #  #  #  # ]:          0 :                         log_debug("Found unreferenced %s " UID_FMT " after reload/reexec. Cleaning up.",
    4369                 :            :                                   _clean_ipc == clean_ipc_by_uid ? "UID" : "GID",
    4370                 :            :                                   uid);
    4371                 :          0 :                         (void) _clean_ipc(uid);
    4372                 :            :                 }
    4373                 :            : 
    4374         [ #  # ]:          0 :                 assert_se(hashmap_remove(*uid_refs, k) == p);
    4375                 :            :         }
    4376                 :        104 : }
    4377                 :            : 
    4378                 :         52 : void manager_vacuum_uid_refs(Manager *m) {
    4379                 :         52 :         manager_vacuum_uid_refs_internal(m, &m->uid_refs, clean_ipc_by_uid);
    4380                 :         52 : }
    4381                 :            : 
    4382                 :         52 : void manager_vacuum_gid_refs(Manager *m) {
    4383                 :         52 :         manager_vacuum_uid_refs_internal(m, &m->gid_refs, clean_ipc_by_gid);
    4384                 :         52 : }
    4385                 :            : 
    4386                 :          0 : static void manager_serialize_uid_refs_internal(
    4387                 :            :                 Manager *m,
    4388                 :            :                 FILE *f,
    4389                 :            :                 Hashmap **uid_refs,
    4390                 :            :                 const char *field_name) {
    4391                 :            : 
    4392                 :            :         Iterator i;
    4393                 :            :         void *p, *k;
    4394                 :            : 
    4395         [ #  # ]:          0 :         assert(m);
    4396         [ #  # ]:          0 :         assert(f);
    4397         [ #  # ]:          0 :         assert(uid_refs);
    4398         [ #  # ]:          0 :         assert(field_name);
    4399                 :            : 
    4400                 :            :         /* Serialize the UID reference table. Or actually, just the IPC destruction flag of it, as the actual counter
    4401                 :            :          * of it is better rebuild after a reload/reexec. */
    4402                 :            : 
    4403         [ #  # ]:          0 :         HASHMAP_FOREACH_KEY(p, k, *uid_refs, i) {
    4404                 :            :                 uint32_t c;
    4405                 :            :                 uid_t uid;
    4406                 :            : 
    4407                 :          0 :                 uid = PTR_TO_UID(k);
    4408                 :          0 :                 c = PTR_TO_UINT32(p);
    4409                 :            : 
    4410         [ #  # ]:          0 :                 if (!(c & DESTROY_IPC_FLAG))
    4411                 :          0 :                         continue;
    4412                 :            : 
    4413                 :          0 :                 (void) serialize_item_format(f, field_name, UID_FMT, uid);
    4414                 :            :         }
    4415                 :          0 : }
    4416                 :            : 
    4417                 :          0 : void manager_serialize_uid_refs(Manager *m, FILE *f) {
    4418                 :          0 :         manager_serialize_uid_refs_internal(m, f, &m->uid_refs, "destroy-ipc-uid");
    4419                 :          0 : }
    4420                 :            : 
    4421                 :          0 : void manager_serialize_gid_refs(Manager *m, FILE *f) {
    4422                 :          0 :         manager_serialize_uid_refs_internal(m, f, &m->gid_refs, "destroy-ipc-gid");
    4423                 :          0 : }
    4424                 :            : 
    4425                 :          0 : static void manager_deserialize_uid_refs_one_internal(
    4426                 :            :                 Manager *m,
    4427                 :            :                 Hashmap** uid_refs,
    4428                 :            :                 const char *value) {
    4429                 :            : 
    4430                 :            :         uid_t uid;
    4431                 :            :         uint32_t c;
    4432                 :            :         int r;
    4433                 :            : 
    4434         [ #  # ]:          0 :         assert(m);
    4435         [ #  # ]:          0 :         assert(uid_refs);
    4436         [ #  # ]:          0 :         assert(value);
    4437                 :            : 
    4438                 :          0 :         r = parse_uid(value, &uid);
    4439   [ #  #  #  # ]:          0 :         if (r < 0 || uid == 0) {
    4440         [ #  # ]:          0 :                 log_debug("Unable to parse UID reference serialization");
    4441                 :          0 :                 return;
    4442                 :            :         }
    4443                 :            : 
    4444                 :          0 :         r = hashmap_ensure_allocated(uid_refs, &trivial_hash_ops);
    4445         [ #  # ]:          0 :         if (r < 0) {
    4446                 :          0 :                 log_oom();
    4447                 :          0 :                 return;
    4448                 :            :         }
    4449                 :            : 
    4450                 :          0 :         c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid)));
    4451         [ #  # ]:          0 :         if (c & DESTROY_IPC_FLAG)
    4452                 :          0 :                 return;
    4453                 :            : 
    4454                 :          0 :         c |= DESTROY_IPC_FLAG;
    4455                 :            : 
    4456                 :          0 :         r = hashmap_replace(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c));
    4457         [ #  # ]:          0 :         if (r < 0) {
    4458         [ #  # ]:          0 :                 log_debug_errno(r, "Failed to add UID reference entry: %m");
    4459                 :          0 :                 return;
    4460                 :            :         }
    4461                 :            : }
    4462                 :            : 
    4463                 :          0 : void manager_deserialize_uid_refs_one(Manager *m, const char *value) {
    4464                 :          0 :         manager_deserialize_uid_refs_one_internal(m, &m->uid_refs, value);
    4465                 :          0 : }
    4466                 :            : 
    4467                 :          0 : void manager_deserialize_gid_refs_one(Manager *m, const char *value) {
    4468                 :          0 :         manager_deserialize_uid_refs_one_internal(m, &m->gid_refs, value);
    4469                 :          0 : }
    4470                 :            : 
    4471                 :          0 : int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
    4472                 :            :         struct buffer {
    4473                 :            :                 uid_t uid;
    4474                 :            :                 gid_t gid;
    4475                 :            :                 char unit_name[UNIT_NAME_MAX+1];
    4476                 :            :         } _packed_ buffer;
    4477                 :            : 
    4478                 :          0 :         Manager *m = userdata;
    4479                 :            :         ssize_t l;
    4480                 :            :         size_t n;
    4481                 :            :         Unit *u;
    4482                 :            : 
    4483         [ #  # ]:          0 :         assert_se(source);
    4484         [ #  # ]:          0 :         assert_se(m);
    4485                 :            : 
    4486                 :            :         /* Invoked whenever a child process succeeded resolving its user/group to use and sent us the resulting UID/GID
    4487                 :            :          * in a datagram. We parse the datagram here and pass it off to the unit, so that it can add a reference to the
    4488                 :            :          * UID/GID so that it can destroy the UID/GID's IPC objects when the reference counter drops to 0. */
    4489                 :            : 
    4490                 :          0 :         l = recv(fd, &buffer, sizeof(buffer), MSG_DONTWAIT);
    4491         [ #  # ]:          0 :         if (l < 0) {
    4492   [ #  #  #  # ]:          0 :                 if (IN_SET(errno, EINTR, EAGAIN))
    4493                 :          0 :                         return 0;
    4494                 :            : 
    4495         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to read from user lookup fd: %m");
    4496                 :            :         }
    4497                 :            : 
    4498         [ #  # ]:          0 :         if ((size_t) l <= offsetof(struct buffer, unit_name)) {
    4499         [ #  # ]:          0 :                 log_warning("Received too short user lookup message, ignoring.");
    4500                 :          0 :                 return 0;
    4501                 :            :         }
    4502                 :            : 
    4503         [ #  # ]:          0 :         if ((size_t) l > offsetof(struct buffer, unit_name) + UNIT_NAME_MAX) {
    4504         [ #  # ]:          0 :                 log_warning("Received too long user lookup message, ignoring.");
    4505                 :          0 :                 return 0;
    4506                 :            :         }
    4507                 :            : 
    4508   [ #  #  #  # ]:          0 :         if (!uid_is_valid(buffer.uid) && !gid_is_valid(buffer.gid)) {
    4509         [ #  # ]:          0 :                 log_warning("Got user lookup message with invalid UID/GID pair, ignoring.");
    4510                 :          0 :                 return 0;
    4511                 :            :         }
    4512                 :            : 
    4513                 :          0 :         n = (size_t) l - offsetof(struct buffer, unit_name);
    4514         [ #  # ]:          0 :         if (memchr(buffer.unit_name, 0, n)) {
    4515         [ #  # ]:          0 :                 log_warning("Received lookup message with embedded NUL character, ignoring.");
    4516                 :          0 :                 return 0;
    4517                 :            :         }
    4518                 :            : 
    4519                 :          0 :         buffer.unit_name[n] = 0;
    4520                 :          0 :         u = manager_get_unit(m, buffer.unit_name);
    4521         [ #  # ]:          0 :         if (!u) {
    4522         [ #  # ]:          0 :                 log_debug("Got user lookup message but unit doesn't exist, ignoring.");
    4523                 :          0 :                 return 0;
    4524                 :            :         }
    4525                 :            : 
    4526         [ #  # ]:          0 :         log_unit_debug(u, "User lookup succeeded: uid=" UID_FMT " gid=" GID_FMT, buffer.uid, buffer.gid);
    4527                 :            : 
    4528                 :          0 :         unit_notify_user_lookup(u, buffer.uid, buffer.gid);
    4529                 :          0 :         return 0;
    4530                 :            : }
    4531                 :            : 
    4532                 :          0 : char *manager_taint_string(Manager *m) {
    4533                 :          0 :         _cleanup_free_ char *destination = NULL, *overflowuid = NULL, *overflowgid = NULL;
    4534                 :            :         char *buf, *e;
    4535                 :            :         int r;
    4536                 :            : 
    4537                 :            :         /* Returns a "taint string", e.g. "local-hwclock:var-run-bad".
    4538                 :            :          * Only things that are detected at runtime should be tagged
    4539                 :            :          * here. For stuff that is set during compilation, emit a warning
    4540                 :            :          * in the configuration phase. */
    4541                 :            : 
    4542         [ #  # ]:          0 :         assert(m);
    4543                 :            : 
    4544                 :          0 :         buf = new(char, sizeof("split-usr:"
    4545                 :            :                                "cgroups-missing:"
    4546                 :            :                                "local-hwclock:"
    4547                 :            :                                "var-run-bad:"
    4548                 :            :                                "overflowuid-not-65534:"
    4549                 :            :                                "overflowgid-not-65534:"));
    4550         [ #  # ]:          0 :         if (!buf)
    4551                 :          0 :                 return NULL;
    4552                 :            : 
    4553                 :          0 :         e = buf;
    4554                 :          0 :         buf[0] = 0;
    4555                 :            : 
    4556         [ #  # ]:          0 :         if (m->taint_usr)
    4557                 :          0 :                 e = stpcpy(e, "split-usr:");
    4558                 :            : 
    4559         [ #  # ]:          0 :         if (access("/proc/cgroups", F_OK) < 0)
    4560                 :          0 :                 e = stpcpy(e, "cgroups-missing:");
    4561                 :            : 
    4562         [ #  # ]:          0 :         if (clock_is_localtime(NULL) > 0)
    4563                 :          0 :                 e = stpcpy(e, "local-hwclock:");
    4564                 :            : 
    4565                 :          0 :         r = readlink_malloc("/var/run", &destination);
    4566   [ #  #  #  #  :          0 :         if (r < 0 || !PATH_IN_SET(destination, "../run", "/run"))
          #  #  #  #  #  
                      # ]
    4567                 :          0 :                 e = stpcpy(e, "var-run-bad:");
    4568                 :            : 
    4569                 :          0 :         r = read_one_line_file("/proc/sys/kernel/overflowuid", &overflowuid);
    4570   [ #  #  #  # ]:          0 :         if (r >= 0 && !streq(overflowuid, "65534"))
    4571                 :          0 :                 e = stpcpy(e, "overflowuid-not-65534:");
    4572                 :            : 
    4573                 :          0 :         r = read_one_line_file("/proc/sys/kernel/overflowgid", &overflowgid);
    4574   [ #  #  #  # ]:          0 :         if (r >= 0 && !streq(overflowgid, "65534"))
    4575                 :          0 :                 e = stpcpy(e, "overflowgid-not-65534:");
    4576                 :            : 
    4577                 :            :         /* remove the last ':' */
    4578         [ #  # ]:          0 :         if (e != buf)
    4579                 :          0 :                 e[-1] = 0;
    4580                 :            : 
    4581                 :          0 :         return buf;
    4582                 :            : }
    4583                 :            : 
    4584                 :          0 : void manager_ref_console(Manager *m) {
    4585         [ #  # ]:          0 :         assert(m);
    4586                 :            : 
    4587                 :          0 :         m->n_on_console++;
    4588                 :          0 : }
    4589                 :            : 
    4590                 :          0 : void manager_unref_console(Manager *m) {
    4591                 :            : 
    4592         [ #  # ]:          0 :         assert(m->n_on_console > 0);
    4593                 :          0 :         m->n_on_console--;
    4594                 :            : 
    4595         [ #  # ]:          0 :         if (m->n_on_console == 0)
    4596                 :          0 :                 m->no_console_output = false; /* unset no_console_output flag, since the console is definitely free now */
    4597                 :          0 : }
    4598                 :            : 
    4599                 :          0 : void manager_override_log_level(Manager *m, int level) {
    4600                 :          0 :         _cleanup_free_ char *s = NULL;
    4601         [ #  # ]:          0 :         assert(m);
    4602                 :            : 
    4603         [ #  # ]:          0 :         if (!m->log_level_overridden) {
    4604                 :          0 :                 m->original_log_level = log_get_max_level();
    4605                 :          0 :                 m->log_level_overridden = true;
    4606                 :            :         }
    4607                 :            : 
    4608                 :          0 :         (void) log_level_to_string_alloc(level, &s);
    4609         [ #  # ]:          0 :         log_info("Setting log level to %s.", strna(s));
    4610                 :            : 
    4611                 :          0 :         log_set_max_level(level);
    4612                 :          0 : }
    4613                 :            : 
    4614                 :          0 : void manager_restore_original_log_level(Manager *m) {
    4615         [ #  # ]:          0 :         _cleanup_free_ char *s = NULL;
    4616         [ #  # ]:          0 :         assert(m);
    4617                 :            : 
    4618         [ #  # ]:          0 :         if (!m->log_level_overridden)
    4619                 :          0 :                 return;
    4620                 :            : 
    4621                 :          0 :         (void) log_level_to_string_alloc(m->original_log_level, &s);
    4622         [ #  # ]:          0 :         log_info("Restoring log level to original (%s).", strna(s));
    4623                 :            : 
    4624                 :          0 :         log_set_max_level(m->original_log_level);
    4625                 :          0 :         m->log_level_overridden = false;
    4626                 :            : }
    4627                 :            : 
    4628                 :          0 : void manager_override_log_target(Manager *m, LogTarget target) {
    4629         [ #  # ]:          0 :         assert(m);
    4630                 :            : 
    4631         [ #  # ]:          0 :         if (!m->log_target_overridden) {
    4632                 :          0 :                 m->original_log_target = log_get_target();
    4633                 :          0 :                 m->log_target_overridden = true;
    4634                 :            :         }
    4635                 :            : 
    4636         [ #  # ]:          0 :         log_info("Setting log target to %s.", log_target_to_string(target));
    4637                 :          0 :         log_set_target(target);
    4638                 :          0 : }
    4639                 :            : 
    4640                 :          0 : void manager_restore_original_log_target(Manager *m) {
    4641         [ #  # ]:          0 :         assert(m);
    4642                 :            : 
    4643         [ #  # ]:          0 :         if (!m->log_target_overridden)
    4644                 :          0 :                 return;
    4645                 :            : 
    4646         [ #  # ]:          0 :         log_info("Restoring log target to original %s.", log_target_to_string(m->original_log_target));
    4647                 :            : 
    4648                 :          0 :         log_set_target(m->original_log_target);
    4649                 :          0 :         m->log_target_overridden = false;
    4650                 :            : }
    4651                 :            : 
    4652                 :        208 : ManagerTimestamp manager_timestamp_initrd_mangle(ManagerTimestamp s) {
    4653   [ -  +  #  # ]:        208 :         if (in_initrd() &&
    4654         [ #  # ]:          0 :             s >= MANAGER_TIMESTAMP_SECURITY_START &&
    4655                 :            :             s <= MANAGER_TIMESTAMP_UNITS_LOAD_FINISH)
    4656                 :          0 :                 return s - MANAGER_TIMESTAMP_SECURITY_START + MANAGER_TIMESTAMP_INITRD_SECURITY_START;
    4657                 :        208 :         return s;
    4658                 :            : }
    4659                 :            : 
    4660                 :            : static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
    4661                 :            :         [MANAGER_INITIALIZING] = "initializing",
    4662                 :            :         [MANAGER_STARTING] = "starting",
    4663                 :            :         [MANAGER_RUNNING] = "running",
    4664                 :            :         [MANAGER_DEGRADED] = "degraded",
    4665                 :            :         [MANAGER_MAINTENANCE] = "maintenance",
    4666                 :            :         [MANAGER_STOPPING] = "stopping",
    4667                 :            : };
    4668                 :            : 
    4669   [ +  +  +  + ]:         64 : DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState);
    4670                 :            : 
    4671                 :            : static const char *const manager_timestamp_table[_MANAGER_TIMESTAMP_MAX] = {
    4672                 :            :         [MANAGER_TIMESTAMP_FIRMWARE] = "firmware",
    4673                 :            :         [MANAGER_TIMESTAMP_LOADER] = "loader",
    4674                 :            :         [MANAGER_TIMESTAMP_KERNEL] = "kernel",
    4675                 :            :         [MANAGER_TIMESTAMP_INITRD] = "initrd",
    4676                 :            :         [MANAGER_TIMESTAMP_USERSPACE] = "userspace",
    4677                 :            :         [MANAGER_TIMESTAMP_FINISH] = "finish",
    4678                 :            :         [MANAGER_TIMESTAMP_SECURITY_START] = "security-start",
    4679                 :            :         [MANAGER_TIMESTAMP_SECURITY_FINISH] = "security-finish",
    4680                 :            :         [MANAGER_TIMESTAMP_GENERATORS_START] = "generators-start",
    4681                 :            :         [MANAGER_TIMESTAMP_GENERATORS_FINISH] = "generators-finish",
    4682                 :            :         [MANAGER_TIMESTAMP_UNITS_LOAD_START] = "units-load-start",
    4683                 :            :         [MANAGER_TIMESTAMP_UNITS_LOAD_FINISH] = "units-load-finish",
    4684                 :            :         [MANAGER_TIMESTAMP_INITRD_SECURITY_START] = "initrd-security-start",
    4685                 :            :         [MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH] = "initrd-security-finish",
    4686                 :            :         [MANAGER_TIMESTAMP_INITRD_GENERATORS_START] = "initrd-generators-start",
    4687                 :            :         [MANAGER_TIMESTAMP_INITRD_GENERATORS_FINISH] = "initrd-generators-finish",
    4688                 :            :         [MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_START] = "initrd-units-load-start",
    4689                 :            :         [MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_FINISH] = "initrd-units-load-finish",
    4690                 :            : };
    4691                 :            : 
    4692   [ +  +  +  + ]:        160 : DEFINE_STRING_TABLE_LOOKUP(manager_timestamp, ManagerTimestamp);
    4693                 :            : 
    4694                 :            : static const char* const oom_policy_table[_OOM_POLICY_MAX] = {
    4695                 :            :         [OOM_CONTINUE] = "continue",
    4696                 :            :         [OOM_STOP] = "stop",
    4697                 :            :         [OOM_KILL] = "kill",
    4698                 :            : };
    4699                 :            : 
    4700   [ +  -  -  + ]:        176 : DEFINE_STRING_TABLE_LOOKUP(oom_policy, OOMPolicy);

Generated by: LCOV version 1.14