LCOV - code coverage report
Current view: top level - core - dbus-manager.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 0 1078 0.0 %
Date: 2015-07-29 18:47:03 Functions: 0 82 0.0 %

          Line data    Source code
       1             : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
       2             : 
       3             : /***
       4             :   This file is part of systemd.
       5             : 
       6             :   Copyright 2010 Lennart Poettering
       7             : 
       8             :   systemd is free software; you can redistribute it and/or modify it
       9             :   under the terms of the GNU Lesser General Public License as published by
      10             :   the Free Software Foundation; either version 2.1 of the License, or
      11             :   (at your option) any later version.
      12             : 
      13             :   systemd is distributed in the hope that it will be useful, but
      14             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      16             :   Lesser General Public License for more details.
      17             : 
      18             :   You should have received a copy of the GNU Lesser General Public License
      19             :   along with systemd; If not, see <http://www.gnu.org/licenses/>.
      20             : ***/
      21             : 
      22             : #include <errno.h>
      23             : #include <unistd.h>
      24             : 
      25             : #include "log.h"
      26             : #include "strv.h"
      27             : #include "build.h"
      28             : #include "install.h"
      29             : #include "selinux-access.h"
      30             : #include "watchdog.h"
      31             : #include "clock-util.h"
      32             : #include "path-util.h"
      33             : #include "virt.h"
      34             : #include "architecture.h"
      35             : #include "env-util.h"
      36             : #include "dbus.h"
      37             : #include "dbus-job.h"
      38             : #include "dbus-manager.h"
      39             : #include "dbus-unit.h"
      40             : #include "dbus-snapshot.h"
      41             : #include "dbus-execute.h"
      42             : #include "bus-common-errors.h"
      43             : #include "formats-util.h"
      44             : 
      45           0 : static int property_get_version(
      46             :                 sd_bus *bus,
      47             :                 const char *path,
      48             :                 const char *interface,
      49             :                 const char *property,
      50             :                 sd_bus_message *reply,
      51             :                 void *userdata,
      52             :                 sd_bus_error *error) {
      53             : 
      54           0 :         assert(bus);
      55           0 :         assert(reply);
      56             : 
      57           0 :         return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
      58             : }
      59             : 
      60           0 : static int property_get_features(
      61             :                 sd_bus *bus,
      62             :                 const char *path,
      63             :                 const char *interface,
      64             :                 const char *property,
      65             :                 sd_bus_message *reply,
      66             :                 void *userdata,
      67             :                 sd_bus_error *error) {
      68             : 
      69           0 :         assert(bus);
      70           0 :         assert(reply);
      71             : 
      72           0 :         return sd_bus_message_append(reply, "s", SYSTEMD_FEATURES);
      73             : }
      74             : 
      75           0 : static int property_get_virtualization(
      76             :                 sd_bus *bus,
      77             :                 const char *path,
      78             :                 const char *interface,
      79             :                 const char *property,
      80             :                 sd_bus_message *reply,
      81             :                 void *userdata,
      82             :                 sd_bus_error *error) {
      83             : 
      84           0 :         const char *id = NULL;
      85             : 
      86           0 :         assert(bus);
      87           0 :         assert(reply);
      88             : 
      89           0 :         detect_virtualization(&id);
      90             : 
      91           0 :         return sd_bus_message_append(reply, "s", id);
      92             : }
      93             : 
      94           0 : static int property_get_architecture(
      95             :                 sd_bus *bus,
      96             :                 const char *path,
      97             :                 const char *interface,
      98             :                 const char *property,
      99             :                 sd_bus_message *reply,
     100             :                 void *userdata,
     101             :                 sd_bus_error *error) {
     102             : 
     103           0 :         assert(bus);
     104           0 :         assert(reply);
     105             : 
     106           0 :         return sd_bus_message_append(reply, "s", architecture_to_string(uname_architecture()));
     107             : }
     108             : 
     109           0 : static int property_get_tainted(
     110             :                 sd_bus *bus,
     111             :                 const char *path,
     112             :                 const char *interface,
     113             :                 const char *property,
     114             :                 sd_bus_message *reply,
     115             :                 void *userdata,
     116             :                 sd_bus_error *error) {
     117             : 
     118           0 :         char buf[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e = buf;
     119           0 :         _cleanup_free_ char *p = NULL;
     120           0 :         Manager *m = userdata;
     121             : 
     122           0 :         assert(bus);
     123           0 :         assert(reply);
     124           0 :         assert(m);
     125             : 
     126           0 :         if (m->taint_usr)
     127           0 :                 e = stpcpy(e, "split-usr:");
     128             : 
     129           0 :         if (readlink_malloc("/etc/mtab", &p) < 0)
     130           0 :                 e = stpcpy(e, "mtab-not-symlink:");
     131             : 
     132           0 :         if (access("/proc/cgroups", F_OK) < 0)
     133           0 :                 e = stpcpy(e, "cgroups-missing:");
     134             : 
     135           0 :         if (clock_is_localtime() > 0)
     136           0 :                 e = stpcpy(e, "local-hwclock:");
     137             : 
     138             :         /* remove the last ':' */
     139           0 :         if (e != buf)
     140           0 :                 e[-1] = 0;
     141             : 
     142           0 :         return sd_bus_message_append(reply, "s", buf);
     143             : }
     144             : 
     145           0 : static int property_get_log_target(
     146             :                 sd_bus *bus,
     147             :                 const char *path,
     148             :                 const char *interface,
     149             :                 const char *property,
     150             :                 sd_bus_message *reply,
     151             :                 void *userdata,
     152             :                 sd_bus_error *error) {
     153             : 
     154           0 :         assert(bus);
     155           0 :         assert(reply);
     156             : 
     157           0 :         return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
     158             : }
     159             : 
     160           0 : static int property_set_log_target(
     161             :                 sd_bus *bus,
     162             :                 const char *path,
     163             :                 const char *interface,
     164             :                 const char *property,
     165             :                 sd_bus_message *value,
     166             :                 void *userdata,
     167             :                 sd_bus_error *error) {
     168             : 
     169             :         const char *t;
     170             :         int r;
     171             : 
     172           0 :         assert(bus);
     173           0 :         assert(value);
     174             : 
     175           0 :         r = sd_bus_message_read(value, "s", &t);
     176           0 :         if (r < 0)
     177           0 :                 return r;
     178             : 
     179           0 :         return log_set_target_from_string(t);
     180             : }
     181             : 
     182           0 : static int property_get_log_level(
     183             :                 sd_bus *bus,
     184             :                 const char *path,
     185             :                 const char *interface,
     186             :                 const char *property,
     187             :                 sd_bus_message *reply,
     188             :                 void *userdata,
     189             :                 sd_bus_error *error) {
     190             : 
     191           0 :         _cleanup_free_ char *t = NULL;
     192             :         int r;
     193             : 
     194           0 :         assert(bus);
     195           0 :         assert(reply);
     196             : 
     197           0 :         r = log_level_to_string_alloc(log_get_max_level(), &t);
     198           0 :         if (r < 0)
     199           0 :                 return r;
     200             : 
     201           0 :         return sd_bus_message_append(reply, "s", t);
     202             : }
     203             : 
     204           0 : static int property_set_log_level(
     205             :                 sd_bus *bus,
     206             :                 const char *path,
     207             :                 const char *interface,
     208             :                 const char *property,
     209             :                 sd_bus_message *value,
     210             :                 void *userdata,
     211             :                 sd_bus_error *error) {
     212             : 
     213             :         const char *t;
     214             :         int r;
     215             : 
     216           0 :         assert(bus);
     217           0 :         assert(value);
     218             : 
     219           0 :         r = sd_bus_message_read(value, "s", &t);
     220           0 :         if (r < 0)
     221           0 :                 return r;
     222             : 
     223           0 :         return log_set_max_level_from_string(t);
     224             : }
     225             : 
     226           0 : static int property_get_n_names(
     227             :                 sd_bus *bus,
     228             :                 const char *path,
     229             :                 const char *interface,
     230             :                 const char *property,
     231             :                 sd_bus_message *reply,
     232             :                 void *userdata,
     233             :                 sd_bus_error *error) {
     234             : 
     235           0 :         Manager *m = userdata;
     236             : 
     237           0 :         assert(bus);
     238           0 :         assert(reply);
     239           0 :         assert(m);
     240             : 
     241           0 :         return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
     242             : }
     243             : 
     244           0 : static int property_get_n_failed_units(
     245             :                 sd_bus *bus,
     246             :                 const char *path,
     247             :                 const char *interface,
     248             :                 const char *property,
     249             :                 sd_bus_message *reply,
     250             :                 void *userdata,
     251             :                 sd_bus_error *error) {
     252             : 
     253           0 :         Manager *m = userdata;
     254             : 
     255           0 :         assert(bus);
     256           0 :         assert(reply);
     257           0 :         assert(m);
     258             : 
     259           0 :         return sd_bus_message_append(reply, "u", (uint32_t) set_size(m->failed_units));
     260             : }
     261             : 
     262           0 : static int property_get_n_jobs(
     263             :                 sd_bus *bus,
     264             :                 const char *path,
     265             :                 const char *interface,
     266             :                 const char *property,
     267             :                 sd_bus_message *reply,
     268             :                 void *userdata,
     269             :                 sd_bus_error *error) {
     270             : 
     271           0 :         Manager *m = userdata;
     272             : 
     273           0 :         assert(bus);
     274           0 :         assert(reply);
     275           0 :         assert(m);
     276             : 
     277           0 :         return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
     278             : }
     279             : 
     280           0 : static int property_get_progress(
     281             :                 sd_bus *bus,
     282             :                 const char *path,
     283             :                 const char *interface,
     284             :                 const char *property,
     285             :                 sd_bus_message *reply,
     286             :                 void *userdata,
     287             :                 sd_bus_error *error) {
     288             : 
     289           0 :         Manager *m = userdata;
     290             :         double d;
     291             : 
     292           0 :         assert(bus);
     293           0 :         assert(reply);
     294           0 :         assert(m);
     295             : 
     296           0 :         if (dual_timestamp_is_set(&m->finish_timestamp))
     297           0 :                 d = 1.0;
     298             :         else
     299           0 :                 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
     300             : 
     301           0 :         return sd_bus_message_append(reply, "d", d);
     302             : }
     303             : 
     304           0 : static int property_get_system_state(
     305             :                 sd_bus *bus,
     306             :                 const char *path,
     307             :                 const char *interface,
     308             :                 const char *property,
     309             :                 sd_bus_message *reply,
     310             :                 void *userdata,
     311             :                 sd_bus_error *error) {
     312             : 
     313           0 :         Manager *m = userdata;
     314             : 
     315           0 :         assert(bus);
     316           0 :         assert(reply);
     317           0 :         assert(m);
     318             : 
     319           0 :         return sd_bus_message_append(reply, "s", manager_state_to_string(manager_state(m)));
     320             : }
     321             : 
     322           0 : static int property_set_runtime_watchdog(
     323             :                 sd_bus *bus,
     324             :                 const char *path,
     325             :                 const char *interface,
     326             :                 const char *property,
     327             :                 sd_bus_message *value,
     328             :                 void *userdata,
     329             :                 sd_bus_error *error) {
     330             : 
     331           0 :         usec_t *t = userdata;
     332             :         int r;
     333             : 
     334           0 :         assert(bus);
     335           0 :         assert(value);
     336             : 
     337             :         assert_cc(sizeof(usec_t) == sizeof(uint64_t));
     338             : 
     339           0 :         r = sd_bus_message_read(value, "t", t);
     340           0 :         if (r < 0)
     341           0 :                 return r;
     342             : 
     343           0 :         return watchdog_set_timeout(t);
     344             : }
     345             : 
     346           0 : static int method_get_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     347           0 :         _cleanup_free_ char *path = NULL;
     348           0 :         Manager *m = userdata;
     349             :         const char *name;
     350             :         Unit *u;
     351             :         int r;
     352             : 
     353           0 :         assert(message);
     354           0 :         assert(m);
     355             : 
     356             :         /* Anyone can call this method */
     357             : 
     358           0 :         r = sd_bus_message_read(message, "s", &name);
     359           0 :         if (r < 0)
     360           0 :                 return r;
     361             : 
     362           0 :         if (isempty(name)) {
     363           0 :                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
     364             :                 pid_t pid;
     365             : 
     366           0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
     367           0 :                 if (r < 0)
     368           0 :                         return r;
     369             : 
     370           0 :                 r = sd_bus_creds_get_pid(creds, &pid);
     371           0 :                 if (r < 0)
     372           0 :                         return r;
     373             : 
     374           0 :                 u = manager_get_unit_by_pid(m, pid);
     375           0 :                 if (!u)
     376           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
     377             :         } else {
     378           0 :                 u = manager_get_unit(m, name);
     379           0 :                 if (!u)
     380           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
     381             :         }
     382             : 
     383           0 :         r = mac_selinux_unit_access_check(u, message, "status", error);
     384           0 :         if (r < 0)
     385           0 :                 return r;
     386             : 
     387           0 :         path = unit_dbus_path(u);
     388           0 :         if (!path)
     389           0 :                 return -ENOMEM;
     390             : 
     391           0 :         return sd_bus_reply_method_return(message, "o", path);
     392             : }
     393             : 
     394           0 : static int method_get_unit_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     395           0 :         _cleanup_free_ char *path = NULL;
     396           0 :         Manager *m = userdata;
     397             :         pid_t pid;
     398             :         Unit *u;
     399             :         int r;
     400             : 
     401           0 :         assert(message);
     402           0 :         assert(m);
     403             : 
     404             :         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
     405             : 
     406             :         /* Anyone can call this method */
     407             : 
     408           0 :         r = sd_bus_message_read(message, "u", &pid);
     409           0 :         if (r < 0)
     410           0 :                 return r;
     411           0 :         if (pid < 0)
     412           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PID " PID_FMT, pid);
     413             : 
     414           0 :         if (pid == 0) {
     415           0 :                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
     416             : 
     417           0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
     418           0 :                 if (r < 0)
     419           0 :                         return r;
     420             : 
     421           0 :                 r = sd_bus_creds_get_pid(creds, &pid);
     422           0 :                 if (r < 0)
     423           0 :                         return r;
     424             :         }
     425             : 
     426           0 :         u = manager_get_unit_by_pid(m, pid);
     427           0 :         if (!u)
     428           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid);
     429             : 
     430           0 :         r = mac_selinux_unit_access_check(u, message, "status", error);
     431           0 :         if (r < 0)
     432           0 :                 return r;
     433             : 
     434           0 :         path = unit_dbus_path(u);
     435           0 :         if (!path)
     436           0 :                 return -ENOMEM;
     437             : 
     438           0 :         return sd_bus_reply_method_return(message, "o", path);
     439             : }
     440             : 
     441           0 : static int method_load_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     442           0 :         _cleanup_free_ char *path = NULL;
     443           0 :         Manager *m = userdata;
     444             :         const char *name;
     445             :         Unit *u;
     446             :         int r;
     447             : 
     448           0 :         assert(message);
     449           0 :         assert(m);
     450             : 
     451             :         /* Anyone can call this method */
     452             : 
     453           0 :         r = sd_bus_message_read(message, "s", &name);
     454           0 :         if (r < 0)
     455           0 :                 return r;
     456             : 
     457           0 :         if (isempty(name)) {
     458           0 :                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
     459             :                 pid_t pid;
     460             : 
     461           0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
     462           0 :                 if (r < 0)
     463           0 :                         return r;
     464             : 
     465           0 :                 r = sd_bus_creds_get_pid(creds, &pid);
     466           0 :                 if (r < 0)
     467           0 :                         return r;
     468             : 
     469           0 :                 u = manager_get_unit_by_pid(m, pid);
     470           0 :                 if (!u)
     471           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
     472             :         } else {
     473           0 :                 r = manager_load_unit(m, name, NULL, error, &u);
     474           0 :                 if (r < 0)
     475           0 :                         return r;
     476             :         }
     477             : 
     478           0 :         r = mac_selinux_unit_access_check(u, message, "status", error);
     479           0 :         if (r < 0)
     480           0 :                 return r;
     481             : 
     482           0 :         path = unit_dbus_path(u);
     483           0 :         if (!path)
     484           0 :                 return -ENOMEM;
     485             : 
     486           0 :         return sd_bus_reply_method_return(message, "o", path);
     487             : }
     488             : 
     489           0 : static int method_start_unit_generic(sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
     490             :         const char *name;
     491             :         Unit *u;
     492             :         int r;
     493             : 
     494           0 :         assert(message);
     495           0 :         assert(m);
     496             : 
     497           0 :         r = sd_bus_message_read(message, "s", &name);
     498           0 :         if (r < 0)
     499           0 :                 return r;
     500             : 
     501           0 :         r = manager_load_unit(m, name, NULL, error, &u);
     502           0 :         if (r < 0)
     503           0 :                 return r;
     504             : 
     505           0 :         return bus_unit_method_start_generic(message, u, job_type, reload_if_possible, error);
     506             : }
     507             : 
     508           0 : static int method_start_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     509           0 :         return method_start_unit_generic(message, userdata, JOB_START, false, error);
     510             : }
     511             : 
     512           0 : static int method_stop_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     513           0 :         return method_start_unit_generic(message, userdata, JOB_STOP, false, error);
     514             : }
     515             : 
     516           0 : static int method_reload_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     517           0 :         return method_start_unit_generic(message, userdata, JOB_RELOAD, false, error);
     518             : }
     519             : 
     520           0 : static int method_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     521           0 :         return method_start_unit_generic(message, userdata, JOB_RESTART, false, error);
     522             : }
     523             : 
     524           0 : static int method_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     525           0 :         return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, false, error);
     526             : }
     527             : 
     528           0 : static int method_reload_or_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     529           0 :         return method_start_unit_generic(message, userdata, JOB_RESTART, true, error);
     530             : }
     531             : 
     532           0 : static int method_reload_or_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     533           0 :         return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, true, error);
     534             : }
     535             : 
     536           0 : static int method_start_unit_replace(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     537           0 :         Manager *m = userdata;
     538             :         const char *old_name;
     539             :         Unit *u;
     540             :         int r;
     541             : 
     542           0 :         assert(message);
     543           0 :         assert(m);
     544             : 
     545           0 :         r = sd_bus_message_read(message, "s", &old_name);
     546           0 :         if (r < 0)
     547           0 :                 return r;
     548             : 
     549           0 :         u = manager_get_unit(m, old_name);
     550           0 :         if (!u || !u->job || u->job->type != JOB_START)
     551           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
     552             : 
     553           0 :         return method_start_unit_generic(message, m, JOB_START, false, error);
     554             : }
     555             : 
     556           0 : static int method_kill_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     557           0 :         Manager *m = userdata;
     558             :         const char *name;
     559             :         Unit *u;
     560             :         int r;
     561             : 
     562           0 :         assert(message);
     563           0 :         assert(m);
     564             : 
     565           0 :         r = sd_bus_message_read(message, "s", &name);
     566           0 :         if (r < 0)
     567           0 :                 return r;
     568             : 
     569           0 :         u = manager_get_unit(m, name);
     570           0 :         if (!u)
     571           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
     572             : 
     573           0 :         return bus_unit_method_kill(message, u, error);
     574             : }
     575             : 
     576           0 : static int method_reset_failed_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     577           0 :         Manager *m = userdata;
     578             :         const char *name;
     579             :         Unit *u;
     580             :         int r;
     581             : 
     582           0 :         assert(message);
     583           0 :         assert(m);
     584             : 
     585           0 :         r = sd_bus_message_read(message, "s", &name);
     586           0 :         if (r < 0)
     587           0 :                 return r;
     588             : 
     589           0 :         u = manager_get_unit(m, name);
     590           0 :         if (!u)
     591           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
     592             : 
     593           0 :         return bus_unit_method_reset_failed(message, u, error);
     594             : }
     595             : 
     596           0 : static int method_set_unit_properties(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     597           0 :         Manager *m = userdata;
     598             :         const char *name;
     599             :         Unit *u;
     600             :         int r;
     601             : 
     602           0 :         assert(message);
     603           0 :         assert(m);
     604             : 
     605           0 :         r = sd_bus_message_read(message, "s", &name);
     606           0 :         if (r < 0)
     607           0 :                 return r;
     608             : 
     609           0 :         u = manager_get_unit(m, name);
     610           0 :         if (!u)
     611           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
     612             : 
     613           0 :         return bus_unit_method_set_properties(message, u, error);
     614             : }
     615             : 
     616           0 : static int transient_unit_from_message(
     617             :                 Manager *m,
     618             :                 sd_bus_message *message,
     619             :                 const char *name,
     620             :                 Unit **unit,
     621             :                 sd_bus_error *error) {
     622             : 
     623             :         Unit *u;
     624             :         int r;
     625             : 
     626           0 :         assert(m);
     627           0 :         assert(message);
     628           0 :         assert(name);
     629             : 
     630           0 :         r = manager_load_unit(m, name, NULL, error, &u);
     631           0 :         if (r < 0)
     632           0 :                 return r;
     633             : 
     634           0 :         if (u->load_state != UNIT_NOT_FOUND ||
     635           0 :             set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
     636           0 :                 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
     637             : 
     638             :         /* OK, the unit failed to load and is unreferenced, now let's
     639             :          * fill in the transient data instead */
     640           0 :         r = unit_make_transient(u);
     641           0 :         if (r < 0)
     642           0 :                 return r;
     643             : 
     644             :         /* Set our properties */
     645           0 :         r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
     646           0 :         if (r < 0)
     647           0 :                 return r;
     648             : 
     649           0 :         *unit = u;
     650             : 
     651           0 :         return 0;
     652             : }
     653             : 
     654           0 : static int transient_aux_units_from_message(
     655             :                 Manager *m,
     656             :                 sd_bus_message *message,
     657             :                 sd_bus_error *error) {
     658             : 
     659             :         Unit *u;
     660           0 :         char *name = NULL;
     661             :         int r;
     662             : 
     663           0 :         assert(m);
     664           0 :         assert(message);
     665             : 
     666           0 :         r = sd_bus_message_enter_container(message, 'a', "(sa(sv))");
     667           0 :         if (r < 0)
     668           0 :                 return r;
     669             : 
     670           0 :         while ((r = sd_bus_message_enter_container(message, 'r', "sa(sv)")) > 0) {
     671           0 :                 r = sd_bus_message_read(message, "s", &name);
     672           0 :                 if (r < 0)
     673           0 :                         return r;
     674             : 
     675           0 :                 r = transient_unit_from_message(m, message, name, &u, error);
     676           0 :                 if (r < 0 && r != -EEXIST)
     677           0 :                         return r;
     678             : 
     679           0 :                 if (r != -EEXIST) {
     680           0 :                         r = unit_load(u);
     681           0 :                         if (r < 0)
     682           0 :                                 return r;
     683             :                 }
     684             : 
     685           0 :                 r = sd_bus_message_exit_container(message);
     686           0 :                 if (r < 0)
     687           0 :                         return r;
     688             :         }
     689           0 :         if (r < 0)
     690           0 :                 return r;
     691             : 
     692           0 :         r = sd_bus_message_exit_container(message);
     693           0 :         if (r < 0)
     694           0 :                 return r;
     695             : 
     696           0 :         return 0;
     697             : }
     698             : 
     699           0 : static int method_start_transient_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     700             :         const char *name, *smode;
     701           0 :         Manager *m = userdata;
     702             :         JobMode mode;
     703             :         UnitType t;
     704             :         Unit *u;
     705             :         int r;
     706             : 
     707           0 :         assert(message);
     708           0 :         assert(m);
     709             : 
     710           0 :         r = mac_selinux_access_check(message, "start", error);
     711           0 :         if (r < 0)
     712           0 :                 return r;
     713             : 
     714           0 :         r = sd_bus_message_read(message, "ss", &name, &smode);
     715           0 :         if (r < 0)
     716           0 :                 return r;
     717             : 
     718           0 :         t = unit_name_to_type(name);
     719           0 :         if (t < 0)
     720           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
     721             : 
     722           0 :         if (!unit_vtable[t]->can_transient)
     723           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
     724             : 
     725           0 :         mode = job_mode_from_string(smode);
     726           0 :         if (mode < 0)
     727           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
     728             : 
     729           0 :         r = bus_verify_manage_units_async(m, message, error);
     730           0 :         if (r < 0)
     731           0 :                 return r;
     732           0 :         if (r == 0)
     733           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
     734             : 
     735           0 :         r = transient_unit_from_message(m, message, name, &u, error);
     736           0 :         if (r < 0)
     737           0 :                 return r;
     738             : 
     739           0 :         r = transient_aux_units_from_message(m, message, error);
     740           0 :         if (r < 0)
     741           0 :                 return r;
     742             : 
     743             :         /* And load this stub fully */
     744           0 :         r = unit_load(u);
     745           0 :         if (r < 0)
     746           0 :                 return r;
     747             : 
     748           0 :         manager_dispatch_load_queue(m);
     749             : 
     750             :         /* Finally, start it */
     751           0 :         return bus_unit_queue_job(message, u, JOB_START, mode, false, error);
     752             : }
     753             : 
     754           0 : static int method_get_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     755           0 :         _cleanup_free_ char *path = NULL;
     756           0 :         Manager *m = userdata;
     757             :         uint32_t id;
     758             :         Job *j;
     759             :         int r;
     760             : 
     761           0 :         assert(message);
     762           0 :         assert(m);
     763             : 
     764             :         /* Anyone can call this method */
     765             : 
     766           0 :         r = sd_bus_message_read(message, "u", &id);
     767           0 :         if (r < 0)
     768           0 :                 return r;
     769             : 
     770           0 :         j = manager_get_job(m, id);
     771           0 :         if (!j)
     772           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
     773             : 
     774           0 :         r = mac_selinux_unit_access_check(j->unit, message, "status", error);
     775           0 :         if (r < 0)
     776           0 :                 return r;
     777             : 
     778           0 :         path = job_dbus_path(j);
     779           0 :         if (!path)
     780           0 :                 return -ENOMEM;
     781             : 
     782           0 :         return sd_bus_reply_method_return(message, "o", path);
     783             : }
     784             : 
     785           0 : static int method_cancel_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     786           0 :         Manager *m = userdata;
     787             :         uint32_t id;
     788             :         Job *j;
     789             :         int r;
     790             : 
     791           0 :         assert(message);
     792           0 :         assert(m);
     793             : 
     794           0 :         r = sd_bus_message_read(message, "u", &id);
     795           0 :         if (r < 0)
     796           0 :                 return r;
     797             : 
     798           0 :         j = manager_get_job(m, id);
     799           0 :         if (!j)
     800           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
     801             : 
     802           0 :         return bus_job_method_cancel(message, j, error);
     803             : }
     804             : 
     805           0 : static int method_clear_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     806           0 :         Manager *m = userdata;
     807             :         int r;
     808             : 
     809           0 :         assert(message);
     810           0 :         assert(m);
     811             : 
     812           0 :         r = mac_selinux_access_check(message, "reload", error);
     813           0 :         if (r < 0)
     814           0 :                 return r;
     815             : 
     816           0 :         r = bus_verify_manage_units_async(m, message, error);
     817           0 :         if (r < 0)
     818           0 :                 return r;
     819           0 :         if (r == 0)
     820           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
     821             : 
     822           0 :         manager_clear_jobs(m);
     823             : 
     824           0 :         return sd_bus_reply_method_return(message, NULL);
     825             : }
     826             : 
     827           0 : static int method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     828           0 :         Manager *m = userdata;
     829             :         int r;
     830             : 
     831           0 :         assert(message);
     832           0 :         assert(m);
     833             : 
     834           0 :         r = mac_selinux_access_check(message, "reload", error);
     835           0 :         if (r < 0)
     836           0 :                 return r;
     837             : 
     838           0 :         r = bus_verify_manage_units_async(m, message, error);
     839           0 :         if (r < 0)
     840           0 :                 return r;
     841           0 :         if (r == 0)
     842           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
     843             : 
     844           0 :         manager_reset_failed(m);
     845             : 
     846           0 :         return sd_bus_reply_method_return(message, NULL);
     847             : }
     848             : 
     849           0 : static int list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
     850           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
     851           0 :         Manager *m = userdata;
     852             :         const char *k;
     853             :         Iterator i;
     854             :         Unit *u;
     855             :         int r;
     856             : 
     857           0 :         assert(message);
     858           0 :         assert(m);
     859             : 
     860             :         /* Anyone can call this method */
     861             : 
     862           0 :         r = mac_selinux_access_check(message, "status", error);
     863           0 :         if (r < 0)
     864           0 :                 return r;
     865             : 
     866           0 :         r = sd_bus_message_new_method_return(message, &reply);
     867           0 :         if (r < 0)
     868           0 :                 return r;
     869             : 
     870           0 :         r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
     871           0 :         if (r < 0)
     872           0 :                 return r;
     873             : 
     874           0 :         HASHMAP_FOREACH_KEY(u, k, m->units, i) {
     875           0 :                 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
     876             :                 Unit *following;
     877             : 
     878           0 :                 if (k != u->id)
     879           0 :                         continue;
     880             : 
     881           0 :                 following = unit_following(u);
     882             : 
     883           0 :                 if (!strv_isempty(states) &&
     884           0 :                     !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
     885           0 :                     !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
     886           0 :                     !strv_contains(states, unit_sub_state_to_string(u)))
     887           0 :                         continue;
     888             : 
     889           0 :                 unit_path = unit_dbus_path(u);
     890           0 :                 if (!unit_path)
     891           0 :                         return -ENOMEM;
     892             : 
     893           0 :                 if (u->job) {
     894           0 :                         job_path = job_dbus_path(u->job);
     895           0 :                         if (!job_path)
     896           0 :                                 return -ENOMEM;
     897             :                 }
     898             : 
     899           0 :                 r = sd_bus_message_append(
     900             :                                 reply, "(ssssssouso)",
     901           0 :                                 u->id,
     902             :                                 unit_description(u),
     903           0 :                                 unit_load_state_to_string(u->load_state),
     904             :                                 unit_active_state_to_string(unit_active_state(u)),
     905             :                                 unit_sub_state_to_string(u),
     906             :                                 following ? following->id : "",
     907             :                                 unit_path,
     908           0 :                                 u->job ? u->job->id : 0,
     909           0 :                                 u->job ? job_type_to_string(u->job->type) : "",
     910           0 :                                 job_path ? job_path : "/");
     911           0 :                 if (r < 0)
     912           0 :                         return r;
     913             :         }
     914             : 
     915           0 :         r = sd_bus_message_close_container(reply);
     916           0 :         if (r < 0)
     917           0 :                 return r;
     918             : 
     919           0 :         return sd_bus_send(NULL, reply, NULL);
     920             : }
     921             : 
     922           0 : static int method_list_units(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     923           0 :         return list_units_filtered(message, userdata, error, NULL);
     924             : }
     925             : 
     926           0 : static int method_list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     927           0 :         _cleanup_strv_free_ char **states = NULL;
     928             :         int r;
     929             : 
     930           0 :         r = sd_bus_message_read_strv(message, &states);
     931           0 :         if (r < 0)
     932           0 :                 return r;
     933             : 
     934           0 :         return list_units_filtered(message, userdata, error, states);
     935             : }
     936             : 
     937           0 : static int method_list_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     938           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
     939           0 :         Manager *m = userdata;
     940             :         Iterator i;
     941             :         Job *j;
     942             :         int r;
     943             : 
     944           0 :         assert(message);
     945           0 :         assert(m);
     946             : 
     947             :         /* Anyone can call this method */
     948             : 
     949           0 :         r = mac_selinux_access_check(message, "status", error);
     950           0 :         if (r < 0)
     951           0 :                 return r;
     952             : 
     953           0 :         r = sd_bus_message_new_method_return(message, &reply);
     954           0 :         if (r < 0)
     955           0 :                 return r;
     956             : 
     957           0 :         r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
     958           0 :         if (r < 0)
     959           0 :                 return r;
     960             : 
     961           0 :         HASHMAP_FOREACH(j, m->jobs, i) {
     962           0 :                 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
     963             : 
     964           0 :                 job_path = job_dbus_path(j);
     965           0 :                 if (!job_path)
     966           0 :                         return -ENOMEM;
     967             : 
     968           0 :                 unit_path = unit_dbus_path(j->unit);
     969           0 :                 if (!unit_path)
     970           0 :                         return -ENOMEM;
     971             : 
     972           0 :                 r = sd_bus_message_append(
     973             :                                 reply, "(usssoo)",
     974           0 :                                 j->id,
     975           0 :                                 j->unit->id,
     976           0 :                                 job_type_to_string(j->type),
     977           0 :                                 job_state_to_string(j->state),
     978             :                                 job_path,
     979             :                                 unit_path);
     980           0 :                 if (r < 0)
     981           0 :                         return r;
     982             :         }
     983             : 
     984           0 :         r = sd_bus_message_close_container(reply);
     985           0 :         if (r < 0)
     986           0 :                 return r;
     987             : 
     988           0 :         return sd_bus_send(NULL, reply, NULL);
     989             : }
     990             : 
     991           0 : static int method_subscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     992           0 :         Manager *m = userdata;
     993             :         int r;
     994             : 
     995           0 :         assert(message);
     996           0 :         assert(m);
     997             : 
     998             :         /* Anyone can call this method */
     999             : 
    1000           0 :         r = mac_selinux_access_check(message, "status", error);
    1001           0 :         if (r < 0)
    1002           0 :                 return r;
    1003             : 
    1004           0 :         if (sd_bus_message_get_bus(message) == m->api_bus) {
    1005             : 
    1006             :                 /* Note that direct bus connection subscribe by
    1007             :                  * default, we only track peers on the API bus here */
    1008             : 
    1009           0 :                 if (!m->subscribed) {
    1010           0 :                         r = sd_bus_track_new(sd_bus_message_get_bus(message), &m->subscribed, NULL, NULL);
    1011           0 :                         if (r < 0)
    1012           0 :                                 return r;
    1013             :                 }
    1014             : 
    1015           0 :                 r = sd_bus_track_add_sender(m->subscribed, message);
    1016           0 :                 if (r < 0)
    1017           0 :                         return r;
    1018           0 :                 if (r == 0)
    1019           0 :                         return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
    1020             :         }
    1021             : 
    1022           0 :         return sd_bus_reply_method_return(message, NULL);
    1023             : }
    1024             : 
    1025           0 : static int method_unsubscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1026           0 :         Manager *m = userdata;
    1027             :         int r;
    1028             : 
    1029           0 :         assert(message);
    1030           0 :         assert(m);
    1031             : 
    1032             :         /* Anyone can call this method */
    1033             : 
    1034           0 :         r = mac_selinux_access_check(message, "status", error);
    1035           0 :         if (r < 0)
    1036           0 :                 return r;
    1037             : 
    1038           0 :         if (sd_bus_message_get_bus(message) == m->api_bus) {
    1039           0 :                 r = sd_bus_track_remove_sender(m->subscribed, message);
    1040           0 :                 if (r < 0)
    1041           0 :                         return r;
    1042           0 :                 if (r == 0)
    1043           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
    1044             :         }
    1045             : 
    1046           0 :         return sd_bus_reply_method_return(message, NULL);
    1047             : }
    1048             : 
    1049           0 : static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1050           0 :         _cleanup_free_ char *dump = NULL;
    1051           0 :         _cleanup_fclose_ FILE *f = NULL;
    1052           0 :         Manager *m = userdata;
    1053             :         size_t size;
    1054             :         int r;
    1055             : 
    1056           0 :         assert(message);
    1057           0 :         assert(m);
    1058             : 
    1059             :         /* Anyone can call this method */
    1060             : 
    1061           0 :         r = mac_selinux_access_check(message, "status", error);
    1062           0 :         if (r < 0)
    1063           0 :                 return r;
    1064             : 
    1065           0 :         f = open_memstream(&dump, &size);
    1066           0 :         if (!f)
    1067           0 :                 return -ENOMEM;
    1068             : 
    1069           0 :         manager_dump_units(m, f, NULL);
    1070           0 :         manager_dump_jobs(m, f, NULL);
    1071             : 
    1072           0 :         fflush(f);
    1073             : 
    1074           0 :         if (ferror(f))
    1075           0 :                 return -ENOMEM;
    1076             : 
    1077           0 :         return sd_bus_reply_method_return(message, "s", dump);
    1078             : }
    1079             : 
    1080           0 : static int method_create_snapshot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1081           0 :         _cleanup_free_ char *path = NULL;
    1082           0 :         Manager *m = userdata;
    1083             :         const char *name;
    1084             :         int cleanup;
    1085           0 :         Snapshot *s = NULL;
    1086             :         int r;
    1087             : 
    1088           0 :         assert(message);
    1089           0 :         assert(m);
    1090             : 
    1091           0 :         r = mac_selinux_access_check(message, "start", error);
    1092           0 :         if (r < 0)
    1093           0 :                 return r;
    1094             : 
    1095           0 :         r = sd_bus_message_read(message, "sb", &name, &cleanup);
    1096           0 :         if (r < 0)
    1097           0 :                 return r;
    1098             : 
    1099           0 :         if (isempty(name))
    1100           0 :                 name = NULL;
    1101             : 
    1102           0 :         r = bus_verify_manage_units_async(m, message, error);
    1103           0 :         if (r < 0)
    1104           0 :                 return r;
    1105           0 :         if (r == 0)
    1106           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1107             : 
    1108           0 :         r = snapshot_create(m, name, cleanup, error, &s);
    1109           0 :         if (r < 0)
    1110           0 :                 return r;
    1111             : 
    1112           0 :         path = unit_dbus_path(UNIT(s));
    1113           0 :         if (!path)
    1114           0 :                 return -ENOMEM;
    1115             : 
    1116           0 :         return sd_bus_reply_method_return(message, "o", path);
    1117             : }
    1118             : 
    1119           0 : static int method_remove_snapshot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1120           0 :         Manager *m = userdata;
    1121             :         const char *name;
    1122             :         Unit *u;
    1123             :         int r;
    1124             : 
    1125           0 :         assert(message);
    1126           0 :         assert(m);
    1127             : 
    1128           0 :         r = sd_bus_message_read(message, "s", &name);
    1129           0 :         if (r < 0)
    1130           0 :                 return r;
    1131             : 
    1132           0 :         u = manager_get_unit(m, name);
    1133           0 :         if (!u)
    1134           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
    1135             : 
    1136           0 :         if (u->type != UNIT_SNAPSHOT)
    1137           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
    1138             : 
    1139           0 :         return bus_snapshot_method_remove(message, u, error);
    1140             : }
    1141             : 
    1142           0 : static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1143           0 :         Manager *m = userdata;
    1144             :         int r;
    1145             : 
    1146           0 :         assert(message);
    1147           0 :         assert(m);
    1148             : 
    1149           0 :         r = mac_selinux_access_check(message, "reload", error);
    1150           0 :         if (r < 0)
    1151           0 :                 return r;
    1152             : 
    1153           0 :         r = bus_verify_reload_daemon_async(m, message, error);
    1154           0 :         if (r < 0)
    1155           0 :                 return r;
    1156           0 :         if (r == 0)
    1157           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1158             : 
    1159             :         /* Instead of sending the reply back right away, we just
    1160             :          * remember that we need to and then send it after the reload
    1161             :          * is finished. That way the caller knows when the reload
    1162             :          * finished. */
    1163             : 
    1164           0 :         assert(!m->queued_message);
    1165           0 :         r = sd_bus_message_new_method_return(message, &m->queued_message);
    1166           0 :         if (r < 0)
    1167           0 :                 return r;
    1168             : 
    1169           0 :         m->exit_code = MANAGER_RELOAD;
    1170             : 
    1171           0 :         return 1;
    1172             : }
    1173             : 
    1174           0 : static int method_reexecute(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1175           0 :         Manager *m = userdata;
    1176             :         int r;
    1177             : 
    1178           0 :         assert(message);
    1179           0 :         assert(m);
    1180             : 
    1181           0 :         r = mac_selinux_access_check(message, "reload", error);
    1182           0 :         if (r < 0)
    1183           0 :                 return r;
    1184             : 
    1185           0 :         r = bus_verify_reload_daemon_async(m, message, error);
    1186           0 :         if (r < 0)
    1187           0 :                 return r;
    1188           0 :         if (r == 0)
    1189           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1190             : 
    1191             :         /* We don't send a reply back here, the client should
    1192             :          * just wait for us disconnecting. */
    1193             : 
    1194           0 :         m->exit_code = MANAGER_REEXECUTE;
    1195           0 :         return 1;
    1196             : }
    1197             : 
    1198           0 : static int method_exit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1199           0 :         Manager *m = userdata;
    1200             :         int r;
    1201             : 
    1202           0 :         assert(message);
    1203           0 :         assert(m);
    1204             : 
    1205           0 :         r = mac_selinux_access_check(message, "halt", error);
    1206           0 :         if (r < 0)
    1207           0 :                 return r;
    1208             : 
    1209           0 :         if (m->running_as == MANAGER_SYSTEM)
    1210           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
    1211             : 
    1212           0 :         m->exit_code = MANAGER_EXIT;
    1213             : 
    1214           0 :         return sd_bus_reply_method_return(message, NULL);
    1215             : }
    1216             : 
    1217           0 : static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1218           0 :         Manager *m = userdata;
    1219             :         int r;
    1220             : 
    1221           0 :         assert(message);
    1222           0 :         assert(m);
    1223             : 
    1224           0 :         r = mac_selinux_access_check(message, "reboot", error);
    1225           0 :         if (r < 0)
    1226           0 :                 return r;
    1227             : 
    1228           0 :         if (m->running_as != MANAGER_SYSTEM)
    1229           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
    1230             : 
    1231           0 :         m->exit_code = MANAGER_REBOOT;
    1232             : 
    1233           0 :         return sd_bus_reply_method_return(message, NULL);
    1234             : }
    1235             : 
    1236           0 : static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1237           0 :         Manager *m = userdata;
    1238             :         int r;
    1239             : 
    1240           0 :         assert(message);
    1241           0 :         assert(m);
    1242             : 
    1243           0 :         r = mac_selinux_access_check(message, "halt", error);
    1244           0 :         if (r < 0)
    1245           0 :                 return r;
    1246             : 
    1247           0 :         if (m->running_as != MANAGER_SYSTEM)
    1248           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
    1249             : 
    1250           0 :         m->exit_code = MANAGER_POWEROFF;
    1251             : 
    1252           0 :         return sd_bus_reply_method_return(message, NULL);
    1253             : }
    1254             : 
    1255           0 : static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1256           0 :         Manager *m = userdata;
    1257             :         int r;
    1258             : 
    1259           0 :         assert(message);
    1260           0 :         assert(m);
    1261             : 
    1262           0 :         r = mac_selinux_access_check(message, "halt", error);
    1263           0 :         if (r < 0)
    1264           0 :                 return r;
    1265             : 
    1266           0 :         if (m->running_as != MANAGER_SYSTEM)
    1267           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
    1268             : 
    1269           0 :         m->exit_code = MANAGER_HALT;
    1270             : 
    1271           0 :         return sd_bus_reply_method_return(message, NULL);
    1272             : }
    1273             : 
    1274           0 : static int method_kexec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1275           0 :         Manager *m = userdata;
    1276             :         int r;
    1277             : 
    1278           0 :         assert(message);
    1279           0 :         assert(m);
    1280             : 
    1281           0 :         r = mac_selinux_access_check(message, "reboot", error);
    1282           0 :         if (r < 0)
    1283           0 :                 return r;
    1284             : 
    1285           0 :         if (m->running_as != MANAGER_SYSTEM)
    1286           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
    1287             : 
    1288           0 :         m->exit_code = MANAGER_KEXEC;
    1289             : 
    1290           0 :         return sd_bus_reply_method_return(message, NULL);
    1291             : }
    1292             : 
    1293           0 : static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1294           0 :         char *ri = NULL, *rt = NULL;
    1295             :         const char *root, *init;
    1296           0 :         Manager *m = userdata;
    1297             :         int r;
    1298             : 
    1299           0 :         assert(message);
    1300           0 :         assert(m);
    1301             : 
    1302           0 :         r = mac_selinux_access_check(message, "reboot", error);
    1303           0 :         if (r < 0)
    1304           0 :                 return r;
    1305             : 
    1306           0 :         if (m->running_as != MANAGER_SYSTEM)
    1307           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
    1308             : 
    1309           0 :         r = sd_bus_message_read(message, "ss", &root, &init);
    1310           0 :         if (r < 0)
    1311           0 :                 return r;
    1312             : 
    1313           0 :         if (path_equal(root, "/") || !path_is_absolute(root))
    1314           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
    1315             : 
    1316             :         /* Safety check */
    1317           0 :         if (isempty(init)) {
    1318           0 :                 if (!path_is_os_tree(root))
    1319           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. os-release file is missing.", root);
    1320             :         } else {
    1321           0 :                 _cleanup_free_ char *p = NULL;
    1322             : 
    1323           0 :                 if (!path_is_absolute(init))
    1324           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
    1325             : 
    1326           0 :                 p = strappend(root, init);
    1327           0 :                 if (!p)
    1328           0 :                         return -ENOMEM;
    1329             : 
    1330           0 :                 if (access(p, X_OK) < 0)
    1331           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
    1332             :         }
    1333             : 
    1334           0 :         rt = strdup(root);
    1335           0 :         if (!rt)
    1336           0 :                 return -ENOMEM;
    1337             : 
    1338           0 :         if (!isempty(init)) {
    1339           0 :                 ri = strdup(init);
    1340           0 :                 if (!ri) {
    1341           0 :                         free(rt);
    1342           0 :                         return -ENOMEM;
    1343             :                 }
    1344             :         }
    1345             : 
    1346           0 :         free(m->switch_root);
    1347           0 :         m->switch_root = rt;
    1348             : 
    1349           0 :         free(m->switch_root_init);
    1350           0 :         m->switch_root_init = ri;
    1351             : 
    1352           0 :         m->exit_code = MANAGER_SWITCH_ROOT;
    1353             : 
    1354           0 :         return sd_bus_reply_method_return(message, NULL);
    1355             : }
    1356             : 
    1357           0 : static int method_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1358           0 :         _cleanup_strv_free_ char **plus = NULL;
    1359           0 :         Manager *m = userdata;
    1360             :         int r;
    1361             : 
    1362           0 :         assert(message);
    1363           0 :         assert(m);
    1364             : 
    1365           0 :         r = mac_selinux_access_check(message, "reload", error);
    1366           0 :         if (r < 0)
    1367           0 :                 return r;
    1368             : 
    1369           0 :         r = sd_bus_message_read_strv(message, &plus);
    1370           0 :         if (r < 0)
    1371           0 :                 return r;
    1372           0 :         if (!strv_env_is_valid(plus))
    1373           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
    1374             : 
    1375           0 :         r = bus_verify_set_environment_async(m, message, error);
    1376           0 :         if (r < 0)
    1377           0 :                 return r;
    1378           0 :         if (r == 0)
    1379           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1380             : 
    1381           0 :         r = manager_environment_add(m, NULL, plus);
    1382           0 :         if (r < 0)
    1383           0 :                 return r;
    1384             : 
    1385           0 :         return sd_bus_reply_method_return(message, NULL);
    1386             : }
    1387             : 
    1388           0 : static int method_unset_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1389           0 :         _cleanup_strv_free_ char **minus = NULL;
    1390           0 :         Manager *m = userdata;
    1391             :         int r;
    1392             : 
    1393           0 :         assert(message);
    1394           0 :         assert(m);
    1395             : 
    1396           0 :         r = mac_selinux_access_check(message, "reload", error);
    1397           0 :         if (r < 0)
    1398           0 :                 return r;
    1399             : 
    1400           0 :         r = sd_bus_message_read_strv(message, &minus);
    1401           0 :         if (r < 0)
    1402           0 :                 return r;
    1403             : 
    1404           0 :         if (!strv_env_name_or_assignment_is_valid(minus))
    1405           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
    1406             : 
    1407           0 :         r = bus_verify_set_environment_async(m, message, error);
    1408           0 :         if (r < 0)
    1409           0 :                 return r;
    1410           0 :         if (r == 0)
    1411           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1412             : 
    1413           0 :         r = manager_environment_add(m, minus, NULL);
    1414           0 :         if (r < 0)
    1415           0 :                 return r;
    1416             : 
    1417           0 :         return sd_bus_reply_method_return(message, NULL);
    1418             : }
    1419             : 
    1420           0 : static int method_unset_and_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1421           0 :         _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
    1422           0 :         Manager *m = userdata;
    1423             :         int r;
    1424             : 
    1425           0 :         assert(message);
    1426           0 :         assert(m);
    1427             : 
    1428           0 :         r = mac_selinux_access_check(message, "reload", error);
    1429           0 :         if (r < 0)
    1430           0 :                 return r;
    1431             : 
    1432           0 :         r = sd_bus_message_read_strv(message, &minus);
    1433           0 :         if (r < 0)
    1434           0 :                 return r;
    1435             : 
    1436           0 :         r = sd_bus_message_read_strv(message, &plus);
    1437           0 :         if (r < 0)
    1438           0 :                 return r;
    1439             : 
    1440           0 :         if (!strv_env_name_or_assignment_is_valid(minus))
    1441           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
    1442           0 :         if (!strv_env_is_valid(plus))
    1443           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
    1444             : 
    1445           0 :         r = bus_verify_set_environment_async(m, message, error);
    1446           0 :         if (r < 0)
    1447           0 :                 return r;
    1448           0 :         if (r == 0)
    1449           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1450             : 
    1451           0 :         r = manager_environment_add(m, minus, plus);
    1452           0 :         if (r < 0)
    1453           0 :                 return r;
    1454             : 
    1455           0 :         return sd_bus_reply_method_return(message, NULL);
    1456             : }
    1457             : 
    1458           0 : static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1459           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
    1460           0 :         Manager *m = userdata;
    1461             :         UnitFileList *item;
    1462             :         Hashmap *h;
    1463             :         Iterator i;
    1464             :         int r;
    1465             : 
    1466           0 :         assert(message);
    1467           0 :         assert(m);
    1468             : 
    1469             :         /* Anyone can call this method */
    1470             : 
    1471           0 :         r = mac_selinux_access_check(message, "status", error);
    1472           0 :         if (r < 0)
    1473           0 :                 return r;
    1474             : 
    1475           0 :         r = sd_bus_message_new_method_return(message, &reply);
    1476           0 :         if (r < 0)
    1477           0 :                 return r;
    1478             : 
    1479           0 :         h = hashmap_new(&string_hash_ops);
    1480           0 :         if (!h)
    1481           0 :                 return -ENOMEM;
    1482             : 
    1483           0 :         r = unit_file_get_list(m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
    1484           0 :         if (r < 0)
    1485           0 :                 goto fail;
    1486             : 
    1487           0 :         r = sd_bus_message_open_container(reply, 'a', "(ss)");
    1488           0 :         if (r < 0)
    1489           0 :                 goto fail;
    1490             : 
    1491           0 :         HASHMAP_FOREACH(item, h, i) {
    1492             : 
    1493           0 :                 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
    1494           0 :                 if (r < 0)
    1495           0 :                         goto fail;
    1496             :         }
    1497             : 
    1498           0 :         unit_file_list_free(h);
    1499             : 
    1500           0 :         r = sd_bus_message_close_container(reply);
    1501           0 :         if (r < 0)
    1502           0 :                 return r;
    1503             : 
    1504           0 :         return sd_bus_send(NULL, reply, NULL);
    1505             : 
    1506             : fail:
    1507           0 :         unit_file_list_free(h);
    1508           0 :         return r;
    1509             : }
    1510             : 
    1511           0 : static int method_get_unit_file_state(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1512           0 :         Manager *m = userdata;
    1513             :         const char *name;
    1514             :         UnitFileState state;
    1515             :         UnitFileScope scope;
    1516             :         int r;
    1517             : 
    1518           0 :         assert(message);
    1519           0 :         assert(m);
    1520             : 
    1521             :         /* Anyone can call this method */
    1522             : 
    1523           0 :         r = mac_selinux_access_check(message, "status", error);
    1524           0 :         if (r < 0)
    1525           0 :                 return r;
    1526             : 
    1527           0 :         r = sd_bus_message_read(message, "s", &name);
    1528           0 :         if (r < 0)
    1529           0 :                 return r;
    1530             : 
    1531           0 :         scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
    1532             : 
    1533           0 :         state = unit_file_get_state(scope, NULL, name);
    1534           0 :         if (state < 0)
    1535           0 :                 return state;
    1536             : 
    1537           0 :         return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
    1538             : }
    1539             : 
    1540           0 : static int method_get_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1541           0 :         _cleanup_free_ char *default_target = NULL;
    1542           0 :         Manager *m = userdata;
    1543             :         UnitFileScope scope;
    1544             :         int r;
    1545             : 
    1546           0 :         assert(message);
    1547           0 :         assert(m);
    1548             : 
    1549             :         /* Anyone can call this method */
    1550             : 
    1551           0 :         r = mac_selinux_access_check(message, "status", error);
    1552           0 :         if (r < 0)
    1553           0 :                 return r;
    1554             : 
    1555           0 :         scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
    1556             : 
    1557           0 :         r = unit_file_get_default(scope, NULL, &default_target);
    1558           0 :         if (r < 0)
    1559           0 :                 return r;
    1560             : 
    1561           0 :         return sd_bus_reply_method_return(message, "s", default_target);
    1562             : }
    1563             : 
    1564           0 : static int send_unit_files_changed(sd_bus *bus, void *userdata) {
    1565           0 :         _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
    1566             :         int r;
    1567             : 
    1568           0 :         assert(bus);
    1569             : 
    1570           0 :         r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
    1571           0 :         if (r < 0)
    1572           0 :                 return r;
    1573             : 
    1574           0 :         return sd_bus_send(bus, message, NULL);
    1575             : }
    1576             : 
    1577           0 : static int reply_unit_file_changes_and_free(
    1578             :                 Manager *m,
    1579             :                 sd_bus_message *message,
    1580             :                 int carries_install_info,
    1581             :                 UnitFileChange *changes,
    1582             :                 unsigned n_changes) {
    1583             : 
    1584           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
    1585             :         unsigned i;
    1586             :         int r;
    1587             : 
    1588           0 :         if (n_changes > 0) {
    1589           0 :                 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
    1590           0 :                 if (r < 0)
    1591           0 :                         log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
    1592             :         }
    1593             : 
    1594           0 :         r = sd_bus_message_new_method_return(message, &reply);
    1595           0 :         if (r < 0)
    1596           0 :                 goto fail;
    1597             : 
    1598           0 :         if (carries_install_info >= 0) {
    1599           0 :                 r = sd_bus_message_append(reply, "b", carries_install_info);
    1600           0 :                 if (r < 0)
    1601           0 :                         goto fail;
    1602             :         }
    1603             : 
    1604           0 :         r = sd_bus_message_open_container(reply, 'a', "(sss)");
    1605           0 :         if (r < 0)
    1606           0 :                 goto fail;
    1607             : 
    1608           0 :         for (i = 0; i < n_changes; i++) {
    1609           0 :                 r = sd_bus_message_append(
    1610             :                                 reply, "(sss)",
    1611           0 :                                 unit_file_change_type_to_string(changes[i].type),
    1612           0 :                                 changes[i].path,
    1613           0 :                                 changes[i].source);
    1614           0 :                 if (r < 0)
    1615           0 :                         goto fail;
    1616             :         }
    1617             : 
    1618           0 :         r = sd_bus_message_close_container(reply);
    1619           0 :         if (r < 0)
    1620           0 :                 goto fail;
    1621             : 
    1622           0 :         return sd_bus_send(NULL, reply, NULL);
    1623             : 
    1624             : fail:
    1625           0 :         unit_file_changes_free(changes, n_changes);
    1626           0 :         return r;
    1627             : }
    1628             : 
    1629           0 : static int method_enable_unit_files_generic(
    1630             :                 sd_bus_message *message,
    1631             :                 Manager *m,
    1632             :                 const char *verb,
    1633             :                 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
    1634             :                 bool carries_install_info,
    1635             :                 sd_bus_error *error) {
    1636             : 
    1637           0 :         _cleanup_strv_free_ char **l = NULL;
    1638           0 :         UnitFileChange *changes = NULL;
    1639           0 :         unsigned n_changes = 0;
    1640             :         UnitFileScope scope;
    1641             :         int runtime, force, r;
    1642             : 
    1643           0 :         assert(message);
    1644           0 :         assert(m);
    1645             : 
    1646           0 :         r = sd_bus_message_read_strv(message, &l);
    1647           0 :         if (r < 0)
    1648           0 :                 return r;
    1649             : 
    1650           0 :         r = sd_bus_message_read(message, "bb", &runtime, &force);
    1651           0 :         if (r < 0)
    1652           0 :                 return r;
    1653             : 
    1654           0 :         r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
    1655           0 :         if (r < 0)
    1656           0 :                 return r;
    1657             : 
    1658           0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    1659           0 :         if (r < 0)
    1660           0 :                 return r;
    1661           0 :         if (r == 0)
    1662           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1663             : 
    1664           0 :         scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
    1665             : 
    1666           0 :         r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
    1667           0 :         if (r < 0)
    1668           0 :                 return r;
    1669             : 
    1670           0 :         return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes);
    1671             : }
    1672             : 
    1673           0 : static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1674           0 :         return method_enable_unit_files_generic(message, userdata, "enable", unit_file_enable, true, error);
    1675             : }
    1676             : 
    1677           0 : static int method_reenable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1678           0 :         return method_enable_unit_files_generic(message, userdata, "enable", unit_file_reenable, true, error);
    1679             : }
    1680             : 
    1681           0 : static int method_link_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1682           0 :         return method_enable_unit_files_generic(message, userdata, "enable", unit_file_link, false, error);
    1683             : }
    1684             : 
    1685           0 : static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
    1686           0 :         return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
    1687             : }
    1688             : 
    1689           0 : static int method_preset_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1690           0 :         return method_enable_unit_files_generic(message, userdata, "enable", unit_file_preset_without_mode, true, error);
    1691             : }
    1692             : 
    1693           0 : static int method_mask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1694           0 :         return method_enable_unit_files_generic(message, userdata, "disable", unit_file_mask, false, error);
    1695             : }
    1696             : 
    1697           0 : static int method_preset_unit_files_with_mode(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1698             : 
    1699           0 :         _cleanup_strv_free_ char **l = NULL;
    1700           0 :         UnitFileChange *changes = NULL;
    1701           0 :         unsigned n_changes = 0;
    1702           0 :         Manager *m = userdata;
    1703             :         UnitFilePresetMode mm;
    1704             :         UnitFileScope scope;
    1705             :         int runtime, force, r;
    1706             :         const char *mode;
    1707             : 
    1708           0 :         assert(message);
    1709           0 :         assert(m);
    1710             : 
    1711           0 :         r = sd_bus_message_read_strv(message, &l);
    1712           0 :         if (r < 0)
    1713           0 :                 return r;
    1714             : 
    1715           0 :         r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
    1716           0 :         if (r < 0)
    1717           0 :                 return r;
    1718             : 
    1719           0 :         if (isempty(mode))
    1720           0 :                 mm = UNIT_FILE_PRESET_FULL;
    1721             :         else {
    1722           0 :                 mm = unit_file_preset_mode_from_string(mode);
    1723           0 :                 if (mm < 0)
    1724           0 :                         return -EINVAL;
    1725             :         }
    1726             : 
    1727           0 :         r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
    1728           0 :         if (r < 0)
    1729           0 :                 return r;
    1730             : 
    1731           0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    1732           0 :         if (r < 0)
    1733           0 :                 return r;
    1734           0 :         if (r == 0)
    1735           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1736             : 
    1737           0 :         scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
    1738             : 
    1739           0 :         r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
    1740           0 :         if (r < 0)
    1741           0 :                 return r;
    1742             : 
    1743           0 :         return reply_unit_file_changes_and_free(m, message, r, changes, n_changes);
    1744             : }
    1745             : 
    1746           0 : static int method_disable_unit_files_generic(
    1747             :                 sd_bus_message *message,
    1748             :                 Manager *m, const
    1749             :                 char *verb,
    1750             :                 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
    1751             :                 sd_bus_error *error) {
    1752             : 
    1753           0 :         _cleanup_strv_free_ char **l = NULL;
    1754           0 :         UnitFileChange *changes = NULL;
    1755           0 :         unsigned n_changes = 0;
    1756             :         UnitFileScope scope;
    1757             :         int r, runtime;
    1758             : 
    1759           0 :         assert(message);
    1760           0 :         assert(m);
    1761             : 
    1762           0 :         r = sd_bus_message_read_strv(message, &l);
    1763           0 :         if (r < 0)
    1764           0 :                 return r;
    1765             : 
    1766           0 :         r = sd_bus_message_read(message, "b", &runtime);
    1767           0 :         if (r < 0)
    1768           0 :                 return r;
    1769             : 
    1770           0 :         r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
    1771           0 :         if (r < 0)
    1772           0 :                 return r;
    1773             : 
    1774           0 :         scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
    1775             : 
    1776           0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    1777           0 :         if (r < 0)
    1778           0 :                 return r;
    1779           0 :         if (r == 0)
    1780           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1781             : 
    1782           0 :         r = call(scope, runtime, NULL, l, &changes, &n_changes);
    1783           0 :         if (r < 0)
    1784           0 :                 return r;
    1785             : 
    1786           0 :         return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
    1787             : }
    1788             : 
    1789           0 : static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1790           0 :         return method_disable_unit_files_generic(message, userdata, "disable", unit_file_disable, error);
    1791             : }
    1792             : 
    1793           0 : static int method_unmask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1794           0 :         return method_disable_unit_files_generic(message, userdata, "enable", unit_file_unmask, error);
    1795             : }
    1796             : 
    1797           0 : static int method_set_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1798           0 :         UnitFileChange *changes = NULL;
    1799           0 :         unsigned n_changes = 0;
    1800           0 :         Manager *m = userdata;
    1801             :         UnitFileScope scope;
    1802             :         const char *name;
    1803             :         int force, r;
    1804             : 
    1805           0 :         assert(message);
    1806           0 :         assert(m);
    1807             : 
    1808           0 :         r = mac_selinux_access_check(message, "enable", error);
    1809           0 :         if (r < 0)
    1810           0 :                 return r;
    1811             : 
    1812           0 :         r = sd_bus_message_read(message, "sb", &name, &force);
    1813           0 :         if (r < 0)
    1814           0 :                 return r;
    1815             : 
    1816           0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    1817           0 :         if (r < 0)
    1818           0 :                 return r;
    1819           0 :         if (r == 0)
    1820           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1821             : 
    1822           0 :         scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
    1823             : 
    1824           0 :         r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
    1825           0 :         if (r < 0)
    1826           0 :                 return r;
    1827             : 
    1828           0 :         return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
    1829             : }
    1830             : 
    1831           0 : static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1832           0 :         UnitFileChange *changes = NULL;
    1833           0 :         unsigned n_changes = 0;
    1834           0 :         Manager *m = userdata;
    1835             :         UnitFilePresetMode mm;
    1836             :         UnitFileScope scope;
    1837             :         const char *mode;
    1838             :         int force, runtime, r;
    1839             : 
    1840           0 :         assert(message);
    1841           0 :         assert(m);
    1842             : 
    1843           0 :         r = mac_selinux_access_check(message, "enable", error);
    1844           0 :         if (r < 0)
    1845           0 :                 return r;
    1846             : 
    1847           0 :         r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
    1848           0 :         if (r < 0)
    1849           0 :                 return r;
    1850             : 
    1851           0 :         if (isempty(mode))
    1852           0 :                 mm = UNIT_FILE_PRESET_FULL;
    1853             :         else {
    1854           0 :                 mm = unit_file_preset_mode_from_string(mode);
    1855           0 :                 if (mm < 0)
    1856           0 :                         return -EINVAL;
    1857             :         }
    1858             : 
    1859           0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    1860           0 :         if (r < 0)
    1861           0 :                 return r;
    1862           0 :         if (r == 0)
    1863           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1864             : 
    1865           0 :         scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
    1866             : 
    1867           0 :         r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
    1868           0 :         if (r < 0)
    1869           0 :                 return r;
    1870             : 
    1871           0 :         return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
    1872             : }
    1873             : 
    1874           0 : static int method_add_dependency_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1875           0 :         _cleanup_strv_free_ char **l = NULL;
    1876           0 :         Manager *m = userdata;
    1877           0 :         UnitFileChange *changes = NULL;
    1878           0 :         unsigned n_changes = 0;
    1879             :         UnitFileScope scope;
    1880             :         int runtime, force, r;
    1881             :         char *target;
    1882             :         char *type;
    1883             :         UnitDependency dep;
    1884             : 
    1885           0 :         assert(message);
    1886           0 :         assert(m);
    1887             : 
    1888           0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    1889           0 :         if (r < 0)
    1890           0 :                 return r;
    1891           0 :         if (r == 0)
    1892           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1893             : 
    1894           0 :         r = sd_bus_message_read_strv(message, &l);
    1895           0 :         if (r < 0)
    1896           0 :                 return r;
    1897             : 
    1898           0 :         r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
    1899           0 :         if (r < 0)
    1900           0 :                 return r;
    1901             : 
    1902           0 :         dep = unit_dependency_from_string(type);
    1903           0 :         if (dep < 0)
    1904           0 :                 return -EINVAL;
    1905             : 
    1906           0 :         r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
    1907           0 :         if (r < 0)
    1908           0 :                 return r;
    1909             : 
    1910           0 :         scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
    1911             : 
    1912           0 :         r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
    1913           0 :         if (r < 0)
    1914           0 :                 return r;
    1915             : 
    1916           0 :         return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
    1917             : }
    1918             : 
    1919             : const sd_bus_vtable bus_manager_vtable[] = {
    1920             :         SD_BUS_VTABLE_START(0),
    1921             : 
    1922             :         SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    1923             :         SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    1924             :         SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    1925             :         SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    1926             :         SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    1927             :         BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
    1928             :         BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
    1929             :         BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
    1930             :         BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
    1931             :         BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
    1932             :         BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
    1933             :         BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
    1934             :         BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
    1935             :         BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
    1936             :         BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
    1937             :         BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
    1938             :         BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
    1939             :         SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
    1940             :         SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
    1941             :         SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
    1942             :         SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
    1943             :         SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
    1944             :         SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
    1945             :         SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
    1946             :         SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
    1947             :         SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
    1948             :         SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
    1949             :         SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
    1950             :         SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
    1951             :         SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
    1952             :         SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
    1953             :         SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
    1954             :         SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
    1955             :         SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
    1956             :         SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
    1957             : 
    1958             :         SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    1959             :         SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
    1960             :         SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    1961             :         SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    1962             :         SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
    1963             :         SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    1964             :         SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    1965             :         SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    1966             :         SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    1967             :         SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    1968             :         SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    1969             :         SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    1970             :         SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    1971             :         SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
    1972             :         SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    1973             :         SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
    1974             :         SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
    1975             :         SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
    1976             :         SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
    1977             :         SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
    1978             :         SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
    1979             :         SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
    1980             :         SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
    1981             :         SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
    1982             :         SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
    1983             :         SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
    1984             :         SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
    1985             :         SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
    1986             :         SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
    1987             :         SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
    1988             :         SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
    1989             :         SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
    1990             :         SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
    1991             :         SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
    1992             :         SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
    1993             :         SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
    1994             :         SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, SD_BUS_VTABLE_UNPRIVILEGED),
    1995             :         SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
    1996             :         SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    1997             :         SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
    1998             :         SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    1999             :         SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2000             :         SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2001             :         SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2002             :         SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2003             :         SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
    2004             :         SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2005             :         SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2006             :         SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
    2007             :         SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
    2008             :         SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2009             :         SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2010             : 
    2011             :         SD_BUS_SIGNAL("UnitNew", "so", 0),
    2012             :         SD_BUS_SIGNAL("UnitRemoved", "so", 0),
    2013             :         SD_BUS_SIGNAL("JobNew", "uos", 0),
    2014             :         SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
    2015             :         SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
    2016             :         SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
    2017             :         SD_BUS_SIGNAL("Reloading", "b", 0),
    2018             : 
    2019             :         SD_BUS_VTABLE_END
    2020             : };
    2021             : 
    2022           0 : static int send_finished(sd_bus *bus, void *userdata) {
    2023           0 :         _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
    2024           0 :         usec_t *times = userdata;
    2025             :         int r;
    2026             : 
    2027           0 :         assert(bus);
    2028           0 :         assert(times);
    2029             : 
    2030           0 :         r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
    2031           0 :         if (r < 0)
    2032           0 :                 return r;
    2033             : 
    2034           0 :         r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
    2035           0 :         if (r < 0)
    2036           0 :                 return r;
    2037             : 
    2038           0 :         return sd_bus_send(bus, message, NULL);
    2039             : }
    2040             : 
    2041           0 : void bus_manager_send_finished(
    2042             :                 Manager *m,
    2043             :                 usec_t firmware_usec,
    2044             :                 usec_t loader_usec,
    2045             :                 usec_t kernel_usec,
    2046             :                 usec_t initrd_usec,
    2047             :                 usec_t userspace_usec,
    2048             :                 usec_t total_usec) {
    2049             : 
    2050             :         int r;
    2051             : 
    2052           0 :         assert(m);
    2053             : 
    2054           0 :         r = bus_foreach_bus(
    2055             :                         m,
    2056             :                         NULL,
    2057             :                         send_finished,
    2058           0 :                         (usec_t[6]) {
    2059             :                                 firmware_usec,
    2060             :                                 loader_usec,
    2061             :                                 kernel_usec,
    2062             :                                 initrd_usec,
    2063             :                                 userspace_usec,
    2064             :                                 total_usec
    2065             :                         });
    2066           0 :         if (r < 0)
    2067           0 :                 log_debug_errno(r, "Failed to send finished signal: %m");
    2068           0 : }
    2069             : 
    2070           0 : static int send_reloading(sd_bus *bus, void *userdata) {
    2071           0 :         _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
    2072             :         int r;
    2073             : 
    2074           0 :         assert(bus);
    2075             : 
    2076           0 :         r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
    2077           0 :         if (r < 0)
    2078           0 :                 return r;
    2079             : 
    2080           0 :         r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
    2081           0 :         if (r < 0)
    2082           0 :                 return r;
    2083             : 
    2084           0 :         return sd_bus_send(bus, message, NULL);
    2085             : }
    2086             : 
    2087           0 : void bus_manager_send_reloading(Manager *m, bool active) {
    2088             :         int r;
    2089             : 
    2090           0 :         assert(m);
    2091             : 
    2092           0 :         r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
    2093           0 :         if (r < 0)
    2094           0 :                 log_debug_errno(r, "Failed to send reloading signal: %m");
    2095           0 : }
    2096             : 
    2097           0 : static int send_changed_signal(sd_bus *bus, void *userdata) {
    2098           0 :         assert(bus);
    2099             : 
    2100           0 :         return sd_bus_emit_properties_changed_strv(bus,
    2101             :                                                    "/org/freedesktop/systemd1",
    2102             :                                                    "org.freedesktop.systemd1.Manager",
    2103             :                                                    NULL);
    2104             : }
    2105             : 
    2106           0 : void bus_manager_send_change_signal(Manager *m) {
    2107             :         int r;
    2108             : 
    2109           0 :         assert(m);
    2110             : 
    2111           0 :         r = bus_foreach_bus(m, NULL, send_changed_signal, NULL);
    2112           0 :         if (r < 0)
    2113           0 :                 log_debug_errno(r, "Failed to send manager change signal: %m");
    2114           0 : }

Generated by: LCOV version 1.11