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