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