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