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