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