]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/systemctl/systemctl.c
systemctl: don't assert on the arguments array unnecessarily
[thirdparty/systemd.git] / src / systemctl / systemctl.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 Copyright 2013 Marc-Antoine Perennou
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 ***/
22
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <getopt.h>
26 #include <linux/reboot.h>
27 #include <locale.h>
28 #include <stdbool.h>
29 #include <stddef.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <sys/reboot.h>
33 #include <sys/socket.h>
34 #include <unistd.h>
35
36 #include "sd-bus.h"
37 #include "sd-daemon.h"
38 #include "sd-login.h"
39
40 #include "bus-common-errors.h"
41 #include "bus-error.h"
42 #include "bus-message.h"
43 #include "bus-util.h"
44 #include "cgroup-show.h"
45 #include "cgroup-util.h"
46 #include "copy.h"
47 #include "dropin.h"
48 #include "efivars.h"
49 #include "env-util.h"
50 #include "exit-status.h"
51 #include "fileio.h"
52 #include "formats-util.h"
53 #include "hostname-util.h"
54 #include "initreq.h"
55 #include "install.h"
56 #include "list.h"
57 #include "log.h"
58 #include "logs-show.h"
59 #include "macro.h"
60 #include "mkdir.h"
61 #include "pager.h"
62 #include "path-lookup.h"
63 #include "path-util.h"
64 #include "process-util.h"
65 #include "set.h"
66 #include "signal-util.h"
67 #include "socket-util.h"
68 #include "spawn-ask-password-agent.h"
69 #include "spawn-polkit-agent.h"
70 #include "special.h"
71 #include "strv.h"
72 #include "terminal-util.h"
73 #include "unit-name.h"
74 #include "util.h"
75 #include "utmp-wtmp.h"
76
77 static char **arg_types = NULL;
78 static char **arg_states = NULL;
79 static char **arg_properties = NULL;
80 static bool arg_all = false;
81 static enum dependency {
82 DEPENDENCY_FORWARD,
83 DEPENDENCY_REVERSE,
84 DEPENDENCY_AFTER,
85 DEPENDENCY_BEFORE,
86 _DEPENDENCY_MAX
87 } arg_dependency = DEPENDENCY_FORWARD;
88 static const char *arg_job_mode = "replace";
89 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
90 static bool arg_no_block = false;
91 static bool arg_no_legend = false;
92 static bool arg_no_pager = false;
93 static bool arg_no_wtmp = false;
94 static bool arg_no_wall = false;
95 static bool arg_no_reload = false;
96 static bool arg_show_types = false;
97 static bool arg_ignore_inhibitors = false;
98 static bool arg_dry = false;
99 static bool arg_quiet = false;
100 static bool arg_full = false;
101 static bool arg_recursive = false;
102 static int arg_force = 0;
103 static bool arg_ask_password = false;
104 static bool arg_runtime = false;
105 static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
106 static char **arg_wall = NULL;
107 static const char *arg_kill_who = NULL;
108 static int arg_signal = SIGTERM;
109 static const char *arg_root = NULL;
110 static usec_t arg_when = 0;
111 static enum action {
112 _ACTION_INVALID,
113 ACTION_SYSTEMCTL,
114 ACTION_HALT,
115 ACTION_POWEROFF,
116 ACTION_REBOOT,
117 ACTION_KEXEC,
118 ACTION_EXIT,
119 ACTION_SUSPEND,
120 ACTION_HIBERNATE,
121 ACTION_HYBRID_SLEEP,
122 ACTION_RUNLEVEL2,
123 ACTION_RUNLEVEL3,
124 ACTION_RUNLEVEL4,
125 ACTION_RUNLEVEL5,
126 ACTION_RESCUE,
127 ACTION_EMERGENCY,
128 ACTION_DEFAULT,
129 ACTION_RELOAD,
130 ACTION_REEXEC,
131 ACTION_RUNLEVEL,
132 ACTION_CANCEL_SHUTDOWN,
133 _ACTION_MAX
134 } arg_action = ACTION_SYSTEMCTL;
135 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
136 static const char *arg_host = NULL;
137 static unsigned arg_lines = 10;
138 static OutputMode arg_output = OUTPUT_SHORT;
139 static bool arg_plain = false;
140 static bool arg_firmware_setup = false;
141 static bool arg_now = false;
142
143 static int daemon_reload(char **args);
144 static int halt_now(enum action a);
145 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
146
147 static bool original_stdout_is_tty;
148
149 typedef enum BusFocus {
150 BUS_FULL, /* The full bus indicated via --system or --user */
151 BUS_MANAGER, /* The manager itself, possibly directly, possibly via the bus */
152 _BUS_FOCUS_MAX
153 } BusFocus;
154
155 static sd_bus *busses[_BUS_FOCUS_MAX] = {};
156
157 static int acquire_bus(BusFocus focus, sd_bus **ret) {
158 int r;
159
160 assert(focus < _BUS_FOCUS_MAX);
161 assert(ret);
162
163 /* We only go directly to the manager, if we are using a local transport */
164 if (arg_transport != BUS_TRANSPORT_LOCAL)
165 focus = BUS_FULL;
166
167 if (!busses[focus]) {
168 bool user;
169
170 user = arg_scope != UNIT_FILE_SYSTEM;
171
172 if (focus == BUS_MANAGER)
173 r = bus_connect_transport_systemd(arg_transport, arg_host, user, &busses[focus]);
174 else
175 r = bus_connect_transport(arg_transport, arg_host, user, &busses[focus]);
176 if (r < 0)
177 return log_error_errno(r, "Failed to connect to bus: %m");
178
179 (void) sd_bus_set_allow_interactive_authorization(busses[focus], arg_ask_password);
180 }
181
182 *ret = busses[focus];
183 return 0;
184 }
185
186 static void release_busses(void) {
187 BusFocus w;
188
189 for (w = 0; w < _BUS_FOCUS_MAX; w++)
190 busses[w] = sd_bus_flush_close_unref(busses[w]);
191 }
192
193 static void pager_open_if_enabled(void) {
194
195 if (arg_no_pager)
196 return;
197
198 pager_open(false);
199 }
200
201 static void ask_password_agent_open_if_enabled(void) {
202
203 /* Open the password agent as a child process if necessary */
204
205 if (!arg_ask_password)
206 return;
207
208 if (arg_scope != UNIT_FILE_SYSTEM)
209 return;
210
211 if (arg_transport != BUS_TRANSPORT_LOCAL)
212 return;
213
214 ask_password_agent_open();
215 }
216
217 static void polkit_agent_open_if_enabled(void) {
218
219 /* Open the polkit agent as a child process if necessary */
220
221 if (!arg_ask_password)
222 return;
223
224 if (arg_scope != UNIT_FILE_SYSTEM)
225 return;
226
227 if (arg_transport != BUS_TRANSPORT_LOCAL)
228 return;
229
230 polkit_agent_open();
231 }
232
233 static OutputFlags get_output_flags(void) {
234 return
235 arg_all * OUTPUT_SHOW_ALL |
236 arg_full * OUTPUT_FULL_WIDTH |
237 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
238 on_tty() * OUTPUT_COLOR |
239 !arg_quiet * OUTPUT_WARN_CUTOFF;
240 }
241
242 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
243 assert(error);
244
245 if (!sd_bus_error_is_set(error))
246 return r;
247
248 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
249 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
250 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
251 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
252 return EXIT_NOPERMISSION;
253
254 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
255 return EXIT_NOTINSTALLED;
256
257 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
258 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
259 return EXIT_NOTIMPLEMENTED;
260
261 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
262 return EXIT_NOTCONFIGURED;
263
264 if (r != 0)
265 return r;
266
267 return EXIT_FAILURE;
268 }
269
270 static bool install_client_side(void) {
271
272 /* Decides when to execute enable/disable/... operations
273 * client-side rather than server-side. */
274
275 if (running_in_chroot() > 0)
276 return true;
277
278 if (sd_booted() <= 0)
279 return true;
280
281 if (!isempty(arg_root))
282 return true;
283
284 if (arg_scope == UNIT_FILE_GLOBAL)
285 return true;
286
287 return false;
288 }
289
290 static int compare_unit_info(const void *a, const void *b) {
291 const UnitInfo *u = a, *v = b;
292 const char *d1, *d2;
293 int r;
294
295 /* First, order by machine */
296 if (!u->machine && v->machine)
297 return -1;
298 if (u->machine && !v->machine)
299 return 1;
300 if (u->machine && v->machine) {
301 r = strcasecmp(u->machine, v->machine);
302 if (r != 0)
303 return r;
304 }
305
306 /* Second, order by unit type */
307 d1 = strrchr(u->id, '.');
308 d2 = strrchr(v->id, '.');
309 if (d1 && d2) {
310 r = strcasecmp(d1, d2);
311 if (r != 0)
312 return r;
313 }
314
315 /* Third, order by name */
316 return strcasecmp(u->id, v->id);
317 }
318
319 static bool output_show_unit(const UnitInfo *u, char **patterns) {
320 if (!strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
321 return false;
322
323 if (arg_types) {
324 const char *dot;
325
326 dot = strrchr(u->id, '.');
327 if (!dot)
328 return false;
329
330 if (!strv_find(arg_types, dot+1))
331 return false;
332 }
333
334 if (arg_all)
335 return true;
336
337 if (u->job_id > 0)
338 return true;
339
340 if (streq(u->active_state, "inactive") || u->following[0])
341 return false;
342
343 return true;
344 }
345
346 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
347 unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
348 const UnitInfo *u;
349 unsigned n_shown = 0;
350 int job_count = 0;
351
352 max_id_len = strlen("UNIT");
353 load_len = strlen("LOAD");
354 active_len = strlen("ACTIVE");
355 sub_len = strlen("SUB");
356 job_len = strlen("JOB");
357 desc_len = 0;
358
359 for (u = unit_infos; u < unit_infos + c; u++) {
360 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
361 load_len = MAX(load_len, strlen(u->load_state));
362 active_len = MAX(active_len, strlen(u->active_state));
363 sub_len = MAX(sub_len, strlen(u->sub_state));
364
365 if (u->job_id != 0) {
366 job_len = MAX(job_len, strlen(u->job_type));
367 job_count++;
368 }
369
370 if (!arg_no_legend &&
371 (streq(u->active_state, "failed") ||
372 STR_IN_SET(u->load_state, "error", "not-found", "masked")))
373 circle_len = 2;
374 }
375
376 if (!arg_full && original_stdout_is_tty) {
377 unsigned basic_len;
378
379 id_len = MIN(max_id_len, 25u);
380 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
381
382 if (job_count)
383 basic_len += job_len + 1;
384
385 if (basic_len < (unsigned) columns()) {
386 unsigned extra_len, incr;
387 extra_len = columns() - basic_len;
388
389 /* Either UNIT already got 25, or is fully satisfied.
390 * Grant up to 25 to DESC now. */
391 incr = MIN(extra_len, 25u);
392 desc_len += incr;
393 extra_len -= incr;
394
395 /* split the remaining space between UNIT and DESC,
396 * but do not give UNIT more than it needs. */
397 if (extra_len > 0) {
398 incr = MIN(extra_len / 2, max_id_len - id_len);
399 id_len += incr;
400 desc_len += extra_len - incr;
401 }
402 }
403 } else
404 id_len = max_id_len;
405
406 for (u = unit_infos; u < unit_infos + c; u++) {
407 _cleanup_free_ char *e = NULL, *j = NULL;
408 const char *on_loaded = "", *off_loaded = "";
409 const char *on_active = "", *off_active = "";
410 const char *on_circle = "", *off_circle = "";
411 const char *id;
412 bool circle = false;
413
414 if (!n_shown && !arg_no_legend) {
415
416 if (circle_len > 0)
417 fputs(" ", stdout);
418
419 printf("%-*s %-*s %-*s %-*s ",
420 id_len, "UNIT",
421 load_len, "LOAD",
422 active_len, "ACTIVE",
423 sub_len, "SUB");
424
425 if (job_count)
426 printf("%-*s ", job_len, "JOB");
427
428 if (!arg_full && arg_no_pager)
429 printf("%.*s\n", desc_len, "DESCRIPTION");
430 else
431 printf("%s\n", "DESCRIPTION");
432 }
433
434 n_shown++;
435
436 if (STR_IN_SET(u->load_state, "error", "not-found", "masked") && !arg_plain) {
437 on_loaded = ansi_highlight_red();
438 on_circle = ansi_highlight_yellow();
439 off_loaded = off_circle = ansi_normal();
440 circle = true;
441 } else if (streq(u->active_state, "failed") && !arg_plain) {
442 on_circle = on_active = ansi_highlight_red();
443 off_circle = off_active = ansi_normal();
444 circle = true;
445 }
446
447 if (u->machine) {
448 j = strjoin(u->machine, ":", u->id, NULL);
449 if (!j)
450 return log_oom();
451
452 id = j;
453 } else
454 id = u->id;
455
456 if (arg_full) {
457 e = ellipsize(id, id_len, 33);
458 if (!e)
459 return log_oom();
460
461 id = e;
462 }
463
464 if (circle_len > 0)
465 printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
466
467 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
468 on_active, id_len, id, off_active,
469 on_loaded, load_len, u->load_state, off_loaded,
470 on_active, active_len, u->active_state,
471 sub_len, u->sub_state, off_active,
472 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
473
474 if (desc_len > 0)
475 printf("%.*s\n", desc_len, u->description);
476 else
477 printf("%s\n", u->description);
478 }
479
480 if (!arg_no_legend) {
481 const char *on, *off;
482
483 if (n_shown) {
484 puts("\n"
485 "LOAD = Reflects whether the unit definition was properly loaded.\n"
486 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
487 "SUB = The low-level unit activation state, values depend on unit type.");
488 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
489 on = ansi_highlight();
490 off = ansi_normal();
491 } else {
492 on = ansi_highlight_red();
493 off = ansi_normal();
494 }
495
496 if (arg_all)
497 printf("%s%u loaded units listed.%s\n"
498 "To show all installed unit files use 'systemctl list-unit-files'.\n",
499 on, n_shown, off);
500 else
501 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
502 "To show all installed unit files use 'systemctl list-unit-files'.\n",
503 on, n_shown, off);
504 }
505
506 return 0;
507 }
508
509 static int get_unit_list(
510 sd_bus *bus,
511 const char *machine,
512 char **patterns,
513 UnitInfo **unit_infos,
514 int c,
515 sd_bus_message **_reply) {
516
517 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
518 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
519 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
520 size_t size = c;
521 int r;
522 UnitInfo u;
523
524 assert(bus);
525 assert(unit_infos);
526 assert(_reply);
527
528 r = sd_bus_message_new_method_call(
529 bus,
530 &m,
531 "org.freedesktop.systemd1",
532 "/org/freedesktop/systemd1",
533 "org.freedesktop.systemd1.Manager",
534 "ListUnitsFiltered");
535
536 if (r < 0)
537 return bus_log_create_error(r);
538
539 r = sd_bus_message_append_strv(m, arg_states);
540 if (r < 0)
541 return bus_log_create_error(r);
542
543 r = sd_bus_call(bus, m, 0, &error, &reply);
544 if (r < 0)
545 return log_error_errno(r, "Failed to list units: %s", bus_error_message(&error, r));
546
547 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
548 if (r < 0)
549 return bus_log_parse_error(r);
550
551 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
552 u.machine = machine;
553
554 if (!output_show_unit(&u, patterns))
555 continue;
556
557 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
558 return log_oom();
559
560 (*unit_infos)[c++] = u;
561 }
562 if (r < 0)
563 return bus_log_parse_error(r);
564
565 r = sd_bus_message_exit_container(reply);
566 if (r < 0)
567 return bus_log_parse_error(r);
568
569 *_reply = reply;
570 reply = NULL;
571
572 return c;
573 }
574
575 static void message_set_freep(Set **set) {
576 sd_bus_message *m;
577
578 while ((m = set_steal_first(*set)))
579 sd_bus_message_unref(m);
580
581 set_free(*set);
582 }
583
584 static int get_unit_list_recursive(
585 sd_bus *bus,
586 char **patterns,
587 UnitInfo **_unit_infos,
588 Set **_replies,
589 char ***_machines) {
590
591 _cleanup_free_ UnitInfo *unit_infos = NULL;
592 _cleanup_(message_set_freep) Set *replies;
593 sd_bus_message *reply;
594 int c, r;
595
596 assert(bus);
597 assert(_replies);
598 assert(_unit_infos);
599 assert(_machines);
600
601 replies = set_new(NULL);
602 if (!replies)
603 return log_oom();
604
605 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
606 if (c < 0)
607 return c;
608
609 r = set_put(replies, reply);
610 if (r < 0) {
611 sd_bus_message_unref(reply);
612 return log_oom();
613 }
614
615 if (arg_recursive) {
616 _cleanup_strv_free_ char **machines = NULL;
617 char **i;
618
619 r = sd_get_machine_names(&machines);
620 if (r < 0)
621 return log_error_errno(r, "Failed to get machine names: %m");
622
623 STRV_FOREACH(i, machines) {
624 _cleanup_bus_flush_close_unref_ sd_bus *container = NULL;
625 int k;
626
627 r = sd_bus_open_system_machine(&container, *i);
628 if (r < 0) {
629 log_warning_errno(r, "Failed to connect to container %s, ignoring: %m", *i);
630 continue;
631 }
632
633 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
634 if (k < 0)
635 return k;
636
637 c = k;
638
639 r = set_put(replies, reply);
640 if (r < 0) {
641 sd_bus_message_unref(reply);
642 return log_oom();
643 }
644 }
645
646 *_machines = machines;
647 machines = NULL;
648 } else
649 *_machines = NULL;
650
651 *_unit_infos = unit_infos;
652 unit_infos = NULL;
653
654 *_replies = replies;
655 replies = NULL;
656
657 return c;
658 }
659
660 static int list_units(char **args) {
661 _cleanup_free_ UnitInfo *unit_infos = NULL;
662 _cleanup_(message_set_freep) Set *replies = NULL;
663 _cleanup_strv_free_ char **machines = NULL;
664 sd_bus *bus;
665 int r;
666
667 pager_open_if_enabled();
668
669 r = acquire_bus(BUS_MANAGER, &bus);
670 if (r < 0)
671 return r;
672
673 r = get_unit_list_recursive(bus, strv_skip(args, 1), &unit_infos, &replies, &machines);
674 if (r < 0)
675 return r;
676
677 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
678 return output_units_list(unit_infos, r);
679 }
680
681 static int get_triggered_units(
682 sd_bus *bus,
683 const char* path,
684 char*** ret) {
685
686 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
687 int r;
688
689 assert(bus);
690 assert(path);
691 assert(ret);
692
693 r = sd_bus_get_property_strv(
694 bus,
695 "org.freedesktop.systemd1",
696 path,
697 "org.freedesktop.systemd1.Unit",
698 "Triggers",
699 &error,
700 ret);
701 if (r < 0)
702 return log_error_errno(r, "Failed to determine triggers: %s", bus_error_message(&error, r));
703
704 return 0;
705 }
706
707 static int get_listening(
708 sd_bus *bus,
709 const char* unit_path,
710 char*** listening) {
711
712 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
713 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
714 const char *type, *path;
715 int r, n = 0;
716
717 r = sd_bus_get_property(
718 bus,
719 "org.freedesktop.systemd1",
720 unit_path,
721 "org.freedesktop.systemd1.Socket",
722 "Listen",
723 &error,
724 &reply,
725 "a(ss)");
726 if (r < 0)
727 return log_error_errno(r, "Failed to get list of listening sockets: %s", bus_error_message(&error, r));
728
729 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
730 if (r < 0)
731 return bus_log_parse_error(r);
732
733 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
734
735 r = strv_extend(listening, type);
736 if (r < 0)
737 return log_oom();
738
739 r = strv_extend(listening, path);
740 if (r < 0)
741 return log_oom();
742
743 n++;
744 }
745 if (r < 0)
746 return bus_log_parse_error(r);
747
748 r = sd_bus_message_exit_container(reply);
749 if (r < 0)
750 return bus_log_parse_error(r);
751
752 return n;
753 }
754
755 struct socket_info {
756 const char *machine;
757 const char* id;
758
759 char* type;
760 char* path;
761
762 /* Note: triggered is a list here, although it almost certainly
763 * will always be one unit. Nevertheless, dbus API allows for multiple
764 * values, so let's follow that. */
765 char** triggered;
766
767 /* The strv above is shared. free is set only in the first one. */
768 bool own_triggered;
769 };
770
771 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
772 int o;
773
774 assert(a);
775 assert(b);
776
777 if (!a->machine && b->machine)
778 return -1;
779 if (a->machine && !b->machine)
780 return 1;
781 if (a->machine && b->machine) {
782 o = strcasecmp(a->machine, b->machine);
783 if (o != 0)
784 return o;
785 }
786
787 o = strcmp(a->path, b->path);
788 if (o == 0)
789 o = strcmp(a->type, b->type);
790
791 return o;
792 }
793
794 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
795 struct socket_info *s;
796 unsigned pathlen = strlen("LISTEN"),
797 typelen = strlen("TYPE") * arg_show_types,
798 socklen = strlen("UNIT"),
799 servlen = strlen("ACTIVATES");
800 const char *on, *off;
801
802 for (s = socket_infos; s < socket_infos + cs; s++) {
803 unsigned tmp = 0;
804 char **a;
805
806 socklen = MAX(socklen, strlen(s->id));
807 if (arg_show_types)
808 typelen = MAX(typelen, strlen(s->type));
809 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
810
811 STRV_FOREACH(a, s->triggered)
812 tmp += strlen(*a) + 2*(a != s->triggered);
813 servlen = MAX(servlen, tmp);
814 }
815
816 if (cs) {
817 if (!arg_no_legend)
818 printf("%-*s %-*.*s%-*s %s\n",
819 pathlen, "LISTEN",
820 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
821 socklen, "UNIT",
822 "ACTIVATES");
823
824 for (s = socket_infos; s < socket_infos + cs; s++) {
825 _cleanup_free_ char *j = NULL;
826 const char *path;
827 char **a;
828
829 if (s->machine) {
830 j = strjoin(s->machine, ":", s->path, NULL);
831 if (!j)
832 return log_oom();
833 path = j;
834 } else
835 path = s->path;
836
837 if (arg_show_types)
838 printf("%-*s %-*s %-*s",
839 pathlen, path, typelen, s->type, socklen, s->id);
840 else
841 printf("%-*s %-*s",
842 pathlen, path, socklen, s->id);
843 STRV_FOREACH(a, s->triggered)
844 printf("%s %s",
845 a == s->triggered ? "" : ",", *a);
846 printf("\n");
847 }
848
849 on = ansi_highlight();
850 off = ansi_normal();
851 if (!arg_no_legend)
852 printf("\n");
853 } else {
854 on = ansi_highlight_red();
855 off = ansi_normal();
856 }
857
858 if (!arg_no_legend) {
859 printf("%s%u sockets listed.%s\n", on, cs, off);
860 if (!arg_all)
861 printf("Pass --all to see loaded but inactive sockets, too.\n");
862 }
863
864 return 0;
865 }
866
867 static int list_sockets(char **args) {
868 _cleanup_(message_set_freep) Set *replies = NULL;
869 _cleanup_strv_free_ char **machines = NULL;
870 _cleanup_free_ UnitInfo *unit_infos = NULL;
871 _cleanup_free_ struct socket_info *socket_infos = NULL;
872 const UnitInfo *u;
873 struct socket_info *s;
874 unsigned cs = 0;
875 size_t size = 0;
876 int r = 0, n;
877 sd_bus *bus;
878
879 pager_open_if_enabled();
880
881 r = acquire_bus(BUS_MANAGER, &bus);
882 if (r < 0)
883 return r;
884
885 n = get_unit_list_recursive(bus, strv_skip(args, 1), &unit_infos, &replies, &machines);
886 if (n < 0)
887 return n;
888
889 for (u = unit_infos; u < unit_infos + n; u++) {
890 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
891 int i, c;
892
893 if (!endswith(u->id, ".socket"))
894 continue;
895
896 r = get_triggered_units(bus, u->unit_path, &triggered);
897 if (r < 0)
898 goto cleanup;
899
900 c = get_listening(bus, u->unit_path, &listening);
901 if (c < 0) {
902 r = c;
903 goto cleanup;
904 }
905
906 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
907 r = log_oom();
908 goto cleanup;
909 }
910
911 for (i = 0; i < c; i++)
912 socket_infos[cs + i] = (struct socket_info) {
913 .machine = u->machine,
914 .id = u->id,
915 .type = listening[i*2],
916 .path = listening[i*2 + 1],
917 .triggered = triggered,
918 .own_triggered = i==0,
919 };
920
921 /* from this point on we will cleanup those socket_infos */
922 cs += c;
923 free(listening);
924 listening = triggered = NULL; /* avoid cleanup */
925 }
926
927 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
928 (__compar_fn_t) socket_info_compare);
929
930 output_sockets_list(socket_infos, cs);
931
932 cleanup:
933 assert(cs == 0 || socket_infos);
934 for (s = socket_infos; s < socket_infos + cs; s++) {
935 free(s->type);
936 free(s->path);
937 if (s->own_triggered)
938 strv_free(s->triggered);
939 }
940
941 return r;
942 }
943
944 static int get_next_elapse(
945 sd_bus *bus,
946 const char *path,
947 dual_timestamp *next) {
948
949 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
950 dual_timestamp t;
951 int r;
952
953 assert(bus);
954 assert(path);
955 assert(next);
956
957 r = sd_bus_get_property_trivial(
958 bus,
959 "org.freedesktop.systemd1",
960 path,
961 "org.freedesktop.systemd1.Timer",
962 "NextElapseUSecMonotonic",
963 &error,
964 't',
965 &t.monotonic);
966 if (r < 0)
967 return log_error_errno(r, "Failed to get next elapsation time: %s", bus_error_message(&error, r));
968
969 r = sd_bus_get_property_trivial(
970 bus,
971 "org.freedesktop.systemd1",
972 path,
973 "org.freedesktop.systemd1.Timer",
974 "NextElapseUSecRealtime",
975 &error,
976 't',
977 &t.realtime);
978 if (r < 0)
979 return log_error_errno(r, "Failed to get next elapsation time: %s", bus_error_message(&error, r));
980
981 *next = t;
982 return 0;
983 }
984
985 static int get_last_trigger(
986 sd_bus *bus,
987 const char *path,
988 usec_t *last) {
989
990 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
991 int r;
992
993 assert(bus);
994 assert(path);
995 assert(last);
996
997 r = sd_bus_get_property_trivial(
998 bus,
999 "org.freedesktop.systemd1",
1000 path,
1001 "org.freedesktop.systemd1.Timer",
1002 "LastTriggerUSec",
1003 &error,
1004 't',
1005 last);
1006 if (r < 0)
1007 return log_error_errno(r, "Failed to get last trigger time: %s", bus_error_message(&error, r));
1008
1009 return 0;
1010 }
1011
1012 struct timer_info {
1013 const char* machine;
1014 const char* id;
1015 usec_t next_elapse;
1016 usec_t last_trigger;
1017 char** triggered;
1018 };
1019
1020 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1021 int o;
1022
1023 assert(a);
1024 assert(b);
1025
1026 if (!a->machine && b->machine)
1027 return -1;
1028 if (a->machine && !b->machine)
1029 return 1;
1030 if (a->machine && b->machine) {
1031 o = strcasecmp(a->machine, b->machine);
1032 if (o != 0)
1033 return o;
1034 }
1035
1036 if (a->next_elapse < b->next_elapse)
1037 return -1;
1038 if (a->next_elapse > b->next_elapse)
1039 return 1;
1040
1041 return strcmp(a->id, b->id);
1042 }
1043
1044 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1045 struct timer_info *t;
1046 unsigned
1047 nextlen = strlen("NEXT"),
1048 leftlen = strlen("LEFT"),
1049 lastlen = strlen("LAST"),
1050 passedlen = strlen("PASSED"),
1051 unitlen = strlen("UNIT"),
1052 activatelen = strlen("ACTIVATES");
1053
1054 const char *on, *off;
1055
1056 assert(timer_infos || n == 0);
1057
1058 for (t = timer_infos; t < timer_infos + n; t++) {
1059 unsigned ul = 0;
1060 char **a;
1061
1062 if (t->next_elapse > 0) {
1063 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1064
1065 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1066 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1067
1068 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1069 leftlen = MAX(leftlen, strlen(trel));
1070 }
1071
1072 if (t->last_trigger > 0) {
1073 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1074
1075 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1076 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1077
1078 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1079 passedlen = MAX(passedlen, strlen(trel));
1080 }
1081
1082 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1083
1084 STRV_FOREACH(a, t->triggered)
1085 ul += strlen(*a) + 2*(a != t->triggered);
1086
1087 activatelen = MAX(activatelen, ul);
1088 }
1089
1090 if (n > 0) {
1091 if (!arg_no_legend)
1092 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1093 nextlen, "NEXT",
1094 leftlen, "LEFT",
1095 lastlen, "LAST",
1096 passedlen, "PASSED",
1097 unitlen, "UNIT",
1098 "ACTIVATES");
1099
1100 for (t = timer_infos; t < timer_infos + n; t++) {
1101 _cleanup_free_ char *j = NULL;
1102 const char *unit;
1103 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1104 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1105 char **a;
1106
1107 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1108 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1109
1110 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1111 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1112
1113 if (t->machine) {
1114 j = strjoin(t->machine, ":", t->id, NULL);
1115 if (!j)
1116 return log_oom();
1117 unit = j;
1118 } else
1119 unit = t->id;
1120
1121 printf("%-*s %-*s %-*s %-*s %-*s",
1122 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1123
1124 STRV_FOREACH(a, t->triggered)
1125 printf("%s %s",
1126 a == t->triggered ? "" : ",", *a);
1127 printf("\n");
1128 }
1129
1130 on = ansi_highlight();
1131 off = ansi_normal();
1132 if (!arg_no_legend)
1133 printf("\n");
1134 } else {
1135 on = ansi_highlight_red();
1136 off = ansi_normal();
1137 }
1138
1139 if (!arg_no_legend) {
1140 printf("%s%u timers listed.%s\n", on, n, off);
1141 if (!arg_all)
1142 printf("Pass --all to see loaded but inactive timers, too.\n");
1143 }
1144
1145 return 0;
1146 }
1147
1148 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1149 usec_t next_elapse;
1150
1151 assert(nw);
1152 assert(next);
1153
1154 if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1155 usec_t converted;
1156
1157 if (next->monotonic > nw->monotonic)
1158 converted = nw->realtime + (next->monotonic - nw->monotonic);
1159 else
1160 converted = nw->realtime - (nw->monotonic - next->monotonic);
1161
1162 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1163 next_elapse = MIN(converted, next->realtime);
1164 else
1165 next_elapse = converted;
1166
1167 } else
1168 next_elapse = next->realtime;
1169
1170 return next_elapse;
1171 }
1172
1173 static int list_timers(char **args) {
1174 _cleanup_(message_set_freep) Set *replies = NULL;
1175 _cleanup_strv_free_ char **machines = NULL;
1176 _cleanup_free_ struct timer_info *timer_infos = NULL;
1177 _cleanup_free_ UnitInfo *unit_infos = NULL;
1178 struct timer_info *t;
1179 const UnitInfo *u;
1180 size_t size = 0;
1181 int n, c = 0;
1182 dual_timestamp nw;
1183 sd_bus *bus;
1184 int r = 0;
1185
1186 pager_open_if_enabled();
1187
1188 r = acquire_bus(BUS_MANAGER, &bus);
1189 if (r < 0)
1190 return r;
1191
1192 n = get_unit_list_recursive(bus, strv_skip(args, 1), &unit_infos, &replies, &machines);
1193 if (n < 0)
1194 return n;
1195
1196 dual_timestamp_get(&nw);
1197
1198 for (u = unit_infos; u < unit_infos + n; u++) {
1199 _cleanup_strv_free_ char **triggered = NULL;
1200 dual_timestamp next = DUAL_TIMESTAMP_NULL;
1201 usec_t m, last = 0;
1202
1203 if (!endswith(u->id, ".timer"))
1204 continue;
1205
1206 r = get_triggered_units(bus, u->unit_path, &triggered);
1207 if (r < 0)
1208 goto cleanup;
1209
1210 r = get_next_elapse(bus, u->unit_path, &next);
1211 if (r < 0)
1212 goto cleanup;
1213
1214 get_last_trigger(bus, u->unit_path, &last);
1215
1216 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1217 r = log_oom();
1218 goto cleanup;
1219 }
1220
1221 m = calc_next_elapse(&nw, &next);
1222
1223 timer_infos[c++] = (struct timer_info) {
1224 .machine = u->machine,
1225 .id = u->id,
1226 .next_elapse = m,
1227 .last_trigger = last,
1228 .triggered = triggered,
1229 };
1230
1231 triggered = NULL; /* avoid cleanup */
1232 }
1233
1234 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1235 (__compar_fn_t) timer_info_compare);
1236
1237 output_timers_list(timer_infos, c);
1238
1239 cleanup:
1240 for (t = timer_infos; t < timer_infos + c; t++)
1241 strv_free(t->triggered);
1242
1243 return r;
1244 }
1245
1246 static int compare_unit_file_list(const void *a, const void *b) {
1247 const char *d1, *d2;
1248 const UnitFileList *u = a, *v = b;
1249
1250 d1 = strrchr(u->path, '.');
1251 d2 = strrchr(v->path, '.');
1252
1253 if (d1 && d2) {
1254 int r;
1255
1256 r = strcasecmp(d1, d2);
1257 if (r != 0)
1258 return r;
1259 }
1260
1261 return strcasecmp(basename(u->path), basename(v->path));
1262 }
1263
1264 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1265 if (!strv_fnmatch_or_empty(patterns, basename(u->path), FNM_NOESCAPE))
1266 return false;
1267
1268 if (!strv_isempty(arg_types)) {
1269 const char *dot;
1270
1271 dot = strrchr(u->path, '.');
1272 if (!dot)
1273 return false;
1274
1275 if (!strv_find(arg_types, dot+1))
1276 return false;
1277 }
1278
1279 if (!strv_isempty(arg_states) &&
1280 !strv_find(arg_states, unit_file_state_to_string(u->state)))
1281 return false;
1282
1283 return true;
1284 }
1285
1286 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1287 unsigned max_id_len, id_cols, state_cols;
1288 const UnitFileList *u;
1289
1290 max_id_len = strlen("UNIT FILE");
1291 state_cols = strlen("STATE");
1292
1293 for (u = units; u < units + c; u++) {
1294 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1295 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1296 }
1297
1298 if (!arg_full) {
1299 unsigned basic_cols;
1300
1301 id_cols = MIN(max_id_len, 25u);
1302 basic_cols = 1 + id_cols + state_cols;
1303 if (basic_cols < (unsigned) columns())
1304 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1305 } else
1306 id_cols = max_id_len;
1307
1308 if (!arg_no_legend)
1309 printf("%-*s %-*s\n",
1310 id_cols, "UNIT FILE",
1311 state_cols, "STATE");
1312
1313 for (u = units; u < units + c; u++) {
1314 _cleanup_free_ char *e = NULL;
1315 const char *on, *off;
1316 const char *id;
1317
1318 if (IN_SET(u->state,
1319 UNIT_FILE_MASKED,
1320 UNIT_FILE_MASKED_RUNTIME,
1321 UNIT_FILE_DISABLED,
1322 UNIT_FILE_INVALID)) {
1323 on = ansi_highlight_red();
1324 off = ansi_normal();
1325 } else if (u->state == UNIT_FILE_ENABLED) {
1326 on = ansi_highlight_green();
1327 off = ansi_normal();
1328 } else
1329 on = off = "";
1330
1331 id = basename(u->path);
1332
1333 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1334
1335 printf("%-*s %s%-*s%s\n",
1336 id_cols, e ? e : id,
1337 on, state_cols, unit_file_state_to_string(u->state), off);
1338 }
1339
1340 if (!arg_no_legend)
1341 printf("\n%u unit files listed.\n", c);
1342 }
1343
1344 static int list_unit_files(char **args) {
1345 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1346 _cleanup_free_ UnitFileList *units = NULL;
1347 UnitFileList *unit;
1348 size_t size = 0;
1349 unsigned c = 0;
1350 const char *state;
1351 char *path;
1352 int r;
1353
1354 pager_open_if_enabled();
1355
1356 if (install_client_side()) {
1357 Hashmap *h;
1358 UnitFileList *u;
1359 Iterator i;
1360 unsigned n_units;
1361
1362 h = hashmap_new(&string_hash_ops);
1363 if (!h)
1364 return log_oom();
1365
1366 r = unit_file_get_list(arg_scope, arg_root, h);
1367 if (r < 0) {
1368 unit_file_list_free(h);
1369 return log_error_errno(r, "Failed to get unit file list: %m");
1370 }
1371
1372 n_units = hashmap_size(h);
1373
1374 units = new(UnitFileList, n_units);
1375 if (!units && n_units > 0) {
1376 unit_file_list_free(h);
1377 return log_oom();
1378 }
1379
1380 HASHMAP_FOREACH(u, h, i) {
1381 if (!output_show_unit_file(u, strv_skip(args, 1)))
1382 continue;
1383
1384 units[c++] = *u;
1385 free(u);
1386 }
1387
1388 assert(c <= n_units);
1389 hashmap_free(h);
1390 } else {
1391 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1392 sd_bus *bus;
1393
1394 r = acquire_bus(BUS_MANAGER, &bus);
1395 if (r < 0)
1396 return r;
1397
1398 r = sd_bus_call_method(
1399 bus,
1400 "org.freedesktop.systemd1",
1401 "/org/freedesktop/systemd1",
1402 "org.freedesktop.systemd1.Manager",
1403 "ListUnitFiles",
1404 &error,
1405 &reply,
1406 NULL);
1407 if (r < 0)
1408 return log_error_errno(r, "Failed to list unit files: %s", bus_error_message(&error, r));
1409
1410 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1411 if (r < 0)
1412 return bus_log_parse_error(r);
1413
1414 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1415
1416 if (!GREEDY_REALLOC(units, size, c + 1))
1417 return log_oom();
1418
1419 units[c] = (struct UnitFileList) {
1420 path,
1421 unit_file_state_from_string(state)
1422 };
1423
1424 if (output_show_unit_file(&units[c], strv_skip(args, 1)))
1425 c ++;
1426
1427 }
1428 if (r < 0)
1429 return bus_log_parse_error(r);
1430
1431 r = sd_bus_message_exit_container(reply);
1432 if (r < 0)
1433 return bus_log_parse_error(r);
1434 }
1435
1436 qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1437 output_unit_file_list(units, c);
1438
1439 if (install_client_side()) {
1440 for (unit = units; unit < units + c; unit++)
1441 free(unit->path);
1442 }
1443
1444 return 0;
1445 }
1446
1447 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1448 _cleanup_free_ char *n = NULL;
1449 size_t max_len = MAX(columns(),20u);
1450 size_t len = 0;
1451 int i;
1452
1453 if (!arg_plain) {
1454
1455 for (i = level - 1; i >= 0; i--) {
1456 len += 2;
1457 if (len > max_len - 3 && !arg_full) {
1458 printf("%s...\n",max_len % 2 ? "" : " ");
1459 return 0;
1460 }
1461 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1462 }
1463 len += 2;
1464
1465 if (len > max_len - 3 && !arg_full) {
1466 printf("%s...\n",max_len % 2 ? "" : " ");
1467 return 0;
1468 }
1469
1470 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1471 }
1472
1473 if (arg_full){
1474 printf("%s\n", name);
1475 return 0;
1476 }
1477
1478 n = ellipsize(name, max_len-len, 100);
1479 if (!n)
1480 return log_oom();
1481
1482 printf("%s\n", n);
1483 return 0;
1484 }
1485
1486 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1487
1488 static const char *dependencies[_DEPENDENCY_MAX] = {
1489 [DEPENDENCY_FORWARD] = "Requires\0"
1490 "RequiresOverridable\0"
1491 "Requisite\0"
1492 "RequisiteOverridable\0"
1493 "Wants\0"
1494 "ConsistsOf\0"
1495 "BindsTo\0",
1496 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1497 "RequiredByOverridable\0"
1498 "RequisiteOf\0"
1499 "RequisiteOfOverridable\0"
1500 "WantedBy\0"
1501 "PartOf\0"
1502 "BoundBy\0",
1503 [DEPENDENCY_AFTER] = "After\0",
1504 [DEPENDENCY_BEFORE] = "Before\0",
1505 };
1506
1507 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1508 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1509 _cleanup_strv_free_ char **ret = NULL;
1510 _cleanup_free_ char *path = NULL;
1511 int r;
1512
1513 assert(bus);
1514 assert(name);
1515 assert(deps);
1516 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1517
1518 path = unit_dbus_path_from_name(name);
1519 if (!path)
1520 return log_oom();
1521
1522 r = sd_bus_call_method(
1523 bus,
1524 "org.freedesktop.systemd1",
1525 path,
1526 "org.freedesktop.DBus.Properties",
1527 "GetAll",
1528 &error,
1529 &reply,
1530 "s", "org.freedesktop.systemd1.Unit");
1531 if (r < 0)
1532 return log_error_errno(r, "Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1533
1534 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1535 if (r < 0)
1536 return bus_log_parse_error(r);
1537
1538 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1539 const char *prop;
1540
1541 r = sd_bus_message_read(reply, "s", &prop);
1542 if (r < 0)
1543 return bus_log_parse_error(r);
1544
1545 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1546 r = sd_bus_message_skip(reply, "v");
1547 if (r < 0)
1548 return bus_log_parse_error(r);
1549 } else {
1550
1551 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1552 if (r < 0)
1553 return bus_log_parse_error(r);
1554
1555 r = bus_message_read_strv_extend(reply, &ret);
1556 if (r < 0)
1557 return bus_log_parse_error(r);
1558
1559 r = sd_bus_message_exit_container(reply);
1560 if (r < 0)
1561 return bus_log_parse_error(r);
1562 }
1563
1564 r = sd_bus_message_exit_container(reply);
1565 if (r < 0)
1566 return bus_log_parse_error(r);
1567
1568 }
1569 if (r < 0)
1570 return bus_log_parse_error(r);
1571
1572 r = sd_bus_message_exit_container(reply);
1573 if (r < 0)
1574 return bus_log_parse_error(r);
1575
1576 *deps = ret;
1577 ret = NULL;
1578
1579 return 0;
1580 }
1581
1582 static int list_dependencies_compare(const void *_a, const void *_b) {
1583 const char **a = (const char**) _a, **b = (const char**) _b;
1584
1585 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1586 return 1;
1587 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1588 return -1;
1589
1590 return strcasecmp(*a, *b);
1591 }
1592
1593 static int list_dependencies_one(
1594 sd_bus *bus,
1595 const char *name,
1596 int level,
1597 char ***units,
1598 unsigned int branches) {
1599
1600 _cleanup_strv_free_ char **deps = NULL;
1601 char **c;
1602 int r = 0;
1603
1604 assert(bus);
1605 assert(name);
1606 assert(units);
1607
1608 r = strv_extend(units, name);
1609 if (r < 0)
1610 return log_oom();
1611
1612 r = list_dependencies_get_dependencies(bus, name, &deps);
1613 if (r < 0)
1614 return r;
1615
1616 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1617
1618 STRV_FOREACH(c, deps) {
1619 if (strv_contains(*units, *c)) {
1620 if (!arg_plain) {
1621 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1622 if (r < 0)
1623 return r;
1624 }
1625 continue;
1626 }
1627
1628 if (arg_plain)
1629 printf(" ");
1630 else {
1631 int state;
1632 const char *on;
1633
1634 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1635 on = state > 0 ? ansi_highlight_green() : ansi_highlight_red();
1636 printf("%s%s%s ", on, draw_special_char(DRAW_BLACK_CIRCLE), ansi_normal());
1637 }
1638
1639 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1640 if (r < 0)
1641 return r;
1642
1643 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1644 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1645 if (r < 0)
1646 return r;
1647 }
1648 }
1649
1650 if (!arg_plain)
1651 strv_remove(*units, name);
1652
1653 return 0;
1654 }
1655
1656 static int list_dependencies(char **args) {
1657 _cleanup_strv_free_ char **units = NULL;
1658 _cleanup_free_ char *unit = NULL;
1659 const char *u;
1660 sd_bus *bus;
1661 int r;
1662
1663 if (args[1]) {
1664 r = unit_name_mangle(args[1], UNIT_NAME_NOGLOB, &unit);
1665 if (r < 0)
1666 return log_error_errno(r, "Failed to mangle unit name: %m");
1667
1668 u = unit;
1669 } else
1670 u = SPECIAL_DEFAULT_TARGET;
1671
1672 pager_open_if_enabled();
1673
1674 r = acquire_bus(BUS_MANAGER, &bus);
1675 if (r < 0)
1676 return r;
1677
1678 puts(u);
1679
1680 return list_dependencies_one(bus, u, 0, &units, 0);
1681 }
1682
1683 struct machine_info {
1684 bool is_host;
1685 char *name;
1686 char *state;
1687 char *control_group;
1688 uint32_t n_failed_units;
1689 uint32_t n_jobs;
1690 usec_t timestamp;
1691 };
1692
1693 static const struct bus_properties_map machine_info_property_map[] = {
1694 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1695 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1696 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1697 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1698 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1699 {}
1700 };
1701
1702 static void machine_info_clear(struct machine_info *info) {
1703 if (info) {
1704 free(info->name);
1705 free(info->state);
1706 free(info->control_group);
1707 zero(*info);
1708 }
1709 }
1710
1711 static void free_machines_list(struct machine_info *machine_infos, int n) {
1712 int i;
1713
1714 if (!machine_infos)
1715 return;
1716
1717 for (i = 0; i < n; i++)
1718 machine_info_clear(&machine_infos[i]);
1719
1720 free(machine_infos);
1721 }
1722
1723 static int compare_machine_info(const void *a, const void *b) {
1724 const struct machine_info *u = a, *v = b;
1725
1726 if (u->is_host != v->is_host)
1727 return u->is_host > v->is_host ? -1 : 1;
1728
1729 return strcasecmp(u->name, v->name);
1730 }
1731
1732 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1733 _cleanup_bus_flush_close_unref_ sd_bus *container = NULL;
1734 int r;
1735
1736 assert(mi);
1737
1738 if (!bus) {
1739 r = sd_bus_open_system_machine(&container, mi->name);
1740 if (r < 0)
1741 return r;
1742
1743 bus = container;
1744 }
1745
1746 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1747 if (r < 0)
1748 return r;
1749
1750 return 0;
1751 }
1752
1753 static bool output_show_machine(const char *name, char **patterns) {
1754 return strv_fnmatch_or_empty(patterns, name, FNM_NOESCAPE);
1755 }
1756
1757 static int get_machine_list(
1758 sd_bus *bus,
1759 struct machine_info **_machine_infos,
1760 char **patterns) {
1761
1762 struct machine_info *machine_infos = NULL;
1763 _cleanup_strv_free_ char **m = NULL;
1764 _cleanup_free_ char *hn = NULL;
1765 size_t sz = 0;
1766 char **i;
1767 int c = 0, r;
1768
1769 hn = gethostname_malloc();
1770 if (!hn)
1771 return log_oom();
1772
1773 if (output_show_machine(hn, patterns)) {
1774 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1775 return log_oom();
1776
1777 machine_infos[c].is_host = true;
1778 machine_infos[c].name = hn;
1779 hn = NULL;
1780
1781 get_machine_properties(bus, &machine_infos[c]);
1782 c++;
1783 }
1784
1785 r = sd_get_machine_names(&m);
1786 if (r < 0)
1787 return log_error_errno(r, "Failed to get machine list: %m");
1788
1789 STRV_FOREACH(i, m) {
1790 _cleanup_free_ char *class = NULL;
1791
1792 if (!output_show_machine(*i, patterns))
1793 continue;
1794
1795 sd_machine_get_class(*i, &class);
1796 if (!streq_ptr(class, "container"))
1797 continue;
1798
1799 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1800 free_machines_list(machine_infos, c);
1801 return log_oom();
1802 }
1803
1804 machine_infos[c].is_host = false;
1805 machine_infos[c].name = strdup(*i);
1806 if (!machine_infos[c].name) {
1807 free_machines_list(machine_infos, c);
1808 return log_oom();
1809 }
1810
1811 get_machine_properties(NULL, &machine_infos[c]);
1812 c++;
1813 }
1814
1815 *_machine_infos = machine_infos;
1816 return c;
1817 }
1818
1819 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1820 struct machine_info *m;
1821 unsigned
1822 circle_len = 0,
1823 namelen = sizeof("NAME") - 1,
1824 statelen = sizeof("STATE") - 1,
1825 failedlen = sizeof("FAILED") - 1,
1826 jobslen = sizeof("JOBS") - 1;
1827
1828 assert(machine_infos || n == 0);
1829
1830 for (m = machine_infos; m < machine_infos + n; m++) {
1831 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1832 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1833 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1834 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1835
1836 if (!arg_plain && !streq_ptr(m->state, "running"))
1837 circle_len = 2;
1838 }
1839
1840 if (!arg_no_legend) {
1841 if (circle_len > 0)
1842 fputs(" ", stdout);
1843
1844 printf("%-*s %-*s %-*s %-*s\n",
1845 namelen, "NAME",
1846 statelen, "STATE",
1847 failedlen, "FAILED",
1848 jobslen, "JOBS");
1849 }
1850
1851 for (m = machine_infos; m < machine_infos + n; m++) {
1852 const char *on_state = "", *off_state = "";
1853 const char *on_failed = "", *off_failed = "";
1854 bool circle = false;
1855
1856 if (streq_ptr(m->state, "degraded")) {
1857 on_state = ansi_highlight_red();
1858 off_state = ansi_normal();
1859 circle = true;
1860 } else if (!streq_ptr(m->state, "running")) {
1861 on_state = ansi_highlight_yellow();
1862 off_state = ansi_normal();
1863 circle = true;
1864 }
1865
1866 if (m->n_failed_units > 0) {
1867 on_failed = ansi_highlight_red();
1868 off_failed = ansi_normal();
1869 } else
1870 on_failed = off_failed = "";
1871
1872 if (circle_len > 0)
1873 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1874
1875 if (m->is_host)
1876 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1877 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1878 on_state, statelen, strna(m->state), off_state,
1879 on_failed, failedlen, m->n_failed_units, off_failed,
1880 jobslen, m->n_jobs);
1881 else
1882 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1883 namelen, strna(m->name),
1884 on_state, statelen, strna(m->state), off_state,
1885 on_failed, failedlen, m->n_failed_units, off_failed,
1886 jobslen, m->n_jobs);
1887 }
1888
1889 if (!arg_no_legend)
1890 printf("\n%u machines listed.\n", n);
1891 }
1892
1893 static int list_machines(char **args) {
1894 struct machine_info *machine_infos = NULL;
1895 sd_bus *bus;
1896 int r;
1897
1898 if (geteuid() != 0) {
1899 log_error("Must be root.");
1900 return -EPERM;
1901 }
1902
1903 pager_open_if_enabled();
1904
1905 r = acquire_bus(BUS_MANAGER, &bus);
1906 if (r < 0)
1907 return r;
1908
1909 r = get_machine_list(bus, &machine_infos, strv_skip(args, 1));
1910 if (r < 0)
1911 return r;
1912
1913 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1914 output_machines_list(machine_infos, r);
1915 free_machines_list(machine_infos, r);
1916
1917 return 0;
1918 }
1919
1920 static int get_default(char **args) {
1921 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1922 _cleanup_free_ char *_path = NULL;
1923 const char *path;
1924 int r;
1925
1926 if (install_client_side()) {
1927 r = unit_file_get_default(arg_scope, arg_root, &_path);
1928 if (r < 0)
1929 return log_error_errno(r, "Failed to get default target: %m");
1930 path = _path;
1931
1932 } else {
1933 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1934 sd_bus *bus;
1935
1936 r = acquire_bus(BUS_MANAGER, &bus);
1937 if (r < 0)
1938 return r;
1939
1940 r = sd_bus_call_method(
1941 bus,
1942 "org.freedesktop.systemd1",
1943 "/org/freedesktop/systemd1",
1944 "org.freedesktop.systemd1.Manager",
1945 "GetDefaultTarget",
1946 &error,
1947 &reply,
1948 NULL);
1949 if (r < 0)
1950 return log_error_errno(r, "Failed to get default target: %s", bus_error_message(&error, r));
1951
1952 r = sd_bus_message_read(reply, "s", &path);
1953 if (r < 0)
1954 return bus_log_parse_error(r);
1955 }
1956
1957 if (path)
1958 printf("%s\n", path);
1959
1960 return 0;
1961 }
1962
1963 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1964 unsigned i;
1965
1966 assert(changes || n_changes == 0);
1967
1968 for (i = 0; i < n_changes; i++) {
1969 if (changes[i].type == UNIT_FILE_SYMLINK)
1970 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1971 else
1972 log_info("Removed symlink %s.", changes[i].path);
1973 }
1974 }
1975
1976 static int set_default(char **args) {
1977 _cleanup_free_ char *unit = NULL;
1978 int r;
1979
1980 r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".target", &unit);
1981 if (r < 0)
1982 return log_error_errno(r, "Failed to mangle unit name: %m");
1983
1984 if (install_client_side()) {
1985 UnitFileChange *changes = NULL;
1986 unsigned n_changes = 0;
1987
1988 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1989 if (r < 0)
1990 return log_error_errno(r, "Failed to set default target: %m");
1991
1992 if (!arg_quiet)
1993 dump_unit_file_changes(changes, n_changes);
1994
1995 unit_file_changes_free(changes, n_changes);
1996 r = 0;
1997 } else {
1998 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1999 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2000 sd_bus *bus;
2001
2002 polkit_agent_open_if_enabled();
2003
2004 r = acquire_bus(BUS_MANAGER, &bus);
2005 if (r < 0)
2006 return r;
2007
2008 r = sd_bus_call_method(
2009 bus,
2010 "org.freedesktop.systemd1",
2011 "/org/freedesktop/systemd1",
2012 "org.freedesktop.systemd1.Manager",
2013 "SetDefaultTarget",
2014 &error,
2015 &reply,
2016 "sb", unit, 1);
2017 if (r < 0)
2018 return log_error_errno(r, "Failed to set default target: %s", bus_error_message(&error, r));
2019
2020 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
2021 if (r < 0)
2022 return r;
2023
2024 /* Try to reload if enabled */
2025 if (!arg_no_reload)
2026 r = daemon_reload(args);
2027 else
2028 r = 0;
2029 }
2030
2031 return r;
2032 }
2033
2034 struct job_info {
2035 uint32_t id;
2036 const char *name, *type, *state;
2037 };
2038
2039 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2040 unsigned id_len, unit_len, type_len, state_len;
2041 const struct job_info *j;
2042 const char *on, *off;
2043 bool shorten = false;
2044
2045 assert(n == 0 || jobs);
2046
2047 if (n == 0) {
2048 if (!arg_no_legend) {
2049 on = ansi_highlight_green();
2050 off = ansi_normal();
2051
2052 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2053 }
2054 return;
2055 }
2056
2057 pager_open_if_enabled();
2058
2059 id_len = strlen("JOB");
2060 unit_len = strlen("UNIT");
2061 type_len = strlen("TYPE");
2062 state_len = strlen("STATE");
2063
2064 for (j = jobs; j < jobs + n; j++) {
2065 uint32_t id = j->id;
2066 assert(j->name && j->type && j->state);
2067
2068 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2069 unit_len = MAX(unit_len, strlen(j->name));
2070 type_len = MAX(type_len, strlen(j->type));
2071 state_len = MAX(state_len, strlen(j->state));
2072 }
2073
2074 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2075 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2076 shorten = true;
2077 }
2078
2079 if (!arg_no_legend)
2080 printf("%*s %-*s %-*s %-*s\n",
2081 id_len, "JOB",
2082 unit_len, "UNIT",
2083 type_len, "TYPE",
2084 state_len, "STATE");
2085
2086 for (j = jobs; j < jobs + n; j++) {
2087 _cleanup_free_ char *e = NULL;
2088
2089 if (streq(j->state, "running")) {
2090 on = ansi_highlight();
2091 off = ansi_normal();
2092 } else
2093 on = off = "";
2094
2095 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2096 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2097 id_len, j->id,
2098 on, unit_len, e ? e : j->name, off,
2099 type_len, j->type,
2100 on, state_len, j->state, off);
2101 }
2102
2103 if (!arg_no_legend) {
2104 on = ansi_highlight();
2105 off = ansi_normal();
2106
2107 printf("\n%s%u jobs listed%s.\n", on, n, off);
2108 }
2109 }
2110
2111 static bool output_show_job(struct job_info *job, char **patterns) {
2112 return strv_fnmatch_or_empty(patterns, job->name, FNM_NOESCAPE);
2113 }
2114
2115 static int list_jobs(char **args) {
2116 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2117 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2118 const char *name, *type, *state, *job_path, *unit_path;
2119 _cleanup_free_ struct job_info *jobs = NULL;
2120 size_t size = 0;
2121 unsigned c = 0;
2122 sd_bus *bus;
2123 uint32_t id;
2124 int r;
2125 bool skipped = false;
2126
2127 pager_open_if_enabled();
2128
2129 r = acquire_bus(BUS_MANAGER, &bus);
2130 if (r < 0)
2131 return r;
2132
2133 r = sd_bus_call_method(
2134 bus,
2135 "org.freedesktop.systemd1",
2136 "/org/freedesktop/systemd1",
2137 "org.freedesktop.systemd1.Manager",
2138 "ListJobs",
2139 &error,
2140 &reply,
2141 NULL);
2142 if (r < 0)
2143 return log_error_errno(r, "Failed to list jobs: %s", bus_error_message(&error, r));
2144
2145 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2146 if (r < 0)
2147 return bus_log_parse_error(r);
2148
2149 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2150 struct job_info job = { id, name, type, state };
2151
2152 if (!output_show_job(&job, strv_skip(args, 1))) {
2153 skipped = true;
2154 continue;
2155 }
2156
2157 if (!GREEDY_REALLOC(jobs, size, c + 1))
2158 return log_oom();
2159
2160 jobs[c++] = job;
2161 }
2162 if (r < 0)
2163 return bus_log_parse_error(r);
2164
2165 r = sd_bus_message_exit_container(reply);
2166 if (r < 0)
2167 return bus_log_parse_error(r);
2168
2169 output_jobs_list(jobs, c, skipped);
2170 return r;
2171 }
2172
2173 static int cancel_job(char **args) {
2174 sd_bus *bus;
2175 char **name;
2176 int r = 0;
2177
2178 if (strv_length(args) <= 1)
2179 return daemon_reload(args);
2180
2181 polkit_agent_open_if_enabled();
2182
2183 r = acquire_bus(BUS_MANAGER, &bus);
2184 if (r < 0)
2185 return r;
2186
2187 STRV_FOREACH(name, args+1) {
2188 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2189 uint32_t id;
2190 int q;
2191
2192 q = safe_atou32(*name, &id);
2193 if (q < 0)
2194 return log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
2195
2196 q = sd_bus_call_method(
2197 bus,
2198 "org.freedesktop.systemd1",
2199 "/org/freedesktop/systemd1",
2200 "org.freedesktop.systemd1.Manager",
2201 "CancelJob",
2202 &error,
2203 NULL,
2204 "u", id);
2205 if (q < 0) {
2206 log_error_errno(q, "Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2207 if (r == 0)
2208 r = q;
2209 }
2210 }
2211
2212 return r;
2213 }
2214
2215 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2216 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2217 const char *path;
2218 int b, r;
2219
2220 /* We ignore all errors here, since this is used to show a
2221 * warning only */
2222
2223 /* We don't use unit_dbus_path_from_name() directly since we
2224 * don't want to load the unit if it isn't loaded. */
2225
2226 r = sd_bus_call_method(
2227 bus,
2228 "org.freedesktop.systemd1",
2229 "/org/freedesktop/systemd1",
2230 "org.freedesktop.systemd1.Manager",
2231 "GetUnit",
2232 NULL,
2233 &reply,
2234 "s", unit);
2235 if (r < 0)
2236 return r;
2237
2238 r = sd_bus_message_read(reply, "o", &path);
2239 if (r < 0)
2240 return r;
2241
2242 r = sd_bus_get_property_trivial(
2243 bus,
2244 "org.freedesktop.systemd1",
2245 path,
2246 "org.freedesktop.systemd1.Unit",
2247 "NeedDaemonReload",
2248 NULL,
2249 'b', &b);
2250 if (r < 0)
2251 return r;
2252
2253 return b;
2254 }
2255
2256 static void warn_unit_file_changed(const char *name) {
2257 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2258 ansi_highlight_red(),
2259 ansi_normal(),
2260 name,
2261 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2262 }
2263
2264 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
2265 char **p;
2266
2267 assert(lp);
2268 assert(unit_name);
2269 assert(unit_path);
2270
2271 STRV_FOREACH(p, lp->unit_path) {
2272 _cleanup_free_ char *path;
2273
2274 path = path_join(arg_root, *p, unit_name);
2275 if (!path)
2276 return log_oom();
2277
2278 if (access(path, F_OK) == 0) {
2279 *unit_path = path;
2280 path = NULL;
2281 return 1;
2282 }
2283 }
2284
2285 return 0;
2286 }
2287
2288 static int unit_find_paths(
2289 sd_bus *bus,
2290 const char *unit_name,
2291 LookupPaths *lp,
2292 char **fragment_path,
2293 char ***dropin_paths) {
2294
2295 _cleanup_free_ char *path = NULL;
2296 _cleanup_strv_free_ char **dropins = NULL;
2297 int r;
2298
2299 /**
2300 * Finds where the unit is defined on disk. Returns 0 if the unit
2301 * is not found. Returns 1 if it is found, and sets
2302 * - the path to the unit in *path, if it exists on disk,
2303 * - and a strv of existing drop-ins in *dropins,
2304 * if the arg is not NULL and any dropins were found.
2305 */
2306
2307 assert(unit_name);
2308 assert(fragment_path);
2309 assert(lp);
2310
2311 if (!install_client_side() && !unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) {
2312 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2313 _cleanup_bus_message_unref_ sd_bus_message *unit_load_error = NULL;
2314 _cleanup_free_ char *unit = NULL;
2315 char *unit_load_error_name, *unit_load_error_message;
2316
2317 unit = unit_dbus_path_from_name(unit_name);
2318 if (!unit)
2319 return log_oom();
2320
2321 if (need_daemon_reload(bus, unit_name) > 0)
2322 warn_unit_file_changed(unit_name);
2323
2324 r = sd_bus_get_property(
2325 bus,
2326 "org.freedesktop.systemd1",
2327 unit,
2328 "org.freedesktop.systemd1.Unit",
2329 "LoadError",
2330 &error,
2331 &unit_load_error,
2332 "(ss)");
2333 if (r < 0)
2334 return log_error_errno(r, "Failed to get LoadError: %s", bus_error_message(&error, r));
2335
2336 r = sd_bus_message_read(
2337 unit_load_error,
2338 "(ss)",
2339 &unit_load_error_name,
2340 &unit_load_error_message);
2341 if (r < 0)
2342 return bus_log_parse_error(r);
2343
2344 if (!isempty(unit_load_error_name)) {
2345 log_error("Unit %s is not loaded: %s", unit_name, unit_load_error_message);
2346 return 0;
2347 }
2348
2349 r = sd_bus_get_property_string(
2350 bus,
2351 "org.freedesktop.systemd1",
2352 unit,
2353 "org.freedesktop.systemd1.Unit",
2354 "FragmentPath",
2355 &error,
2356 &path);
2357 if (r < 0)
2358 return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
2359
2360 if (dropin_paths) {
2361 r = sd_bus_get_property_strv(
2362 bus,
2363 "org.freedesktop.systemd1",
2364 unit,
2365 "org.freedesktop.systemd1.Unit",
2366 "DropInPaths",
2367 &error,
2368 &dropins);
2369 if (r < 0)
2370 return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2371 }
2372 } else {
2373 _cleanup_set_free_ Set *names;
2374
2375 names = set_new(NULL);
2376 if (!names)
2377 return log_oom();
2378
2379 r = set_put(names, unit_name);
2380 if (r < 0)
2381 return log_error_errno(r, "Failed to add unit name: %m");
2382
2383 r = unit_file_find_path(lp, unit_name, &path);
2384 if (r < 0)
2385 return r;
2386
2387 if (r == 0) {
2388 _cleanup_free_ char *template = NULL;
2389
2390 r = unit_name_template(unit_name, &template);
2391 if (r < 0 && r != -EINVAL)
2392 return log_error_errno(r, "Failed to determine template name: %m");
2393 if (r >= 0) {
2394 r = unit_file_find_path(lp, template, &path);
2395 if (r < 0)
2396 return r;
2397 }
2398 }
2399
2400 if (dropin_paths) {
2401 r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, &dropins);
2402 if (r < 0)
2403 return r;
2404 }
2405 }
2406
2407 r = 0;
2408
2409 if (!isempty(path)) {
2410 *fragment_path = path;
2411 path = NULL;
2412 r = 1;
2413 }
2414
2415 if (dropin_paths && !strv_isempty(dropins)) {
2416 *dropin_paths = dropins;
2417 dropins = NULL;
2418 r = 1;
2419 }
2420
2421 if (r == 0)
2422 log_error("No files found for %s.", unit_name);
2423
2424 return r;
2425 }
2426
2427 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2428 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2429 _cleanup_free_ char *n = NULL, *state = NULL;
2430 const char *path;
2431 int r;
2432
2433 assert(name);
2434
2435 r = unit_name_mangle(name, UNIT_NAME_NOGLOB, &n);
2436 if (r < 0)
2437 return log_error_errno(r, "Failed to mangle unit name: %m");
2438
2439 /* We don't use unit_dbus_path_from_name() directly since we
2440 * don't want to load the unit if it isn't loaded. */
2441
2442 r = sd_bus_call_method(
2443 bus,
2444 "org.freedesktop.systemd1",
2445 "/org/freedesktop/systemd1",
2446 "org.freedesktop.systemd1.Manager",
2447 "GetUnit",
2448 NULL,
2449 &reply,
2450 "s", n);
2451 if (r < 0) {
2452 if (!quiet)
2453 puts("unknown");
2454 return 0;
2455 }
2456
2457 r = sd_bus_message_read(reply, "o", &path);
2458 if (r < 0)
2459 return bus_log_parse_error(r);
2460
2461 r = sd_bus_get_property_string(
2462 bus,
2463 "org.freedesktop.systemd1",
2464 path,
2465 "org.freedesktop.systemd1.Unit",
2466 "ActiveState",
2467 NULL,
2468 &state);
2469 if (r < 0) {
2470 if (!quiet)
2471 puts("unknown");
2472 return 0;
2473 }
2474
2475 if (!quiet)
2476 puts(state);
2477
2478 return nulstr_contains(good_states, state);
2479 }
2480
2481 static int check_triggering_units(
2482 sd_bus *bus,
2483 const char *name) {
2484
2485 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2486 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2487 _cleanup_strv_free_ char **triggered_by = NULL;
2488 bool print_warning_label = true;
2489 char **i;
2490 int r;
2491
2492 r = unit_name_mangle(name, UNIT_NAME_NOGLOB, &n);
2493 if (r < 0)
2494 return log_error_errno(r, "Failed to mangle unit name: %m");
2495
2496 path = unit_dbus_path_from_name(n);
2497 if (!path)
2498 return log_oom();
2499
2500 r = sd_bus_get_property_string(
2501 bus,
2502 "org.freedesktop.systemd1",
2503 path,
2504 "org.freedesktop.systemd1.Unit",
2505 "LoadState",
2506 &error,
2507 &state);
2508 if (r < 0)
2509 return log_error_errno(r, "Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2510
2511 if (streq(state, "masked"))
2512 return 0;
2513
2514 r = sd_bus_get_property_strv(
2515 bus,
2516 "org.freedesktop.systemd1",
2517 path,
2518 "org.freedesktop.systemd1.Unit",
2519 "TriggeredBy",
2520 &error,
2521 &triggered_by);
2522 if (r < 0)
2523 return log_error_errno(r, "Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2524
2525 STRV_FOREACH(i, triggered_by) {
2526 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2527 if (r < 0)
2528 return log_error_errno(r, "Failed to check unit: %m");
2529
2530 if (r == 0)
2531 continue;
2532
2533 if (print_warning_label) {
2534 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2535 print_warning_label = false;
2536 }
2537
2538 log_warning(" %s", *i);
2539 }
2540
2541 return 0;
2542 }
2543
2544 static const struct {
2545 const char *verb;
2546 const char *method;
2547 } unit_actions[] = {
2548 { "start", "StartUnit" },
2549 { "stop", "StopUnit" },
2550 { "condstop", "StopUnit" },
2551 { "reload", "ReloadUnit" },
2552 { "restart", "RestartUnit" },
2553 { "try-restart", "TryRestartUnit" },
2554 { "condrestart", "TryRestartUnit" },
2555 { "reload-or-restart", "ReloadOrRestartUnit" },
2556 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2557 { "condreload", "ReloadOrTryRestartUnit" },
2558 { "force-reload", "ReloadOrTryRestartUnit" }
2559 };
2560
2561 static const char *verb_to_method(const char *verb) {
2562 uint i;
2563
2564 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2565 if (streq_ptr(unit_actions[i].verb, verb))
2566 return unit_actions[i].method;
2567
2568 return "StartUnit";
2569 }
2570
2571 static const char *method_to_verb(const char *method) {
2572 uint i;
2573
2574 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2575 if (streq_ptr(unit_actions[i].method, method))
2576 return unit_actions[i].verb;
2577
2578 return "n/a";
2579 }
2580
2581 static int start_unit_one(
2582 sd_bus *bus,
2583 const char *method,
2584 const char *name,
2585 const char *mode,
2586 sd_bus_error *error,
2587 BusWaitForJobs *w) {
2588
2589 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2590 const char *path;
2591 int r;
2592
2593 assert(method);
2594 assert(name);
2595 assert(mode);
2596 assert(error);
2597
2598 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2599
2600 r = sd_bus_call_method(
2601 bus,
2602 "org.freedesktop.systemd1",
2603 "/org/freedesktop/systemd1",
2604 "org.freedesktop.systemd1.Manager",
2605 method,
2606 error,
2607 &reply,
2608 "ss", name, mode);
2609 if (r < 0) {
2610 const char *verb;
2611
2612 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2613 /* There's always a fallback possible for
2614 * legacy actions. */
2615 return -EADDRNOTAVAIL;
2616
2617 verb = method_to_verb(method);
2618
2619 return log_error_errno(r, "Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2620 }
2621
2622 r = sd_bus_message_read(reply, "o", &path);
2623 if (r < 0)
2624 return bus_log_parse_error(r);
2625
2626 if (need_daemon_reload(bus, name) > 0)
2627 warn_unit_file_changed(name);
2628
2629 if (w) {
2630 log_debug("Adding %s to the set", path);
2631 r = bus_wait_for_jobs_add(w, path);
2632 if (r < 0)
2633 return log_oom();
2634 }
2635
2636 return 0;
2637 }
2638
2639 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2640 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2641 char **name;
2642 int r, i;
2643
2644 assert(bus);
2645 assert(ret);
2646
2647 STRV_FOREACH(name, names) {
2648 char *t;
2649
2650 if (suffix)
2651 r = unit_name_mangle_with_suffix(*name, UNIT_NAME_GLOB, suffix, &t);
2652 else
2653 r = unit_name_mangle(*name, UNIT_NAME_GLOB, &t);
2654 if (r < 0)
2655 return log_error_errno(r, "Failed to mangle name: %m");
2656
2657 if (string_is_glob(t))
2658 r = strv_consume(&globs, t);
2659 else
2660 r = strv_consume(&mangled, t);
2661 if (r < 0)
2662 return log_oom();
2663 }
2664
2665 /* Query the manager only if any of the names are a glob, since
2666 * this is fairly expensive */
2667 if (!strv_isempty(globs)) {
2668 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2669 _cleanup_free_ UnitInfo *unit_infos = NULL;
2670
2671 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2672 if (r < 0)
2673 return r;
2674
2675 for (i = 0; i < r; i++)
2676 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2677 return log_oom();
2678 }
2679
2680 *ret = mangled;
2681 mangled = NULL; /* do not free */
2682
2683 return 0;
2684 }
2685
2686 static const struct {
2687 const char *target;
2688 const char *verb;
2689 const char *mode;
2690 } action_table[_ACTION_MAX] = {
2691 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2692 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2693 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2694 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2695 [ACTION_RUNLEVEL2] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
2696 [ACTION_RUNLEVEL3] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
2697 [ACTION_RUNLEVEL4] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
2698 [ACTION_RUNLEVEL5] = { SPECIAL_GRAPHICAL_TARGET, NULL, "isolate" },
2699 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2700 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2701 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2702 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2703 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2704 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2705 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2706 };
2707
2708 static enum action verb_to_action(const char *verb) {
2709 enum action i;
2710
2711 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2712 if (streq_ptr(action_table[i].verb, verb))
2713 return i;
2714
2715 return _ACTION_INVALID;
2716 }
2717
2718 static int start_unit(char **args) {
2719 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
2720 const char *method, *mode, *one_name, *suffix = NULL;
2721 _cleanup_strv_free_ char **names = NULL;
2722 sd_bus *bus;
2723 char **name;
2724 int r = 0;
2725
2726 ask_password_agent_open_if_enabled();
2727 polkit_agent_open_if_enabled();
2728
2729 r = acquire_bus(BUS_MANAGER, &bus);
2730 if (r < 0)
2731 return r;
2732
2733 if (arg_action == ACTION_SYSTEMCTL) {
2734 enum action action;
2735 method = verb_to_method(args[0]);
2736 action = verb_to_action(args[0]);
2737
2738 if (streq(args[0], "isolate")) {
2739 mode = "isolate";
2740 suffix = ".target";
2741 } else
2742 mode = action_table[action].mode ?: arg_job_mode;
2743
2744 one_name = action_table[action].target;
2745 } else {
2746 assert(arg_action < ELEMENTSOF(action_table));
2747 assert(action_table[arg_action].target);
2748
2749 method = "StartUnit";
2750
2751 mode = action_table[arg_action].mode;
2752 one_name = action_table[arg_action].target;
2753 }
2754
2755 if (one_name)
2756 names = strv_new(one_name, NULL);
2757 else {
2758 r = expand_names(bus, strv_skip(args, 1), suffix, &names);
2759 if (r < 0)
2760 return log_error_errno(r, "Failed to expand names: %m");
2761 }
2762
2763 if (!arg_no_block) {
2764 r = bus_wait_for_jobs_new(bus, &w);
2765 if (r < 0)
2766 return log_error_errno(r, "Could not watch jobs: %m");
2767 }
2768
2769 STRV_FOREACH(name, names) {
2770 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2771 int q;
2772
2773 q = start_unit_one(bus, method, *name, mode, &error, w);
2774 if (r >= 0 && q < 0)
2775 r = translate_bus_error_to_exit_status(q, &error);
2776 }
2777
2778 if (!arg_no_block) {
2779 int q;
2780
2781 q = bus_wait_for_jobs(w, arg_quiet);
2782 if (q < 0)
2783 return q;
2784
2785 /* When stopping units, warn if they can still be triggered by
2786 * another active unit (socket, path, timer) */
2787 if (!arg_quiet && streq(method, "StopUnit"))
2788 STRV_FOREACH(name, names)
2789 check_triggering_units(bus, *name);
2790 }
2791
2792 return r;
2793 }
2794
2795 static int logind_set_wall_message(void) {
2796 #ifdef HAVE_LOGIND
2797 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2798 sd_bus *bus;
2799 _cleanup_free_ char *m = NULL;
2800 int r;
2801
2802 r = acquire_bus(BUS_FULL, &bus);
2803 if (r < 0)
2804 return r;
2805
2806 m = strv_join(arg_wall, " ");
2807 if (!m)
2808 return log_oom();
2809
2810 r = sd_bus_call_method(
2811 bus,
2812 "org.freedesktop.login1",
2813 "/org/freedesktop/login1",
2814 "org.freedesktop.login1.Manager",
2815 "SetWallMessage",
2816 &error,
2817 NULL,
2818 "sb",
2819 m,
2820 !arg_no_wall);
2821
2822 if (r < 0)
2823 return log_warning_errno(r, "Failed to set wall message, ignoring: %s", bus_error_message(&error, r));
2824
2825 #endif
2826 return 0;
2827 }
2828
2829 /* Ask systemd-logind, which might grant access to unprivileged users
2830 * through PolicyKit */
2831 static int logind_reboot(enum action a) {
2832 #ifdef HAVE_LOGIND
2833 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2834 const char *method, *description;
2835 sd_bus *bus;
2836 int r;
2837
2838 polkit_agent_open_if_enabled();
2839 (void) logind_set_wall_message();
2840
2841 r = acquire_bus(BUS_FULL, &bus);
2842 if (r < 0)
2843 return r;
2844
2845 switch (a) {
2846
2847 case ACTION_REBOOT:
2848 method = "Reboot";
2849 description = "reboot system";
2850 break;
2851
2852 case ACTION_POWEROFF:
2853 method = "PowerOff";
2854 description = "power off system";
2855 break;
2856
2857 case ACTION_SUSPEND:
2858 method = "Suspend";
2859 description = "suspend system";
2860 break;
2861
2862 case ACTION_HIBERNATE:
2863 method = "Hibernate";
2864 description = "hibernate system";
2865 break;
2866
2867 case ACTION_HYBRID_SLEEP:
2868 method = "HybridSleep";
2869 description = "put system into hybrid sleep";
2870 break;
2871
2872 default:
2873 return -EINVAL;
2874 }
2875
2876 r = sd_bus_call_method(
2877 bus,
2878 "org.freedesktop.login1",
2879 "/org/freedesktop/login1",
2880 "org.freedesktop.login1.Manager",
2881 method,
2882 &error,
2883 NULL,
2884 "b", arg_ask_password);
2885 if (r < 0)
2886 return log_error_errno(r, "Failed to %s via logind: %s", description, bus_error_message(&error, r));
2887
2888 return 0;
2889 #else
2890 return -ENOSYS;
2891 #endif
2892 }
2893
2894 static int logind_check_inhibitors(enum action a) {
2895 #ifdef HAVE_LOGIND
2896 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2897 _cleanup_strv_free_ char **sessions = NULL;
2898 const char *what, *who, *why, *mode;
2899 uint32_t uid, pid;
2900 sd_bus *bus;
2901 unsigned c = 0;
2902 char **s;
2903 int r;
2904
2905 if (arg_ignore_inhibitors || arg_force > 0)
2906 return 0;
2907
2908 if (arg_when > 0)
2909 return 0;
2910
2911 if (geteuid() == 0)
2912 return 0;
2913
2914 if (!on_tty())
2915 return 0;
2916
2917 r = acquire_bus(BUS_FULL, &bus);
2918 if (r < 0)
2919 return r;
2920
2921 r = sd_bus_call_method(
2922 bus,
2923 "org.freedesktop.login1",
2924 "/org/freedesktop/login1",
2925 "org.freedesktop.login1.Manager",
2926 "ListInhibitors",
2927 NULL,
2928 &reply,
2929 NULL);
2930 if (r < 0)
2931 /* If logind is not around, then there are no inhibitors... */
2932 return 0;
2933
2934 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2935 if (r < 0)
2936 return bus_log_parse_error(r);
2937
2938 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2939 _cleanup_free_ char *comm = NULL, *user = NULL;
2940 _cleanup_strv_free_ char **sv = NULL;
2941
2942 if (!streq(mode, "block"))
2943 continue;
2944
2945 sv = strv_split(what, ":");
2946 if (!sv)
2947 return log_oom();
2948
2949 if ((pid_t) pid < 0)
2950 return log_error_errno(ERANGE, "Bad PID %"PRIu32": %m", pid);
2951
2952 if (!strv_contains(sv,
2953 IN_SET(a,
2954 ACTION_HALT,
2955 ACTION_POWEROFF,
2956 ACTION_REBOOT,
2957 ACTION_KEXEC) ? "shutdown" : "sleep"))
2958 continue;
2959
2960 get_process_comm(pid, &comm);
2961 user = uid_to_name(uid);
2962
2963 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2964 who, (pid_t) pid, strna(comm), strna(user), why);
2965
2966 c++;
2967 }
2968 if (r < 0)
2969 return bus_log_parse_error(r);
2970
2971 r = sd_bus_message_exit_container(reply);
2972 if (r < 0)
2973 return bus_log_parse_error(r);
2974
2975 /* Check for current sessions */
2976 sd_get_sessions(&sessions);
2977 STRV_FOREACH(s, sessions) {
2978 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2979
2980 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2981 continue;
2982
2983 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2984 continue;
2985
2986 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2987 continue;
2988
2989 sd_session_get_tty(*s, &tty);
2990 sd_session_get_seat(*s, &seat);
2991 sd_session_get_service(*s, &service);
2992 user = uid_to_name(uid);
2993
2994 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2995 c++;
2996 }
2997
2998 if (c <= 0)
2999 return 0;
3000
3001 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3002 action_table[a].verb);
3003
3004 return -EPERM;
3005 #else
3006 return 0;
3007 #endif
3008 }
3009
3010 static int logind_prepare_firmware_setup(void) {
3011 #ifdef HAVE_LOGIND
3012 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3013 sd_bus *bus;
3014 int r;
3015
3016 r = acquire_bus(BUS_FULL, &bus);
3017 if (r < 0)
3018 return r;
3019
3020 r = sd_bus_call_method(
3021 bus,
3022 "org.freedesktop.login1",
3023 "/org/freedesktop/login1",
3024 "org.freedesktop.login1.Manager",
3025 "SetRebootToFirmwareSetup",
3026 &error,
3027 NULL,
3028 "b", true);
3029 if (r < 0)
3030 return log_error_errno(r, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error, r));
3031
3032 return 0;
3033 #else
3034 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3035 return -ENOSYS;
3036 #endif
3037 }
3038
3039 static int prepare_firmware_setup(void) {
3040 int r;
3041
3042 if (!arg_firmware_setup)
3043 return 0;
3044
3045 if (arg_transport == BUS_TRANSPORT_LOCAL) {
3046
3047 r = efi_set_reboot_to_firmware(true);
3048 if (r < 0)
3049 log_debug_errno(r, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3050 else
3051 return r;
3052 }
3053
3054 return logind_prepare_firmware_setup();
3055 }
3056
3057 static int start_special(char **args) {
3058 enum action a;
3059 int r;
3060
3061 assert(args);
3062
3063 a = verb_to_action(args[0]);
3064
3065 r = logind_check_inhibitors(a);
3066 if (r < 0)
3067 return r;
3068
3069 if (arg_force >= 2 && geteuid() != 0) {
3070 log_error("Must be root.");
3071 return -EPERM;
3072 }
3073
3074 r = prepare_firmware_setup();
3075 if (r < 0)
3076 return r;
3077
3078 if (a == ACTION_REBOOT && args[1]) {
3079 r = update_reboot_param_file(args[1]);
3080 if (r < 0)
3081 return r;
3082 } else if (a == ACTION_EXIT && strv_length(args) > 1) {
3083 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3084 /* If the exit code is not given on the command line, don't
3085 * reset it to zero: just keep it as it might have been set
3086 * previously. */
3087 uint8_t code = 0;
3088 sd_bus *bus;
3089
3090 r = safe_atou8(args[1], &code);
3091 if (r < 0) {
3092 log_error("Invalid exit code.");
3093 return -EINVAL;
3094 }
3095
3096 r = acquire_bus(BUS_MANAGER, &bus);
3097 if (r < 0)
3098 return r;
3099
3100 r = sd_bus_call_method(
3101 bus,
3102 "org.freedesktop.systemd1",
3103 "/org/freedesktop/systemd1",
3104 "org.freedesktop.systemd1.Manager",
3105 "SetExitCode",
3106 &error,
3107 NULL,
3108 "y", code);
3109 if (r < 0)
3110 return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
3111 }
3112
3113 if (arg_force >= 2 &&
3114 IN_SET(a,
3115 ACTION_HALT,
3116 ACTION_POWEROFF,
3117 ACTION_REBOOT))
3118 return halt_now(a);
3119
3120 if (arg_force >= 1 &&
3121 IN_SET(a,
3122 ACTION_HALT,
3123 ACTION_POWEROFF,
3124 ACTION_REBOOT,
3125 ACTION_KEXEC,
3126 ACTION_EXIT))
3127 return daemon_reload(args);
3128
3129 /* first try logind, to allow authentication with polkit */
3130 if (geteuid() != 0 &&
3131 IN_SET(a,
3132 ACTION_POWEROFF,
3133 ACTION_REBOOT,
3134 ACTION_SUSPEND,
3135 ACTION_HIBERNATE,
3136 ACTION_HYBRID_SLEEP)) {
3137 r = logind_reboot(a);
3138 if (r >= 0)
3139 return r;
3140 if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
3141 /* requested operation is not supported or already in progress */
3142 return r;
3143 /* on all other errors, try low-level operation */
3144 }
3145
3146 return start_unit(args);
3147 }
3148
3149 static int check_unit_generic(int code, const char *good_states, char **args) {
3150 _cleanup_strv_free_ char **names = NULL;
3151 sd_bus *bus;
3152 char **name;
3153 int r;
3154
3155 r = acquire_bus(BUS_MANAGER, &bus);
3156 if (r < 0)
3157 return r;
3158
3159 r = expand_names(bus, args, NULL, &names);
3160 if (r < 0)
3161 return log_error_errno(r, "Failed to expand names: %m");
3162
3163 STRV_FOREACH(name, names) {
3164 int state;
3165
3166 state = check_one_unit(bus, *name, good_states, arg_quiet);
3167 if (state < 0)
3168 return state;
3169 if (state == 0)
3170 r = code;
3171 }
3172
3173 return r;
3174 }
3175
3176 static int check_unit_active(char **args) {
3177 /* According to LSB: 3, "program is not running" */
3178 return check_unit_generic(3, "active\0reloading\0", strv_skip(args, 1));
3179 }
3180
3181 static int check_unit_failed(char **args) {
3182 return check_unit_generic(1, "failed\0", strv_skip(args, 1));
3183 }
3184
3185 static int kill_unit(char **args) {
3186 _cleanup_strv_free_ char **names = NULL;
3187 char *kill_who = NULL, **name;
3188 sd_bus *bus;
3189 int r, q;
3190
3191 polkit_agent_open_if_enabled();
3192
3193 r = acquire_bus(BUS_MANAGER, &bus);
3194 if (r < 0)
3195 return r;
3196
3197 if (!arg_kill_who)
3198 arg_kill_who = "all";
3199
3200 /* --fail was specified */
3201 if (streq(arg_job_mode, "fail"))
3202 kill_who = strjoina(arg_kill_who, "-fail", NULL);
3203
3204 r = expand_names(bus, strv_skip(args, 1), NULL, &names);
3205 if (r < 0)
3206 return log_error_errno(r, "Failed to expand names: %m");
3207
3208 STRV_FOREACH(name, names) {
3209 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3210
3211 q = sd_bus_call_method(
3212 bus,
3213 "org.freedesktop.systemd1",
3214 "/org/freedesktop/systemd1",
3215 "org.freedesktop.systemd1.Manager",
3216 "KillUnit",
3217 &error,
3218 NULL,
3219 "ssi", *names, kill_who ? kill_who : arg_kill_who, arg_signal);
3220 if (q < 0) {
3221 log_error_errno(q, "Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3222 if (r == 0)
3223 r = q;
3224 }
3225 }
3226
3227 return r;
3228 }
3229
3230 typedef struct ExecStatusInfo {
3231 char *name;
3232
3233 char *path;
3234 char **argv;
3235
3236 bool ignore;
3237
3238 usec_t start_timestamp;
3239 usec_t exit_timestamp;
3240 pid_t pid;
3241 int code;
3242 int status;
3243
3244 LIST_FIELDS(struct ExecStatusInfo, exec);
3245 } ExecStatusInfo;
3246
3247 static void exec_status_info_free(ExecStatusInfo *i) {
3248 assert(i);
3249
3250 free(i->name);
3251 free(i->path);
3252 strv_free(i->argv);
3253 free(i);
3254 }
3255
3256 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3257 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3258 const char *path;
3259 uint32_t pid;
3260 int32_t code, status;
3261 int ignore, r;
3262
3263 assert(m);
3264 assert(i);
3265
3266 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3267 if (r < 0)
3268 return bus_log_parse_error(r);
3269 else if (r == 0)
3270 return 0;
3271
3272 r = sd_bus_message_read(m, "s", &path);
3273 if (r < 0)
3274 return bus_log_parse_error(r);
3275
3276 i->path = strdup(path);
3277 if (!i->path)
3278 return log_oom();
3279
3280 r = sd_bus_message_read_strv(m, &i->argv);
3281 if (r < 0)
3282 return bus_log_parse_error(r);
3283
3284 r = sd_bus_message_read(m,
3285 "bttttuii",
3286 &ignore,
3287 &start_timestamp, &start_timestamp_monotonic,
3288 &exit_timestamp, &exit_timestamp_monotonic,
3289 &pid,
3290 &code, &status);
3291 if (r < 0)
3292 return bus_log_parse_error(r);
3293
3294 i->ignore = ignore;
3295 i->start_timestamp = (usec_t) start_timestamp;
3296 i->exit_timestamp = (usec_t) exit_timestamp;
3297 i->pid = (pid_t) pid;
3298 i->code = code;
3299 i->status = status;
3300
3301 r = sd_bus_message_exit_container(m);
3302 if (r < 0)
3303 return bus_log_parse_error(r);
3304
3305 return 1;
3306 }
3307
3308 typedef struct UnitStatusInfo {
3309 const char *id;
3310 const char *load_state;
3311 const char *active_state;
3312 const char *sub_state;
3313 const char *unit_file_state;
3314 const char *unit_file_preset;
3315
3316 const char *description;
3317 const char *following;
3318
3319 char **documentation;
3320
3321 const char *fragment_path;
3322 const char *source_path;
3323 const char *control_group;
3324
3325 char **dropin_paths;
3326
3327 const char *load_error;
3328 const char *result;
3329
3330 usec_t inactive_exit_timestamp;
3331 usec_t inactive_exit_timestamp_monotonic;
3332 usec_t active_enter_timestamp;
3333 usec_t active_exit_timestamp;
3334 usec_t inactive_enter_timestamp;
3335
3336 bool need_daemon_reload;
3337
3338 /* Service */
3339 pid_t main_pid;
3340 pid_t control_pid;
3341 const char *status_text;
3342 const char *pid_file;
3343 bool running:1;
3344 int status_errno;
3345
3346 usec_t start_timestamp;
3347 usec_t exit_timestamp;
3348
3349 int exit_code, exit_status;
3350
3351 usec_t condition_timestamp;
3352 bool condition_result;
3353 bool failed_condition_trigger;
3354 bool failed_condition_negate;
3355 const char *failed_condition;
3356 const char *failed_condition_parameter;
3357
3358 usec_t assert_timestamp;
3359 bool assert_result;
3360 bool failed_assert_trigger;
3361 bool failed_assert_negate;
3362 const char *failed_assert;
3363 const char *failed_assert_parameter;
3364
3365 /* Socket */
3366 unsigned n_accepted;
3367 unsigned n_connections;
3368 bool accept;
3369
3370 /* Pairs of type, path */
3371 char **listen;
3372
3373 /* Device */
3374 const char *sysfs_path;
3375
3376 /* Mount, Automount */
3377 const char *where;
3378
3379 /* Swap */
3380 const char *what;
3381
3382 /* CGroup */
3383 uint64_t memory_current;
3384 uint64_t memory_limit;
3385 uint64_t cpu_usage_nsec;
3386 uint64_t tasks_current;
3387 uint64_t tasks_max;
3388
3389 LIST_HEAD(ExecStatusInfo, exec);
3390 } UnitStatusInfo;
3391
3392 static void print_status_info(
3393 UnitStatusInfo *i,
3394 bool *ellipsized) {
3395
3396 ExecStatusInfo *p;
3397 const char *active_on, *active_off, *on, *off, *ss;
3398 usec_t timestamp;
3399 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3400 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3401 const char *path;
3402 char **t, **t2;
3403
3404 assert(i);
3405
3406 /* This shows pretty information about a unit. See
3407 * print_property() for a low-level property printer */
3408
3409 if (streq_ptr(i->active_state, "failed")) {
3410 active_on = ansi_highlight_red();
3411 active_off = ansi_normal();
3412 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3413 active_on = ansi_highlight_green();
3414 active_off = ansi_normal();
3415 } else
3416 active_on = active_off = "";
3417
3418 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3419
3420 if (i->description && !streq_ptr(i->id, i->description))
3421 printf(" - %s", i->description);
3422
3423 printf("\n");
3424
3425 if (i->following)
3426 printf(" Follow: unit currently follows state of %s\n", i->following);
3427
3428 if (streq_ptr(i->load_state, "error")) {
3429 on = ansi_highlight_red();
3430 off = ansi_normal();
3431 } else
3432 on = off = "";
3433
3434 path = i->source_path ? i->source_path : i->fragment_path;
3435
3436 if (i->load_error)
3437 printf(" Loaded: %s%s%s (Reason: %s)\n",
3438 on, strna(i->load_state), off, i->load_error);
3439 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3440 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3441 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3442 else if (path && !isempty(i->unit_file_state))
3443 printf(" Loaded: %s%s%s (%s; %s)\n",
3444 on, strna(i->load_state), off, path, i->unit_file_state);
3445 else if (path)
3446 printf(" Loaded: %s%s%s (%s)\n",
3447 on, strna(i->load_state), off, path);
3448 else
3449 printf(" Loaded: %s%s%s\n",
3450 on, strna(i->load_state), off);
3451
3452 if (!strv_isempty(i->dropin_paths)) {
3453 _cleanup_free_ char *dir = NULL;
3454 bool last = false;
3455 char ** dropin;
3456
3457 STRV_FOREACH(dropin, i->dropin_paths) {
3458 if (! dir || last) {
3459 printf(dir ? " " : " Drop-In: ");
3460
3461 dir = mfree(dir);
3462
3463 if (path_get_parent(*dropin, &dir) < 0) {
3464 log_oom();
3465 return;
3466 }
3467
3468 printf("%s\n %s", dir,
3469 draw_special_char(DRAW_TREE_RIGHT));
3470 }
3471
3472 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3473
3474 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3475 }
3476 }
3477
3478 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3479 if (ss)
3480 printf(" Active: %s%s (%s)%s",
3481 active_on, strna(i->active_state), ss, active_off);
3482 else
3483 printf(" Active: %s%s%s",
3484 active_on, strna(i->active_state), active_off);
3485
3486 if (!isempty(i->result) && !streq(i->result, "success"))
3487 printf(" (Result: %s)", i->result);
3488
3489 timestamp = (streq_ptr(i->active_state, "active") ||
3490 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3491 (streq_ptr(i->active_state, "inactive") ||
3492 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3493 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3494 i->active_exit_timestamp;
3495
3496 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3497 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3498
3499 if (s1)
3500 printf(" since %s; %s\n", s2, s1);
3501 else if (s2)
3502 printf(" since %s\n", s2);
3503 else
3504 printf("\n");
3505
3506 if (!i->condition_result && i->condition_timestamp > 0) {
3507 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3508 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3509
3510 printf("Condition: start %scondition failed%s at %s%s%s\n",
3511 ansi_highlight_yellow(), ansi_normal(),
3512 s2, s1 ? "; " : "", s1 ? s1 : "");
3513 if (i->failed_condition_trigger)
3514 printf(" none of the trigger conditions were met\n");
3515 else if (i->failed_condition)
3516 printf(" %s=%s%s was not met\n",
3517 i->failed_condition,
3518 i->failed_condition_negate ? "!" : "",
3519 i->failed_condition_parameter);
3520 }
3521
3522 if (!i->assert_result && i->assert_timestamp > 0) {
3523 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3524 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3525
3526 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3527 ansi_highlight_red(), ansi_normal(),
3528 s2, s1 ? "; " : "", s1 ? s1 : "");
3529 if (i->failed_assert_trigger)
3530 printf(" none of the trigger assertions were met\n");
3531 else if (i->failed_assert)
3532 printf(" %s=%s%s was not met\n",
3533 i->failed_assert,
3534 i->failed_assert_negate ? "!" : "",
3535 i->failed_assert_parameter);
3536 }
3537
3538 if (i->sysfs_path)
3539 printf(" Device: %s\n", i->sysfs_path);
3540 if (i->where)
3541 printf(" Where: %s\n", i->where);
3542 if (i->what)
3543 printf(" What: %s\n", i->what);
3544
3545 STRV_FOREACH(t, i->documentation)
3546 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3547
3548 STRV_FOREACH_PAIR(t, t2, i->listen)
3549 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3550
3551 if (i->accept)
3552 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3553
3554 LIST_FOREACH(exec, p, i->exec) {
3555 _cleanup_free_ char *argv = NULL;
3556 bool good;
3557
3558 /* Only show exited processes here */
3559 if (p->code == 0)
3560 continue;
3561
3562 argv = strv_join(p->argv, " ");
3563 printf(" Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
3564
3565 good = is_clean_exit_lsb(p->code, p->status, NULL);
3566 if (!good) {
3567 on = ansi_highlight_red();
3568 off = ansi_normal();
3569 } else
3570 on = off = "";
3571
3572 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3573
3574 if (p->code == CLD_EXITED) {
3575 const char *c;
3576
3577 printf("status=%i", p->status);
3578
3579 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3580 if (c)
3581 printf("/%s", c);
3582
3583 } else
3584 printf("signal=%s", signal_to_string(p->status));
3585
3586 printf(")%s\n", off);
3587
3588 if (i->main_pid == p->pid &&
3589 i->start_timestamp == p->start_timestamp &&
3590 i->exit_timestamp == p->start_timestamp)
3591 /* Let's not show this twice */
3592 i->main_pid = 0;
3593
3594 if (p->pid == i->control_pid)
3595 i->control_pid = 0;
3596 }
3597
3598 if (i->main_pid > 0 || i->control_pid > 0) {
3599 if (i->main_pid > 0) {
3600 printf(" Main PID: "PID_FMT, i->main_pid);
3601
3602 if (i->running) {
3603 _cleanup_free_ char *comm = NULL;
3604 get_process_comm(i->main_pid, &comm);
3605 if (comm)
3606 printf(" (%s)", comm);
3607 } else if (i->exit_code > 0) {
3608 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3609
3610 if (i->exit_code == CLD_EXITED) {
3611 const char *c;
3612
3613 printf("status=%i", i->exit_status);
3614
3615 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3616 if (c)
3617 printf("/%s", c);
3618
3619 } else
3620 printf("signal=%s", signal_to_string(i->exit_status));
3621 printf(")");
3622 }
3623
3624 if (i->control_pid > 0)
3625 printf(";");
3626 }
3627
3628 if (i->control_pid > 0) {
3629 _cleanup_free_ char *c = NULL;
3630
3631 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3632
3633 get_process_comm(i->control_pid, &c);
3634 if (c)
3635 printf(" (%s)", c);
3636 }
3637
3638 printf("\n");
3639 }
3640
3641 if (i->status_text)
3642 printf(" Status: \"%s\"\n", i->status_text);
3643 if (i->status_errno > 0)
3644 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3645
3646 if (i->tasks_current != (uint64_t) -1) {
3647 printf(" Tasks: %" PRIu64, i->tasks_current);
3648
3649 if (i->tasks_max != (uint64_t) -1)
3650 printf(" (limit: %" PRIi64 ")\n", i->tasks_max);
3651 else
3652 printf("\n");
3653 }
3654
3655 if (i->memory_current != (uint64_t) -1) {
3656 char buf[FORMAT_BYTES_MAX];
3657
3658 printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
3659
3660 if (i->memory_limit != (uint64_t) -1)
3661 printf(" (limit: %s)\n", format_bytes(buf, sizeof(buf), i->memory_limit));
3662 else
3663 printf("\n");
3664 }
3665
3666 if (i->cpu_usage_nsec != (uint64_t) -1) {
3667 char buf[FORMAT_TIMESPAN_MAX];
3668 printf(" CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
3669 }
3670
3671 if (i->control_group &&
3672 (i->main_pid > 0 || i->control_pid > 0 ||
3673 (!IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group) == 0))) {
3674 unsigned c;
3675
3676 printf(" CGroup: %s\n", i->control_group);
3677
3678 if (IN_SET(arg_transport,
3679 BUS_TRANSPORT_LOCAL,
3680 BUS_TRANSPORT_MACHINE)) {
3681 unsigned k = 0;
3682 pid_t extra[2];
3683 static const char prefix[] = " ";
3684
3685 c = columns();
3686 if (c > sizeof(prefix) - 1)
3687 c -= sizeof(prefix) - 1;
3688 else
3689 c = 0;
3690
3691 if (i->main_pid > 0)
3692 extra[k++] = i->main_pid;
3693
3694 if (i->control_pid > 0)
3695 extra[k++] = i->control_pid;
3696
3697 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
3698 }
3699 }
3700
3701 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL)
3702 show_journal_by_unit(
3703 stdout,
3704 i->id,
3705 arg_output,
3706 0,
3707 i->inactive_exit_timestamp_monotonic,
3708 arg_lines,
3709 getuid(),
3710 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
3711 SD_JOURNAL_LOCAL_ONLY,
3712 arg_scope == UNIT_FILE_SYSTEM,
3713 ellipsized);
3714
3715 if (i->need_daemon_reload)
3716 warn_unit_file_changed(i->id);
3717 }
3718
3719 static void show_unit_help(UnitStatusInfo *i) {
3720 char **p;
3721
3722 assert(i);
3723
3724 if (!i->documentation) {
3725 log_info("Documentation for %s not known.", i->id);
3726 return;
3727 }
3728
3729 STRV_FOREACH(p, i->documentation)
3730 if (startswith(*p, "man:"))
3731 show_man_page(*p + 4, false);
3732 else
3733 log_info("Can't show: %s", *p);
3734 }
3735
3736 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3737 int r;
3738
3739 assert(name);
3740 assert(m);
3741 assert(i);
3742
3743 switch (contents[0]) {
3744
3745 case SD_BUS_TYPE_STRING: {
3746 const char *s;
3747
3748 r = sd_bus_message_read(m, "s", &s);
3749 if (r < 0)
3750 return bus_log_parse_error(r);
3751
3752 if (!isempty(s)) {
3753 if (streq(name, "Id"))
3754 i->id = s;
3755 else if (streq(name, "LoadState"))
3756 i->load_state = s;
3757 else if (streq(name, "ActiveState"))
3758 i->active_state = s;
3759 else if (streq(name, "SubState"))
3760 i->sub_state = s;
3761 else if (streq(name, "Description"))
3762 i->description = s;
3763 else if (streq(name, "FragmentPath"))
3764 i->fragment_path = s;
3765 else if (streq(name, "SourcePath"))
3766 i->source_path = s;
3767 #ifndef NOLEGACY
3768 else if (streq(name, "DefaultControlGroup")) {
3769 const char *e;
3770 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3771 if (e)
3772 i->control_group = e;
3773 }
3774 #endif
3775 else if (streq(name, "ControlGroup"))
3776 i->control_group = s;
3777 else if (streq(name, "StatusText"))
3778 i->status_text = s;
3779 else if (streq(name, "PIDFile"))
3780 i->pid_file = s;
3781 else if (streq(name, "SysFSPath"))
3782 i->sysfs_path = s;
3783 else if (streq(name, "Where"))
3784 i->where = s;
3785 else if (streq(name, "What"))
3786 i->what = s;
3787 else if (streq(name, "Following"))
3788 i->following = s;
3789 else if (streq(name, "UnitFileState"))
3790 i->unit_file_state = s;
3791 else if (streq(name, "UnitFilePreset"))
3792 i->unit_file_preset = s;
3793 else if (streq(name, "Result"))
3794 i->result = s;
3795 }
3796
3797 break;
3798 }
3799
3800 case SD_BUS_TYPE_BOOLEAN: {
3801 int b;
3802
3803 r = sd_bus_message_read(m, "b", &b);
3804 if (r < 0)
3805 return bus_log_parse_error(r);
3806
3807 if (streq(name, "Accept"))
3808 i->accept = b;
3809 else if (streq(name, "NeedDaemonReload"))
3810 i->need_daemon_reload = b;
3811 else if (streq(name, "ConditionResult"))
3812 i->condition_result = b;
3813 else if (streq(name, "AssertResult"))
3814 i->assert_result = b;
3815
3816 break;
3817 }
3818
3819 case SD_BUS_TYPE_UINT32: {
3820 uint32_t u;
3821
3822 r = sd_bus_message_read(m, "u", &u);
3823 if (r < 0)
3824 return bus_log_parse_error(r);
3825
3826 if (streq(name, "MainPID")) {
3827 if (u > 0) {
3828 i->main_pid = (pid_t) u;
3829 i->running = true;
3830 }
3831 } else if (streq(name, "ControlPID"))
3832 i->control_pid = (pid_t) u;
3833 else if (streq(name, "ExecMainPID")) {
3834 if (u > 0)
3835 i->main_pid = (pid_t) u;
3836 } else if (streq(name, "NAccepted"))
3837 i->n_accepted = u;
3838 else if (streq(name, "NConnections"))
3839 i->n_connections = u;
3840
3841 break;
3842 }
3843
3844 case SD_BUS_TYPE_INT32: {
3845 int32_t j;
3846
3847 r = sd_bus_message_read(m, "i", &j);
3848 if (r < 0)
3849 return bus_log_parse_error(r);
3850
3851 if (streq(name, "ExecMainCode"))
3852 i->exit_code = (int) j;
3853 else if (streq(name, "ExecMainStatus"))
3854 i->exit_status = (int) j;
3855 else if (streq(name, "StatusErrno"))
3856 i->status_errno = (int) j;
3857
3858 break;
3859 }
3860
3861 case SD_BUS_TYPE_UINT64: {
3862 uint64_t u;
3863
3864 r = sd_bus_message_read(m, "t", &u);
3865 if (r < 0)
3866 return bus_log_parse_error(r);
3867
3868 if (streq(name, "ExecMainStartTimestamp"))
3869 i->start_timestamp = (usec_t) u;
3870 else if (streq(name, "ExecMainExitTimestamp"))
3871 i->exit_timestamp = (usec_t) u;
3872 else if (streq(name, "ActiveEnterTimestamp"))
3873 i->active_enter_timestamp = (usec_t) u;
3874 else if (streq(name, "InactiveEnterTimestamp"))
3875 i->inactive_enter_timestamp = (usec_t) u;
3876 else if (streq(name, "InactiveExitTimestamp"))
3877 i->inactive_exit_timestamp = (usec_t) u;
3878 else if (streq(name, "InactiveExitTimestampMonotonic"))
3879 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3880 else if (streq(name, "ActiveExitTimestamp"))
3881 i->active_exit_timestamp = (usec_t) u;
3882 else if (streq(name, "ConditionTimestamp"))
3883 i->condition_timestamp = (usec_t) u;
3884 else if (streq(name, "AssertTimestamp"))
3885 i->assert_timestamp = (usec_t) u;
3886 else if (streq(name, "MemoryCurrent"))
3887 i->memory_current = u;
3888 else if (streq(name, "MemoryLimit"))
3889 i->memory_limit = u;
3890 else if (streq(name, "TasksCurrent"))
3891 i->tasks_current = u;
3892 else if (streq(name, "TasksMax"))
3893 i->tasks_max = u;
3894 else if (streq(name, "CPUUsageNSec"))
3895 i->cpu_usage_nsec = u;
3896
3897 break;
3898 }
3899
3900 case SD_BUS_TYPE_ARRAY:
3901
3902 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3903 _cleanup_free_ ExecStatusInfo *info = NULL;
3904
3905 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3906 if (r < 0)
3907 return bus_log_parse_error(r);
3908
3909 info = new0(ExecStatusInfo, 1);
3910 if (!info)
3911 return log_oom();
3912
3913 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3914
3915 info->name = strdup(name);
3916 if (!info->name)
3917 return log_oom();
3918
3919 LIST_PREPEND(exec, i->exec, info);
3920
3921 info = new0(ExecStatusInfo, 1);
3922 if (!info)
3923 return log_oom();
3924 }
3925
3926 if (r < 0)
3927 return bus_log_parse_error(r);
3928
3929 r = sd_bus_message_exit_container(m);
3930 if (r < 0)
3931 return bus_log_parse_error(r);
3932
3933 return 0;
3934
3935 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3936 const char *type, *path;
3937
3938 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3939 if (r < 0)
3940 return bus_log_parse_error(r);
3941
3942 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3943
3944 r = strv_extend(&i->listen, type);
3945 if (r < 0)
3946 return r;
3947
3948 r = strv_extend(&i->listen, path);
3949 if (r < 0)
3950 return r;
3951 }
3952 if (r < 0)
3953 return bus_log_parse_error(r);
3954
3955 r = sd_bus_message_exit_container(m);
3956 if (r < 0)
3957 return bus_log_parse_error(r);
3958
3959 return 0;
3960
3961 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3962
3963 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3964 if (r < 0)
3965 return bus_log_parse_error(r);
3966
3967 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3968
3969 r = sd_bus_message_read_strv(m, &i->documentation);
3970 if (r < 0)
3971 return bus_log_parse_error(r);
3972
3973 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3974 const char *cond, *param;
3975 int trigger, negate;
3976 int32_t state;
3977
3978 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3979 if (r < 0)
3980 return bus_log_parse_error(r);
3981
3982 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3983 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3984 if (state < 0 && (!trigger || !i->failed_condition)) {
3985 i->failed_condition = cond;
3986 i->failed_condition_trigger = trigger;
3987 i->failed_condition_negate = negate;
3988 i->failed_condition_parameter = param;
3989 }
3990 }
3991 if (r < 0)
3992 return bus_log_parse_error(r);
3993
3994 r = sd_bus_message_exit_container(m);
3995 if (r < 0)
3996 return bus_log_parse_error(r);
3997
3998 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3999 const char *cond, *param;
4000 int trigger, negate;
4001 int32_t state;
4002
4003 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
4004 if (r < 0)
4005 return bus_log_parse_error(r);
4006
4007 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
4008 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
4009 if (state < 0 && (!trigger || !i->failed_assert)) {
4010 i->failed_assert = cond;
4011 i->failed_assert_trigger = trigger;
4012 i->failed_assert_negate = negate;
4013 i->failed_assert_parameter = param;
4014 }
4015 }
4016 if (r < 0)
4017 return bus_log_parse_error(r);
4018
4019 r = sd_bus_message_exit_container(m);
4020 if (r < 0)
4021 return bus_log_parse_error(r);
4022
4023 } else
4024 goto skip;
4025
4026 break;
4027
4028 case SD_BUS_TYPE_STRUCT_BEGIN:
4029
4030 if (streq(name, "LoadError")) {
4031 const char *n, *message;
4032
4033 r = sd_bus_message_read(m, "(ss)", &n, &message);
4034 if (r < 0)
4035 return bus_log_parse_error(r);
4036
4037 if (!isempty(message))
4038 i->load_error = message;
4039 } else
4040 goto skip;
4041
4042 break;
4043
4044 default:
4045 goto skip;
4046 }
4047
4048 return 0;
4049
4050 skip:
4051 r = sd_bus_message_skip(m, contents);
4052 if (r < 0)
4053 return bus_log_parse_error(r);
4054
4055 return 0;
4056 }
4057
4058 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
4059 int r;
4060
4061 assert(name);
4062 assert(m);
4063
4064 /* This is a low-level property printer, see
4065 * print_status_info() for the nicer output */
4066
4067 if (arg_properties && !strv_find(arg_properties, name)) {
4068 /* skip what we didn't read */
4069 r = sd_bus_message_skip(m, contents);
4070 return r;
4071 }
4072
4073 switch (contents[0]) {
4074
4075 case SD_BUS_TYPE_STRUCT_BEGIN:
4076
4077 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
4078 uint32_t u;
4079
4080 r = sd_bus_message_read(m, "(uo)", &u, NULL);
4081 if (r < 0)
4082 return bus_log_parse_error(r);
4083
4084 if (u > 0)
4085 printf("%s=%"PRIu32"\n", name, u);
4086 else if (arg_all)
4087 printf("%s=\n", name);
4088
4089 return 0;
4090
4091 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
4092 const char *s;
4093
4094 r = sd_bus_message_read(m, "(so)", &s, NULL);
4095 if (r < 0)
4096 return bus_log_parse_error(r);
4097
4098 if (arg_all || !isempty(s))
4099 printf("%s=%s\n", name, s);
4100
4101 return 0;
4102
4103 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
4104 const char *a = NULL, *b = NULL;
4105
4106 r = sd_bus_message_read(m, "(ss)", &a, &b);
4107 if (r < 0)
4108 return bus_log_parse_error(r);
4109
4110 if (arg_all || !isempty(a) || !isempty(b))
4111 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
4112
4113 return 0;
4114 } else if (streq_ptr(name, "SystemCallFilter")) {
4115 _cleanup_strv_free_ char **l = NULL;
4116 int whitelist;
4117
4118 r = sd_bus_message_enter_container(m, 'r', "bas");
4119 if (r < 0)
4120 return bus_log_parse_error(r);
4121
4122 r = sd_bus_message_read(m, "b", &whitelist);
4123 if (r < 0)
4124 return bus_log_parse_error(r);
4125
4126 r = sd_bus_message_read_strv(m, &l);
4127 if (r < 0)
4128 return bus_log_parse_error(r);
4129
4130 r = sd_bus_message_exit_container(m);
4131 if (r < 0)
4132 return bus_log_parse_error(r);
4133
4134 if (arg_all || whitelist || !strv_isempty(l)) {
4135 bool first = true;
4136 char **i;
4137
4138 fputs(name, stdout);
4139 fputc('=', stdout);
4140
4141 if (!whitelist)
4142 fputc('~', stdout);
4143
4144 STRV_FOREACH(i, l) {
4145 if (first)
4146 first = false;
4147 else
4148 fputc(' ', stdout);
4149
4150 fputs(*i, stdout);
4151 }
4152 fputc('\n', stdout);
4153 }
4154
4155 return 0;
4156 }
4157
4158 break;
4159
4160 case SD_BUS_TYPE_ARRAY:
4161
4162 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4163 const char *path;
4164 int ignore;
4165
4166 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4167 if (r < 0)
4168 return bus_log_parse_error(r);
4169
4170 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4171 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4172
4173 if (r < 0)
4174 return bus_log_parse_error(r);
4175
4176 r = sd_bus_message_exit_container(m);
4177 if (r < 0)
4178 return bus_log_parse_error(r);
4179
4180 return 0;
4181
4182 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4183 const char *type, *path;
4184
4185 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4186 if (r < 0)
4187 return bus_log_parse_error(r);
4188
4189 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4190 printf("%s=%s\n", type, path);
4191 if (r < 0)
4192 return bus_log_parse_error(r);
4193
4194 r = sd_bus_message_exit_container(m);
4195 if (r < 0)
4196 return bus_log_parse_error(r);
4197
4198 return 0;
4199
4200 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4201 const char *type, *path;
4202
4203 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4204 if (r < 0)
4205 return bus_log_parse_error(r);
4206
4207 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4208 printf("Listen%s=%s\n", type, path);
4209 if (r < 0)
4210 return bus_log_parse_error(r);
4211
4212 r = sd_bus_message_exit_container(m);
4213 if (r < 0)
4214 return bus_log_parse_error(r);
4215
4216 return 0;
4217
4218 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4219 const char *base;
4220 uint64_t value, next_elapse;
4221
4222 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4223 if (r < 0)
4224 return bus_log_parse_error(r);
4225
4226 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4227 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4228
4229 printf("%s={ value=%s ; next_elapse=%s }\n",
4230 base,
4231 format_timespan(timespan1, sizeof(timespan1), value, 0),
4232 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4233 }
4234 if (r < 0)
4235 return bus_log_parse_error(r);
4236
4237 r = sd_bus_message_exit_container(m);
4238 if (r < 0)
4239 return bus_log_parse_error(r);
4240
4241 return 0;
4242
4243 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4244 ExecStatusInfo info = {};
4245
4246 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4247 if (r < 0)
4248 return bus_log_parse_error(r);
4249
4250 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4251 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4252 _cleanup_free_ char *tt;
4253
4254 tt = strv_join(info.argv, " ");
4255
4256 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }\n",
4257 name,
4258 strna(info.path),
4259 strna(tt),
4260 yes_no(info.ignore),
4261 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4262 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4263 info.pid,
4264 sigchld_code_to_string(info.code),
4265 info.status,
4266 info.code == CLD_EXITED ? "" : "/",
4267 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4268
4269 free(info.path);
4270 strv_free(info.argv);
4271 zero(info);
4272 }
4273
4274 r = sd_bus_message_exit_container(m);
4275 if (r < 0)
4276 return bus_log_parse_error(r);
4277
4278 return 0;
4279
4280 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4281 const char *path, *rwm;
4282
4283 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4284 if (r < 0)
4285 return bus_log_parse_error(r);
4286
4287 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4288 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4289 if (r < 0)
4290 return bus_log_parse_error(r);
4291
4292 r = sd_bus_message_exit_container(m);
4293 if (r < 0)
4294 return bus_log_parse_error(r);
4295
4296 return 0;
4297
4298 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4299 const char *path;
4300 uint64_t weight;
4301
4302 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4303 if (r < 0)
4304 return bus_log_parse_error(r);
4305
4306 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4307 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4308 if (r < 0)
4309 return bus_log_parse_error(r);
4310
4311 r = sd_bus_message_exit_container(m);
4312 if (r < 0)
4313 return bus_log_parse_error(r);
4314
4315 return 0;
4316
4317 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4318 const char *path;
4319 uint64_t bandwidth;
4320
4321 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4322 if (r < 0)
4323 return bus_log_parse_error(r);
4324
4325 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4326 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4327 if (r < 0)
4328 return bus_log_parse_error(r);
4329
4330 r = sd_bus_message_exit_container(m);
4331 if (r < 0)
4332 return bus_log_parse_error(r);
4333
4334 return 0;
4335 }
4336
4337 break;
4338 }
4339
4340 r = bus_print_property(name, m, arg_all);
4341 if (r < 0)
4342 return bus_log_parse_error(r);
4343
4344 if (r == 0) {
4345 r = sd_bus_message_skip(m, contents);
4346 if (r < 0)
4347 return bus_log_parse_error(r);
4348
4349 if (arg_all)
4350 printf("%s=[unprintable]\n", name);
4351 }
4352
4353 return 0;
4354 }
4355
4356 static int show_one(
4357 const char *verb,
4358 sd_bus *bus,
4359 const char *path,
4360 bool show_properties,
4361 bool *new_line,
4362 bool *ellipsized) {
4363
4364 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4365 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4366 UnitStatusInfo info = {
4367 .memory_current = (uint64_t) -1,
4368 .memory_limit = (uint64_t) -1,
4369 .cpu_usage_nsec = (uint64_t) -1,
4370 .tasks_current = (uint64_t) -1,
4371 .tasks_max = (uint64_t) -1,
4372 };
4373 ExecStatusInfo *p;
4374 int r;
4375
4376 assert(path);
4377 assert(new_line);
4378
4379 log_debug("Showing one %s", path);
4380
4381 r = sd_bus_call_method(
4382 bus,
4383 "org.freedesktop.systemd1",
4384 path,
4385 "org.freedesktop.DBus.Properties",
4386 "GetAll",
4387 &error,
4388 &reply,
4389 "s", "");
4390 if (r < 0)
4391 return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
4392
4393 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4394 if (r < 0)
4395 return bus_log_parse_error(r);
4396
4397 if (*new_line)
4398 printf("\n");
4399
4400 *new_line = true;
4401
4402 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4403 const char *name, *contents;
4404
4405 r = sd_bus_message_read(reply, "s", &name);
4406 if (r < 0)
4407 return bus_log_parse_error(r);
4408
4409 r = sd_bus_message_peek_type(reply, NULL, &contents);
4410 if (r < 0)
4411 return bus_log_parse_error(r);
4412
4413 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4414 if (r < 0)
4415 return bus_log_parse_error(r);
4416
4417 if (show_properties)
4418 r = print_property(name, reply, contents);
4419 else
4420 r = status_property(name, reply, &info, contents);
4421 if (r < 0)
4422 return r;
4423
4424 r = sd_bus_message_exit_container(reply);
4425 if (r < 0)
4426 return bus_log_parse_error(r);
4427
4428 r = sd_bus_message_exit_container(reply);
4429 if (r < 0)
4430 return bus_log_parse_error(r);
4431 }
4432 if (r < 0)
4433 return bus_log_parse_error(r);
4434
4435 r = sd_bus_message_exit_container(reply);
4436 if (r < 0)
4437 return bus_log_parse_error(r);
4438
4439 r = 0;
4440
4441 if (!show_properties) {
4442 if (streq(verb, "help"))
4443 show_unit_help(&info);
4444 else
4445 print_status_info(&info, ellipsized);
4446 }
4447
4448 strv_free(info.documentation);
4449 strv_free(info.dropin_paths);
4450 strv_free(info.listen);
4451
4452 if (!streq_ptr(info.active_state, "active") &&
4453 !streq_ptr(info.active_state, "reloading") &&
4454 streq(verb, "status")) {
4455 /* According to LSB: "program not running" */
4456 /* 0: program is running or service is OK
4457 * 1: program is dead and /run PID file exists
4458 * 2: program is dead and /run/lock lock file exists
4459 * 3: program is not running
4460 * 4: program or service status is unknown
4461 */
4462 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4463 r = 1;
4464 else
4465 r = 3;
4466 }
4467
4468 while ((p = info.exec)) {
4469 LIST_REMOVE(exec, info.exec, p);
4470 exec_status_info_free(p);
4471 }
4472
4473 return r;
4474 }
4475
4476 static int get_unit_dbus_path_by_pid(
4477 sd_bus *bus,
4478 uint32_t pid,
4479 char **unit) {
4480
4481 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4482 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4483 char *u;
4484 int r;
4485
4486 r = sd_bus_call_method(
4487 bus,
4488 "org.freedesktop.systemd1",
4489 "/org/freedesktop/systemd1",
4490 "org.freedesktop.systemd1.Manager",
4491 "GetUnitByPID",
4492 &error,
4493 &reply,
4494 "u", pid);
4495 if (r < 0)
4496 return log_error_errno(r, "Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
4497
4498 r = sd_bus_message_read(reply, "o", &u);
4499 if (r < 0)
4500 return bus_log_parse_error(r);
4501
4502 u = strdup(u);
4503 if (!u)
4504 return log_oom();
4505
4506 *unit = u;
4507 return 0;
4508 }
4509
4510 static int show_all(
4511 const char* verb,
4512 sd_bus *bus,
4513 bool show_properties,
4514 bool *new_line,
4515 bool *ellipsized) {
4516
4517 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4518 _cleanup_free_ UnitInfo *unit_infos = NULL;
4519 const UnitInfo *u;
4520 unsigned c;
4521 int r, ret = 0;
4522
4523 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4524 if (r < 0)
4525 return r;
4526
4527 pager_open_if_enabled();
4528
4529 c = (unsigned) r;
4530
4531 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4532
4533 for (u = unit_infos; u < unit_infos + c; u++) {
4534 _cleanup_free_ char *p = NULL;
4535
4536 p = unit_dbus_path_from_name(u->id);
4537 if (!p)
4538 return log_oom();
4539
4540 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4541 if (r < 0)
4542 return r;
4543 else if (r > 0 && ret == 0)
4544 ret = r;
4545 }
4546
4547 return ret;
4548 }
4549
4550 static int show_system_status(sd_bus *bus) {
4551 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4552 _cleanup_free_ char *hn = NULL;
4553 _cleanup_(machine_info_clear) struct machine_info mi = {};
4554 const char *on, *off;
4555 int r;
4556
4557 hn = gethostname_malloc();
4558 if (!hn)
4559 return log_oom();
4560
4561 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4562 if (r < 0)
4563 return log_error_errno(r, "Failed to read server status: %m");
4564
4565 if (streq_ptr(mi.state, "degraded")) {
4566 on = ansi_highlight_red();
4567 off = ansi_normal();
4568 } else if (!streq_ptr(mi.state, "running")) {
4569 on = ansi_highlight_yellow();
4570 off = ansi_normal();
4571 } else
4572 on = off = "";
4573
4574 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4575
4576 printf(" State: %s%s%s\n",
4577 on, strna(mi.state), off);
4578
4579 printf(" Jobs: %u queued\n", mi.n_jobs);
4580 printf(" Failed: %u units\n", mi.n_failed_units);
4581
4582 printf(" Since: %s; %s\n",
4583 format_timestamp(since2, sizeof(since2), mi.timestamp),
4584 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4585
4586 printf(" CGroup: %s\n", mi.control_group ?: "/");
4587 if (IN_SET(arg_transport,
4588 BUS_TRANSPORT_LOCAL,
4589 BUS_TRANSPORT_MACHINE)) {
4590 static const char prefix[] = " ";
4591 unsigned c;
4592
4593 c = columns();
4594 if (c > sizeof(prefix) - 1)
4595 c -= sizeof(prefix) - 1;
4596 else
4597 c = 0;
4598
4599 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
4600 }
4601
4602 return 0;
4603 }
4604
4605 static int show(char **args) {
4606 bool show_properties, show_status, new_line = false;
4607 bool ellipsized = false;
4608 int r, ret = 0;
4609 sd_bus *bus;
4610
4611 assert(args);
4612
4613 show_properties = streq(args[0], "show");
4614 show_status = streq(args[0], "status");
4615
4616 if (show_properties)
4617 pager_open_if_enabled();
4618
4619 if (show_status)
4620 /* Increase max number of open files to 16K if we can, we
4621 * might needs this when browsing journal files, which might
4622 * be split up into many files. */
4623 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
4624
4625 r = acquire_bus(BUS_MANAGER, &bus);
4626 if (r < 0)
4627 return r;
4628
4629 /* If no argument is specified inspect the manager itself */
4630 if (show_properties && strv_length(args) <= 1)
4631 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4632
4633 if (show_status && strv_length(args) <= 1) {
4634
4635 pager_open_if_enabled();
4636 show_system_status(bus);
4637 new_line = true;
4638
4639 if (arg_all)
4640 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4641 } else {
4642 _cleanup_free_ char **patterns = NULL;
4643 char **name;
4644
4645 STRV_FOREACH(name, strv_skip(args, 1)) {
4646 _cleanup_free_ char *unit = NULL;
4647 uint32_t id;
4648
4649 if (safe_atou32(*name, &id) < 0) {
4650 if (strv_push(&patterns, *name) < 0)
4651 return log_oom();
4652
4653 continue;
4654 } else if (show_properties) {
4655 /* Interpret as job id */
4656 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4657 return log_oom();
4658
4659 } else {
4660 /* Interpret as PID */
4661 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4662 if (r < 0) {
4663 ret = r;
4664 continue;
4665 }
4666 }
4667
4668 r = show_one(args[0], bus, unit, show_properties,
4669 &new_line, &ellipsized);
4670 if (r < 0)
4671 return r;
4672 else if (r > 0 && ret == 0)
4673 ret = r;
4674 }
4675
4676 if (!strv_isempty(patterns)) {
4677 _cleanup_strv_free_ char **names = NULL;
4678
4679 r = expand_names(bus, patterns, NULL, &names);
4680 if (r < 0)
4681 return log_error_errno(r, "Failed to expand names: %m");
4682
4683 STRV_FOREACH(name, names) {
4684 _cleanup_free_ char *unit;
4685
4686 unit = unit_dbus_path_from_name(*name);
4687 if (!unit)
4688 return log_oom();
4689
4690 r = show_one(args[0], bus, unit, show_properties,
4691 &new_line, &ellipsized);
4692 if (r < 0)
4693 return r;
4694 else if (r > 0 && ret == 0)
4695 ret = r;
4696 }
4697 }
4698 }
4699
4700 if (ellipsized && !arg_quiet)
4701 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4702
4703 return ret;
4704 }
4705
4706 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4707 int r;
4708
4709 assert(user_home);
4710 assert(user_runtime);
4711 assert(lp);
4712
4713 if (arg_scope == UNIT_FILE_USER) {
4714 r = user_config_home(user_home);
4715 if (r < 0)
4716 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4717 else if (r == 0)
4718 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4719
4720 r = user_runtime_dir(user_runtime);
4721 if (r < 0)
4722 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4723 else if (r == 0)
4724 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4725 }
4726
4727 r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
4728 if (r < 0)
4729 return log_error_errno(r, "Failed to query unit lookup paths: %m");
4730
4731 return 0;
4732 }
4733
4734 static int cat_file(const char *filename, bool newline) {
4735 _cleanup_close_ int fd;
4736
4737 fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4738 if (fd < 0)
4739 return -errno;
4740
4741 printf("%s%s# %s%s\n",
4742 newline ? "\n" : "",
4743 ansi_highlight_blue(),
4744 filename,
4745 ansi_normal());
4746 fflush(stdout);
4747
4748 return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, false);
4749 }
4750
4751 static int cat(char **args) {
4752 _cleanup_free_ char *user_home = NULL;
4753 _cleanup_free_ char *user_runtime = NULL;
4754 _cleanup_lookup_paths_free_ LookupPaths lp = {};
4755 _cleanup_strv_free_ char **names = NULL;
4756 char **name;
4757 sd_bus *bus;
4758 bool first = true;
4759 int r;
4760
4761 if (arg_transport != BUS_TRANSPORT_LOCAL) {
4762 log_error("Cannot remotely cat units.");
4763 return -EINVAL;
4764 }
4765
4766 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4767 if (r < 0)
4768 return r;
4769
4770 r = acquire_bus(BUS_MANAGER, &bus);
4771 if (r < 0)
4772 return r;
4773
4774 r = expand_names(bus, strv_skip(args, 1), NULL, &names);
4775 if (r < 0)
4776 return log_error_errno(r, "Failed to expand names: %m");
4777
4778 pager_open_if_enabled();
4779
4780 STRV_FOREACH(name, names) {
4781 _cleanup_free_ char *fragment_path = NULL;
4782 _cleanup_strv_free_ char **dropin_paths = NULL;
4783 char **path;
4784
4785 r = unit_find_paths(bus, *name, &lp, &fragment_path, &dropin_paths);
4786 if (r < 0)
4787 return r;
4788 else if (r == 0)
4789 return -ENOENT;
4790
4791 if (first)
4792 first = false;
4793 else
4794 puts("");
4795
4796 if (fragment_path) {
4797 r = cat_file(fragment_path, false);
4798 if (r < 0)
4799 return log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4800 }
4801
4802 STRV_FOREACH(path, dropin_paths) {
4803 r = cat_file(*path, path == dropin_paths);
4804 if (r < 0)
4805 return log_warning_errno(r, "Failed to cat %s: %m", *path);
4806 }
4807 }
4808
4809 return 0;
4810 }
4811
4812 static int set_property(char **args) {
4813 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4814 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4815 _cleanup_free_ char *n = NULL;
4816 sd_bus *bus;
4817 char **i;
4818 int r;
4819
4820 polkit_agent_open_if_enabled();
4821
4822 r = acquire_bus(BUS_MANAGER, &bus);
4823 if (r < 0)
4824 return r;
4825
4826 r = sd_bus_message_new_method_call(
4827 bus,
4828 &m,
4829 "org.freedesktop.systemd1",
4830 "/org/freedesktop/systemd1",
4831 "org.freedesktop.systemd1.Manager",
4832 "SetUnitProperties");
4833 if (r < 0)
4834 return bus_log_create_error(r);
4835
4836 r = unit_name_mangle(args[1], UNIT_NAME_NOGLOB, &n);
4837 if (r < 0)
4838 return log_error_errno(r, "Failed to mangle unit name: %m");
4839
4840 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4841 if (r < 0)
4842 return bus_log_create_error(r);
4843
4844 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4845 if (r < 0)
4846 return bus_log_create_error(r);
4847
4848 STRV_FOREACH(i, args + 2) {
4849 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4850 if (r < 0)
4851 return bus_log_create_error(r);
4852
4853 r = bus_append_unit_property_assignment(m, *i);
4854 if (r < 0)
4855 return r;
4856
4857 r = sd_bus_message_close_container(m);
4858 if (r < 0)
4859 return bus_log_create_error(r);
4860 }
4861
4862 r = sd_bus_message_close_container(m);
4863 if (r < 0)
4864 return bus_log_create_error(r);
4865
4866 r = sd_bus_call(bus, m, 0, &error, NULL);
4867 if (r < 0)
4868 return log_error_errno(r, "Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4869
4870 return 0;
4871 }
4872
4873 static int snapshot(char **args) {
4874 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4875 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4876 _cleanup_free_ char *n = NULL, *id = NULL;
4877 const char *path;
4878 sd_bus *bus;
4879 int r;
4880
4881 polkit_agent_open_if_enabled();
4882
4883 if (strv_length(args) > 1) {
4884 r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".snapshot", &n);
4885 if (r < 0)
4886 return log_error_errno(r, "Failed to generate unit name: %m");
4887 } else {
4888 n = strdup("");
4889 if (!n)
4890 return log_oom();
4891 }
4892
4893 r = acquire_bus(BUS_MANAGER, &bus);
4894 if (r < 0)
4895 return r;
4896
4897 r = sd_bus_call_method(
4898 bus,
4899 "org.freedesktop.systemd1",
4900 "/org/freedesktop/systemd1",
4901 "org.freedesktop.systemd1.Manager",
4902 "CreateSnapshot",
4903 &error,
4904 &reply,
4905 "sb", n, false);
4906 if (r < 0)
4907 return log_error_errno(r, "Failed to create snapshot: %s", bus_error_message(&error, r));
4908
4909 r = sd_bus_message_read(reply, "o", &path);
4910 if (r < 0)
4911 return bus_log_parse_error(r);
4912
4913 r = sd_bus_get_property_string(
4914 bus,
4915 "org.freedesktop.systemd1",
4916 path,
4917 "org.freedesktop.systemd1.Unit",
4918 "Id",
4919 &error,
4920 &id);
4921 if (r < 0)
4922 return log_error_errno(r, "Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4923
4924 if (!arg_quiet)
4925 puts(id);
4926
4927 return 0;
4928 }
4929
4930 static int delete_snapshot(char **args) {
4931 _cleanup_strv_free_ char **names = NULL;
4932 sd_bus *bus;
4933 char **name;
4934 int r;
4935
4936 polkit_agent_open_if_enabled();
4937
4938 r = acquire_bus(BUS_MANAGER, &bus);
4939 if (r < 0)
4940 return r;
4941
4942 r = expand_names(bus, strv_skip(args, 1), ".snapshot", &names);
4943 if (r < 0)
4944 return log_error_errno(r, "Failed to expand names: %m");
4945
4946 STRV_FOREACH(name, names) {
4947 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4948 int q;
4949
4950 q = sd_bus_call_method(
4951 bus,
4952 "org.freedesktop.systemd1",
4953 "/org/freedesktop/systemd1",
4954 "org.freedesktop.systemd1.Manager",
4955 "RemoveSnapshot",
4956 &error,
4957 NULL,
4958 "s", *name);
4959 if (q < 0) {
4960 log_error_errno(q, "Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4961 if (r == 0)
4962 r = q;
4963 }
4964 }
4965
4966 return r;
4967 }
4968
4969 static int daemon_reload(char **args) {
4970 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4971 const char *method;
4972 sd_bus *bus;
4973 int r;
4974
4975 polkit_agent_open_if_enabled();
4976
4977 r = acquire_bus(BUS_MANAGER, &bus);
4978 if (r < 0)
4979 return r;
4980
4981 if (arg_action == ACTION_RELOAD)
4982 method = "Reload";
4983 else if (arg_action == ACTION_REEXEC)
4984 method = "Reexecute";
4985 else {
4986 assert(arg_action == ACTION_SYSTEMCTL);
4987
4988 method =
4989 streq(args[0], "clear-jobs") ||
4990 streq(args[0], "cancel") ? "ClearJobs" :
4991 streq(args[0], "daemon-reexec") ? "Reexecute" :
4992 streq(args[0], "reset-failed") ? "ResetFailed" :
4993 streq(args[0], "halt") ? "Halt" :
4994 streq(args[0], "poweroff") ? "PowerOff" :
4995 streq(args[0], "reboot") ? "Reboot" :
4996 streq(args[0], "kexec") ? "KExec" :
4997 streq(args[0], "exit") ? "Exit" :
4998 /* "daemon-reload" */ "Reload";
4999 }
5000
5001 r = sd_bus_call_method(
5002 bus,
5003 "org.freedesktop.systemd1",
5004 "/org/freedesktop/systemd1",
5005 "org.freedesktop.systemd1.Manager",
5006 method,
5007 &error,
5008 NULL,
5009 NULL);
5010 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
5011 /* There's always a fallback possible for
5012 * legacy actions. */
5013 r = -EADDRNOTAVAIL;
5014 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
5015 /* On reexecution, we expect a disconnect, not a
5016 * reply */
5017 r = 0;
5018 else if (r < 0)
5019 return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
5020
5021 return r < 0 ? r : 0;
5022 }
5023
5024 static int reset_failed(char **args) {
5025 _cleanup_strv_free_ char **names = NULL;
5026 sd_bus *bus;
5027 char **name;
5028 int r, q;
5029
5030 if (strv_length(args) <= 1)
5031 return daemon_reload(args);
5032
5033 polkit_agent_open_if_enabled();
5034
5035 r = acquire_bus(BUS_MANAGER, &bus);
5036 if (r < 0)
5037 return r;
5038
5039 r = expand_names(bus, strv_skip(args, 1), NULL, &names);
5040 if (r < 0)
5041 return log_error_errno(r, "Failed to expand names: %m");
5042
5043 STRV_FOREACH(name, names) {
5044 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5045
5046 q = sd_bus_call_method(
5047 bus,
5048 "org.freedesktop.systemd1",
5049 "/org/freedesktop/systemd1",
5050 "org.freedesktop.systemd1.Manager",
5051 "ResetFailedUnit",
5052 &error,
5053 NULL,
5054 "s", *name);
5055 if (q < 0) {
5056 log_error_errno(q, "Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
5057 if (r == 0)
5058 r = q;
5059 }
5060 }
5061
5062 return r;
5063 }
5064
5065 static int show_environment(char **args) {
5066 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5067 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5068 const char *text;
5069 sd_bus *bus;
5070 int r;
5071
5072 pager_open_if_enabled();
5073
5074 r = acquire_bus(BUS_MANAGER, &bus);
5075 if (r < 0)
5076 return r;
5077
5078 r = sd_bus_get_property(
5079 bus,
5080 "org.freedesktop.systemd1",
5081 "/org/freedesktop/systemd1",
5082 "org.freedesktop.systemd1.Manager",
5083 "Environment",
5084 &error,
5085 &reply,
5086 "as");
5087 if (r < 0)
5088 return log_error_errno(r, "Failed to get environment: %s", bus_error_message(&error, r));
5089
5090 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
5091 if (r < 0)
5092 return bus_log_parse_error(r);
5093
5094 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
5095 puts(text);
5096 if (r < 0)
5097 return bus_log_parse_error(r);
5098
5099 r = sd_bus_message_exit_container(reply);
5100 if (r < 0)
5101 return bus_log_parse_error(r);
5102
5103 return 0;
5104 }
5105
5106 static int switch_root(char **args) {
5107 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5108 _cleanup_free_ char *cmdline_init = NULL;
5109 const char *root, *init;
5110 sd_bus *bus;
5111 unsigned l;
5112 int r;
5113
5114 if (arg_transport != BUS_TRANSPORT_LOCAL) {
5115 log_error("Cannot switch root remotely.");
5116 return -EINVAL;
5117 }
5118
5119 l = strv_length(args);
5120 if (l < 2 || l > 3) {
5121 log_error("Wrong number of arguments.");
5122 return -EINVAL;
5123 }
5124
5125 root = args[1];
5126
5127 if (l >= 3)
5128 init = args[2];
5129 else {
5130 r = parse_env_file("/proc/cmdline", WHITESPACE,
5131 "init", &cmdline_init,
5132 NULL);
5133 if (r < 0)
5134 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
5135
5136 init = cmdline_init;
5137 }
5138
5139 if (isempty(init))
5140 init = NULL;
5141
5142 if (init) {
5143 const char *root_systemd_path = NULL, *root_init_path = NULL;
5144
5145 root_systemd_path = strjoina(root, "/" SYSTEMD_BINARY_PATH);
5146 root_init_path = strjoina(root, "/", init);
5147
5148 /* If the passed init is actually the same as the
5149 * systemd binary, then let's suppress it. */
5150 if (files_same(root_init_path, root_systemd_path) > 0)
5151 init = NULL;
5152 }
5153
5154 r = acquire_bus(BUS_MANAGER, &bus);
5155 if (r < 0)
5156 return r;
5157
5158 log_debug("Switching root - root: %s; init: %s", root, strna(init));
5159
5160 r = sd_bus_call_method(
5161 bus,
5162 "org.freedesktop.systemd1",
5163 "/org/freedesktop/systemd1",
5164 "org.freedesktop.systemd1.Manager",
5165 "SwitchRoot",
5166 &error,
5167 NULL,
5168 "ss", root, init);
5169 if (r < 0)
5170 return log_error_errno(r, "Failed to switch root: %s", bus_error_message(&error, r));
5171
5172 return 0;
5173 }
5174
5175 static int set_environment(char **args) {
5176 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5177 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5178 const char *method;
5179 sd_bus *bus;
5180 int r;
5181
5182 assert(args);
5183
5184 polkit_agent_open_if_enabled();
5185
5186 r = acquire_bus(BUS_MANAGER, &bus);
5187 if (r < 0)
5188 return r;
5189
5190 method = streq(args[0], "set-environment")
5191 ? "SetEnvironment"
5192 : "UnsetEnvironment";
5193
5194 r = sd_bus_message_new_method_call(
5195 bus,
5196 &m,
5197 "org.freedesktop.systemd1",
5198 "/org/freedesktop/systemd1",
5199 "org.freedesktop.systemd1.Manager",
5200 method);
5201 if (r < 0)
5202 return bus_log_create_error(r);
5203
5204 r = sd_bus_message_append_strv(m, strv_skip(args, 1));
5205 if (r < 0)
5206 return bus_log_create_error(r);
5207
5208 r = sd_bus_call(bus, m, 0, &error, NULL);
5209 if (r < 0)
5210 return log_error_errno(r, "Failed to set environment: %s", bus_error_message(&error, r));
5211
5212 return 0;
5213 }
5214
5215 static int import_environment(char **args) {
5216 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5217 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5218 sd_bus *bus;
5219 int r;
5220
5221 polkit_agent_open_if_enabled();
5222
5223 r = acquire_bus(BUS_MANAGER, &bus);
5224 if (r < 0)
5225 return r;
5226
5227 r = sd_bus_message_new_method_call(
5228 bus,
5229 &m,
5230 "org.freedesktop.systemd1",
5231 "/org/freedesktop/systemd1",
5232 "org.freedesktop.systemd1.Manager",
5233 "SetEnvironment");
5234 if (r < 0)
5235 return bus_log_create_error(r);
5236
5237 if (strv_isempty(strv_skip(args, 1)))
5238 r = sd_bus_message_append_strv(m, environ);
5239 else {
5240 char **a, **b;
5241
5242 r = sd_bus_message_open_container(m, 'a', "s");
5243 if (r < 0)
5244 return bus_log_create_error(r);
5245
5246 STRV_FOREACH(a, strv_skip(args, 1)) {
5247
5248 if (!env_name_is_valid(*a)) {
5249 log_error("Not a valid environment variable name: %s", *a);
5250 return -EINVAL;
5251 }
5252
5253 STRV_FOREACH(b, environ) {
5254 const char *eq;
5255
5256 eq = startswith(*b, *a);
5257 if (eq && *eq == '=') {
5258
5259 r = sd_bus_message_append(m, "s", *b);
5260 if (r < 0)
5261 return bus_log_create_error(r);
5262
5263 break;
5264 }
5265 }
5266 }
5267
5268 r = sd_bus_message_close_container(m);
5269 }
5270 if (r < 0)
5271 return bus_log_create_error(r);
5272
5273 r = sd_bus_call(bus, m, 0, &error, NULL);
5274 if (r < 0)
5275 return log_error_errno(r, "Failed to import environment: %s", bus_error_message(&error, r));
5276
5277 return 0;
5278 }
5279
5280 static int enable_sysv_units(const char *verb, char **args) {
5281 int r = 0;
5282
5283 #if defined(HAVE_SYSV_COMPAT)
5284 unsigned f = 0;
5285 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5286
5287 if (arg_scope != UNIT_FILE_SYSTEM)
5288 return 0;
5289
5290 if (!STR_IN_SET(verb,
5291 "enable",
5292 "disable",
5293 "is-enabled"))
5294 return 0;
5295
5296 /* Processes all SysV units, and reshuffles the array so that
5297 * afterwards only the native units remain */
5298
5299 r = lookup_paths_init(&paths, MANAGER_SYSTEM, false, arg_root, NULL, NULL, NULL);
5300 if (r < 0)
5301 return r;
5302
5303 r = 0;
5304 while (args[f]) {
5305 const char *name;
5306 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5307 bool found_native = false, found_sysv;
5308 unsigned c = 1;
5309 const char *argv[6] = { ROOTLIBEXECDIR "/systemd-sysv-install", NULL, NULL, NULL, NULL };
5310 char **k;
5311 int j;
5312 pid_t pid;
5313 siginfo_t status;
5314
5315 name = args[f++];
5316
5317 if (!endswith(name, ".service"))
5318 continue;
5319
5320 if (path_is_absolute(name))
5321 continue;
5322
5323 STRV_FOREACH(k, paths.unit_path) {
5324 _cleanup_free_ char *path = NULL;
5325
5326 path = path_join(arg_root, *k, name);
5327 if (!path)
5328 return log_oom();
5329
5330 found_native = access(path, F_OK) >= 0;
5331 if (found_native)
5332 break;
5333 }
5334
5335 /* If we have both a native unit and a SysV script,
5336 * enable/disable them both (below); for is-enabled, prefer the
5337 * native unit */
5338 if (found_native && streq(verb, "is-enabled"))
5339 continue;
5340
5341 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5342 if (!p)
5343 return log_oom();
5344
5345 p[strlen(p) - strlen(".service")] = 0;
5346 found_sysv = access(p, F_OK) >= 0;
5347 if (!found_sysv)
5348 continue;
5349
5350 if (found_native)
5351 log_info("Synchronizing state of %s with SysV init with %s...", name, argv[0]);
5352 else
5353 log_info("%s is not a native service, redirecting to systemd-sysv-install", name);
5354
5355 if (!isempty(arg_root))
5356 argv[c++] = q = strappend("--root=", arg_root);
5357
5358 argv[c++] = verb;
5359 argv[c++] = basename(p);
5360 argv[c] = NULL;
5361
5362 l = strv_join((char**)argv, " ");
5363 if (!l)
5364 return log_oom();
5365
5366 log_info("Executing %s", l);
5367
5368 pid = fork();
5369 if (pid < 0)
5370 return log_error_errno(errno, "Failed to fork: %m");
5371 else if (pid == 0) {
5372 /* Child */
5373
5374 (void) reset_all_signal_handlers();
5375 (void) reset_signal_mask();
5376
5377 execv(argv[0], (char**) argv);
5378 log_error_errno(r, "Failed to execute %s: %m", argv[0]);
5379 _exit(EXIT_FAILURE);
5380 }
5381
5382 j = wait_for_terminate(pid, &status);
5383 if (j < 0) {
5384 log_error_errno(j, "Failed to wait for child: %m");
5385 return j;
5386 }
5387
5388 if (status.si_code == CLD_EXITED) {
5389 if (streq(verb, "is-enabled")) {
5390 if (status.si_status == 0) {
5391 if (!arg_quiet)
5392 puts("enabled");
5393 r = 1;
5394 } else {
5395 if (!arg_quiet)
5396 puts("disabled");
5397 }
5398
5399 } else if (status.si_status != 0)
5400 return -EINVAL;
5401 } else
5402 return -EPROTO;
5403
5404 if (found_native)
5405 continue;
5406
5407 /* Remove this entry, so that we don't try enabling it as native unit */
5408 assert(f > 0);
5409 f--;
5410 assert(args[f] == name);
5411 strv_remove(args, name);
5412 }
5413
5414 #endif
5415 return r;
5416 }
5417
5418 static int mangle_names(char **original_names, char ***mangled_names) {
5419 char **i, **l, **name;
5420 int r;
5421
5422 l = i = new(char*, strv_length(original_names) + 1);
5423 if (!l)
5424 return log_oom();
5425
5426 STRV_FOREACH(name, original_names) {
5427
5428 /* When enabling units qualified path names are OK,
5429 * too, hence allow them explicitly. */
5430
5431 if (is_path(*name)) {
5432 *i = strdup(*name);
5433 if (!*i) {
5434 strv_free(l);
5435 return log_oom();
5436 }
5437 } else {
5438 r = unit_name_mangle(*name, UNIT_NAME_NOGLOB, i);
5439 if (r < 0) {
5440 strv_free(l);
5441 return log_error_errno(r, "Failed to mangle unit name: %m");
5442 }
5443 }
5444
5445 i++;
5446 }
5447
5448 *i = NULL;
5449 *mangled_names = l;
5450
5451 return 0;
5452 }
5453
5454 static int enable_unit(char **args) {
5455 _cleanup_strv_free_ char **names = NULL;
5456 const char *verb = args[0];
5457 UnitFileChange *changes = NULL;
5458 unsigned n_changes = 0;
5459 int carries_install_info = -1;
5460 int r;
5461
5462 if (!args[1])
5463 return 0;
5464
5465 r = mangle_names(args+1, &names);
5466 if (r < 0)
5467 return r;
5468
5469 r = enable_sysv_units(verb, names);
5470 if (r < 0)
5471 return r;
5472
5473 /* If the operation was fully executed by the SysV compat,
5474 * let's finish early */
5475 if (strv_isempty(names))
5476 return 0;
5477
5478 if (install_client_side()) {
5479 if (streq(verb, "enable")) {
5480 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5481 carries_install_info = r;
5482 } else if (streq(verb, "disable"))
5483 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5484 else if (streq(verb, "reenable")) {
5485 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5486 carries_install_info = r;
5487 } else if (streq(verb, "link"))
5488 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5489 else if (streq(verb, "preset")) {
5490 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5491 carries_install_info = r;
5492 } else if (streq(verb, "mask"))
5493 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5494 else if (streq(verb, "unmask"))
5495 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5496 else
5497 assert_not_reached("Unknown verb");
5498
5499 if (r < 0) {
5500 log_error_errno(r, "Operation failed: %m");
5501 goto finish;
5502 }
5503
5504 if (!arg_quiet)
5505 dump_unit_file_changes(changes, n_changes);
5506
5507 r = 0;
5508 } else {
5509 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5510 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5511 int expect_carries_install_info = false;
5512 bool send_force = true, send_preset_mode = false;
5513 const char *method;
5514 sd_bus *bus;
5515
5516 polkit_agent_open_if_enabled();
5517
5518 r = acquire_bus(BUS_MANAGER, &bus);
5519 if (r < 0)
5520 return r;
5521
5522 if (streq(verb, "enable")) {
5523 method = "EnableUnitFiles";
5524 expect_carries_install_info = true;
5525 } else if (streq(verb, "disable")) {
5526 method = "DisableUnitFiles";
5527 send_force = false;
5528 } else if (streq(verb, "reenable")) {
5529 method = "ReenableUnitFiles";
5530 expect_carries_install_info = true;
5531 } else if (streq(verb, "link"))
5532 method = "LinkUnitFiles";
5533 else if (streq(verb, "preset")) {
5534
5535 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5536 method = "PresetUnitFilesWithMode";
5537 send_preset_mode = true;
5538 } else
5539 method = "PresetUnitFiles";
5540
5541 expect_carries_install_info = true;
5542 } else if (streq(verb, "mask"))
5543 method = "MaskUnitFiles";
5544 else if (streq(verb, "unmask")) {
5545 method = "UnmaskUnitFiles";
5546 send_force = false;
5547 } else
5548 assert_not_reached("Unknown verb");
5549
5550 r = sd_bus_message_new_method_call(
5551 bus,
5552 &m,
5553 "org.freedesktop.systemd1",
5554 "/org/freedesktop/systemd1",
5555 "org.freedesktop.systemd1.Manager",
5556 method);
5557 if (r < 0)
5558 return bus_log_create_error(r);
5559
5560 r = sd_bus_message_append_strv(m, names);
5561 if (r < 0)
5562 return bus_log_create_error(r);
5563
5564 if (send_preset_mode) {
5565 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5566 if (r < 0)
5567 return bus_log_create_error(r);
5568 }
5569
5570 r = sd_bus_message_append(m, "b", arg_runtime);
5571 if (r < 0)
5572 return bus_log_create_error(r);
5573
5574 if (send_force) {
5575 r = sd_bus_message_append(m, "b", arg_force);
5576 if (r < 0)
5577 return bus_log_create_error(r);
5578 }
5579
5580 r = sd_bus_call(bus, m, 0, &error, &reply);
5581 if (r < 0)
5582 return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
5583
5584 if (expect_carries_install_info) {
5585 r = sd_bus_message_read(reply, "b", &carries_install_info);
5586 if (r < 0)
5587 return bus_log_parse_error(r);
5588 }
5589
5590 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
5591 if (r < 0)
5592 return r;
5593
5594 /* Try to reload if enabled */
5595 if (!arg_no_reload)
5596 r = daemon_reload(args);
5597 else
5598 r = 0;
5599 }
5600
5601 if (carries_install_info == 0)
5602 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5603 "using systemctl.\n"
5604 "Possible reasons for having this kind of units are:\n"
5605 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5606 " .wants/ or .requires/ directory.\n"
5607 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5608 " a requirement dependency on it.\n"
5609 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5610 " D-Bus, udev, scripted systemctl call, ...).\n");
5611
5612 if (arg_now && n_changes > 0 && STR_IN_SET(args[0], "enable", "disable", "mask")) {
5613 char *new_args[n_changes + 2];
5614 sd_bus *bus;
5615 unsigned i;
5616
5617 r = acquire_bus(BUS_MANAGER, &bus);
5618 if (r < 0)
5619 return r;
5620
5621 new_args[0] = (char*) (streq(args[0], "enable") ? "start" : "stop");
5622 for (i = 0; i < n_changes; i++)
5623 new_args[i + 1] = basename(changes[i].path);
5624 new_args[i + 1] = NULL;
5625
5626 r = start_unit(new_args);
5627 }
5628
5629 finish:
5630 unit_file_changes_free(changes, n_changes);
5631
5632 return r;
5633 }
5634
5635 static int add_dependency(char **args) {
5636 _cleanup_strv_free_ char **names = NULL;
5637 _cleanup_free_ char *target = NULL;
5638 const char *verb = args[0];
5639 UnitDependency dep;
5640 int r = 0;
5641
5642 if (!args[1])
5643 return 0;
5644
5645 r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".target", &target);
5646 if (r < 0)
5647 return log_error_errno(r, "Failed to mangle unit name: %m");
5648
5649 r = mangle_names(args+2, &names);
5650 if (r < 0)
5651 return r;
5652
5653 if (streq(verb, "add-wants"))
5654 dep = UNIT_WANTS;
5655 else if (streq(verb, "add-requires"))
5656 dep = UNIT_REQUIRES;
5657 else
5658 assert_not_reached("Unknown verb");
5659
5660 if (install_client_side()) {
5661 UnitFileChange *changes = NULL;
5662 unsigned n_changes = 0;
5663
5664 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5665
5666 if (r < 0)
5667 return log_error_errno(r, "Can't add dependency: %m");
5668
5669 if (!arg_quiet)
5670 dump_unit_file_changes(changes, n_changes);
5671
5672 unit_file_changes_free(changes, n_changes);
5673
5674 } else {
5675 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5676 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5677 sd_bus *bus;
5678
5679 polkit_agent_open_if_enabled();
5680
5681 r = acquire_bus(BUS_MANAGER, &bus);
5682 if (r < 0)
5683 return r;
5684
5685 r = sd_bus_message_new_method_call(
5686 bus,
5687 &m,
5688 "org.freedesktop.systemd1",
5689 "/org/freedesktop/systemd1",
5690 "org.freedesktop.systemd1.Manager",
5691 "AddDependencyUnitFiles");
5692 if (r < 0)
5693 return bus_log_create_error(r);
5694
5695 r = sd_bus_message_append_strv(m, names);
5696 if (r < 0)
5697 return bus_log_create_error(r);
5698
5699 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5700 if (r < 0)
5701 return bus_log_create_error(r);
5702
5703 r = sd_bus_call(bus, m, 0, &error, &reply);
5704 if (r < 0)
5705 return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
5706
5707 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
5708 if (r < 0)
5709 return r;
5710
5711 if (!arg_no_reload)
5712 r = daemon_reload(args);
5713 else
5714 r = 0;
5715 }
5716
5717 return r;
5718 }
5719
5720 static int preset_all(char **args) {
5721 UnitFileChange *changes = NULL;
5722 unsigned n_changes = 0;
5723 int r;
5724
5725 if (install_client_side()) {
5726
5727 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5728 if (r < 0) {
5729 log_error_errno(r, "Operation failed: %m");
5730 goto finish;
5731 }
5732
5733 if (!arg_quiet)
5734 dump_unit_file_changes(changes, n_changes);
5735
5736 r = 0;
5737
5738 } else {
5739 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5740 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5741 sd_bus *bus;
5742
5743 polkit_agent_open_if_enabled();
5744
5745 r = acquire_bus(BUS_MANAGER, &bus);
5746 if (r < 0)
5747 return r;
5748
5749 r = sd_bus_call_method(
5750 bus,
5751 "org.freedesktop.systemd1",
5752 "/org/freedesktop/systemd1",
5753 "org.freedesktop.systemd1.Manager",
5754 "PresetAllUnitFiles",
5755 &error,
5756 &reply,
5757 "sbb",
5758 unit_file_preset_mode_to_string(arg_preset_mode),
5759 arg_runtime,
5760 arg_force);
5761 if (r < 0)
5762 return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
5763
5764 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
5765 if (r < 0)
5766 return r;
5767
5768 if (!arg_no_reload)
5769 r = daemon_reload(args);
5770 else
5771 r = 0;
5772 }
5773
5774 finish:
5775 unit_file_changes_free(changes, n_changes);
5776
5777 return r;
5778 }
5779
5780 static int unit_is_enabled(char **args) {
5781
5782 _cleanup_strv_free_ char **names = NULL;
5783 bool enabled;
5784 char **name;
5785 int r;
5786
5787 r = mangle_names(args+1, &names);
5788 if (r < 0)
5789 return r;
5790
5791 r = enable_sysv_units(args[0], names);
5792 if (r < 0)
5793 return r;
5794
5795 enabled = r > 0;
5796
5797 if (install_client_side()) {
5798
5799 STRV_FOREACH(name, names) {
5800 UnitFileState state;
5801
5802 state = unit_file_get_state(arg_scope, arg_root, *name);
5803 if (state < 0)
5804 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5805
5806 if (IN_SET(state,
5807 UNIT_FILE_ENABLED,
5808 UNIT_FILE_ENABLED_RUNTIME,
5809 UNIT_FILE_STATIC,
5810 UNIT_FILE_INDIRECT))
5811 enabled = true;
5812
5813 if (!arg_quiet)
5814 puts(unit_file_state_to_string(state));
5815 }
5816
5817 } else {
5818 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5819 sd_bus *bus;
5820
5821 r = acquire_bus(BUS_MANAGER, &bus);
5822 if (r < 0)
5823 return r;
5824
5825 STRV_FOREACH(name, names) {
5826 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5827 const char *s;
5828
5829 r = sd_bus_call_method(
5830 bus,
5831 "org.freedesktop.systemd1",
5832 "/org/freedesktop/systemd1",
5833 "org.freedesktop.systemd1.Manager",
5834 "GetUnitFileState",
5835 &error,
5836 &reply,
5837 "s", *name);
5838 if (r < 0)
5839 return log_error_errno(r, "Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5840
5841 r = sd_bus_message_read(reply, "s", &s);
5842 if (r < 0)
5843 return bus_log_parse_error(r);
5844
5845 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5846 enabled = true;
5847
5848 if (!arg_quiet)
5849 puts(s);
5850 }
5851 }
5852
5853 return !enabled;
5854 }
5855
5856 static int is_system_running(char **args) {
5857 _cleanup_free_ char *state = NULL;
5858 sd_bus *bus;
5859 int r;
5860
5861 if (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted()) {
5862 if (!arg_quiet)
5863 puts("offline");
5864 return EXIT_FAILURE;
5865 }
5866
5867 r = acquire_bus(BUS_MANAGER, &bus);
5868 if (r < 0)
5869 return r;
5870
5871 r = sd_bus_get_property_string(
5872 bus,
5873 "org.freedesktop.systemd1",
5874 "/org/freedesktop/systemd1",
5875 "org.freedesktop.systemd1.Manager",
5876 "SystemState",
5877 NULL,
5878 &state);
5879 if (r < 0) {
5880 if (!arg_quiet)
5881 puts("unknown");
5882 return 0;
5883 }
5884
5885 if (!arg_quiet)
5886 puts(state);
5887
5888 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5889 }
5890
5891 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5892 char *t;
5893 int r;
5894
5895 assert(new_path);
5896 assert(original_path);
5897 assert(ret_tmp_fn);
5898
5899 r = tempfn_random(new_path, NULL, &t);
5900 if (r < 0)
5901 return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
5902
5903 r = mkdir_parents(new_path, 0755);
5904 if (r < 0) {
5905 free(t);
5906 return log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
5907 }
5908
5909 r = copy_file(original_path, t, 0, 0644, 0);
5910 if (r == -ENOENT) {
5911 r = touch(t);
5912 if (r < 0) {
5913 log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
5914 free(t);
5915 return r;
5916 }
5917 } else if (r < 0) {
5918 log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
5919 free(t);
5920 return r;
5921 }
5922
5923 *ret_tmp_fn = t;
5924
5925 return 0;
5926 }
5927
5928 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5929 _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5930
5931 switch (arg_scope) {
5932 case UNIT_FILE_SYSTEM:
5933 path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5934 if (arg_runtime)
5935 run = path_join(arg_root, "/run/systemd/system/", name);
5936 break;
5937 case UNIT_FILE_GLOBAL:
5938 path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5939 if (arg_runtime)
5940 run = path_join(arg_root, "/run/systemd/user/", name);
5941 break;
5942 case UNIT_FILE_USER:
5943 assert(user_home);
5944 assert(user_runtime);
5945
5946 path = path_join(arg_root, user_home, name);
5947 if (arg_runtime) {
5948 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5949 if (!path2)
5950 return log_oom();
5951 run = path_join(arg_root, user_runtime, name);
5952 }
5953 break;
5954 default:
5955 assert_not_reached("Invalid scope");
5956 }
5957 if (!path || (arg_runtime && !run))
5958 return log_oom();
5959
5960 if (arg_runtime) {
5961 if (access(path, F_OK) >= 0) {
5962 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path);
5963 return -EEXIST;
5964 }
5965
5966 if (path2 && access(path2, F_OK) >= 0) {
5967 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path2);
5968 return -EEXIST;
5969 }
5970
5971 *ret_path = run;
5972 run = NULL;
5973 } else {
5974 *ret_path = path;
5975 path = NULL;
5976 }
5977
5978 return 0;
5979 }
5980
5981 static int unit_file_create_dropin(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_new_path, char **ret_tmp_path) {
5982 char *tmp_new_path, *ending;
5983 char *tmp_tmp_path;
5984 int r;
5985
5986 assert(unit_name);
5987 assert(ret_new_path);
5988 assert(ret_tmp_path);
5989
5990 ending = strjoina(unit_name, ".d/override.conf");
5991 r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5992 if (r < 0)
5993 return r;
5994
5995 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5996 if (r < 0) {
5997 free(tmp_new_path);
5998 return r;
5999 }
6000
6001 *ret_new_path = tmp_new_path;
6002 *ret_tmp_path = tmp_tmp_path;
6003
6004 return 0;
6005 }
6006
6007 static int unit_file_create_copy(
6008 const char *unit_name,
6009 const char *fragment_path,
6010 const char *user_home,
6011 const char *user_runtime,
6012 char **ret_new_path,
6013 char **ret_tmp_path) {
6014
6015 char *tmp_new_path;
6016 char *tmp_tmp_path;
6017 int r;
6018
6019 assert(fragment_path);
6020 assert(unit_name);
6021 assert(ret_new_path);
6022 assert(ret_tmp_path);
6023
6024 r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
6025 if (r < 0)
6026 return r;
6027
6028 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
6029 char response;
6030
6031 r = ask_char(&response, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path, fragment_path);
6032 if (r < 0) {
6033 free(tmp_new_path);
6034 return r;
6035 }
6036 if (response != 'y') {
6037 log_warning("%s ignored", unit_name);
6038 free(tmp_new_path);
6039 return -1;
6040 }
6041 }
6042
6043 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
6044 if (r < 0) {
6045 log_error_errno(r, "Failed to create temporary file for \"%s\": %m", tmp_new_path);
6046 free(tmp_new_path);
6047 return r;
6048 }
6049
6050 *ret_new_path = tmp_new_path;
6051 *ret_tmp_path = tmp_tmp_path;
6052
6053 return 0;
6054 }
6055
6056 static int run_editor(char **paths) {
6057 pid_t pid;
6058 int r;
6059
6060 assert(paths);
6061
6062 pid = fork();
6063 if (pid < 0)
6064 return log_error_errno(errno, "Failed to fork: %m");
6065
6066 if (pid == 0) {
6067 const char **args;
6068 char *editor, **editor_args = NULL;
6069 char **tmp_path, **original_path, *p;
6070 unsigned n_editor_args = 0, i = 1;
6071 size_t argc;
6072
6073 (void) reset_all_signal_handlers();
6074 (void) reset_signal_mask();
6075
6076 argc = strv_length(paths)/2 + 1;
6077
6078 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6079 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6080 * we try to execute well known editors
6081 */
6082 editor = getenv("SYSTEMD_EDITOR");
6083 if (!editor)
6084 editor = getenv("EDITOR");
6085 if (!editor)
6086 editor = getenv("VISUAL");
6087
6088 if (!isempty(editor)) {
6089 editor_args = strv_split(editor, WHITESPACE);
6090 if (!editor_args) {
6091 (void) log_oom();
6092 _exit(EXIT_FAILURE);
6093 }
6094 n_editor_args = strv_length(editor_args);
6095 argc += n_editor_args - 1;
6096 }
6097 args = newa(const char*, argc + 1);
6098
6099 if (n_editor_args > 0) {
6100 args[0] = editor_args[0];
6101 for (; i < n_editor_args; i++)
6102 args[i] = editor_args[i];
6103 }
6104
6105 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
6106 args[i] = *tmp_path;
6107 i++;
6108 }
6109 args[i] = NULL;
6110
6111 if (n_editor_args > 0)
6112 execvp(args[0], (char* const*) args);
6113
6114 FOREACH_STRING(p, "editor", "nano", "vim", "vi") {
6115 args[0] = p;
6116 execvp(p, (char* const*) args);
6117 /* We do not fail if the editor doesn't exist
6118 * because we want to try each one of them before
6119 * failing.
6120 */
6121 if (errno != ENOENT) {
6122 log_error_errno(errno, "Failed to execute %s: %m", editor);
6123 _exit(EXIT_FAILURE);
6124 }
6125 }
6126
6127 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6128 _exit(EXIT_FAILURE);
6129 }
6130
6131 r = wait_for_terminate_and_warn("editor", pid, true);
6132 if (r < 0)
6133 return log_error_errno(r, "Failed to wait for child: %m");
6134
6135 return r;
6136 }
6137
6138 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
6139 _cleanup_free_ char *user_home = NULL;
6140 _cleanup_free_ char *user_runtime = NULL;
6141 _cleanup_lookup_paths_free_ LookupPaths lp = {};
6142 char **name;
6143 int r;
6144
6145 assert(names);
6146 assert(paths);
6147
6148 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
6149 if (r < 0)
6150 return r;
6151
6152 STRV_FOREACH(name, names) {
6153 _cleanup_free_ char *path = NULL;
6154 char *new_path, *tmp_path;
6155
6156 r = unit_find_paths(bus, *name, &lp, &path, NULL);
6157 if (r < 0)
6158 return r;
6159 else if (r == 0)
6160 return -ENOENT;
6161 else if (!path) {
6162 // FIXME: support units with path==NULL (no FragmentPath)
6163 log_error("No fragment exists for %s.", *name);
6164 return -ENOENT;
6165 }
6166
6167 if (arg_full)
6168 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
6169 else
6170 r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
6171 if (r < 0)
6172 return r;
6173
6174 r = strv_push_pair(paths, new_path, tmp_path);
6175 if (r < 0)
6176 return log_oom();
6177 }
6178
6179 return 0;
6180 }
6181
6182 static int edit(char **args) {
6183 _cleanup_strv_free_ char **names = NULL;
6184 _cleanup_strv_free_ char **paths = NULL;
6185 char **original, **tmp;
6186 sd_bus *bus;
6187 int r;
6188
6189 if (!on_tty()) {
6190 log_error("Cannot edit units if not on a tty.");
6191 return -EINVAL;
6192 }
6193
6194 if (arg_transport != BUS_TRANSPORT_LOCAL) {
6195 log_error("Cannot edit units remotely.");
6196 return -EINVAL;
6197 }
6198
6199 r = acquire_bus(BUS_MANAGER, &bus);
6200 if (r < 0)
6201 return r;
6202
6203 r = expand_names(bus, strv_skip(args, 1), NULL, &names);
6204 if (r < 0)
6205 return log_error_errno(r, "Failed to expand names: %m");
6206
6207 r = find_paths_to_edit(bus, names, &paths);
6208 if (r < 0)
6209 return r;
6210
6211 if (strv_isempty(paths))
6212 return -ENOENT;
6213
6214 r = run_editor(paths);
6215 if (r < 0)
6216 goto end;
6217
6218 STRV_FOREACH_PAIR(original, tmp, paths) {
6219 /* If the temporary file is empty we ignore it.
6220 * It's useful if the user wants to cancel its modification
6221 */
6222 if (null_or_empty_path(*tmp)) {
6223 log_warning("Editing \"%s\" canceled: temporary file is empty", *original);
6224 continue;
6225 }
6226 r = rename(*tmp, *original);
6227 if (r < 0) {
6228 r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
6229 goto end;
6230 }
6231 }
6232
6233 if (!arg_no_reload && bus && !install_client_side())
6234 r = daemon_reload(args);
6235
6236 end:
6237 STRV_FOREACH_PAIR(original, tmp, paths)
6238 unlink_noerrno(*tmp);
6239
6240 return r;
6241 }
6242
6243 static void systemctl_help(void) {
6244
6245 pager_open_if_enabled();
6246
6247 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6248 "Query or send control commands to the systemd manager.\n\n"
6249 " -h --help Show this help\n"
6250 " --version Show package version\n"
6251 " --system Connect to system manager\n"
6252 " --user Connect to user service manager\n"
6253 " -H --host=[USER@]HOST\n"
6254 " Operate on remote host\n"
6255 " -M --machine=CONTAINER\n"
6256 " Operate on local container\n"
6257 " -t --type=TYPE List units of a particular type\n"
6258 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6259 " -p --property=NAME Show only properties by this name\n"
6260 " -a --all Show all loaded units/properties, including dead/empty\n"
6261 " ones. To list all units installed on the system, use\n"
6262 " the 'list-unit-files' command instead.\n"
6263 " -l --full Don't ellipsize unit names on output\n"
6264 " -r --recursive Show unit list of host and local containers\n"
6265 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6266 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6267 " queueing a new job\n"
6268 " --show-types When showing sockets, explicitly show their type\n"
6269 " -i --ignore-inhibitors\n"
6270 " When shutting down or sleeping, ignore inhibitors\n"
6271 " --kill-who=WHO Who to send signal to\n"
6272 " -s --signal=SIGNAL Which signal to send\n"
6273 " --now Start or stop unit in addition to enabling or disabling it\n"
6274 " -q --quiet Suppress output\n"
6275 " --no-block Do not wait until operation finished\n"
6276 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6277 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6278 " --no-legend Do not print a legend (column headers and hints)\n"
6279 " --no-pager Do not pipe output into a pager\n"
6280 " --no-ask-password\n"
6281 " Do not ask for system passwords\n"
6282 " --global Enable/disable unit files globally\n"
6283 " --runtime Enable unit files only temporarily until next reboot\n"
6284 " -f --force When enabling unit files, override existing symlinks\n"
6285 " When shutting down, execute action immediately\n"
6286 " --preset-mode= Apply only enable, only disable, or all presets\n"
6287 " --root=PATH Enable unit files in the specified root directory\n"
6288 " -n --lines=INTEGER Number of journal entries to show\n"
6289 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6290 " short-precise, short-monotonic, verbose,\n"
6291 " export, json, json-pretty, json-sse, cat)\n"
6292 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6293 " --plain Print unit dependencies as a list instead of a tree\n\n"
6294 "Unit Commands:\n"
6295 " list-units [PATTERN...] List loaded units\n"
6296 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6297 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6298 " start NAME... Start (activate) one or more units\n"
6299 " stop NAME... Stop (deactivate) one or more units\n"
6300 " reload NAME... Reload one or more units\n"
6301 " restart NAME... Start or restart one or more units\n"
6302 " try-restart NAME... Restart one or more units if active\n"
6303 " reload-or-restart NAME... Reload one or more units if possible,\n"
6304 " otherwise start or restart\n"
6305 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6306 " otherwise restart if active\n"
6307 " isolate NAME Start one unit and stop all others\n"
6308 " kill NAME... Send signal to processes of a unit\n"
6309 " is-active PATTERN... Check whether units are active\n"
6310 " is-failed PATTERN... Check whether units are failed\n"
6311 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6312 " show [PATTERN...|JOB...] Show properties of one or more\n"
6313 " units/jobs or the manager\n"
6314 " cat PATTERN... Show files and drop-ins of one or more units\n"
6315 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6316 " help PATTERN...|PID... Show manual for one or more units\n"
6317 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6318 " units\n"
6319 " list-dependencies [NAME] Recursively show units which are required\n"
6320 " or wanted by this unit or by which this\n"
6321 " unit is required or wanted\n\n"
6322 "Unit File Commands:\n"
6323 " list-unit-files [PATTERN...] List installed unit files\n"
6324 " enable NAME... Enable one or more unit files\n"
6325 " disable NAME... Disable one or more unit files\n"
6326 " reenable NAME... Reenable one or more unit files\n"
6327 " preset NAME... Enable/disable one or more unit files\n"
6328 " based on preset configuration\n"
6329 " preset-all Enable/disable all unit files based on\n"
6330 " preset configuration\n"
6331 " is-enabled NAME... Check whether unit files are enabled\n"
6332 " mask NAME... Mask one or more units\n"
6333 " unmask NAME... Unmask one or more units\n"
6334 " link PATH... Link one or more units files into\n"
6335 " the search path\n"
6336 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6337 " on specified one or more units\n"
6338 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6339 " on specified one or more units\n"
6340 " edit NAME... Edit one or more unit files\n"
6341 " get-default Get the name of the default target\n"
6342 " set-default NAME Set the default target\n\n"
6343 "Machine Commands:\n"
6344 " list-machines [PATTERN...] List local containers and host\n\n"
6345 "Job Commands:\n"
6346 " list-jobs [PATTERN...] List jobs\n"
6347 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6348 "Snapshot Commands:\n"
6349 " snapshot [NAME] Create a snapshot\n"
6350 " delete NAME... Remove one or more snapshots\n\n"
6351 "Environment Commands:\n"
6352 " show-environment Dump environment\n"
6353 " set-environment NAME=VALUE... Set one or more environment variables\n"
6354 " unset-environment NAME... Unset one or more environment variables\n"
6355 " import-environment [NAME...] Import all or some environment variables\n\n"
6356 "Manager Lifecycle Commands:\n"
6357 " daemon-reload Reload systemd manager configuration\n"
6358 " daemon-reexec Reexecute systemd manager\n\n"
6359 "System Commands:\n"
6360 " is-system-running Check whether system is fully running\n"
6361 " default Enter system default mode\n"
6362 " rescue Enter system rescue mode\n"
6363 " emergency Enter system emergency mode\n"
6364 " halt Shut down and halt the system\n"
6365 " poweroff Shut down and power-off the system\n"
6366 " reboot [ARG] Shut down and reboot the system\n"
6367 " kexec Shut down and reboot the system with kexec\n"
6368 " exit [EXIT_CODE] Request user instance or container exit\n"
6369 " switch-root ROOT [INIT] Change to a different root file system\n"
6370 " suspend Suspend the system\n"
6371 " hibernate Hibernate the system\n"
6372 " hybrid-sleep Hibernate and suspend the system\n",
6373 program_invocation_short_name);
6374 }
6375
6376 static void halt_help(void) {
6377 printf("%s [OPTIONS...]%s\n\n"
6378 "%s the system.\n\n"
6379 " --help Show this help\n"
6380 " --halt Halt the machine\n"
6381 " -p --poweroff Switch off the machine\n"
6382 " --reboot Reboot the machine\n"
6383 " -f --force Force immediate halt/power-off/reboot\n"
6384 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6385 " -d --no-wtmp Don't write wtmp record\n"
6386 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6387 program_invocation_short_name,
6388 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6389 arg_action == ACTION_REBOOT ? "Reboot" :
6390 arg_action == ACTION_POWEROFF ? "Power off" :
6391 "Halt");
6392 }
6393
6394 static void shutdown_help(void) {
6395 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6396 "Shut down the system.\n\n"
6397 " --help Show this help\n"
6398 " -H --halt Halt the machine\n"
6399 " -P --poweroff Power-off the machine\n"
6400 " -r --reboot Reboot the machine\n"
6401 " -h Equivalent to --poweroff, overridden by --halt\n"
6402 " -k Don't halt/power-off/reboot, just send warnings\n"
6403 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6404 " -c Cancel a pending shutdown\n",
6405 program_invocation_short_name);
6406 }
6407
6408 static void telinit_help(void) {
6409 printf("%s [OPTIONS...] {COMMAND}\n\n"
6410 "Send control commands to the init daemon.\n\n"
6411 " --help Show this help\n"
6412 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6413 "Commands:\n"
6414 " 0 Power-off the machine\n"
6415 " 6 Reboot the machine\n"
6416 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6417 " 1, s, S Enter rescue mode\n"
6418 " q, Q Reload init daemon configuration\n"
6419 " u, U Reexecute init daemon\n",
6420 program_invocation_short_name);
6421 }
6422
6423 static void runlevel_help(void) {
6424 printf("%s [OPTIONS...]\n\n"
6425 "Prints the previous and current runlevel of the init system.\n\n"
6426 " --help Show this help\n",
6427 program_invocation_short_name);
6428 }
6429
6430 static void help_types(void) {
6431 int i;
6432 const char *t;
6433
6434 if (!arg_no_legend)
6435 puts("Available unit types:");
6436 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6437 t = unit_type_to_string(i);
6438 if (t)
6439 puts(t);
6440 }
6441 }
6442
6443 static int systemctl_parse_argv(int argc, char *argv[]) {
6444
6445 enum {
6446 ARG_FAIL = 0x100,
6447 ARG_REVERSE,
6448 ARG_AFTER,
6449 ARG_BEFORE,
6450 ARG_SHOW_TYPES,
6451 ARG_IRREVERSIBLE,
6452 ARG_IGNORE_DEPENDENCIES,
6453 ARG_VERSION,
6454 ARG_USER,
6455 ARG_SYSTEM,
6456 ARG_GLOBAL,
6457 ARG_NO_BLOCK,
6458 ARG_NO_LEGEND,
6459 ARG_NO_PAGER,
6460 ARG_NO_WALL,
6461 ARG_ROOT,
6462 ARG_NO_RELOAD,
6463 ARG_KILL_WHO,
6464 ARG_NO_ASK_PASSWORD,
6465 ARG_FAILED,
6466 ARG_RUNTIME,
6467 ARG_FORCE,
6468 ARG_PLAIN,
6469 ARG_STATE,
6470 ARG_JOB_MODE,
6471 ARG_PRESET_MODE,
6472 ARG_FIRMWARE_SETUP,
6473 ARG_NOW,
6474 ARG_MESSAGE,
6475 };
6476
6477 static const struct option options[] = {
6478 { "help", no_argument, NULL, 'h' },
6479 { "version", no_argument, NULL, ARG_VERSION },
6480 { "type", required_argument, NULL, 't' },
6481 { "property", required_argument, NULL, 'p' },
6482 { "all", no_argument, NULL, 'a' },
6483 { "reverse", no_argument, NULL, ARG_REVERSE },
6484 { "after", no_argument, NULL, ARG_AFTER },
6485 { "before", no_argument, NULL, ARG_BEFORE },
6486 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6487 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6488 { "full", no_argument, NULL, 'l' },
6489 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6490 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6491 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6492 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6493 { "ignore-inhibitors", no_argument, NULL, 'i' },
6494 { "user", no_argument, NULL, ARG_USER },
6495 { "system", no_argument, NULL, ARG_SYSTEM },
6496 { "global", no_argument, NULL, ARG_GLOBAL },
6497 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6498 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6499 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6500 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6501 { "quiet", no_argument, NULL, 'q' },
6502 { "root", required_argument, NULL, ARG_ROOT },
6503 { "force", no_argument, NULL, ARG_FORCE },
6504 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6505 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6506 { "signal", required_argument, NULL, 's' },
6507 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6508 { "host", required_argument, NULL, 'H' },
6509 { "machine", required_argument, NULL, 'M' },
6510 { "runtime", no_argument, NULL, ARG_RUNTIME },
6511 { "lines", required_argument, NULL, 'n' },
6512 { "output", required_argument, NULL, 'o' },
6513 { "plain", no_argument, NULL, ARG_PLAIN },
6514 { "state", required_argument, NULL, ARG_STATE },
6515 { "recursive", no_argument, NULL, 'r' },
6516 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6517 { "firmware-setup", no_argument, NULL, ARG_FIRMWARE_SETUP },
6518 { "now", no_argument, NULL, ARG_NOW },
6519 { "message", required_argument, NULL, ARG_MESSAGE },
6520 {}
6521 };
6522
6523 int c;
6524
6525 assert(argc >= 0);
6526 assert(argv);
6527
6528 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6529 arg_ask_password = true;
6530
6531 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6532
6533 switch (c) {
6534
6535 case 'h':
6536 systemctl_help();
6537 return 0;
6538
6539 case ARG_VERSION:
6540 return version();
6541
6542 case 't': {
6543 const char *word, *state;
6544 size_t size;
6545
6546 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6547 _cleanup_free_ char *type;
6548
6549 type = strndup(word, size);
6550 if (!type)
6551 return -ENOMEM;
6552
6553 if (streq(type, "help")) {
6554 help_types();
6555 return 0;
6556 }
6557
6558 if (unit_type_from_string(type) >= 0) {
6559 if (strv_push(&arg_types, type))
6560 return log_oom();
6561 type = NULL;
6562 continue;
6563 }
6564
6565 /* It's much nicer to use --state= for
6566 * load states, but let's support this
6567 * in --types= too for compatibility
6568 * with old versions */
6569 if (unit_load_state_from_string(optarg) >= 0) {
6570 if (strv_push(&arg_states, type) < 0)
6571 return log_oom();
6572 type = NULL;
6573 continue;
6574 }
6575
6576 log_error("Unknown unit type or load state '%s'.", type);
6577 log_info("Use -t help to see a list of allowed values.");
6578 return -EINVAL;
6579 }
6580
6581 break;
6582 }
6583
6584 case 'p': {
6585 /* Make sure that if the empty property list
6586 was specified, we won't show any properties. */
6587 if (isempty(optarg) && !arg_properties) {
6588 arg_properties = new0(char*, 1);
6589 if (!arg_properties)
6590 return log_oom();
6591 } else {
6592 const char *word, *state;
6593 size_t size;
6594
6595 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6596 char *prop;
6597
6598 prop = strndup(word, size);
6599 if (!prop)
6600 return log_oom();
6601
6602 if (strv_consume(&arg_properties, prop) < 0)
6603 return log_oom();
6604 }
6605 }
6606
6607 /* If the user asked for a particular
6608 * property, show it to him, even if it is
6609 * empty. */
6610 arg_all = true;
6611
6612 break;
6613 }
6614
6615 case 'a':
6616 arg_all = true;
6617 break;
6618
6619 case ARG_REVERSE:
6620 arg_dependency = DEPENDENCY_REVERSE;
6621 break;
6622
6623 case ARG_AFTER:
6624 arg_dependency = DEPENDENCY_AFTER;
6625 break;
6626
6627 case ARG_BEFORE:
6628 arg_dependency = DEPENDENCY_BEFORE;
6629 break;
6630
6631 case ARG_SHOW_TYPES:
6632 arg_show_types = true;
6633 break;
6634
6635 case ARG_JOB_MODE:
6636 arg_job_mode = optarg;
6637 break;
6638
6639 case ARG_FAIL:
6640 arg_job_mode = "fail";
6641 break;
6642
6643 case ARG_IRREVERSIBLE:
6644 arg_job_mode = "replace-irreversibly";
6645 break;
6646
6647 case ARG_IGNORE_DEPENDENCIES:
6648 arg_job_mode = "ignore-dependencies";
6649 break;
6650
6651 case ARG_USER:
6652 arg_scope = UNIT_FILE_USER;
6653 break;
6654
6655 case ARG_SYSTEM:
6656 arg_scope = UNIT_FILE_SYSTEM;
6657 break;
6658
6659 case ARG_GLOBAL:
6660 arg_scope = UNIT_FILE_GLOBAL;
6661 break;
6662
6663 case ARG_NO_BLOCK:
6664 arg_no_block = true;
6665 break;
6666
6667 case ARG_NO_LEGEND:
6668 arg_no_legend = true;
6669 break;
6670
6671 case ARG_NO_PAGER:
6672 arg_no_pager = true;
6673 break;
6674
6675 case ARG_NO_WALL:
6676 arg_no_wall = true;
6677 break;
6678
6679 case ARG_ROOT:
6680 arg_root = optarg;
6681 break;
6682
6683 case 'l':
6684 arg_full = true;
6685 break;
6686
6687 case ARG_FAILED:
6688 if (strv_extend(&arg_states, "failed") < 0)
6689 return log_oom();
6690
6691 break;
6692
6693 case 'q':
6694 arg_quiet = true;
6695 break;
6696
6697 case ARG_FORCE:
6698 arg_force ++;
6699 break;
6700
6701 case 'f':
6702 arg_force ++;
6703 break;
6704
6705 case ARG_NO_RELOAD:
6706 arg_no_reload = true;
6707 break;
6708
6709 case ARG_KILL_WHO:
6710 arg_kill_who = optarg;
6711 break;
6712
6713 case 's':
6714 arg_signal = signal_from_string_try_harder(optarg);
6715 if (arg_signal < 0) {
6716 log_error("Failed to parse signal string %s.", optarg);
6717 return -EINVAL;
6718 }
6719 break;
6720
6721 case ARG_NO_ASK_PASSWORD:
6722 arg_ask_password = false;
6723 break;
6724
6725 case 'H':
6726 arg_transport = BUS_TRANSPORT_REMOTE;
6727 arg_host = optarg;
6728 break;
6729
6730 case 'M':
6731 arg_transport = BUS_TRANSPORT_MACHINE;
6732 arg_host = optarg;
6733 break;
6734
6735 case ARG_RUNTIME:
6736 arg_runtime = true;
6737 break;
6738
6739 case 'n':
6740 if (safe_atou(optarg, &arg_lines) < 0) {
6741 log_error("Failed to parse lines '%s'", optarg);
6742 return -EINVAL;
6743 }
6744 break;
6745
6746 case 'o':
6747 arg_output = output_mode_from_string(optarg);
6748 if (arg_output < 0) {
6749 log_error("Unknown output '%s'.", optarg);
6750 return -EINVAL;
6751 }
6752 break;
6753
6754 case 'i':
6755 arg_ignore_inhibitors = true;
6756 break;
6757
6758 case ARG_PLAIN:
6759 arg_plain = true;
6760 break;
6761
6762 case ARG_FIRMWARE_SETUP:
6763 arg_firmware_setup = true;
6764 break;
6765
6766 case ARG_STATE: {
6767 const char *word, *state;
6768 size_t size;
6769
6770 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6771 char *s;
6772
6773 s = strndup(word, size);
6774 if (!s)
6775 return log_oom();
6776
6777 if (strv_consume(&arg_states, s) < 0)
6778 return log_oom();
6779 }
6780 break;
6781 }
6782
6783 case 'r':
6784 if (geteuid() != 0) {
6785 log_error("--recursive requires root privileges.");
6786 return -EPERM;
6787 }
6788
6789 arg_recursive = true;
6790 break;
6791
6792 case ARG_PRESET_MODE:
6793
6794 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6795 if (arg_preset_mode < 0) {
6796 log_error("Failed to parse preset mode: %s.", optarg);
6797 return -EINVAL;
6798 }
6799
6800 break;
6801
6802 case ARG_NOW:
6803 arg_now = true;
6804 break;
6805
6806 case ARG_MESSAGE:
6807 if (strv_extend(&arg_wall, optarg) < 0)
6808 return log_oom();
6809 break;
6810
6811 case '?':
6812 return -EINVAL;
6813
6814 default:
6815 assert_not_reached("Unhandled option");
6816 }
6817
6818 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6819 log_error("Cannot access user instance remotely.");
6820 return -EINVAL;
6821 }
6822
6823 return 1;
6824 }
6825
6826 static int halt_parse_argv(int argc, char *argv[]) {
6827
6828 enum {
6829 ARG_HELP = 0x100,
6830 ARG_HALT,
6831 ARG_REBOOT,
6832 ARG_NO_WALL
6833 };
6834
6835 static const struct option options[] = {
6836 { "help", no_argument, NULL, ARG_HELP },
6837 { "halt", no_argument, NULL, ARG_HALT },
6838 { "poweroff", no_argument, NULL, 'p' },
6839 { "reboot", no_argument, NULL, ARG_REBOOT },
6840 { "force", no_argument, NULL, 'f' },
6841 { "wtmp-only", no_argument, NULL, 'w' },
6842 { "no-wtmp", no_argument, NULL, 'd' },
6843 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6844 {}
6845 };
6846
6847 int c, r, runlevel;
6848
6849 assert(argc >= 0);
6850 assert(argv);
6851
6852 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6853 if (runlevel == '0' || runlevel == '6')
6854 arg_force = 2;
6855
6856 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6857 switch (c) {
6858
6859 case ARG_HELP:
6860 halt_help();
6861 return 0;
6862
6863 case ARG_HALT:
6864 arg_action = ACTION_HALT;
6865 break;
6866
6867 case 'p':
6868 if (arg_action != ACTION_REBOOT)
6869 arg_action = ACTION_POWEROFF;
6870 break;
6871
6872 case ARG_REBOOT:
6873 arg_action = ACTION_REBOOT;
6874 break;
6875
6876 case 'f':
6877 arg_force = 2;
6878 break;
6879
6880 case 'w':
6881 arg_dry = true;
6882 break;
6883
6884 case 'd':
6885 arg_no_wtmp = true;
6886 break;
6887
6888 case ARG_NO_WALL:
6889 arg_no_wall = true;
6890 break;
6891
6892 case 'i':
6893 case 'h':
6894 case 'n':
6895 /* Compatibility nops */
6896 break;
6897
6898 case '?':
6899 return -EINVAL;
6900
6901 default:
6902 assert_not_reached("Unhandled option");
6903 }
6904
6905 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6906 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6907 if (r < 0)
6908 return r;
6909 } else if (optind < argc) {
6910 log_error("Too many arguments.");
6911 return -EINVAL;
6912 }
6913
6914 return 1;
6915 }
6916
6917 static int parse_shutdown_time_spec(const char *t, usec_t *_u) {
6918 assert(t);
6919 assert(_u);
6920
6921 if (streq(t, "now"))
6922 *_u = 0;
6923 else if (!strchr(t, ':')) {
6924 uint64_t u;
6925
6926 if (safe_atou64(t, &u) < 0)
6927 return -EINVAL;
6928
6929 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6930 } else {
6931 char *e = NULL;
6932 long hour, minute;
6933 struct tm tm = {};
6934 time_t s;
6935 usec_t n;
6936
6937 errno = 0;
6938 hour = strtol(t, &e, 10);
6939 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6940 return -EINVAL;
6941
6942 minute = strtol(e+1, &e, 10);
6943 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6944 return -EINVAL;
6945
6946 n = now(CLOCK_REALTIME);
6947 s = (time_t) (n / USEC_PER_SEC);
6948
6949 assert_se(localtime_r(&s, &tm));
6950
6951 tm.tm_hour = (int) hour;
6952 tm.tm_min = (int) minute;
6953 tm.tm_sec = 0;
6954
6955 assert_se(s = mktime(&tm));
6956
6957 *_u = (usec_t) s * USEC_PER_SEC;
6958
6959 while (*_u <= n)
6960 *_u += USEC_PER_DAY;
6961 }
6962
6963 return 0;
6964 }
6965
6966 static int shutdown_parse_argv(int argc, char *argv[]) {
6967
6968 enum {
6969 ARG_HELP = 0x100,
6970 ARG_NO_WALL
6971 };
6972
6973 static const struct option options[] = {
6974 { "help", no_argument, NULL, ARG_HELP },
6975 { "halt", no_argument, NULL, 'H' },
6976 { "poweroff", no_argument, NULL, 'P' },
6977 { "reboot", no_argument, NULL, 'r' },
6978 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6979 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6980 {}
6981 };
6982
6983 char **wall = NULL;
6984 int c, r;
6985
6986 assert(argc >= 0);
6987 assert(argv);
6988
6989 while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6990 switch (c) {
6991
6992 case ARG_HELP:
6993 shutdown_help();
6994 return 0;
6995
6996 case 'H':
6997 arg_action = ACTION_HALT;
6998 break;
6999
7000 case 'P':
7001 arg_action = ACTION_POWEROFF;
7002 break;
7003
7004 case 'r':
7005 if (kexec_loaded())
7006 arg_action = ACTION_KEXEC;
7007 else
7008 arg_action = ACTION_REBOOT;
7009 break;
7010
7011 case 'K':
7012 arg_action = ACTION_KEXEC;
7013 break;
7014
7015 case 'h':
7016 if (arg_action != ACTION_HALT)
7017 arg_action = ACTION_POWEROFF;
7018 break;
7019
7020 case 'k':
7021 arg_dry = true;
7022 break;
7023
7024 case ARG_NO_WALL:
7025 arg_no_wall = true;
7026 break;
7027
7028 case 't':
7029 case 'a':
7030 case 'f':
7031 case 'F':
7032 /* Compatibility nops */
7033 break;
7034
7035 case 'c':
7036 arg_action = ACTION_CANCEL_SHUTDOWN;
7037 break;
7038
7039 case '?':
7040 return -EINVAL;
7041
7042 default:
7043 assert_not_reached("Unhandled option");
7044 }
7045
7046 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
7047 r = parse_shutdown_time_spec(argv[optind], &arg_when);
7048 if (r < 0) {
7049 log_error("Failed to parse time specification: %s", argv[optind]);
7050 return r;
7051 }
7052 } else
7053 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
7054
7055 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
7056 /* No time argument for shutdown cancel */
7057 wall = argv + optind;
7058 else if (argc > optind + 1)
7059 /* We skip the time argument */
7060 wall = argv + optind + 1;
7061
7062 if (wall) {
7063 arg_wall = strv_copy(wall);
7064 if (!arg_wall)
7065 return log_oom();
7066 }
7067
7068 optind = argc;
7069
7070 return 1;
7071 }
7072
7073 static int telinit_parse_argv(int argc, char *argv[]) {
7074
7075 enum {
7076 ARG_HELP = 0x100,
7077 ARG_NO_WALL
7078 };
7079
7080 static const struct option options[] = {
7081 { "help", no_argument, NULL, ARG_HELP },
7082 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7083 {}
7084 };
7085
7086 static const struct {
7087 char from;
7088 enum action to;
7089 } table[] = {
7090 { '0', ACTION_POWEROFF },
7091 { '6', ACTION_REBOOT },
7092 { '1', ACTION_RESCUE },
7093 { '2', ACTION_RUNLEVEL2 },
7094 { '3', ACTION_RUNLEVEL3 },
7095 { '4', ACTION_RUNLEVEL4 },
7096 { '5', ACTION_RUNLEVEL5 },
7097 { 's', ACTION_RESCUE },
7098 { 'S', ACTION_RESCUE },
7099 { 'q', ACTION_RELOAD },
7100 { 'Q', ACTION_RELOAD },
7101 { 'u', ACTION_REEXEC },
7102 { 'U', ACTION_REEXEC }
7103 };
7104
7105 unsigned i;
7106 int c;
7107
7108 assert(argc >= 0);
7109 assert(argv);
7110
7111 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7112 switch (c) {
7113
7114 case ARG_HELP:
7115 telinit_help();
7116 return 0;
7117
7118 case ARG_NO_WALL:
7119 arg_no_wall = true;
7120 break;
7121
7122 case '?':
7123 return -EINVAL;
7124
7125 default:
7126 assert_not_reached("Unhandled option");
7127 }
7128
7129 if (optind >= argc) {
7130 log_error("%s: required argument missing.", program_invocation_short_name);
7131 return -EINVAL;
7132 }
7133
7134 if (optind + 1 < argc) {
7135 log_error("Too many arguments.");
7136 return -EINVAL;
7137 }
7138
7139 if (strlen(argv[optind]) != 1) {
7140 log_error("Expected single character argument.");
7141 return -EINVAL;
7142 }
7143
7144 for (i = 0; i < ELEMENTSOF(table); i++)
7145 if (table[i].from == argv[optind][0])
7146 break;
7147
7148 if (i >= ELEMENTSOF(table)) {
7149 log_error("Unknown command '%s'.", argv[optind]);
7150 return -EINVAL;
7151 }
7152
7153 arg_action = table[i].to;
7154
7155 optind ++;
7156
7157 return 1;
7158 }
7159
7160 static int runlevel_parse_argv(int argc, char *argv[]) {
7161
7162 enum {
7163 ARG_HELP = 0x100,
7164 };
7165
7166 static const struct option options[] = {
7167 { "help", no_argument, NULL, ARG_HELP },
7168 {}
7169 };
7170
7171 int c;
7172
7173 assert(argc >= 0);
7174 assert(argv);
7175
7176 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7177 switch (c) {
7178
7179 case ARG_HELP:
7180 runlevel_help();
7181 return 0;
7182
7183 case '?':
7184 return -EINVAL;
7185
7186 default:
7187 assert_not_reached("Unhandled option");
7188 }
7189
7190 if (optind < argc) {
7191 log_error("Too many arguments.");
7192 return -EINVAL;
7193 }
7194
7195 return 1;
7196 }
7197
7198 static int parse_argv(int argc, char *argv[]) {
7199 assert(argc >= 0);
7200 assert(argv);
7201
7202 if (program_invocation_short_name) {
7203
7204 if (strstr(program_invocation_short_name, "halt")) {
7205 arg_action = ACTION_HALT;
7206 return halt_parse_argv(argc, argv);
7207 } else if (strstr(program_invocation_short_name, "poweroff")) {
7208 arg_action = ACTION_POWEROFF;
7209 return halt_parse_argv(argc, argv);
7210 } else if (strstr(program_invocation_short_name, "reboot")) {
7211 if (kexec_loaded())
7212 arg_action = ACTION_KEXEC;
7213 else
7214 arg_action = ACTION_REBOOT;
7215 return halt_parse_argv(argc, argv);
7216 } else if (strstr(program_invocation_short_name, "shutdown")) {
7217 arg_action = ACTION_POWEROFF;
7218 return shutdown_parse_argv(argc, argv);
7219 } else if (strstr(program_invocation_short_name, "init")) {
7220
7221 if (sd_booted() > 0) {
7222 arg_action = _ACTION_INVALID;
7223 return telinit_parse_argv(argc, argv);
7224 } else {
7225 /* Hmm, so some other init system is
7226 * running, we need to forward this
7227 * request to it. For now we simply
7228 * guess that it is Upstart. */
7229
7230 execv(TELINIT, argv);
7231
7232 log_error("Couldn't find an alternative telinit implementation to spawn.");
7233 return -EIO;
7234 }
7235
7236 } else if (strstr(program_invocation_short_name, "runlevel")) {
7237 arg_action = ACTION_RUNLEVEL;
7238 return runlevel_parse_argv(argc, argv);
7239 }
7240 }
7241
7242 arg_action = ACTION_SYSTEMCTL;
7243 return systemctl_parse_argv(argc, argv);
7244 }
7245
7246 _pure_ static int action_to_runlevel(void) {
7247
7248 static const char table[_ACTION_MAX] = {
7249 [ACTION_HALT] = '0',
7250 [ACTION_POWEROFF] = '0',
7251 [ACTION_REBOOT] = '6',
7252 [ACTION_RUNLEVEL2] = '2',
7253 [ACTION_RUNLEVEL3] = '3',
7254 [ACTION_RUNLEVEL4] = '4',
7255 [ACTION_RUNLEVEL5] = '5',
7256 [ACTION_RESCUE] = '1'
7257 };
7258
7259 assert(arg_action < _ACTION_MAX);
7260
7261 return table[arg_action];
7262 }
7263
7264 static int talk_initctl(void) {
7265 #ifdef HAVE_SYSV_COMPAT
7266 struct init_request request = {
7267 .magic = INIT_MAGIC,
7268 .sleeptime = 0,
7269 .cmd = INIT_CMD_RUNLVL
7270 };
7271
7272 _cleanup_close_ int fd = -1;
7273 char rl;
7274 int r;
7275
7276 rl = action_to_runlevel();
7277 if (!rl)
7278 return 0;
7279
7280 request.runlevel = rl;
7281
7282 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7283 if (fd < 0) {
7284 if (errno == ENOENT)
7285 return 0;
7286
7287 return log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7288 }
7289
7290 r = loop_write(fd, &request, sizeof(request), false);
7291 if (r < 0)
7292 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7293
7294 return 1;
7295 #else
7296 return 0;
7297 #endif
7298 }
7299
7300 static int systemctl_main(int argc, char *argv[], int bus_error) {
7301
7302 static const struct {
7303 const char* verb;
7304 const enum {
7305 MORE,
7306 LESS,
7307 EQUAL
7308 } argc_cmp;
7309 const int argc;
7310 int (* const dispatch)(char **args);
7311 } verbs[] = {
7312 { "list-units", MORE, 0, list_units },
7313 { "list-unit-files", MORE, 1, list_unit_files },
7314 { "list-sockets", MORE, 1, list_sockets },
7315 { "list-timers", MORE, 1, list_timers },
7316 { "list-jobs", MORE, 1, list_jobs },
7317 { "list-machines", MORE, 1, list_machines },
7318 { "clear-jobs", EQUAL, 1, daemon_reload },
7319 { "cancel", MORE, 2, cancel_job },
7320 { "start", MORE, 2, start_unit },
7321 { "stop", MORE, 2, start_unit },
7322 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7323 { "reload", MORE, 2, start_unit },
7324 { "restart", MORE, 2, start_unit },
7325 { "try-restart", MORE, 2, start_unit },
7326 { "reload-or-restart", MORE, 2, start_unit },
7327 { "reload-or-try-restart", MORE, 2, start_unit },
7328 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
7329 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7330 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
7331 { "isolate", EQUAL, 2, start_unit },
7332 { "kill", MORE, 2, kill_unit },
7333 { "is-active", MORE, 2, check_unit_active },
7334 { "check", MORE, 2, check_unit_active },
7335 { "is-failed", MORE, 2, check_unit_failed },
7336 { "show", MORE, 1, show },
7337 { "cat", MORE, 2, cat, },
7338 { "status", MORE, 1, show },
7339 { "help", MORE, 2, show },
7340 { "snapshot", LESS, 2, snapshot },
7341 { "delete", MORE, 2, delete_snapshot },
7342 { "daemon-reload", EQUAL, 1, daemon_reload },
7343 { "daemon-reexec", EQUAL, 1, daemon_reload },
7344 { "show-environment", EQUAL, 1, show_environment },
7345 { "set-environment", MORE, 2, set_environment },
7346 { "unset-environment", MORE, 2, set_environment },
7347 { "import-environment", MORE, 1, import_environment},
7348 { "halt", EQUAL, 1, start_special, },
7349 { "poweroff", EQUAL, 1, start_special, },
7350 { "reboot", MORE, 1, start_special, },
7351 { "kexec", EQUAL, 1, start_special },
7352 { "suspend", EQUAL, 1, start_special },
7353 { "hibernate", EQUAL, 1, start_special },
7354 { "hybrid-sleep", EQUAL, 1, start_special },
7355 { "default", EQUAL, 1, start_special },
7356 { "rescue", EQUAL, 1, start_special },
7357 { "emergency", EQUAL, 1, start_special },
7358 { "exit", LESS, 2, start_special },
7359 { "reset-failed", MORE, 1, reset_failed },
7360 { "enable", MORE, 2, enable_unit, },
7361 { "disable", MORE, 2, enable_unit, },
7362 { "is-enabled", MORE, 2, unit_is_enabled, },
7363 { "reenable", MORE, 2, enable_unit, },
7364 { "preset", MORE, 2, enable_unit, },
7365 { "preset-all", EQUAL, 1, preset_all, },
7366 { "mask", MORE, 2, enable_unit, },
7367 { "unmask", MORE, 2, enable_unit, },
7368 { "link", MORE, 2, enable_unit, },
7369 { "switch-root", MORE, 2, switch_root },
7370 { "list-dependencies", LESS, 2, list_dependencies },
7371 { "set-default", EQUAL, 2, set_default, },
7372 { "get-default", EQUAL, 1, get_default, },
7373 { "set-property", MORE, 3, set_property },
7374 { "is-system-running", EQUAL, 1, is_system_running },
7375 { "add-wants", MORE, 3, add_dependency, },
7376 { "add-requires", MORE, 3, add_dependency, },
7377 { "edit", MORE, 2, edit, },
7378 {}
7379 }, *verb = verbs;
7380
7381 int left;
7382
7383 assert(argc >= 0);
7384 assert(argv);
7385
7386 left = argc - optind;
7387
7388 /* Special rule: no arguments (left == 0) means "list-units" */
7389 if (left > 0) {
7390 if (streq(argv[optind], "help") && !argv[optind+1]) {
7391 log_error("This command expects one or more unit names. Did you mean --help?");
7392 return -EINVAL;
7393 }
7394
7395 for (; verb->verb; verb++)
7396 if (streq(argv[optind], verb->verb))
7397 goto found;
7398
7399 log_error("Unknown operation '%s'.", argv[optind]);
7400 return -EINVAL;
7401 }
7402 found:
7403
7404 switch (verb->argc_cmp) {
7405
7406 case EQUAL:
7407 if (left != verb->argc) {
7408 log_error("Invalid number of arguments.");
7409 return -EINVAL;
7410 }
7411
7412 break;
7413
7414 case MORE:
7415 if (left < verb->argc) {
7416 log_error("Too few arguments.");
7417 return -EINVAL;
7418 }
7419
7420 break;
7421
7422 case LESS:
7423 if (left > verb->argc) {
7424 log_error("Too many arguments.");
7425 return -EINVAL;
7426 }
7427
7428 break;
7429
7430 default:
7431 assert_not_reached("Unknown comparison operator.");
7432 }
7433
7434 return verb->dispatch(argv + optind);
7435 }
7436
7437 static int reload_with_fallback(void) {
7438
7439 /* First, try systemd via D-Bus. */
7440 if (daemon_reload(NULL) >= 0)
7441 return 0;
7442
7443 /* Nothing else worked, so let's try signals */
7444 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7445
7446 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7447 return log_error_errno(errno, "kill() failed: %m");
7448
7449 return 0;
7450 }
7451
7452 static int start_with_fallback(void) {
7453
7454 /* First, try systemd via D-Bus. */
7455 if (start_unit(NULL) >= 0)
7456 return 0;
7457
7458 /* Nothing else worked, so let's try
7459 * /dev/initctl */
7460 if (talk_initctl() > 0)
7461 return 0;
7462
7463 log_error("Failed to talk to init daemon.");
7464 return -EIO;
7465 }
7466
7467 static int halt_now(enum action a) {
7468
7469 /* The kernel will automaticall flush ATA disks and suchlike
7470 * on reboot(), but the file systems need to be synce'd
7471 * explicitly in advance. */
7472 sync();
7473
7474 /* Make sure C-A-D is handled by the kernel from this point
7475 * on... */
7476 reboot(RB_ENABLE_CAD);
7477
7478 switch (a) {
7479
7480 case ACTION_HALT:
7481 log_info("Halting.");
7482 reboot(RB_HALT_SYSTEM);
7483 return -errno;
7484
7485 case ACTION_POWEROFF:
7486 log_info("Powering off.");
7487 reboot(RB_POWER_OFF);
7488 return -errno;
7489
7490 case ACTION_KEXEC:
7491 case ACTION_REBOOT: {
7492 _cleanup_free_ char *param = NULL;
7493
7494 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
7495 log_info("Rebooting with argument '%s'.", param);
7496 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param);
7497 }
7498
7499 log_info("Rebooting.");
7500 reboot(RB_AUTOBOOT);
7501 return -errno;
7502 }
7503
7504 default:
7505 assert_not_reached("Unknown action.");
7506 }
7507 }
7508
7509 static int logind_schedule_shutdown(void) {
7510
7511 #ifdef HAVE_LOGIND
7512 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
7513 char date[FORMAT_TIMESTAMP_MAX];
7514 const char *action;
7515 sd_bus *bus;
7516 int r;
7517
7518 (void) logind_set_wall_message();
7519
7520 r = acquire_bus(BUS_FULL, &bus);
7521 if (r < 0)
7522 return r;
7523
7524 switch (arg_action) {
7525 case ACTION_HALT:
7526 action = "halt";
7527 break;
7528 case ACTION_POWEROFF:
7529 action = "poweroff";
7530 break;
7531 case ACTION_KEXEC:
7532 action = "kexec";
7533 break;
7534 default:
7535 action = "reboot";
7536 break;
7537 }
7538
7539 if (arg_dry)
7540 action = strjoina("dry-", action);
7541
7542 r = sd_bus_call_method(
7543 bus,
7544 "org.freedesktop.login1",
7545 "/org/freedesktop/login1",
7546 "org.freedesktop.login1.Manager",
7547 "ScheduleShutdown",
7548 &error,
7549 NULL,
7550 "st",
7551 action,
7552 arg_when);
7553 if (r < 0)
7554 return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r));
7555
7556 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
7557 return 0;
7558 #else
7559 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7560 return -ENOSYS;
7561 #endif
7562 }
7563
7564 static int halt_main(void) {
7565 int r;
7566
7567 r = logind_check_inhibitors(arg_action);
7568 if (r < 0)
7569 return r;
7570
7571 if (geteuid() != 0) {
7572 if (arg_when > 0 ||
7573 arg_dry ||
7574 arg_force > 0) {
7575 log_error("Must be root.");
7576 return -EPERM;
7577 }
7578
7579 /* Try logind if we are a normal user and no special
7580 * mode applies. Maybe PolicyKit allows us to shutdown
7581 * the machine. */
7582 if (IN_SET(arg_action,
7583 ACTION_POWEROFF,
7584 ACTION_REBOOT)) {
7585 r = logind_reboot(arg_action);
7586 if (r >= 0)
7587 return r;
7588 if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
7589 /* requested operation is not supported or already in progress */
7590 return r;
7591 /* on all other errors, try low-level operation */
7592 }
7593 }
7594
7595 if (arg_when > 0) {
7596 r = logind_schedule_shutdown();
7597 if (r >= 0)
7598 return r;
7599 }
7600
7601 if (!arg_dry && !arg_force)
7602 return start_with_fallback();
7603
7604 assert(geteuid() == 0);
7605
7606 if (!arg_no_wtmp) {
7607 if (sd_booted() > 0)
7608 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7609 else {
7610 r = utmp_put_shutdown();
7611 if (r < 0)
7612 log_warning_errno(r, "Failed to write utmp record: %m");
7613 }
7614 }
7615
7616 if (arg_dry)
7617 return 0;
7618
7619 r = halt_now(arg_action);
7620
7621 return log_error_errno(r, "Failed to reboot: %m");
7622 }
7623
7624 static int runlevel_main(void) {
7625 int r, runlevel, previous;
7626
7627 r = utmp_get_runlevel(&runlevel, &previous);
7628 if (r < 0) {
7629 puts("unknown");
7630 return r;
7631 }
7632
7633 printf("%c %c\n",
7634 previous <= 0 ? 'N' : previous,
7635 runlevel <= 0 ? 'N' : runlevel);
7636
7637 return 0;
7638 }
7639
7640 static int logind_cancel_shutdown(void) {
7641 #ifdef HAVE_LOGIND
7642 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
7643 sd_bus *bus;
7644 int r;
7645
7646 r = acquire_bus(BUS_FULL, &bus);
7647 if (r < 0)
7648 return r;
7649
7650 (void) logind_set_wall_message();
7651
7652 r = sd_bus_call_method(
7653 bus,
7654 "org.freedesktop.login1",
7655 "/org/freedesktop/login1",
7656 "org.freedesktop.login1.Manager",
7657 "CancelScheduledShutdown",
7658 &error,
7659 NULL, NULL);
7660 if (r < 0)
7661 return log_warning_errno(r, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error, r));
7662
7663 return 0;
7664 #else
7665 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7666 return -ENOSYS;
7667 #endif
7668 }
7669
7670 int main(int argc, char*argv[]) {
7671 int r;
7672
7673 setlocale(LC_ALL, "");
7674 log_parse_environment();
7675 log_open();
7676
7677 /* Explicitly not on_tty() to avoid setting cached value.
7678 * This becomes relevant for piping output which might be
7679 * ellipsized. */
7680 original_stdout_is_tty = isatty(STDOUT_FILENO);
7681
7682 r = parse_argv(argc, argv);
7683 if (r <= 0)
7684 goto finish;
7685
7686 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7687 log_info("Running in chroot, ignoring request.");
7688 r = 0;
7689 goto finish;
7690 }
7691
7692 /* systemctl_main() will print an error message for the bus
7693 * connection, but only if it needs to */
7694
7695 switch (arg_action) {
7696
7697 case ACTION_SYSTEMCTL:
7698 r = systemctl_main(argc, argv, r);
7699 break;
7700
7701 case ACTION_HALT:
7702 case ACTION_POWEROFF:
7703 case ACTION_REBOOT:
7704 case ACTION_KEXEC:
7705 r = halt_main();
7706 break;
7707
7708 case ACTION_RUNLEVEL2:
7709 case ACTION_RUNLEVEL3:
7710 case ACTION_RUNLEVEL4:
7711 case ACTION_RUNLEVEL5:
7712 case ACTION_RESCUE:
7713 case ACTION_EMERGENCY:
7714 case ACTION_DEFAULT:
7715 r = start_with_fallback();
7716 break;
7717
7718 case ACTION_RELOAD:
7719 case ACTION_REEXEC:
7720 r = reload_with_fallback();
7721 break;
7722
7723 case ACTION_CANCEL_SHUTDOWN:
7724 r = logind_cancel_shutdown();
7725 break;
7726
7727 case ACTION_RUNLEVEL:
7728 r = runlevel_main();
7729 break;
7730
7731 case _ACTION_INVALID:
7732 default:
7733 assert_not_reached("Unknown action");
7734 }
7735
7736 finish:
7737 pager_close();
7738 ask_password_agent_close();
7739 polkit_agent_close();
7740
7741 strv_free(arg_types);
7742 strv_free(arg_states);
7743 strv_free(arg_properties);
7744
7745 strv_free(arg_wall);
7746
7747 release_busses();
7748
7749 return r < 0 ? EXIT_FAILURE : r;
7750 }