chiark / gitweb /
cgroup: Handle error when destroying cgroup
[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 = mac_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 = mac_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 = mac_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 transient_unit_from_message(
619                 Manager *m,
620                 sd_bus_message *message,
621                 const char *name,
622                 Unit **unit,
623                 sd_bus_error *error) {
624
625         Unit *u;
626         int r;
627
628         assert(m);
629         assert(message);
630         assert(name);
631
632         r = manager_load_unit(m, name, NULL, error, &u);
633         if (r < 0)
634                 return r;
635
636         if (u->load_state != UNIT_NOT_FOUND ||
637             set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
638                 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
639
640         /* OK, the unit failed to load and is unreferenced, now let's
641          * fill in the transient data instead */
642         r = unit_make_transient(u);
643         if (r < 0)
644                 return r;
645
646         /* Set our properties */
647         r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
648         if (r < 0)
649                 return r;
650
651         *unit = u;
652
653         return 0;
654 }
655
656 static int transient_aux_units_from_message(
657                 Manager *m,
658                 sd_bus_message *message,
659                 sd_bus_error *error) {
660
661         Unit *u;
662         char *name = NULL;
663         int r;
664
665         assert(m);
666         assert(message);
667
668         r = sd_bus_message_enter_container(message, 'a', "(sa(sv))");
669         if (r < 0)
670                 return r;
671
672         while ((r = sd_bus_message_enter_container(message, 'r', "sa(sv)")) > 0) {
673                 if (r <= 0)
674                         return r;
675
676                 r = sd_bus_message_read(message, "s", &name);
677                 if (r < 0)
678                         return r;
679
680                 r = transient_unit_from_message(m, message, name, &u, error);
681                 if (r < 0 && r != -EEXIST)
682                         return r;
683
684                 r = unit_load(u);
685                 if (r < 0)
686                         return r;
687
688                 r = sd_bus_message_exit_container(message);
689                 if (r < 0)
690                         return r;
691         }
692         if (r < 0)
693                 return r;
694
695         r = sd_bus_message_exit_container(message);
696         if (r < 0)
697                 return r;
698
699         return 0;
700 }
701
702 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
703         const char *name, *smode;
704         Manager *m = userdata;
705         JobMode mode;
706         UnitType t;
707         Unit *u;
708         int r;
709
710         assert(bus);
711         assert(message);
712         assert(m);
713
714         r = bus_verify_manage_unit_async(m, message, error);
715         if (r < 0)
716                 return r;
717         if (r == 0)
718                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
719
720         r = sd_bus_message_read(message, "ss", &name, &smode);
721         if (r < 0)
722                 return r;
723
724         t = unit_name_to_type(name);
725         if (t < 0)
726                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
727
728         if (!unit_vtable[t]->can_transient)
729                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
730
731         mode = job_mode_from_string(smode);
732         if (mode < 0)
733                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
734
735         r = mac_selinux_access_check(message, "start", error);
736         if (r < 0)
737                 return r;
738
739         r = transient_unit_from_message(m, message, name, &u, error);
740         if (r < 0)
741                 return r;
742
743         r = transient_aux_units_from_message(m, message, error);
744         if (r < 0)
745                 return r;
746
747         /* And load this stub fully */
748         r = unit_load(u);
749         if (r < 0)
750                 return r;
751
752         manager_dispatch_load_queue(m);
753
754         /* Finally, start it */
755         return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
756 }
757
758 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
759         _cleanup_free_ char *path = NULL;
760         Manager *m = userdata;
761         uint32_t id;
762         Job *j;
763         int r;
764
765         assert(bus);
766         assert(message);
767         assert(m);
768
769         /* Anyone can call this method */
770
771         r = sd_bus_message_read(message, "u", &id);
772         if (r < 0)
773                 return r;
774
775         j = manager_get_job(m, id);
776         if (!j)
777                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
778
779         r = mac_selinux_unit_access_check(j->unit, message, "status", error);
780         if (r < 0)
781                 return r;
782
783         path = job_dbus_path(j);
784         if (!path)
785                 return -ENOMEM;
786
787         return sd_bus_reply_method_return(message, "o", path);
788 }
789
790 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
791         Manager *m = userdata;
792         uint32_t id;
793         Job *j;
794         int r;
795
796         assert(bus);
797         assert(message);
798         assert(m);
799
800         r = sd_bus_message_read(message, "u", &id);
801         if (r < 0)
802                 return r;
803
804         j = manager_get_job(m, id);
805         if (!j)
806                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
807
808         return bus_job_method_cancel(bus, message, j, error);
809 }
810
811 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
812         Manager *m = userdata;
813         int r;
814
815         assert(bus);
816         assert(message);
817         assert(m);
818
819         r = mac_selinux_access_check(message, "reboot", error);
820         if (r < 0)
821                 return r;
822
823         manager_clear_jobs(m);
824
825         return sd_bus_reply_method_return(message, NULL);
826 }
827
828 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
829         Manager *m = userdata;
830         int r;
831
832         assert(bus);
833         assert(message);
834         assert(m);
835
836         r = mac_selinux_access_check(message, "reload", error);
837         if (r < 0)
838                 return r;
839
840         manager_reset_failed(m);
841
842         return sd_bus_reply_method_return(message, NULL);
843 }
844
845 static int list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
846         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
847         Manager *m = userdata;
848         const char *k;
849         Iterator i;
850         Unit *u;
851         int r;
852
853         assert(bus);
854         assert(message);
855         assert(m);
856
857         /* Anyone can call this method */
858
859         r = mac_selinux_access_check(message, "status", error);
860         if (r < 0)
861                 return r;
862
863         r = sd_bus_message_new_method_return(message, &reply);
864         if (r < 0)
865                 return r;
866
867         r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
868         if (r < 0)
869                 return r;
870
871         HASHMAP_FOREACH_KEY(u, k, m->units, i) {
872                 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
873                 Unit *following;
874
875                 if (k != u->id)
876                         continue;
877
878                 following = unit_following(u);
879
880                 if (!strv_isempty(states) &&
881                     !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
882                     !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
883                     !strv_contains(states, unit_sub_state_to_string(u)))
884                         continue;
885
886                 unit_path = unit_dbus_path(u);
887                 if (!unit_path)
888                         return -ENOMEM;
889
890                 if (u->job) {
891                         job_path = job_dbus_path(u->job);
892                         if (!job_path)
893                                 return -ENOMEM;
894                 }
895
896                 r = sd_bus_message_append(
897                                 reply, "(ssssssouso)",
898                                 u->id,
899                                 unit_description(u),
900                                 unit_load_state_to_string(u->load_state),
901                                 unit_active_state_to_string(unit_active_state(u)),
902                                 unit_sub_state_to_string(u),
903                                 following ? following->id : "",
904                                 unit_path,
905                                 u->job ? u->job->id : 0,
906                                 u->job ? job_type_to_string(u->job->type) : "",
907                                 job_path ? job_path : "/");
908                 if (r < 0)
909                         return r;
910         }
911
912         r = sd_bus_message_close_container(reply);
913         if (r < 0)
914                 return r;
915
916         return sd_bus_send(bus, reply, NULL);
917 }
918
919 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
920         return list_units_filtered(bus, message, userdata, error, NULL);
921 }
922
923 static int method_list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
924         _cleanup_strv_free_ char **states = NULL;
925         int r;
926
927         r = sd_bus_message_read_strv(message, &states);
928         if (r < 0)
929                 return r;
930
931         return list_units_filtered(bus, message, userdata, error, states);
932 }
933
934 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
935         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
936         Manager *m = userdata;
937         Iterator i;
938         Job *j;
939         int r;
940
941         assert(bus);
942         assert(message);
943         assert(m);
944
945         /* Anyone can call this method */
946
947         r = mac_selinux_access_check(message, "status", error);
948         if (r < 0)
949                 return r;
950
951         r = sd_bus_message_new_method_return(message, &reply);
952         if (r < 0)
953                 return r;
954
955         r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
956         if (r < 0)
957                 return r;
958
959         HASHMAP_FOREACH(j, m->jobs, i) {
960                 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
961
962                 job_path = job_dbus_path(j);
963                 if (!job_path)
964                         return -ENOMEM;
965
966                 unit_path = unit_dbus_path(j->unit);
967                 if (!unit_path)
968                         return -ENOMEM;
969
970                 r = sd_bus_message_append(
971                                 reply, "(usssoo)",
972                                 j->id,
973                                 j->unit->id,
974                                 job_type_to_string(j->type),
975                                 job_state_to_string(j->state),
976                                 job_path,
977                                 unit_path);
978                 if (r < 0)
979                         return r;
980         }
981
982         r = sd_bus_message_close_container(reply);
983         if (r < 0)
984                 return r;
985
986         return sd_bus_send(bus, reply, NULL);
987 }
988
989 static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
990         Manager *m = userdata;
991         int r;
992
993         assert(bus);
994         assert(message);
995         assert(m);
996
997         /* Anyone can call this method */
998
999         r = mac_selinux_access_check(message, "status", error);
1000         if (r < 0)
1001                 return r;
1002
1003         if (bus == m->api_bus) {
1004
1005                 /* Note that direct bus connection subscribe by
1006                  * default, we only track peers on the API bus here */
1007
1008                 if (!m->subscribed) {
1009                         r = sd_bus_track_new(bus, &m->subscribed, NULL, NULL);
1010                         if (r < 0)
1011                                 return r;
1012                 }
1013
1014                 r = sd_bus_track_add_sender(m->subscribed, message);
1015                 if (r < 0)
1016                         return r;
1017                 if (r == 0)
1018                         return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
1019         }
1020
1021         return sd_bus_reply_method_return(message, NULL);
1022 }
1023
1024 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1025         Manager *m = userdata;
1026         int r;
1027
1028         assert(bus);
1029         assert(message);
1030         assert(m);
1031
1032         /* Anyone can call this method */
1033
1034         r = mac_selinux_access_check(message, "status", error);
1035         if (r < 0)
1036                 return r;
1037
1038         if (bus == m->api_bus) {
1039                 r = sd_bus_track_remove_sender(m->subscribed, message);
1040                 if (r < 0)
1041                         return r;
1042                 if (r == 0)
1043                         return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
1044         }
1045
1046         return sd_bus_reply_method_return(message, NULL);
1047 }
1048
1049 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1050         _cleanup_free_ char *dump = NULL;
1051         _cleanup_fclose_ FILE *f = NULL;
1052         Manager *m = userdata;
1053         size_t size;
1054         int r;
1055
1056         assert(bus);
1057         assert(message);
1058         assert(m);
1059
1060         /* Anyone can call this method */
1061
1062         r = mac_selinux_access_check(message, "status", error);
1063         if (r < 0)
1064                 return r;
1065
1066         f = open_memstream(&dump, &size);
1067         if (!f)
1068                 return -ENOMEM;
1069
1070         manager_dump_units(m, f, NULL);
1071         manager_dump_jobs(m, f, NULL);
1072
1073         fflush(f);
1074
1075         if (ferror(f))
1076                 return -ENOMEM;
1077
1078         return sd_bus_reply_method_return(message, "s", dump);
1079 }
1080
1081 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1082         _cleanup_free_ char *path = NULL;
1083         Manager *m = userdata;
1084         const char *name;
1085         int cleanup;
1086         Snapshot *s = NULL;
1087         int r;
1088
1089         assert(bus);
1090         assert(message);
1091         assert(m);
1092
1093         r = mac_selinux_access_check(message, "start", error);
1094         if (r < 0)
1095                 return r;
1096
1097         r = sd_bus_message_read(message, "sb", &name, &cleanup);
1098         if (r < 0)
1099                 return r;
1100
1101         if (isempty(name))
1102                 name = NULL;
1103
1104         r = snapshot_create(m, name, cleanup, error, &s);
1105         if (r < 0)
1106                 return r;
1107
1108         path = unit_dbus_path(UNIT(s));
1109         if (!path)
1110                 return -ENOMEM;
1111
1112         return sd_bus_reply_method_return(message, "o", path);
1113 }
1114
1115 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1116         Manager *m = userdata;
1117         const char *name;
1118         Unit *u;
1119         int r;
1120
1121         assert(bus);
1122         assert(message);
1123         assert(m);
1124
1125         r = mac_selinux_access_check(message, "stop", error);
1126         if (r < 0)
1127                 return r;
1128
1129         r = sd_bus_message_read(message, "s", &name);
1130         if (r < 0)
1131                 return r;
1132
1133         u = manager_get_unit(m, name);
1134         if (!u)
1135                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
1136
1137         if (u->type != UNIT_SNAPSHOT)
1138                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
1139
1140         return bus_snapshot_method_remove(bus, message, u, error);
1141 }
1142
1143 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1144         Manager *m = userdata;
1145         int r;
1146
1147         assert(bus);
1148         assert(message);
1149         assert(m);
1150
1151         r = bus_verify_reload_daemon_async(m, message, error);
1152         if (r < 0)
1153                 return r;
1154         if (r == 0)
1155                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1156
1157         r = mac_selinux_access_check(message, "reload", error);
1158         if (r < 0)
1159                 return r;
1160
1161         /* Instead of sending the reply back right away, we just
1162          * remember that we need to and then send it after the reload
1163          * is finished. That way the caller knows when the reload
1164          * finished. */
1165
1166         assert(!m->queued_message);
1167         r = sd_bus_message_new_method_return(message, &m->queued_message);
1168         if (r < 0)
1169                 return r;
1170
1171         m->queued_message_bus = sd_bus_ref(bus);
1172         m->exit_code = MANAGER_RELOAD;
1173
1174         return 1;
1175 }
1176
1177 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1178         Manager *m = userdata;
1179         int r;
1180
1181         assert(bus);
1182         assert(message);
1183         assert(m);
1184
1185         r = bus_verify_reload_daemon_async(m, message, error);
1186         if (r < 0)
1187                 return r;
1188         if (r == 0)
1189                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1190
1191         r = mac_selinux_access_check(message, "reload", error);
1192         if (r < 0)
1193                 return r;
1194
1195         /* We don't send a reply back here, the client should
1196          * just wait for us disconnecting. */
1197
1198         m->exit_code = MANAGER_REEXECUTE;
1199         return 1;
1200 }
1201
1202 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1203         Manager *m = userdata;
1204         int r;
1205
1206         assert(bus);
1207         assert(message);
1208         assert(m);
1209
1210         r = mac_selinux_access_check(message, "halt", error);
1211         if (r < 0)
1212                 return r;
1213
1214         if (m->running_as == SYSTEMD_SYSTEM)
1215                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
1216
1217         m->exit_code = MANAGER_EXIT;
1218
1219         return sd_bus_reply_method_return(message, NULL);
1220 }
1221
1222 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1223         Manager *m = userdata;
1224         int r;
1225
1226         assert(bus);
1227         assert(message);
1228         assert(m);
1229
1230         r = mac_selinux_access_check(message, "reboot", error);
1231         if (r < 0)
1232                 return r;
1233
1234         if (m->running_as != SYSTEMD_SYSTEM)
1235                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1236
1237         m->exit_code = MANAGER_REBOOT;
1238
1239         return sd_bus_reply_method_return(message, NULL);
1240 }
1241
1242
1243 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1244         Manager *m = userdata;
1245         int r;
1246
1247         assert(bus);
1248         assert(message);
1249         assert(m);
1250
1251         r = mac_selinux_access_check(message, "halt", error);
1252         if (r < 0)
1253                 return r;
1254
1255         if (m->running_as != SYSTEMD_SYSTEM)
1256                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1257
1258         m->exit_code = MANAGER_POWEROFF;
1259
1260         return sd_bus_reply_method_return(message, NULL);
1261 }
1262
1263 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1264         Manager *m = userdata;
1265         int r;
1266
1267         assert(bus);
1268         assert(message);
1269         assert(m);
1270
1271         r = mac_selinux_access_check(message, "halt", error);
1272         if (r < 0)
1273                 return r;
1274
1275         if (m->running_as != SYSTEMD_SYSTEM)
1276                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1277
1278         m->exit_code = MANAGER_HALT;
1279
1280         return sd_bus_reply_method_return(message, NULL);
1281 }
1282
1283 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1284         Manager *m = userdata;
1285         int r;
1286
1287         assert(bus);
1288         assert(message);
1289         assert(m);
1290
1291         r = mac_selinux_access_check(message, "reboot", error);
1292         if (r < 0)
1293                 return r;
1294
1295         if (m->running_as != SYSTEMD_SYSTEM)
1296                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1297
1298         m->exit_code = MANAGER_KEXEC;
1299
1300         return sd_bus_reply_method_return(message, NULL);
1301 }
1302
1303 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1304         char *ri = NULL, *rt = NULL;
1305         const char *root, *init;
1306         Manager *m = userdata;
1307         int r;
1308
1309         assert(bus);
1310         assert(message);
1311         assert(m);
1312
1313         r = mac_selinux_access_check(message, "reboot", error);
1314         if (r < 0)
1315                 return r;
1316
1317         if (m->running_as != SYSTEMD_SYSTEM)
1318                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
1319
1320         r = sd_bus_message_read(message, "ss", &root, &init);
1321         if (r < 0)
1322                 return r;
1323
1324         if (path_equal(root, "/") || !path_is_absolute(root))
1325                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1326
1327         /* Safety check */
1328         if (isempty(init)) {
1329                 if (!path_is_os_tree(root))
1330                         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);
1331         } else {
1332                 _cleanup_free_ char *p = NULL;
1333
1334                 if (!path_is_absolute(init))
1335                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1336
1337                 p = strappend(root, init);
1338                 if (!p)
1339                         return -ENOMEM;
1340
1341                 if (access(p, X_OK) < 0)
1342                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1343         }
1344
1345         rt = strdup(root);
1346         if (!rt)
1347                 return -ENOMEM;
1348
1349         if (!isempty(init)) {
1350                 ri = strdup(init);
1351                 if (!ri) {
1352                         free(rt);
1353                         return -ENOMEM;
1354                 }
1355         }
1356
1357         free(m->switch_root);
1358         m->switch_root = rt;
1359
1360         free(m->switch_root_init);
1361         m->switch_root_init = ri;
1362
1363         m->exit_code = MANAGER_SWITCH_ROOT;
1364
1365         return sd_bus_reply_method_return(message, NULL);
1366 }
1367
1368 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1369         _cleanup_strv_free_ char **plus = NULL;
1370         Manager *m = userdata;
1371         int r;
1372
1373         assert(bus);
1374         assert(message);
1375         assert(m);
1376
1377         r = mac_selinux_access_check(message, "reload", error);
1378         if (r < 0)
1379                 return r;
1380
1381         r = sd_bus_message_read_strv(message, &plus);
1382         if (r < 0)
1383                 return r;
1384         if (!strv_env_is_valid(plus))
1385                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1386
1387         r = manager_environment_add(m, NULL, plus);
1388         if (r < 0)
1389                 return r;
1390
1391         return sd_bus_reply_method_return(message, NULL);
1392 }
1393
1394 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1395         _cleanup_strv_free_ char **minus = NULL;
1396         Manager *m = userdata;
1397         int r;
1398
1399         assert(bus);
1400         assert(message);
1401         assert(m);
1402
1403         r = mac_selinux_access_check(message, "reload", error);
1404         if (r < 0)
1405                 return r;
1406
1407         r = sd_bus_message_read_strv(message, &minus);
1408         if (r < 0)
1409                 return r;
1410
1411         if (!strv_env_name_or_assignment_is_valid(minus))
1412                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1413
1414         r = manager_environment_add(m, minus, NULL);
1415         if (r < 0)
1416                 return r;
1417
1418         return sd_bus_reply_method_return(message, NULL);
1419 }
1420
1421 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1422         _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1423         Manager *m = userdata;
1424         int r;
1425
1426         assert(bus);
1427         assert(message);
1428         assert(m);
1429
1430         r = mac_selinux_access_check(message, "reload", error);
1431         if (r < 0)
1432                 return r;
1433
1434         r = sd_bus_message_read_strv(message, &minus);
1435         if (r < 0)
1436                 return r;
1437
1438         r = sd_bus_message_read_strv(message, &plus);
1439         if (r < 0)
1440                 return r;
1441
1442         if (!strv_env_name_or_assignment_is_valid(minus))
1443                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1444         if (!strv_env_is_valid(plus))
1445                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1446
1447         r = manager_environment_add(m, minus, plus);
1448         if (r < 0)
1449                 return r;
1450
1451         return sd_bus_reply_method_return(message, NULL);
1452 }
1453
1454 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1455         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1456         Manager *m = userdata;
1457         UnitFileList *item;
1458         Hashmap *h;
1459         Iterator i;
1460         int r;
1461
1462         assert(bus);
1463         assert(message);
1464         assert(m);
1465
1466         /* Anyone can call this method */
1467
1468         r = mac_selinux_access_check(message, "status", error);
1469         if (r < 0)
1470                 return r;
1471
1472         r = sd_bus_message_new_method_return(message, &reply);
1473         if (r < 0)
1474                 return r;
1475
1476         h = hashmap_new(&string_hash_ops);
1477         if (!h)
1478                 return -ENOMEM;
1479
1480         r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1481         if (r < 0)
1482                 goto fail;
1483
1484         r = sd_bus_message_open_container(reply, 'a', "(ss)");
1485         if (r < 0)
1486                 goto fail;
1487
1488         HASHMAP_FOREACH(item, h, i) {
1489
1490                 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1491                 if (r < 0)
1492                         goto fail;
1493         }
1494
1495         unit_file_list_free(h);
1496
1497         r = sd_bus_message_close_container(reply);
1498         if (r < 0)
1499                 return r;
1500
1501         return sd_bus_send(bus, reply, NULL);
1502
1503 fail:
1504         unit_file_list_free(h);
1505         return r;
1506 }
1507
1508 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1509         Manager *m = userdata;
1510         const char *name;
1511         UnitFileState state;
1512         UnitFileScope scope;
1513         int r;
1514
1515         assert(bus);
1516         assert(message);
1517         assert(m);
1518
1519         /* Anyone can call this method */
1520
1521         r = mac_selinux_access_check(message, "status", error);
1522         if (r < 0)
1523                 return r;
1524
1525         r = sd_bus_message_read(message, "s", &name);
1526         if (r < 0)
1527                 return r;
1528
1529         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1530
1531         state = unit_file_get_state(scope, NULL, name);
1532         if (state < 0)
1533                 return state;
1534
1535         return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1536 }
1537
1538 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1539         _cleanup_free_ char *default_target = NULL;
1540         Manager *m = userdata;
1541         UnitFileScope scope;
1542         int r;
1543
1544         assert(bus);
1545         assert(message);
1546         assert(m);
1547
1548         /* Anyone can call this method */
1549
1550         r = mac_selinux_access_check(message, "status", error);
1551         if (r < 0)
1552                 return r;
1553
1554         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1555
1556         r = unit_file_get_default(scope, NULL, &default_target);
1557         if (r < 0)
1558                 return r;
1559
1560         return sd_bus_reply_method_return(message, "s", default_target);
1561 }
1562
1563 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
1564         _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1565         int r;
1566
1567         assert(bus);
1568
1569         r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1570         if (r < 0)
1571                 return r;
1572
1573         return sd_bus_send(bus, message, NULL);
1574 }
1575
1576 static int reply_unit_file_changes_and_free(
1577                 Manager *m,
1578                 sd_bus *bus,
1579                 sd_bus_message *message,
1580                 int carries_install_info,
1581                 UnitFileChange *changes,
1582                 unsigned n_changes) {
1583
1584         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1585         unsigned i;
1586         int r;
1587
1588         if (n_changes > 0) {
1589                 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
1590                 if (r < 0)
1591                         log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
1592         }
1593
1594         r = sd_bus_message_new_method_return(message, &reply);
1595         if (r < 0)
1596                 goto fail;
1597
1598         if (carries_install_info >= 0) {
1599                 r = sd_bus_message_append(reply, "b", carries_install_info);
1600                 if (r < 0)
1601                         goto fail;
1602         }
1603
1604         r = sd_bus_message_open_container(reply, 'a', "(sss)");
1605         if (r < 0)
1606                 goto fail;
1607
1608         for (i = 0; i < n_changes; i++) {
1609                 r = sd_bus_message_append(
1610                                 reply, "(sss)",
1611                                 unit_file_change_type_to_string(changes[i].type),
1612                                 changes[i].path,
1613                                 changes[i].source);
1614                 if (r < 0)
1615                         goto fail;
1616         }
1617
1618         r = sd_bus_message_close_container(reply);
1619         if (r < 0)
1620                 goto fail;
1621
1622         return sd_bus_send(bus, reply, NULL);
1623
1624 fail:
1625         unit_file_changes_free(changes, n_changes);
1626         return r;
1627 }
1628
1629 static int method_enable_unit_files_generic(
1630                 sd_bus *bus,
1631                 sd_bus_message *message,
1632                 Manager *m,
1633                 const char *verb,
1634                 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1635                 bool carries_install_info,
1636                 sd_bus_error *error) {
1637
1638         _cleanup_strv_free_ char **l = NULL;
1639         UnitFileChange *changes = NULL;
1640         unsigned n_changes = 0;
1641         UnitFileScope scope;
1642         int runtime, force, r;
1643
1644         assert(bus);
1645         assert(message);
1646         assert(m);
1647
1648         r = bus_verify_manage_unit_files_async(m, message, error);
1649         if (r < 0)
1650                 return r;
1651         if (r == 0)
1652                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1653
1654         r = sd_bus_message_read_strv(message, &l);
1655         if (r < 0)
1656                 return r;
1657
1658         r = sd_bus_message_read(message, "bb", &runtime, &force);
1659         if (r < 0)
1660                 return r;
1661
1662         r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
1663         if (r < 0)
1664                 return r;
1665
1666         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1667
1668         r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1669         if (r < 0)
1670                 return r;
1671
1672         return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1673 }
1674
1675 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1676         return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1677 }
1678
1679 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1680         return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1681 }
1682
1683 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1684         return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1685 }
1686
1687 static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
1688         return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
1689 }
1690
1691 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1692         return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset_without_mode, true, error);
1693 }
1694
1695 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1696         return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
1697 }
1698
1699 static int method_preset_unit_files_with_mode(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1700
1701         _cleanup_strv_free_ char **l = NULL;
1702         UnitFileChange *changes = NULL;
1703         unsigned n_changes = 0;
1704         Manager *m = userdata;
1705         UnitFilePresetMode mm;
1706         UnitFileScope scope;
1707         int runtime, force, r;
1708         const char *mode;
1709
1710         assert(bus);
1711         assert(message);
1712         assert(m);
1713
1714         r = bus_verify_manage_unit_files_async(m, message, error);
1715         if (r < 0)
1716                 return r;
1717         if (r == 0)
1718                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1719
1720         r = sd_bus_message_read_strv(message, &l);
1721         if (r < 0)
1722                 return r;
1723
1724         r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1725         if (r < 0)
1726                 return r;
1727
1728         if (isempty(mode))
1729                 mm = UNIT_FILE_PRESET_FULL;
1730         else {
1731                 mm = unit_file_preset_mode_from_string(mode);
1732                 if (mm < 0)
1733                         return -EINVAL;
1734         }
1735
1736         r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
1737         if (r < 0)
1738                 return r;
1739
1740         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1741
1742         r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
1743         if (r < 0)
1744                 return r;
1745
1746         return reply_unit_file_changes_and_free(m, bus, message, r, changes, n_changes);
1747 }
1748
1749 static int method_disable_unit_files_generic(
1750                 sd_bus *bus,
1751                 sd_bus_message *message,
1752                 Manager *m, const
1753                 char *verb,
1754                 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1755                 sd_bus_error *error) {
1756
1757         _cleanup_strv_free_ char **l = NULL;
1758         UnitFileChange *changes = NULL;
1759         unsigned n_changes = 0;
1760         UnitFileScope scope;
1761         int r, runtime;
1762
1763         assert(bus);
1764         assert(message);
1765         assert(m);
1766
1767         r = bus_verify_manage_unit_files_async(m, message, error);
1768         if (r < 0)
1769                 return r;
1770         if (r == 0)
1771                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1772
1773         r = mac_selinux_access_check(message, verb, error);
1774         if (r < 0)
1775                 return r;
1776
1777         r = sd_bus_message_read_strv(message, &l);
1778         if (r < 0)
1779                 return r;
1780
1781         r = sd_bus_message_read(message, "b", &runtime);
1782         if (r < 0)
1783                 return r;
1784
1785         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1786
1787         r = call(scope, runtime, NULL, l, &changes, &n_changes);
1788         if (r < 0)
1789                 return r;
1790
1791         return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1792 }
1793
1794 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1795         return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1796 }
1797
1798 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1799         return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1800 }
1801
1802 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1803         UnitFileChange *changes = NULL;
1804         unsigned n_changes = 0;
1805         Manager *m = userdata;
1806         UnitFileScope scope;
1807         const char *name;
1808         int force, r;
1809
1810         assert(bus);
1811         assert(message);
1812         assert(m);
1813
1814         r = bus_verify_manage_unit_files_async(m, message, error);
1815         if (r < 0)
1816                 return r;
1817         if (r == 0)
1818                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1819
1820         r = mac_selinux_access_check(message, "enable", error);
1821         if (r < 0)
1822                 return r;
1823
1824         r = sd_bus_message_read(message, "sb", &name, &force);
1825         if (r < 0)
1826                 return r;
1827
1828         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1829
1830         r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1831         if (r < 0)
1832                 return r;
1833
1834         return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1835 }
1836
1837 static int method_preset_all_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1838         UnitFileChange *changes = NULL;
1839         unsigned n_changes = 0;
1840         Manager *m = userdata;
1841         UnitFilePresetMode mm;
1842         UnitFileScope scope;
1843         const char *mode;
1844         int force, runtime, r;
1845
1846         assert(bus);
1847         assert(message);
1848         assert(m);
1849
1850         r = bus_verify_manage_unit_files_async(m, message, error);
1851         if (r < 0)
1852                 return r;
1853         if (r == 0)
1854                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1855
1856         r = mac_selinux_access_check(message, "enable", error);
1857         if (r < 0)
1858                 return r;
1859
1860         r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1861         if (r < 0)
1862                 return r;
1863
1864         if (isempty(mode))
1865                 mm = UNIT_FILE_PRESET_FULL;
1866         else {
1867                 mm = unit_file_preset_mode_from_string(mode);
1868                 if (mm < 0)
1869                         return -EINVAL;
1870         }
1871
1872         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1873
1874         r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
1875         if (r < 0)
1876                 return r;
1877
1878         return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1879 }
1880
1881 static int method_add_dependency_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1882         _cleanup_strv_free_ char **l = NULL;
1883         Manager *m = userdata;
1884         UnitFileChange *changes = NULL;
1885         unsigned n_changes = 0;
1886         UnitFileScope scope;
1887         int runtime, force, r;
1888         char *target;
1889         char *type;
1890         UnitDependency dep;
1891
1892         assert(bus);
1893         assert(message);
1894         assert(m);
1895
1896         r = bus_verify_manage_unit_files_async(m, message, error);
1897         if (r < 0)
1898                 return r;
1899         if (r == 0)
1900                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1901
1902         r = sd_bus_message_read_strv(message, &l);
1903         if (r < 0)
1904                 return r;
1905
1906         r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
1907         if (r < 0)
1908                 return r;
1909
1910         dep = unit_dependency_from_string(type);
1911         if (dep < 0)
1912                 return -EINVAL;
1913
1914         r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
1915         if (r < 0)
1916                 return r;
1917
1918         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1919
1920         r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
1921         if (r < 0)
1922                 return r;
1923
1924         return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1925 }
1926
1927 const sd_bus_vtable bus_manager_vtable[] = {
1928         SD_BUS_VTABLE_START(0),
1929
1930         SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1931         SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1932         SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1933         SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1934         SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1935         BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1936         BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1937         BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1938         BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1939         BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1940         BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1941         BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1942         BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1943         BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1944         BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1945         BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1946         BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1947         SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1948         SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1949         SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1950         SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, 0),
1951         SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1952         SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1953         SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1954         SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1955         SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1956         SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
1957         SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
1958         SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
1959         SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1960         SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1961         SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
1962         SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
1963         SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
1964         SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
1965
1966         SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1967         SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1968         SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1969         SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1970         SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
1971         SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1972         SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1973         SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1974         SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1975         SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1976         SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1977         SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1978         SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1979         SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
1980         SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1981         SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
1982         SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
1983         SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
1984         SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
1985         SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
1986         SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
1987         SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
1988         SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1989         SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1990         SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
1991         SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
1992         SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
1993         SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
1994         SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
1995         SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
1996         SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1997         SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1998         SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1999         SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2000         SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2001         SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, 0),
2002         SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, 0),
2003         SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
2004         SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2005         SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
2006         SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2007         SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2008         SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2009         SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2010         SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2011         SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
2012         SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2013         SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2014         SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2015         SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2016         SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2017         SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2018
2019         SD_BUS_SIGNAL("UnitNew", "so", 0),
2020         SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2021         SD_BUS_SIGNAL("JobNew", "uos", 0),
2022         SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2023         SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2024         SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
2025         SD_BUS_SIGNAL("Reloading", "b", 0),
2026
2027         SD_BUS_VTABLE_END
2028 };
2029
2030 static int send_finished(sd_bus *bus, void *userdata) {
2031         _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
2032         usec_t *times = userdata;
2033         int r;
2034
2035         assert(bus);
2036         assert(times);
2037
2038         r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2039         if (r < 0)
2040                 return r;
2041
2042         r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
2043         if (r < 0)
2044                 return r;
2045
2046         return sd_bus_send(bus, message, NULL);
2047 }
2048
2049 void bus_manager_send_finished(
2050                 Manager *m,
2051                 usec_t firmware_usec,
2052                 usec_t loader_usec,
2053                 usec_t kernel_usec,
2054                 usec_t initrd_usec,
2055                 usec_t userspace_usec,
2056                 usec_t total_usec) {
2057
2058         int r;
2059
2060         assert(m);
2061
2062         r = bus_foreach_bus(
2063                         m,
2064                         NULL,
2065                         send_finished,
2066                         (usec_t[6]) {
2067                                 firmware_usec,
2068                                 loader_usec,
2069                                 kernel_usec,
2070                                 initrd_usec,
2071                                 userspace_usec,
2072                                 total_usec
2073                         });
2074         if (r < 0)
2075                 log_debug_errno(r, "Failed to send finished signal: %m");
2076 }
2077
2078 static int send_reloading(sd_bus *bus, void *userdata) {
2079         _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
2080         int r;
2081
2082         assert(bus);
2083
2084         r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2085         if (r < 0)
2086                 return r;
2087
2088         r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
2089         if (r < 0)
2090                 return r;
2091
2092         return sd_bus_send(bus, message, NULL);
2093 }
2094
2095 void bus_manager_send_reloading(Manager *m, bool active) {
2096         int r;
2097
2098         assert(m);
2099
2100         r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
2101         if (r < 0)
2102                 log_debug_errno(r, "Failed to send reloading signal: %m");
2103
2104 }