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