]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/systemctl/systemctl.c
Merge pull request #2316 from poettering/dnssec14
[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_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
534 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
535 _cleanup_(sd_bus_message_unrefp) 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_(sd_bus_flush_close_unrefp) 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_(sd_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_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
729 _cleanup_(sd_bus_message_unrefp) 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_(sd_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_(sd_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_BAD)) {
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_(sd_bus_message_unrefp) 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_(sd_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_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1520 _cleanup_(sd_bus_message_unrefp) 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_(sd_bus_flush_close_unrefp) 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_(sd_bus_message_unrefp) 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_(sd_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 %s, pointing 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_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2014 _cleanup_(sd_bus_message_unrefp) 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_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2132 _cleanup_(sd_bus_message_unrefp) 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_(sd_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_(sd_bus_message_unrefp) 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_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2328 _cleanup_(sd_bus_message_unrefp) 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_(sd_bus_message_unrefp) 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_(sd_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_(sd_bus_message_unrefp) 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_(sd_bus_message_unrefp) 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_(sd_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, arg_scope != UNIT_FILE_SYSTEM ? "--user" : NULL);
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_(sd_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_(sd_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_(sd_bus_message_unrefp) 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_(sd_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_(sd_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_(sd_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 bool transient;
3364
3365 /* Service */
3366 pid_t main_pid;
3367 pid_t control_pid;
3368 const char *status_text;
3369 const char *pid_file;
3370 bool running:1;
3371 int status_errno;
3372
3373 usec_t start_timestamp;
3374 usec_t exit_timestamp;
3375
3376 int exit_code, exit_status;
3377
3378 usec_t condition_timestamp;
3379 bool condition_result;
3380 bool failed_condition_trigger;
3381 bool failed_condition_negate;
3382 const char *failed_condition;
3383 const char *failed_condition_parameter;
3384
3385 usec_t assert_timestamp;
3386 bool assert_result;
3387 bool failed_assert_trigger;
3388 bool failed_assert_negate;
3389 const char *failed_assert;
3390 const char *failed_assert_parameter;
3391
3392 /* Socket */
3393 unsigned n_accepted;
3394 unsigned n_connections;
3395 bool accept;
3396
3397 /* Pairs of type, path */
3398 char **listen;
3399
3400 /* Device */
3401 const char *sysfs_path;
3402
3403 /* Mount, Automount */
3404 const char *where;
3405
3406 /* Swap */
3407 const char *what;
3408
3409 /* CGroup */
3410 uint64_t memory_current;
3411 uint64_t memory_limit;
3412 uint64_t cpu_usage_nsec;
3413 uint64_t tasks_current;
3414 uint64_t tasks_max;
3415
3416 LIST_HEAD(ExecStatusInfo, exec);
3417 } UnitStatusInfo;
3418
3419 static void print_status_info(
3420 UnitStatusInfo *i,
3421 bool *ellipsized) {
3422
3423 ExecStatusInfo *p;
3424 const char *active_on, *active_off, *on, *off, *ss;
3425 usec_t timestamp;
3426 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3427 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3428 const char *path;
3429 char **t, **t2;
3430
3431 assert(i);
3432
3433 /* This shows pretty information about a unit. See
3434 * print_property() for a low-level property printer */
3435
3436 if (streq_ptr(i->active_state, "failed")) {
3437 active_on = ansi_highlight_red();
3438 active_off = ansi_normal();
3439 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3440 active_on = ansi_highlight_green();
3441 active_off = ansi_normal();
3442 } else
3443 active_on = active_off = "";
3444
3445 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3446
3447 if (i->description && !streq_ptr(i->id, i->description))
3448 printf(" - %s", i->description);
3449
3450 printf("\n");
3451
3452 if (i->following)
3453 printf(" Follow: unit currently follows state of %s\n", i->following);
3454
3455 if (streq_ptr(i->load_state, "error")) {
3456 on = ansi_highlight_red();
3457 off = ansi_normal();
3458 } else
3459 on = off = "";
3460
3461 path = i->source_path ? i->source_path : i->fragment_path;
3462
3463 if (i->load_error != 0)
3464 printf(" Loaded: %s%s%s (Reason: %s)\n",
3465 on, strna(i->load_state), off, i->load_error);
3466 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3467 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3468 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3469 else if (path && !isempty(i->unit_file_state))
3470 printf(" Loaded: %s%s%s (%s; %s)\n",
3471 on, strna(i->load_state), off, path, i->unit_file_state);
3472 else if (path)
3473 printf(" Loaded: %s%s%s (%s)\n",
3474 on, strna(i->load_state), off, path);
3475 else
3476 printf(" Loaded: %s%s%s\n",
3477 on, strna(i->load_state), off);
3478
3479 if (i->transient)
3480 printf("Transient: yes\n");
3481
3482 if (!strv_isempty(i->dropin_paths)) {
3483 _cleanup_free_ char *dir = NULL;
3484 bool last = false;
3485 char ** dropin;
3486
3487 STRV_FOREACH(dropin, i->dropin_paths) {
3488 if (! dir || last) {
3489 printf(dir ? " " : " Drop-In: ");
3490
3491 dir = mfree(dir);
3492
3493 dir = dirname_malloc(*dropin);
3494 if (!dir) {
3495 log_oom();
3496 return;
3497 }
3498
3499 printf("%s\n %s", dir,
3500 draw_special_char(DRAW_TREE_RIGHT));
3501 }
3502
3503 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3504
3505 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3506 }
3507 }
3508
3509 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3510 if (ss)
3511 printf(" Active: %s%s (%s)%s",
3512 active_on, strna(i->active_state), ss, active_off);
3513 else
3514 printf(" Active: %s%s%s",
3515 active_on, strna(i->active_state), active_off);
3516
3517 if (!isempty(i->result) && !streq(i->result, "success"))
3518 printf(" (Result: %s)", i->result);
3519
3520 timestamp = (streq_ptr(i->active_state, "active") ||
3521 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3522 (streq_ptr(i->active_state, "inactive") ||
3523 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3524 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3525 i->active_exit_timestamp;
3526
3527 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3528 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3529
3530 if (s1)
3531 printf(" since %s; %s\n", s2, s1);
3532 else if (s2)
3533 printf(" since %s\n", s2);
3534 else
3535 printf("\n");
3536
3537 if (!i->condition_result && i->condition_timestamp > 0) {
3538 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3539 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3540
3541 printf("Condition: start %scondition failed%s at %s%s%s\n",
3542 ansi_highlight_yellow(), ansi_normal(),
3543 s2, s1 ? "; " : "", strempty(s1));
3544 if (i->failed_condition_trigger)
3545 printf(" none of the trigger conditions were met\n");
3546 else if (i->failed_condition)
3547 printf(" %s=%s%s was not met\n",
3548 i->failed_condition,
3549 i->failed_condition_negate ? "!" : "",
3550 i->failed_condition_parameter);
3551 }
3552
3553 if (!i->assert_result && i->assert_timestamp > 0) {
3554 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3555 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3556
3557 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3558 ansi_highlight_red(), ansi_normal(),
3559 s2, s1 ? "; " : "", strempty(s1));
3560 if (i->failed_assert_trigger)
3561 printf(" none of the trigger assertions were met\n");
3562 else if (i->failed_assert)
3563 printf(" %s=%s%s was not met\n",
3564 i->failed_assert,
3565 i->failed_assert_negate ? "!" : "",
3566 i->failed_assert_parameter);
3567 }
3568
3569 if (i->sysfs_path)
3570 printf(" Device: %s\n", i->sysfs_path);
3571 if (i->where)
3572 printf(" Where: %s\n", i->where);
3573 if (i->what)
3574 printf(" What: %s\n", i->what);
3575
3576 STRV_FOREACH(t, i->documentation)
3577 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3578
3579 STRV_FOREACH_PAIR(t, t2, i->listen)
3580 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3581
3582 if (i->accept)
3583 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3584
3585 LIST_FOREACH(exec, p, i->exec) {
3586 _cleanup_free_ char *argv = NULL;
3587 bool good;
3588
3589 /* Only show exited processes here */
3590 if (p->code == 0)
3591 continue;
3592
3593 argv = strv_join(p->argv, " ");
3594 printf(" Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
3595
3596 good = is_clean_exit_lsb(p->code, p->status, NULL);
3597 if (!good) {
3598 on = ansi_highlight_red();
3599 off = ansi_normal();
3600 } else
3601 on = off = "";
3602
3603 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3604
3605 if (p->code == CLD_EXITED) {
3606 const char *c;
3607
3608 printf("status=%i", p->status);
3609
3610 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3611 if (c)
3612 printf("/%s", c);
3613
3614 } else
3615 printf("signal=%s", signal_to_string(p->status));
3616
3617 printf(")%s\n", off);
3618
3619 if (i->main_pid == p->pid &&
3620 i->start_timestamp == p->start_timestamp &&
3621 i->exit_timestamp == p->start_timestamp)
3622 /* Let's not show this twice */
3623 i->main_pid = 0;
3624
3625 if (p->pid == i->control_pid)
3626 i->control_pid = 0;
3627 }
3628
3629 if (i->main_pid > 0 || i->control_pid > 0) {
3630 if (i->main_pid > 0) {
3631 printf(" Main PID: "PID_FMT, i->main_pid);
3632
3633 if (i->running) {
3634 _cleanup_free_ char *comm = NULL;
3635 get_process_comm(i->main_pid, &comm);
3636 if (comm)
3637 printf(" (%s)", comm);
3638 } else if (i->exit_code > 0) {
3639 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3640
3641 if (i->exit_code == CLD_EXITED) {
3642 const char *c;
3643
3644 printf("status=%i", i->exit_status);
3645
3646 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3647 if (c)
3648 printf("/%s", c);
3649
3650 } else
3651 printf("signal=%s", signal_to_string(i->exit_status));
3652 printf(")");
3653 }
3654
3655 if (i->control_pid > 0)
3656 printf(";");
3657 }
3658
3659 if (i->control_pid > 0) {
3660 _cleanup_free_ char *c = NULL;
3661
3662 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3663
3664 get_process_comm(i->control_pid, &c);
3665 if (c)
3666 printf(" (%s)", c);
3667 }
3668
3669 printf("\n");
3670 }
3671
3672 if (i->status_text)
3673 printf(" Status: \"%s\"\n", i->status_text);
3674 if (i->status_errno > 0)
3675 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3676
3677 if (i->tasks_current != (uint64_t) -1) {
3678 printf(" Tasks: %" PRIu64, i->tasks_current);
3679
3680 if (i->tasks_max != (uint64_t) -1)
3681 printf(" (limit: %" PRIi64 ")\n", i->tasks_max);
3682 else
3683 printf("\n");
3684 }
3685
3686 if (i->memory_current != (uint64_t) -1) {
3687 char buf[FORMAT_BYTES_MAX];
3688
3689 printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
3690
3691 if (i->memory_limit != (uint64_t) -1)
3692 printf(" (limit: %s)\n", format_bytes(buf, sizeof(buf), i->memory_limit));
3693 else
3694 printf("\n");
3695 }
3696
3697 if (i->cpu_usage_nsec != (uint64_t) -1) {
3698 char buf[FORMAT_TIMESPAN_MAX];
3699 printf(" CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
3700 }
3701
3702 if (i->control_group &&
3703 (i->main_pid > 0 || i->control_pid > 0 ||
3704 (!IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group) == 0))) {
3705 unsigned c;
3706
3707 printf(" CGroup: %s\n", i->control_group);
3708
3709 if (IN_SET(arg_transport,
3710 BUS_TRANSPORT_LOCAL,
3711 BUS_TRANSPORT_MACHINE)) {
3712 unsigned k = 0;
3713 pid_t extra[2];
3714 static const char prefix[] = " ";
3715
3716 c = columns();
3717 if (c > sizeof(prefix) - 1)
3718 c -= sizeof(prefix) - 1;
3719 else
3720 c = 0;
3721
3722 if (i->main_pid > 0)
3723 extra[k++] = i->main_pid;
3724
3725 if (i->control_pid > 0)
3726 extra[k++] = i->control_pid;
3727
3728 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
3729 }
3730 }
3731
3732 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL)
3733 show_journal_by_unit(
3734 stdout,
3735 i->id,
3736 arg_output,
3737 0,
3738 i->inactive_exit_timestamp_monotonic,
3739 arg_lines,
3740 getuid(),
3741 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
3742 SD_JOURNAL_LOCAL_ONLY,
3743 arg_scope == UNIT_FILE_SYSTEM,
3744 ellipsized);
3745
3746 if (i->need_daemon_reload)
3747 warn_unit_file_changed(i->id);
3748 }
3749
3750 static void show_unit_help(UnitStatusInfo *i) {
3751 char **p;
3752
3753 assert(i);
3754
3755 if (!i->documentation) {
3756 log_info("Documentation for %s not known.", i->id);
3757 return;
3758 }
3759
3760 STRV_FOREACH(p, i->documentation)
3761 if (startswith(*p, "man:"))
3762 show_man_page(*p + 4, false);
3763 else
3764 log_info("Can't show: %s", *p);
3765 }
3766
3767 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3768 int r;
3769
3770 assert(name);
3771 assert(m);
3772 assert(i);
3773
3774 switch (contents[0]) {
3775
3776 case SD_BUS_TYPE_STRING: {
3777 const char *s;
3778
3779 r = sd_bus_message_read(m, "s", &s);
3780 if (r < 0)
3781 return bus_log_parse_error(r);
3782
3783 if (!isempty(s)) {
3784 if (streq(name, "Id"))
3785 i->id = s;
3786 else if (streq(name, "LoadState"))
3787 i->load_state = s;
3788 else if (streq(name, "ActiveState"))
3789 i->active_state = s;
3790 else if (streq(name, "SubState"))
3791 i->sub_state = s;
3792 else if (streq(name, "Description"))
3793 i->description = s;
3794 else if (streq(name, "FragmentPath"))
3795 i->fragment_path = s;
3796 else if (streq(name, "SourcePath"))
3797 i->source_path = s;
3798 #ifndef NOLEGACY
3799 else if (streq(name, "DefaultControlGroup")) {
3800 const char *e;
3801 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3802 if (e)
3803 i->control_group = e;
3804 }
3805 #endif
3806 else if (streq(name, "ControlGroup"))
3807 i->control_group = s;
3808 else if (streq(name, "StatusText"))
3809 i->status_text = s;
3810 else if (streq(name, "PIDFile"))
3811 i->pid_file = s;
3812 else if (streq(name, "SysFSPath"))
3813 i->sysfs_path = s;
3814 else if (streq(name, "Where"))
3815 i->where = s;
3816 else if (streq(name, "What"))
3817 i->what = s;
3818 else if (streq(name, "Following"))
3819 i->following = s;
3820 else if (streq(name, "UnitFileState"))
3821 i->unit_file_state = s;
3822 else if (streq(name, "UnitFilePreset"))
3823 i->unit_file_preset = s;
3824 else if (streq(name, "Result"))
3825 i->result = s;
3826 }
3827
3828 break;
3829 }
3830
3831 case SD_BUS_TYPE_BOOLEAN: {
3832 int b;
3833
3834 r = sd_bus_message_read(m, "b", &b);
3835 if (r < 0)
3836 return bus_log_parse_error(r);
3837
3838 if (streq(name, "Accept"))
3839 i->accept = b;
3840 else if (streq(name, "NeedDaemonReload"))
3841 i->need_daemon_reload = b;
3842 else if (streq(name, "ConditionResult"))
3843 i->condition_result = b;
3844 else if (streq(name, "AssertResult"))
3845 i->assert_result = b;
3846 else if (streq(name, "Transient"))
3847 i->transient = b;
3848
3849 break;
3850 }
3851
3852 case SD_BUS_TYPE_UINT32: {
3853 uint32_t u;
3854
3855 r = sd_bus_message_read(m, "u", &u);
3856 if (r < 0)
3857 return bus_log_parse_error(r);
3858
3859 if (streq(name, "MainPID")) {
3860 if (u > 0) {
3861 i->main_pid = (pid_t) u;
3862 i->running = true;
3863 }
3864 } else if (streq(name, "ControlPID"))
3865 i->control_pid = (pid_t) u;
3866 else if (streq(name, "ExecMainPID")) {
3867 if (u > 0)
3868 i->main_pid = (pid_t) u;
3869 } else if (streq(name, "NAccepted"))
3870 i->n_accepted = u;
3871 else if (streq(name, "NConnections"))
3872 i->n_connections = u;
3873
3874 break;
3875 }
3876
3877 case SD_BUS_TYPE_INT32: {
3878 int32_t j;
3879
3880 r = sd_bus_message_read(m, "i", &j);
3881 if (r < 0)
3882 return bus_log_parse_error(r);
3883
3884 if (streq(name, "ExecMainCode"))
3885 i->exit_code = (int) j;
3886 else if (streq(name, "ExecMainStatus"))
3887 i->exit_status = (int) j;
3888 else if (streq(name, "StatusErrno"))
3889 i->status_errno = (int) j;
3890
3891 break;
3892 }
3893
3894 case SD_BUS_TYPE_UINT64: {
3895 uint64_t u;
3896
3897 r = sd_bus_message_read(m, "t", &u);
3898 if (r < 0)
3899 return bus_log_parse_error(r);
3900
3901 if (streq(name, "ExecMainStartTimestamp"))
3902 i->start_timestamp = (usec_t) u;
3903 else if (streq(name, "ExecMainExitTimestamp"))
3904 i->exit_timestamp = (usec_t) u;
3905 else if (streq(name, "ActiveEnterTimestamp"))
3906 i->active_enter_timestamp = (usec_t) u;
3907 else if (streq(name, "InactiveEnterTimestamp"))
3908 i->inactive_enter_timestamp = (usec_t) u;
3909 else if (streq(name, "InactiveExitTimestamp"))
3910 i->inactive_exit_timestamp = (usec_t) u;
3911 else if (streq(name, "InactiveExitTimestampMonotonic"))
3912 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3913 else if (streq(name, "ActiveExitTimestamp"))
3914 i->active_exit_timestamp = (usec_t) u;
3915 else if (streq(name, "ConditionTimestamp"))
3916 i->condition_timestamp = (usec_t) u;
3917 else if (streq(name, "AssertTimestamp"))
3918 i->assert_timestamp = (usec_t) u;
3919 else if (streq(name, "MemoryCurrent"))
3920 i->memory_current = u;
3921 else if (streq(name, "MemoryLimit"))
3922 i->memory_limit = u;
3923 else if (streq(name, "TasksCurrent"))
3924 i->tasks_current = u;
3925 else if (streq(name, "TasksMax"))
3926 i->tasks_max = u;
3927 else if (streq(name, "CPUUsageNSec"))
3928 i->cpu_usage_nsec = u;
3929
3930 break;
3931 }
3932
3933 case SD_BUS_TYPE_ARRAY:
3934
3935 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3936 _cleanup_free_ ExecStatusInfo *info = NULL;
3937
3938 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3939 if (r < 0)
3940 return bus_log_parse_error(r);
3941
3942 info = new0(ExecStatusInfo, 1);
3943 if (!info)
3944 return log_oom();
3945
3946 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3947
3948 info->name = strdup(name);
3949 if (!info->name)
3950 return log_oom();
3951
3952 LIST_PREPEND(exec, i->exec, info);
3953
3954 info = new0(ExecStatusInfo, 1);
3955 if (!info)
3956 return log_oom();
3957 }
3958
3959 if (r < 0)
3960 return bus_log_parse_error(r);
3961
3962 r = sd_bus_message_exit_container(m);
3963 if (r < 0)
3964 return bus_log_parse_error(r);
3965
3966 return 0;
3967
3968 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3969 const char *type, *path;
3970
3971 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3972 if (r < 0)
3973 return bus_log_parse_error(r);
3974
3975 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3976
3977 r = strv_extend(&i->listen, type);
3978 if (r < 0)
3979 return r;
3980
3981 r = strv_extend(&i->listen, path);
3982 if (r < 0)
3983 return r;
3984 }
3985 if (r < 0)
3986 return bus_log_parse_error(r);
3987
3988 r = sd_bus_message_exit_container(m);
3989 if (r < 0)
3990 return bus_log_parse_error(r);
3991
3992 return 0;
3993
3994 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3995
3996 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3997 if (r < 0)
3998 return bus_log_parse_error(r);
3999
4000 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
4001
4002 r = sd_bus_message_read_strv(m, &i->documentation);
4003 if (r < 0)
4004 return bus_log_parse_error(r);
4005
4006 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
4007 const char *cond, *param;
4008 int trigger, negate;
4009 int32_t state;
4010
4011 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
4012 if (r < 0)
4013 return bus_log_parse_error(r);
4014
4015 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
4016 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
4017 if (state < 0 && (!trigger || !i->failed_condition)) {
4018 i->failed_condition = cond;
4019 i->failed_condition_trigger = trigger;
4020 i->failed_condition_negate = negate;
4021 i->failed_condition_parameter = param;
4022 }
4023 }
4024 if (r < 0)
4025 return bus_log_parse_error(r);
4026
4027 r = sd_bus_message_exit_container(m);
4028 if (r < 0)
4029 return bus_log_parse_error(r);
4030
4031 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
4032 const char *cond, *param;
4033 int trigger, negate;
4034 int32_t state;
4035
4036 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
4037 if (r < 0)
4038 return bus_log_parse_error(r);
4039
4040 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
4041 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
4042 if (state < 0 && (!trigger || !i->failed_assert)) {
4043 i->failed_assert = cond;
4044 i->failed_assert_trigger = trigger;
4045 i->failed_assert_negate = negate;
4046 i->failed_assert_parameter = param;
4047 }
4048 }
4049 if (r < 0)
4050 return bus_log_parse_error(r);
4051
4052 r = sd_bus_message_exit_container(m);
4053 if (r < 0)
4054 return bus_log_parse_error(r);
4055
4056 } else
4057 goto skip;
4058
4059 break;
4060
4061 case SD_BUS_TYPE_STRUCT_BEGIN:
4062
4063 if (streq(name, "LoadError")) {
4064 const char *n, *message;
4065
4066 r = sd_bus_message_read(m, "(ss)", &n, &message);
4067 if (r < 0)
4068 return bus_log_parse_error(r);
4069
4070 if (!isempty(message))
4071 i->load_error = message;
4072 } else
4073 goto skip;
4074
4075 break;
4076
4077 default:
4078 goto skip;
4079 }
4080
4081 return 0;
4082
4083 skip:
4084 r = sd_bus_message_skip(m, contents);
4085 if (r < 0)
4086 return bus_log_parse_error(r);
4087
4088 return 0;
4089 }
4090
4091 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
4092 int r;
4093
4094 assert(name);
4095 assert(m);
4096
4097 /* This is a low-level property printer, see
4098 * print_status_info() for the nicer output */
4099
4100 if (arg_properties && !strv_find(arg_properties, name)) {
4101 /* skip what we didn't read */
4102 r = sd_bus_message_skip(m, contents);
4103 return r;
4104 }
4105
4106 switch (contents[0]) {
4107
4108 case SD_BUS_TYPE_STRUCT_BEGIN:
4109
4110 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
4111 uint32_t u;
4112
4113 r = sd_bus_message_read(m, "(uo)", &u, NULL);
4114 if (r < 0)
4115 return bus_log_parse_error(r);
4116
4117 if (u > 0)
4118 printf("%s=%"PRIu32"\n", name, u);
4119 else if (arg_all)
4120 printf("%s=\n", name);
4121
4122 return 0;
4123
4124 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
4125 const char *s;
4126
4127 r = sd_bus_message_read(m, "(so)", &s, NULL);
4128 if (r < 0)
4129 return bus_log_parse_error(r);
4130
4131 if (arg_all || !isempty(s))
4132 printf("%s=%s\n", name, s);
4133
4134 return 0;
4135
4136 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
4137 const char *a = NULL, *b = NULL;
4138
4139 r = sd_bus_message_read(m, "(ss)", &a, &b);
4140 if (r < 0)
4141 return bus_log_parse_error(r);
4142
4143 if (arg_all || !isempty(a) || !isempty(b))
4144 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
4145
4146 return 0;
4147 } else if (streq_ptr(name, "SystemCallFilter")) {
4148 _cleanup_strv_free_ char **l = NULL;
4149 int whitelist;
4150
4151 r = sd_bus_message_enter_container(m, 'r', "bas");
4152 if (r < 0)
4153 return bus_log_parse_error(r);
4154
4155 r = sd_bus_message_read(m, "b", &whitelist);
4156 if (r < 0)
4157 return bus_log_parse_error(r);
4158
4159 r = sd_bus_message_read_strv(m, &l);
4160 if (r < 0)
4161 return bus_log_parse_error(r);
4162
4163 r = sd_bus_message_exit_container(m);
4164 if (r < 0)
4165 return bus_log_parse_error(r);
4166
4167 if (arg_all || whitelist || !strv_isempty(l)) {
4168 bool first = true;
4169 char **i;
4170
4171 fputs(name, stdout);
4172 fputc('=', stdout);
4173
4174 if (!whitelist)
4175 fputc('~', stdout);
4176
4177 STRV_FOREACH(i, l) {
4178 if (first)
4179 first = false;
4180 else
4181 fputc(' ', stdout);
4182
4183 fputs(*i, stdout);
4184 }
4185 fputc('\n', stdout);
4186 }
4187
4188 return 0;
4189 }
4190
4191 break;
4192
4193 case SD_BUS_TYPE_ARRAY:
4194
4195 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4196 const char *path;
4197 int ignore;
4198
4199 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4200 if (r < 0)
4201 return bus_log_parse_error(r);
4202
4203 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4204 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4205
4206 if (r < 0)
4207 return bus_log_parse_error(r);
4208
4209 r = sd_bus_message_exit_container(m);
4210 if (r < 0)
4211 return bus_log_parse_error(r);
4212
4213 return 0;
4214
4215 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4216 const char *type, *path;
4217
4218 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4219 if (r < 0)
4220 return bus_log_parse_error(r);
4221
4222 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4223 printf("%s=%s\n", type, path);
4224 if (r < 0)
4225 return bus_log_parse_error(r);
4226
4227 r = sd_bus_message_exit_container(m);
4228 if (r < 0)
4229 return bus_log_parse_error(r);
4230
4231 return 0;
4232
4233 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4234 const char *type, *path;
4235
4236 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4237 if (r < 0)
4238 return bus_log_parse_error(r);
4239
4240 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4241 printf("Listen%s=%s\n", type, path);
4242 if (r < 0)
4243 return bus_log_parse_error(r);
4244
4245 r = sd_bus_message_exit_container(m);
4246 if (r < 0)
4247 return bus_log_parse_error(r);
4248
4249 return 0;
4250
4251 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4252 const char *base;
4253 uint64_t value, next_elapse;
4254
4255 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4256 if (r < 0)
4257 return bus_log_parse_error(r);
4258
4259 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4260 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4261
4262 printf("%s={ value=%s ; next_elapse=%s }\n",
4263 base,
4264 format_timespan(timespan1, sizeof(timespan1), value, 0),
4265 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4266 }
4267 if (r < 0)
4268 return bus_log_parse_error(r);
4269
4270 r = sd_bus_message_exit_container(m);
4271 if (r < 0)
4272 return bus_log_parse_error(r);
4273
4274 return 0;
4275
4276 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4277 ExecStatusInfo info = {};
4278
4279 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4280 if (r < 0)
4281 return bus_log_parse_error(r);
4282
4283 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4284 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4285 _cleanup_free_ char *tt;
4286
4287 tt = strv_join(info.argv, " ");
4288
4289 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",
4290 name,
4291 strna(info.path),
4292 strna(tt),
4293 yes_no(info.ignore),
4294 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4295 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4296 info.pid,
4297 sigchld_code_to_string(info.code),
4298 info.status,
4299 info.code == CLD_EXITED ? "" : "/",
4300 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4301
4302 free(info.path);
4303 strv_free(info.argv);
4304 zero(info);
4305 }
4306
4307 r = sd_bus_message_exit_container(m);
4308 if (r < 0)
4309 return bus_log_parse_error(r);
4310
4311 return 0;
4312
4313 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4314 const char *path, *rwm;
4315
4316 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4317 if (r < 0)
4318 return bus_log_parse_error(r);
4319
4320 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4321 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4322 if (r < 0)
4323 return bus_log_parse_error(r);
4324
4325 r = sd_bus_message_exit_container(m);
4326 if (r < 0)
4327 return bus_log_parse_error(r);
4328
4329 return 0;
4330
4331 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4332 const char *path;
4333 uint64_t weight;
4334
4335 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4336 if (r < 0)
4337 return bus_log_parse_error(r);
4338
4339 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4340 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4341 if (r < 0)
4342 return bus_log_parse_error(r);
4343
4344 r = sd_bus_message_exit_container(m);
4345 if (r < 0)
4346 return bus_log_parse_error(r);
4347
4348 return 0;
4349
4350 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4351 const char *path;
4352 uint64_t bandwidth;
4353
4354 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4355 if (r < 0)
4356 return bus_log_parse_error(r);
4357
4358 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4359 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4360 if (r < 0)
4361 return bus_log_parse_error(r);
4362
4363 r = sd_bus_message_exit_container(m);
4364 if (r < 0)
4365 return bus_log_parse_error(r);
4366
4367 return 0;
4368 }
4369
4370 break;
4371 }
4372
4373 r = bus_print_property(name, m, arg_all);
4374 if (r < 0)
4375 return bus_log_parse_error(r);
4376
4377 if (r == 0) {
4378 r = sd_bus_message_skip(m, contents);
4379 if (r < 0)
4380 return bus_log_parse_error(r);
4381
4382 if (arg_all)
4383 printf("%s=[unprintable]\n", name);
4384 }
4385
4386 return 0;
4387 }
4388
4389 static int show_one(
4390 const char *verb,
4391 sd_bus *bus,
4392 const char *path,
4393 bool show_properties,
4394 bool *new_line,
4395 bool *ellipsized) {
4396
4397 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
4398 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4399 UnitStatusInfo info = {
4400 .memory_current = (uint64_t) -1,
4401 .memory_limit = (uint64_t) -1,
4402 .cpu_usage_nsec = (uint64_t) -1,
4403 .tasks_current = (uint64_t) -1,
4404 .tasks_max = (uint64_t) -1,
4405 };
4406 ExecStatusInfo *p;
4407 int r;
4408
4409 assert(path);
4410 assert(new_line);
4411
4412 log_debug("Showing one %s", path);
4413
4414 r = sd_bus_call_method(
4415 bus,
4416 "org.freedesktop.systemd1",
4417 path,
4418 "org.freedesktop.DBus.Properties",
4419 "GetAll",
4420 &error,
4421 &reply,
4422 "s", "");
4423 if (r < 0)
4424 return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
4425
4426 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4427 if (r < 0)
4428 return bus_log_parse_error(r);
4429
4430 if (*new_line)
4431 printf("\n");
4432
4433 *new_line = true;
4434
4435 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4436 const char *name, *contents;
4437
4438 r = sd_bus_message_read(reply, "s", &name);
4439 if (r < 0)
4440 return bus_log_parse_error(r);
4441
4442 r = sd_bus_message_peek_type(reply, NULL, &contents);
4443 if (r < 0)
4444 return bus_log_parse_error(r);
4445
4446 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4447 if (r < 0)
4448 return bus_log_parse_error(r);
4449
4450 if (show_properties)
4451 r = print_property(name, reply, contents);
4452 else
4453 r = status_property(name, reply, &info, contents);
4454 if (r < 0)
4455 return r;
4456
4457 r = sd_bus_message_exit_container(reply);
4458 if (r < 0)
4459 return bus_log_parse_error(r);
4460
4461 r = sd_bus_message_exit_container(reply);
4462 if (r < 0)
4463 return bus_log_parse_error(r);
4464 }
4465 if (r < 0)
4466 return bus_log_parse_error(r);
4467
4468 r = sd_bus_message_exit_container(reply);
4469 if (r < 0)
4470 return bus_log_parse_error(r);
4471
4472 r = 0;
4473
4474 if (!show_properties) {
4475 if (streq(verb, "help"))
4476 show_unit_help(&info);
4477 else
4478 print_status_info(&info, ellipsized);
4479 }
4480
4481 strv_free(info.documentation);
4482 strv_free(info.dropin_paths);
4483 strv_free(info.listen);
4484
4485 if (!streq_ptr(info.active_state, "active") &&
4486 !streq_ptr(info.active_state, "reloading") &&
4487 streq(verb, "status")) {
4488 /* According to LSB: "program not running" */
4489 /* 0: program is running or service is OK
4490 * 1: program is dead and /run PID file exists
4491 * 2: program is dead and /run/lock lock file exists
4492 * 3: program is not running
4493 * 4: program or service status is unknown
4494 */
4495 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4496 r = 1;
4497 else
4498 r = 3;
4499 }
4500
4501 while ((p = info.exec)) {
4502 LIST_REMOVE(exec, info.exec, p);
4503 exec_status_info_free(p);
4504 }
4505
4506 return r;
4507 }
4508
4509 static int get_unit_dbus_path_by_pid(
4510 sd_bus *bus,
4511 uint32_t pid,
4512 char **unit) {
4513
4514 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4515 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
4516 char *u;
4517 int r;
4518
4519 r = sd_bus_call_method(
4520 bus,
4521 "org.freedesktop.systemd1",
4522 "/org/freedesktop/systemd1",
4523 "org.freedesktop.systemd1.Manager",
4524 "GetUnitByPID",
4525 &error,
4526 &reply,
4527 "u", pid);
4528 if (r < 0)
4529 return log_error_errno(r, "Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
4530
4531 r = sd_bus_message_read(reply, "o", &u);
4532 if (r < 0)
4533 return bus_log_parse_error(r);
4534
4535 u = strdup(u);
4536 if (!u)
4537 return log_oom();
4538
4539 *unit = u;
4540 return 0;
4541 }
4542
4543 static int show_all(
4544 const char* verb,
4545 sd_bus *bus,
4546 bool show_properties,
4547 bool *new_line,
4548 bool *ellipsized) {
4549
4550 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
4551 _cleanup_free_ UnitInfo *unit_infos = NULL;
4552 const UnitInfo *u;
4553 unsigned c;
4554 int r, ret = 0;
4555
4556 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4557 if (r < 0)
4558 return r;
4559
4560 pager_open_if_enabled();
4561
4562 c = (unsigned) r;
4563
4564 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4565
4566 for (u = unit_infos; u < unit_infos + c; u++) {
4567 _cleanup_free_ char *p = NULL;
4568
4569 p = unit_dbus_path_from_name(u->id);
4570 if (!p)
4571 return log_oom();
4572
4573 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4574 if (r < 0)
4575 return r;
4576 else if (r > 0 && ret == 0)
4577 ret = r;
4578 }
4579
4580 return ret;
4581 }
4582
4583 static int show_system_status(sd_bus *bus) {
4584 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4585 _cleanup_free_ char *hn = NULL;
4586 _cleanup_(machine_info_clear) struct machine_info mi = {};
4587 const char *on, *off;
4588 int r;
4589
4590 hn = gethostname_malloc();
4591 if (!hn)
4592 return log_oom();
4593
4594 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4595 if (r < 0)
4596 return log_error_errno(r, "Failed to read server status: %m");
4597
4598 if (streq_ptr(mi.state, "degraded")) {
4599 on = ansi_highlight_red();
4600 off = ansi_normal();
4601 } else if (!streq_ptr(mi.state, "running")) {
4602 on = ansi_highlight_yellow();
4603 off = ansi_normal();
4604 } else
4605 on = off = "";
4606
4607 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4608
4609 printf(" State: %s%s%s\n",
4610 on, strna(mi.state), off);
4611
4612 printf(" Jobs: %u queued\n", mi.n_jobs);
4613 printf(" Failed: %u units\n", mi.n_failed_units);
4614
4615 printf(" Since: %s; %s\n",
4616 format_timestamp(since2, sizeof(since2), mi.timestamp),
4617 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4618
4619 printf(" CGroup: %s\n", mi.control_group ?: "/");
4620 if (IN_SET(arg_transport,
4621 BUS_TRANSPORT_LOCAL,
4622 BUS_TRANSPORT_MACHINE)) {
4623 static const char prefix[] = " ";
4624 unsigned c;
4625
4626 c = columns();
4627 if (c > sizeof(prefix) - 1)
4628 c -= sizeof(prefix) - 1;
4629 else
4630 c = 0;
4631
4632 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
4633 }
4634
4635 return 0;
4636 }
4637
4638 static int show(int argc, char *argv[], void *userdata) {
4639 bool show_properties, show_status, show_help, new_line = false;
4640 bool ellipsized = false;
4641 int r, ret = 0;
4642 sd_bus *bus;
4643
4644 assert(argv);
4645
4646 show_properties = streq(argv[0], "show");
4647 show_status = streq(argv[0], "status");
4648 show_help = streq(argv[0], "help");
4649
4650 if (show_help && argc <= 1) {
4651 log_error("This command expects one or more unit names. Did you mean --help?");
4652 return -EINVAL;
4653 }
4654
4655 pager_open_if_enabled();
4656
4657 if (show_status)
4658 /* Increase max number of open files to 16K if we can, we
4659 * might needs this when browsing journal files, which might
4660 * be split up into many files. */
4661 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
4662
4663 r = acquire_bus(BUS_MANAGER, &bus);
4664 if (r < 0)
4665 return r;
4666
4667 /* If no argument is specified inspect the manager itself */
4668 if (show_properties && argc <= 1)
4669 return show_one(argv[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4670
4671 if (show_status && argc <= 1) {
4672
4673 pager_open_if_enabled();
4674 show_system_status(bus);
4675 new_line = true;
4676
4677 if (arg_all)
4678 ret = show_all(argv[0], bus, false, &new_line, &ellipsized);
4679 } else {
4680 _cleanup_free_ char **patterns = NULL;
4681 char **name;
4682
4683 STRV_FOREACH(name, strv_skip(argv, 1)) {
4684 _cleanup_free_ char *unit = NULL;
4685 uint32_t id;
4686
4687 if (safe_atou32(*name, &id) < 0) {
4688 if (strv_push(&patterns, *name) < 0)
4689 return log_oom();
4690
4691 continue;
4692 } else if (show_properties) {
4693 /* Interpret as job id */
4694 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4695 return log_oom();
4696
4697 } else {
4698 /* Interpret as PID */
4699 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4700 if (r < 0) {
4701 ret = r;
4702 continue;
4703 }
4704 }
4705
4706 r = show_one(argv[0], bus, unit, show_properties, &new_line, &ellipsized);
4707 if (r < 0)
4708 return r;
4709 else if (r > 0 && ret == 0)
4710 ret = r;
4711 }
4712
4713 if (!strv_isempty(patterns)) {
4714 _cleanup_strv_free_ char **names = NULL;
4715
4716 r = expand_names(bus, patterns, NULL, &names);
4717 if (r < 0)
4718 return log_error_errno(r, "Failed to expand names: %m");
4719
4720 STRV_FOREACH(name, names) {
4721 _cleanup_free_ char *unit;
4722
4723 unit = unit_dbus_path_from_name(*name);
4724 if (!unit)
4725 return log_oom();
4726
4727 r = show_one(argv[0], bus, unit, show_properties, &new_line, &ellipsized);
4728 if (r < 0)
4729 return r;
4730 else if (r > 0 && ret == 0)
4731 ret = r;
4732 }
4733 }
4734 }
4735
4736 if (ellipsized && !arg_quiet)
4737 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4738
4739 return ret;
4740 }
4741
4742 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4743 int r;
4744
4745 assert(user_home);
4746 assert(user_runtime);
4747 assert(lp);
4748
4749 if (arg_scope == UNIT_FILE_USER) {
4750 r = user_config_home(user_home);
4751 if (r < 0)
4752 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4753 else if (r == 0)
4754 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4755
4756 r = user_runtime_dir(user_runtime);
4757 if (r < 0)
4758 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4759 else if (r == 0)
4760 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4761 }
4762
4763 r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
4764 if (r < 0)
4765 return log_error_errno(r, "Failed to query unit lookup paths: %m");
4766
4767 return 0;
4768 }
4769
4770 static int cat_file(const char *filename, bool newline) {
4771 _cleanup_close_ int fd;
4772
4773 fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4774 if (fd < 0)
4775 return -errno;
4776
4777 printf("%s%s# %s%s\n",
4778 newline ? "\n" : "",
4779 ansi_highlight_blue(),
4780 filename,
4781 ansi_normal());
4782 fflush(stdout);
4783
4784 return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, false);
4785 }
4786
4787 static int cat(int argc, char *argv[], void *userdata) {
4788 _cleanup_free_ char *user_home = NULL;
4789 _cleanup_free_ char *user_runtime = NULL;
4790 _cleanup_lookup_paths_free_ LookupPaths lp = {};
4791 _cleanup_strv_free_ char **names = NULL;
4792 char **name;
4793 sd_bus *bus;
4794 bool first = true;
4795 int r;
4796
4797 if (arg_transport != BUS_TRANSPORT_LOCAL) {
4798 log_error("Cannot remotely cat units.");
4799 return -EINVAL;
4800 }
4801
4802 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4803 if (r < 0)
4804 return r;
4805
4806 r = acquire_bus(BUS_MANAGER, &bus);
4807 if (r < 0)
4808 return r;
4809
4810 r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
4811 if (r < 0)
4812 return log_error_errno(r, "Failed to expand names: %m");
4813
4814 pager_open_if_enabled();
4815
4816 STRV_FOREACH(name, names) {
4817 _cleanup_free_ char *fragment_path = NULL;
4818 _cleanup_strv_free_ char **dropin_paths = NULL;
4819 char **path;
4820
4821 r = unit_find_paths(bus, *name, &lp, &fragment_path, &dropin_paths);
4822 if (r < 0)
4823 return r;
4824 else if (r == 0)
4825 return -ENOENT;
4826
4827 if (first)
4828 first = false;
4829 else
4830 puts("");
4831
4832 if (fragment_path) {
4833 r = cat_file(fragment_path, false);
4834 if (r < 0)
4835 return log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4836 }
4837
4838 STRV_FOREACH(path, dropin_paths) {
4839 r = cat_file(*path, path == dropin_paths);
4840 if (r < 0)
4841 return log_warning_errno(r, "Failed to cat %s: %m", *path);
4842 }
4843 }
4844
4845 return 0;
4846 }
4847
4848 static int set_property(int argc, char *argv[], void *userdata) {
4849 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
4850 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4851 _cleanup_free_ char *n = NULL;
4852 sd_bus *bus;
4853 char **i;
4854 int r;
4855
4856 polkit_agent_open_if_enabled();
4857
4858 r = acquire_bus(BUS_MANAGER, &bus);
4859 if (r < 0)
4860 return r;
4861
4862 r = sd_bus_message_new_method_call(
4863 bus,
4864 &m,
4865 "org.freedesktop.systemd1",
4866 "/org/freedesktop/systemd1",
4867 "org.freedesktop.systemd1.Manager",
4868 "SetUnitProperties");
4869 if (r < 0)
4870 return bus_log_create_error(r);
4871
4872 r = unit_name_mangle(argv[1], UNIT_NAME_NOGLOB, &n);
4873 if (r < 0)
4874 return log_error_errno(r, "Failed to mangle unit name: %m");
4875
4876 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4877 if (r < 0)
4878 return bus_log_create_error(r);
4879
4880 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4881 if (r < 0)
4882 return bus_log_create_error(r);
4883
4884 STRV_FOREACH(i, strv_skip(argv, 2)) {
4885 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4886 if (r < 0)
4887 return bus_log_create_error(r);
4888
4889 r = bus_append_unit_property_assignment(m, *i);
4890 if (r < 0)
4891 return r;
4892
4893 r = sd_bus_message_close_container(m);
4894 if (r < 0)
4895 return bus_log_create_error(r);
4896 }
4897
4898 r = sd_bus_message_close_container(m);
4899 if (r < 0)
4900 return bus_log_create_error(r);
4901
4902 r = sd_bus_call(bus, m, 0, &error, NULL);
4903 if (r < 0)
4904 return log_error_errno(r, "Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4905
4906 return 0;
4907 }
4908
4909 static int daemon_reload(int argc, char *argv[], void *userdata) {
4910 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4911 const char *method;
4912 sd_bus *bus;
4913 int r;
4914
4915 polkit_agent_open_if_enabled();
4916
4917 r = acquire_bus(BUS_MANAGER, &bus);
4918 if (r < 0)
4919 return r;
4920
4921 if (arg_action == ACTION_RELOAD)
4922 method = "Reload";
4923 else if (arg_action == ACTION_REEXEC)
4924 method = "Reexecute";
4925 else {
4926 assert(arg_action == ACTION_SYSTEMCTL);
4927
4928 method =
4929 streq(argv[0], "clear-jobs") ||
4930 streq(argv[0], "cancel") ? "ClearJobs" :
4931 streq(argv[0], "daemon-reexec") ? "Reexecute" :
4932 streq(argv[0], "reset-failed") ? "ResetFailed" :
4933 streq(argv[0], "halt") ? "Halt" :
4934 streq(argv[0], "poweroff") ? "PowerOff" :
4935 streq(argv[0], "reboot") ? "Reboot" :
4936 streq(argv[0], "kexec") ? "KExec" :
4937 streq(argv[0], "exit") ? "Exit" :
4938 /* "daemon-reload" */ "Reload";
4939 }
4940
4941 r = sd_bus_call_method(
4942 bus,
4943 "org.freedesktop.systemd1",
4944 "/org/freedesktop/systemd1",
4945 "org.freedesktop.systemd1.Manager",
4946 method,
4947 &error,
4948 NULL,
4949 NULL);
4950 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4951 /* There's always a fallback possible for
4952 * legacy actions. */
4953 r = -EADDRNOTAVAIL;
4954 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4955 /* On reexecution, we expect a disconnect, not a
4956 * reply */
4957 r = 0;
4958 else if (r < 0)
4959 return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
4960
4961 return r < 0 ? r : 0;
4962 }
4963
4964 static int reset_failed(int argc, char *argv[], void *userdata) {
4965 _cleanup_strv_free_ char **names = NULL;
4966 sd_bus *bus;
4967 char **name;
4968 int r, q;
4969
4970 if (argc <= 1)
4971 return daemon_reload(argc, argv, userdata);
4972
4973 polkit_agent_open_if_enabled();
4974
4975 r = acquire_bus(BUS_MANAGER, &bus);
4976 if (r < 0)
4977 return r;
4978
4979 r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
4980 if (r < 0)
4981 return log_error_errno(r, "Failed to expand names: %m");
4982
4983 STRV_FOREACH(name, names) {
4984 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4985
4986 q = sd_bus_call_method(
4987 bus,
4988 "org.freedesktop.systemd1",
4989 "/org/freedesktop/systemd1",
4990 "org.freedesktop.systemd1.Manager",
4991 "ResetFailedUnit",
4992 &error,
4993 NULL,
4994 "s", *name);
4995 if (q < 0) {
4996 log_error_errno(q, "Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4997 if (r == 0)
4998 r = q;
4999 }
5000 }
5001
5002 return r;
5003 }
5004
5005 static int show_environment(int argc, char *argv[], void *userdata) {
5006 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5007 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
5008 const char *text;
5009 sd_bus *bus;
5010 int r;
5011
5012 pager_open_if_enabled();
5013
5014 r = acquire_bus(BUS_MANAGER, &bus);
5015 if (r < 0)
5016 return r;
5017
5018 r = sd_bus_get_property(
5019 bus,
5020 "org.freedesktop.systemd1",
5021 "/org/freedesktop/systemd1",
5022 "org.freedesktop.systemd1.Manager",
5023 "Environment",
5024 &error,
5025 &reply,
5026 "as");
5027 if (r < 0)
5028 return log_error_errno(r, "Failed to get environment: %s", bus_error_message(&error, r));
5029
5030 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
5031 if (r < 0)
5032 return bus_log_parse_error(r);
5033
5034 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
5035 puts(text);
5036 if (r < 0)
5037 return bus_log_parse_error(r);
5038
5039 r = sd_bus_message_exit_container(reply);
5040 if (r < 0)
5041 return bus_log_parse_error(r);
5042
5043 return 0;
5044 }
5045
5046 static int switch_root(int argc, char *argv[], void *userdata) {
5047 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5048 _cleanup_free_ char *cmdline_init = NULL;
5049 const char *root, *init;
5050 sd_bus *bus;
5051 int r;
5052
5053 if (arg_transport != BUS_TRANSPORT_LOCAL) {
5054 log_error("Cannot switch root remotely.");
5055 return -EINVAL;
5056 }
5057
5058 if (argc < 2 || argc > 3) {
5059 log_error("Wrong number of arguments.");
5060 return -EINVAL;
5061 }
5062
5063 root = argv[1];
5064
5065 if (argc >= 3)
5066 init = argv[2];
5067 else {
5068 r = parse_env_file("/proc/cmdline", WHITESPACE,
5069 "init", &cmdline_init,
5070 NULL);
5071 if (r < 0)
5072 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
5073
5074 init = cmdline_init;
5075 }
5076
5077 if (isempty(init))
5078 init = NULL;
5079
5080 if (init) {
5081 const char *root_systemd_path = NULL, *root_init_path = NULL;
5082
5083 root_systemd_path = strjoina(root, "/" SYSTEMD_BINARY_PATH);
5084 root_init_path = strjoina(root, "/", init);
5085
5086 /* If the passed init is actually the same as the
5087 * systemd binary, then let's suppress it. */
5088 if (files_same(root_init_path, root_systemd_path) > 0)
5089 init = NULL;
5090 }
5091
5092 r = acquire_bus(BUS_MANAGER, &bus);
5093 if (r < 0)
5094 return r;
5095
5096 log_debug("Switching root - root: %s; init: %s", root, strna(init));
5097
5098 r = sd_bus_call_method(
5099 bus,
5100 "org.freedesktop.systemd1",
5101 "/org/freedesktop/systemd1",
5102 "org.freedesktop.systemd1.Manager",
5103 "SwitchRoot",
5104 &error,
5105 NULL,
5106 "ss", root, init);
5107 if (r < 0)
5108 return log_error_errno(r, "Failed to switch root: %s", bus_error_message(&error, r));
5109
5110 return 0;
5111 }
5112
5113 static int set_environment(int argc, char *argv[], void *userdata) {
5114 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5115 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
5116 const char *method;
5117 sd_bus *bus;
5118 int r;
5119
5120 assert(argc > 1);
5121 assert(argv);
5122
5123 polkit_agent_open_if_enabled();
5124
5125 r = acquire_bus(BUS_MANAGER, &bus);
5126 if (r < 0)
5127 return r;
5128
5129 method = streq(argv[0], "set-environment")
5130 ? "SetEnvironment"
5131 : "UnsetEnvironment";
5132
5133 r = sd_bus_message_new_method_call(
5134 bus,
5135 &m,
5136 "org.freedesktop.systemd1",
5137 "/org/freedesktop/systemd1",
5138 "org.freedesktop.systemd1.Manager",
5139 method);
5140 if (r < 0)
5141 return bus_log_create_error(r);
5142
5143 r = sd_bus_message_append_strv(m, strv_skip(argv, 1));
5144 if (r < 0)
5145 return bus_log_create_error(r);
5146
5147 r = sd_bus_call(bus, m, 0, &error, NULL);
5148 if (r < 0)
5149 return log_error_errno(r, "Failed to set environment: %s", bus_error_message(&error, r));
5150
5151 return 0;
5152 }
5153
5154 static int import_environment(int argc, char *argv[], void *userdata) {
5155 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5156 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
5157 sd_bus *bus;
5158 int r;
5159
5160 polkit_agent_open_if_enabled();
5161
5162 r = acquire_bus(BUS_MANAGER, &bus);
5163 if (r < 0)
5164 return r;
5165
5166 r = sd_bus_message_new_method_call(
5167 bus,
5168 &m,
5169 "org.freedesktop.systemd1",
5170 "/org/freedesktop/systemd1",
5171 "org.freedesktop.systemd1.Manager",
5172 "SetEnvironment");
5173 if (r < 0)
5174 return bus_log_create_error(r);
5175
5176 if (argc < 2)
5177 r = sd_bus_message_append_strv(m, environ);
5178 else {
5179 char **a, **b;
5180
5181 r = sd_bus_message_open_container(m, 'a', "s");
5182 if (r < 0)
5183 return bus_log_create_error(r);
5184
5185 STRV_FOREACH(a, strv_skip(argv, 1)) {
5186
5187 if (!env_name_is_valid(*a)) {
5188 log_error("Not a valid environment variable name: %s", *a);
5189 return -EINVAL;
5190 }
5191
5192 STRV_FOREACH(b, environ) {
5193 const char *eq;
5194
5195 eq = startswith(*b, *a);
5196 if (eq && *eq == '=') {
5197
5198 r = sd_bus_message_append(m, "s", *b);
5199 if (r < 0)
5200 return bus_log_create_error(r);
5201
5202 break;
5203 }
5204 }
5205 }
5206
5207 r = sd_bus_message_close_container(m);
5208 }
5209 if (r < 0)
5210 return bus_log_create_error(r);
5211
5212 r = sd_bus_call(bus, m, 0, &error, NULL);
5213 if (r < 0)
5214 return log_error_errno(r, "Failed to import environment: %s", bus_error_message(&error, r));
5215
5216 return 0;
5217 }
5218
5219 static int enable_sysv_units(const char *verb, char **args) {
5220 int r = 0;
5221
5222 #if defined(HAVE_SYSV_COMPAT)
5223 unsigned f = 0;
5224 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5225
5226 if (arg_scope != UNIT_FILE_SYSTEM)
5227 return 0;
5228
5229 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5230 return 0;
5231
5232 if (!STR_IN_SET(verb,
5233 "enable",
5234 "disable",
5235 "is-enabled"))
5236 return 0;
5237
5238 /* Processes all SysV units, and reshuffles the array so that
5239 * afterwards only the native units remain */
5240
5241 r = lookup_paths_init(&paths, MANAGER_SYSTEM, false, arg_root, NULL, NULL, NULL);
5242 if (r < 0)
5243 return r;
5244
5245 r = 0;
5246 while (args[f]) {
5247 const char *name;
5248 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5249 bool found_native = false, found_sysv;
5250 unsigned c = 1;
5251 const char *argv[6] = { ROOTLIBEXECDIR "/systemd-sysv-install", NULL, NULL, NULL, NULL };
5252 char **k;
5253 int j;
5254 pid_t pid;
5255 siginfo_t status;
5256
5257 name = args[f++];
5258
5259 if (!endswith(name, ".service"))
5260 continue;
5261
5262 if (path_is_absolute(name))
5263 continue;
5264
5265 STRV_FOREACH(k, paths.unit_path) {
5266 _cleanup_free_ char *path = NULL;
5267
5268 path = path_join(arg_root, *k, name);
5269 if (!path)
5270 return log_oom();
5271
5272 found_native = access(path, F_OK) >= 0;
5273 if (found_native)
5274 break;
5275 }
5276
5277 /* If we have both a native unit and a SysV script,
5278 * enable/disable them both (below); for is-enabled, prefer the
5279 * native unit */
5280 if (found_native && streq(verb, "is-enabled"))
5281 continue;
5282
5283 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5284 if (!p)
5285 return log_oom();
5286
5287 p[strlen(p) - strlen(".service")] = 0;
5288 found_sysv = access(p, F_OK) >= 0;
5289 if (!found_sysv)
5290 continue;
5291
5292 if (found_native)
5293 log_info("Synchronizing state of %s with SysV init with %s...", name, argv[0]);
5294 else
5295 log_info("%s is not a native service, redirecting to systemd-sysv-install", name);
5296
5297 if (!isempty(arg_root))
5298 argv[c++] = q = strappend("--root=", arg_root);
5299
5300 argv[c++] = verb;
5301 argv[c++] = basename(p);
5302 argv[c] = NULL;
5303
5304 l = strv_join((char**)argv, " ");
5305 if (!l)
5306 return log_oom();
5307
5308 log_info("Executing %s", l);
5309
5310 pid = fork();
5311 if (pid < 0)
5312 return log_error_errno(errno, "Failed to fork: %m");
5313 else if (pid == 0) {
5314 /* Child */
5315
5316 (void) reset_all_signal_handlers();
5317 (void) reset_signal_mask();
5318
5319 execv(argv[0], (char**) argv);
5320 log_error_errno(r, "Failed to execute %s: %m", argv[0]);
5321 _exit(EXIT_FAILURE);
5322 }
5323
5324 j = wait_for_terminate(pid, &status);
5325 if (j < 0) {
5326 log_error_errno(j, "Failed to wait for child: %m");
5327 return j;
5328 }
5329
5330 if (status.si_code == CLD_EXITED) {
5331 if (streq(verb, "is-enabled")) {
5332 if (status.si_status == 0) {
5333 if (!arg_quiet)
5334 puts("enabled");
5335 r = 1;
5336 } else {
5337 if (!arg_quiet)
5338 puts("disabled");
5339 }
5340
5341 } else if (status.si_status != 0)
5342 return -EINVAL;
5343 } else
5344 return -EPROTO;
5345
5346 if (found_native)
5347 continue;
5348
5349 /* Remove this entry, so that we don't try enabling it as native unit */
5350 assert(f > 0);
5351 f--;
5352 assert(args[f] == name);
5353 strv_remove(args, name);
5354 }
5355
5356 #endif
5357 return r;
5358 }
5359
5360 static int mangle_names(char **original_names, char ***mangled_names) {
5361 char **i, **l, **name;
5362 int r;
5363
5364 l = i = new(char*, strv_length(original_names) + 1);
5365 if (!l)
5366 return log_oom();
5367
5368 STRV_FOREACH(name, original_names) {
5369
5370 /* When enabling units qualified path names are OK,
5371 * too, hence allow them explicitly. */
5372
5373 if (is_path(*name)) {
5374 *i = strdup(*name);
5375 if (!*i) {
5376 strv_free(l);
5377 return log_oom();
5378 }
5379 } else {
5380 r = unit_name_mangle(*name, UNIT_NAME_NOGLOB, i);
5381 if (r < 0) {
5382 strv_free(l);
5383 return log_error_errno(r, "Failed to mangle unit name: %m");
5384 }
5385 }
5386
5387 i++;
5388 }
5389
5390 *i = NULL;
5391 *mangled_names = l;
5392
5393 return 0;
5394 }
5395
5396 static int enable_unit(int argc, char *argv[], void *userdata) {
5397 _cleanup_strv_free_ char **names = NULL;
5398 const char *verb = argv[0];
5399 UnitFileChange *changes = NULL;
5400 unsigned n_changes = 0;
5401 int carries_install_info = -1;
5402 int r;
5403
5404 if (!argv[1])
5405 return 0;
5406
5407 r = mangle_names(strv_skip(argv, 1), &names);
5408 if (r < 0)
5409 return r;
5410
5411 r = enable_sysv_units(verb, names);
5412 if (r < 0)
5413 return r;
5414
5415 /* If the operation was fully executed by the SysV compat,
5416 * let's finish early */
5417 if (strv_isempty(names))
5418 return 0;
5419
5420 if (install_client_side()) {
5421 if (streq(verb, "enable")) {
5422 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5423 carries_install_info = r;
5424 } else if (streq(verb, "disable"))
5425 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5426 else if (streq(verb, "reenable")) {
5427 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5428 carries_install_info = r;
5429 } else if (streq(verb, "link"))
5430 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5431 else if (streq(verb, "preset")) {
5432 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5433 carries_install_info = r;
5434 } else if (streq(verb, "mask"))
5435 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5436 else if (streq(verb, "unmask"))
5437 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5438 else
5439 assert_not_reached("Unknown verb");
5440
5441 if (r == -ESHUTDOWN)
5442 return log_error_errno(r, "Unit file is masked.");
5443 if (r < 0)
5444 return log_error_errno(r, "Operation failed: %m");
5445
5446 if (!arg_quiet)
5447 dump_unit_file_changes(changes, n_changes);
5448
5449 r = 0;
5450 } else {
5451 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
5452 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5453 int expect_carries_install_info = false;
5454 bool send_force = true, send_preset_mode = false;
5455 const char *method;
5456 sd_bus *bus;
5457
5458 polkit_agent_open_if_enabled();
5459
5460 r = acquire_bus(BUS_MANAGER, &bus);
5461 if (r < 0)
5462 return r;
5463
5464 if (streq(verb, "enable")) {
5465 method = "EnableUnitFiles";
5466 expect_carries_install_info = true;
5467 } else if (streq(verb, "disable")) {
5468 method = "DisableUnitFiles";
5469 send_force = false;
5470 } else if (streq(verb, "reenable")) {
5471 method = "ReenableUnitFiles";
5472 expect_carries_install_info = true;
5473 } else if (streq(verb, "link"))
5474 method = "LinkUnitFiles";
5475 else if (streq(verb, "preset")) {
5476
5477 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5478 method = "PresetUnitFilesWithMode";
5479 send_preset_mode = true;
5480 } else
5481 method = "PresetUnitFiles";
5482
5483 expect_carries_install_info = true;
5484 } else if (streq(verb, "mask"))
5485 method = "MaskUnitFiles";
5486 else if (streq(verb, "unmask")) {
5487 method = "UnmaskUnitFiles";
5488 send_force = false;
5489 } else
5490 assert_not_reached("Unknown verb");
5491
5492 r = sd_bus_message_new_method_call(
5493 bus,
5494 &m,
5495 "org.freedesktop.systemd1",
5496 "/org/freedesktop/systemd1",
5497 "org.freedesktop.systemd1.Manager",
5498 method);
5499 if (r < 0)
5500 return bus_log_create_error(r);
5501
5502 r = sd_bus_message_append_strv(m, names);
5503 if (r < 0)
5504 return bus_log_create_error(r);
5505
5506 if (send_preset_mode) {
5507 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5508 if (r < 0)
5509 return bus_log_create_error(r);
5510 }
5511
5512 r = sd_bus_message_append(m, "b", arg_runtime);
5513 if (r < 0)
5514 return bus_log_create_error(r);
5515
5516 if (send_force) {
5517 r = sd_bus_message_append(m, "b", arg_force);
5518 if (r < 0)
5519 return bus_log_create_error(r);
5520 }
5521
5522 r = sd_bus_call(bus, m, 0, &error, &reply);
5523 if (r < 0)
5524 return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
5525
5526 if (expect_carries_install_info) {
5527 r = sd_bus_message_read(reply, "b", &carries_install_info);
5528 if (r < 0)
5529 return bus_log_parse_error(r);
5530 }
5531
5532 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
5533 if (r < 0)
5534 return r;
5535
5536 /* Try to reload if enabled */
5537 if (!arg_no_reload)
5538 r = daemon_reload(argc, argv, userdata);
5539 else
5540 r = 0;
5541 }
5542
5543 if (carries_install_info == 0)
5544 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5545 "using systemctl.\n"
5546 "Possible reasons for having this kind of units are:\n"
5547 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5548 " .wants/ or .requires/ directory.\n"
5549 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5550 " a requirement dependency on it.\n"
5551 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5552 " D-Bus, udev, scripted systemctl call, ...).\n");
5553
5554 if (arg_now && n_changes > 0 && STR_IN_SET(argv[0], "enable", "disable", "mask")) {
5555 char *new_args[n_changes + 2];
5556 sd_bus *bus;
5557 unsigned i;
5558
5559 r = acquire_bus(BUS_MANAGER, &bus);
5560 if (r < 0)
5561 goto finish;
5562
5563 new_args[0] = (char*) (streq(argv[0], "enable") ? "start" : "stop");
5564 for (i = 0; i < n_changes; i++)
5565 new_args[i + 1] = basename(changes[i].path);
5566 new_args[i + 1] = NULL;
5567
5568 r = start_unit(strv_length(new_args), new_args, userdata);
5569 }
5570
5571 finish:
5572 unit_file_changes_free(changes, n_changes);
5573
5574 return r;
5575 }
5576
5577 static int add_dependency(int argc, char *argv[], void *userdata) {
5578 _cleanup_strv_free_ char **names = NULL;
5579 _cleanup_free_ char *target = NULL;
5580 const char *verb = argv[0];
5581 UnitDependency dep;
5582 int r = 0;
5583
5584 if (!argv[1])
5585 return 0;
5586
5587 r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".target", &target);
5588 if (r < 0)
5589 return log_error_errno(r, "Failed to mangle unit name: %m");
5590
5591 r = mangle_names(strv_skip(argv, 2), &names);
5592 if (r < 0)
5593 return r;
5594
5595 if (streq(verb, "add-wants"))
5596 dep = UNIT_WANTS;
5597 else if (streq(verb, "add-requires"))
5598 dep = UNIT_REQUIRES;
5599 else
5600 assert_not_reached("Unknown verb");
5601
5602 if (install_client_side()) {
5603 UnitFileChange *changes = NULL;
5604 unsigned n_changes = 0;
5605
5606 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5607 if (r == -ESHUTDOWN)
5608 return log_error_errno(r, "Unit file is masked.");
5609 if (r < 0)
5610 return log_error_errno(r, "Can't add dependency: %m");
5611
5612 if (!arg_quiet)
5613 dump_unit_file_changes(changes, n_changes);
5614
5615 unit_file_changes_free(changes, n_changes);
5616
5617 } else {
5618 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
5619 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5620 sd_bus *bus;
5621
5622 polkit_agent_open_if_enabled();
5623
5624 r = acquire_bus(BUS_MANAGER, &bus);
5625 if (r < 0)
5626 return r;
5627
5628 r = sd_bus_message_new_method_call(
5629 bus,
5630 &m,
5631 "org.freedesktop.systemd1",
5632 "/org/freedesktop/systemd1",
5633 "org.freedesktop.systemd1.Manager",
5634 "AddDependencyUnitFiles");
5635 if (r < 0)
5636 return bus_log_create_error(r);
5637
5638 r = sd_bus_message_append_strv(m, names);
5639 if (r < 0)
5640 return bus_log_create_error(r);
5641
5642 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5643 if (r < 0)
5644 return bus_log_create_error(r);
5645
5646 r = sd_bus_call(bus, m, 0, &error, &reply);
5647 if (r < 0)
5648 return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
5649
5650 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
5651 if (r < 0)
5652 return r;
5653
5654 if (!arg_no_reload)
5655 r = daemon_reload(argc, argv, userdata);
5656 else
5657 r = 0;
5658 }
5659
5660 return r;
5661 }
5662
5663 static int preset_all(int argc, char *argv[], void *userdata) {
5664 UnitFileChange *changes = NULL;
5665 unsigned n_changes = 0;
5666 int r;
5667
5668 if (install_client_side()) {
5669
5670 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5671 if (r < 0) {
5672 log_error_errno(r, "Operation failed: %m");
5673 goto finish;
5674 }
5675
5676 if (!arg_quiet)
5677 dump_unit_file_changes(changes, n_changes);
5678
5679 r = 0;
5680
5681 } else {
5682 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5683 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
5684 sd_bus *bus;
5685
5686 polkit_agent_open_if_enabled();
5687
5688 r = acquire_bus(BUS_MANAGER, &bus);
5689 if (r < 0)
5690 return r;
5691
5692 r = sd_bus_call_method(
5693 bus,
5694 "org.freedesktop.systemd1",
5695 "/org/freedesktop/systemd1",
5696 "org.freedesktop.systemd1.Manager",
5697 "PresetAllUnitFiles",
5698 &error,
5699 &reply,
5700 "sbb",
5701 unit_file_preset_mode_to_string(arg_preset_mode),
5702 arg_runtime,
5703 arg_force);
5704 if (r < 0)
5705 return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
5706
5707 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
5708 if (r < 0)
5709 return r;
5710
5711 if (!arg_no_reload)
5712 r = daemon_reload(argc, argv, userdata);
5713 else
5714 r = 0;
5715 }
5716
5717 finish:
5718 unit_file_changes_free(changes, n_changes);
5719
5720 return r;
5721 }
5722
5723 static int unit_is_enabled(int argc, char *argv[], void *userdata) {
5724
5725 _cleanup_strv_free_ char **names = NULL;
5726 bool enabled;
5727 char **name;
5728 int r;
5729
5730 r = mangle_names(strv_skip(argv, 1), &names);
5731 if (r < 0)
5732 return r;
5733
5734 r = enable_sysv_units(argv[0], names);
5735 if (r < 0)
5736 return r;
5737
5738 enabled = r > 0;
5739
5740 if (install_client_side()) {
5741
5742 STRV_FOREACH(name, names) {
5743 UnitFileState state;
5744
5745 r = unit_file_get_state(arg_scope, arg_root, *name, &state);
5746 if (r < 0)
5747 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5748
5749 if (IN_SET(state,
5750 UNIT_FILE_ENABLED,
5751 UNIT_FILE_ENABLED_RUNTIME,
5752 UNIT_FILE_STATIC,
5753 UNIT_FILE_INDIRECT))
5754 enabled = true;
5755
5756 if (!arg_quiet)
5757 puts(unit_file_state_to_string(state));
5758 }
5759
5760 } else {
5761 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5762 sd_bus *bus;
5763
5764 r = acquire_bus(BUS_MANAGER, &bus);
5765 if (r < 0)
5766 return r;
5767
5768 STRV_FOREACH(name, names) {
5769 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
5770 const char *s;
5771
5772 r = sd_bus_call_method(
5773 bus,
5774 "org.freedesktop.systemd1",
5775 "/org/freedesktop/systemd1",
5776 "org.freedesktop.systemd1.Manager",
5777 "GetUnitFileState",
5778 &error,
5779 &reply,
5780 "s", *name);
5781 if (r < 0)
5782 return log_error_errno(r, "Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5783
5784 r = sd_bus_message_read(reply, "s", &s);
5785 if (r < 0)
5786 return bus_log_parse_error(r);
5787
5788 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5789 enabled = true;
5790
5791 if (!arg_quiet)
5792 puts(s);
5793 }
5794 }
5795
5796 return !enabled;
5797 }
5798
5799 static int is_system_running(int argc, char *argv[], void *userdata) {
5800 _cleanup_free_ char *state = NULL;
5801 sd_bus *bus;
5802 int r;
5803
5804 if (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted()) {
5805 if (!arg_quiet)
5806 puts("offline");
5807 return EXIT_FAILURE;
5808 }
5809
5810 r = acquire_bus(BUS_MANAGER, &bus);
5811 if (r < 0)
5812 return r;
5813
5814 r = sd_bus_get_property_string(
5815 bus,
5816 "org.freedesktop.systemd1",
5817 "/org/freedesktop/systemd1",
5818 "org.freedesktop.systemd1.Manager",
5819 "SystemState",
5820 NULL,
5821 &state);
5822 if (r < 0) {
5823 if (!arg_quiet)
5824 puts("unknown");
5825 return 0;
5826 }
5827
5828 if (!arg_quiet)
5829 puts(state);
5830
5831 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5832 }
5833
5834 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5835 _cleanup_free_ char *t = NULL;
5836 int r;
5837
5838 assert(new_path);
5839 assert(original_path);
5840 assert(ret_tmp_fn);
5841
5842 r = tempfn_random(new_path, NULL, &t);
5843 if (r < 0)
5844 return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
5845
5846 r = mkdir_parents(new_path, 0755);
5847 if (r < 0)
5848 return log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
5849
5850 r = copy_file(original_path, t, 0, 0644, 0);
5851 if (r == -ENOENT) {
5852
5853 r = touch(t);
5854 if (r < 0)
5855 return log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
5856
5857 } else if (r < 0)
5858 return log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
5859
5860 *ret_tmp_fn = t;
5861 t = NULL;
5862
5863 return 0;
5864 }
5865
5866 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5867 _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5868
5869 assert(name);
5870 assert(ret_path);
5871
5872 switch (arg_scope) {
5873 case UNIT_FILE_SYSTEM:
5874 path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5875 if (arg_runtime)
5876 run = path_join(arg_root, "/run/systemd/system/", name);
5877 break;
5878 case UNIT_FILE_GLOBAL:
5879 path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5880 if (arg_runtime)
5881 run = path_join(arg_root, "/run/systemd/user/", name);
5882 break;
5883 case UNIT_FILE_USER:
5884 assert(user_home);
5885 assert(user_runtime);
5886
5887 path = path_join(arg_root, user_home, name);
5888 if (arg_runtime) {
5889 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5890 if (!path2)
5891 return log_oom();
5892 run = path_join(arg_root, user_runtime, name);
5893 }
5894 break;
5895 default:
5896 assert_not_reached("Invalid scope");
5897 }
5898 if (!path || (arg_runtime && !run))
5899 return log_oom();
5900
5901 if (arg_runtime) {
5902 if (access(path, F_OK) >= 0) {
5903 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path);
5904 return -EEXIST;
5905 }
5906
5907 if (path2 && access(path2, F_OK) >= 0) {
5908 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path2);
5909 return -EEXIST;
5910 }
5911
5912 *ret_path = run;
5913 run = NULL;
5914 } else {
5915 *ret_path = path;
5916 path = NULL;
5917 }
5918
5919 return 0;
5920 }
5921
5922 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) {
5923 char *tmp_new_path, *tmp_tmp_path, *ending;
5924 int r;
5925
5926 assert(unit_name);
5927 assert(ret_new_path);
5928 assert(ret_tmp_path);
5929
5930 ending = strjoina(unit_name, ".d/override.conf");
5931 r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5932 if (r < 0)
5933 return r;
5934
5935 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5936 if (r < 0) {
5937 free(tmp_new_path);
5938 return r;
5939 }
5940
5941 *ret_new_path = tmp_new_path;
5942 *ret_tmp_path = tmp_tmp_path;
5943
5944 return 0;
5945 }
5946
5947 static int unit_file_create_copy(
5948 const char *unit_name,
5949 const char *fragment_path,
5950 const char *user_home,
5951 const char *user_runtime,
5952 char **ret_new_path,
5953 char **ret_tmp_path) {
5954
5955 char *tmp_new_path, *tmp_tmp_path;
5956 int r;
5957
5958 assert(fragment_path);
5959 assert(unit_name);
5960 assert(ret_new_path);
5961 assert(ret_tmp_path);
5962
5963 r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5964 if (r < 0)
5965 return r;
5966
5967 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5968 char response;
5969
5970 r = ask_char(&response, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path, fragment_path);
5971 if (r < 0) {
5972 free(tmp_new_path);
5973 return r;
5974 }
5975 if (response != 'y') {
5976 log_warning("%s ignored", unit_name);
5977 free(tmp_new_path);
5978 return -1;
5979 }
5980 }
5981
5982 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5983 if (r < 0) {
5984 log_error_errno(r, "Failed to create temporary file for \"%s\": %m", tmp_new_path);
5985 free(tmp_new_path);
5986 return r;
5987 }
5988
5989 *ret_new_path = tmp_new_path;
5990 *ret_tmp_path = tmp_tmp_path;
5991
5992 return 0;
5993 }
5994
5995 static int run_editor(char **paths) {
5996 pid_t pid;
5997 int r;
5998
5999 assert(paths);
6000
6001 pid = fork();
6002 if (pid < 0)
6003 return log_error_errno(errno, "Failed to fork: %m");
6004
6005 if (pid == 0) {
6006 const char **args;
6007 char *editor, **editor_args = NULL;
6008 char **tmp_path, **original_path, *p;
6009 unsigned n_editor_args = 0, i = 1;
6010 size_t argc;
6011
6012 (void) reset_all_signal_handlers();
6013 (void) reset_signal_mask();
6014
6015 argc = strv_length(paths)/2 + 1;
6016
6017 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6018 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6019 * we try to execute well known editors
6020 */
6021 editor = getenv("SYSTEMD_EDITOR");
6022 if (!editor)
6023 editor = getenv("EDITOR");
6024 if (!editor)
6025 editor = getenv("VISUAL");
6026
6027 if (!isempty(editor)) {
6028 editor_args = strv_split(editor, WHITESPACE);
6029 if (!editor_args) {
6030 (void) log_oom();
6031 _exit(EXIT_FAILURE);
6032 }
6033 n_editor_args = strv_length(editor_args);
6034 argc += n_editor_args - 1;
6035 }
6036 args = newa(const char*, argc + 1);
6037
6038 if (n_editor_args > 0) {
6039 args[0] = editor_args[0];
6040 for (; i < n_editor_args; i++)
6041 args[i] = editor_args[i];
6042 }
6043
6044 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
6045 args[i] = *tmp_path;
6046 i++;
6047 }
6048 args[i] = NULL;
6049
6050 if (n_editor_args > 0)
6051 execvp(args[0], (char* const*) args);
6052
6053 FOREACH_STRING(p, "editor", "nano", "vim", "vi") {
6054 args[0] = p;
6055 execvp(p, (char* const*) args);
6056 /* We do not fail if the editor doesn't exist
6057 * because we want to try each one of them before
6058 * failing.
6059 */
6060 if (errno != ENOENT) {
6061 log_error_errno(errno, "Failed to execute %s: %m", editor);
6062 _exit(EXIT_FAILURE);
6063 }
6064 }
6065
6066 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6067 _exit(EXIT_FAILURE);
6068 }
6069
6070 r = wait_for_terminate_and_warn("editor", pid, true);
6071 if (r < 0)
6072 return log_error_errno(r, "Failed to wait for child: %m");
6073
6074 return 0;
6075 }
6076
6077 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
6078 _cleanup_free_ char *user_home = NULL;
6079 _cleanup_free_ char *user_runtime = NULL;
6080 _cleanup_lookup_paths_free_ LookupPaths lp = {};
6081 char **name;
6082 int r;
6083
6084 assert(names);
6085 assert(paths);
6086
6087 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
6088 if (r < 0)
6089 return r;
6090
6091 STRV_FOREACH(name, names) {
6092 _cleanup_free_ char *path = NULL;
6093 char *new_path, *tmp_path;
6094
6095 r = unit_find_paths(bus, *name, &lp, &path, NULL);
6096 if (r < 0)
6097 return r;
6098 else if (r == 0)
6099 return -ENOENT;
6100 else if (!path) {
6101 // FIXME: support units with path==NULL (no FragmentPath)
6102 log_error("No fragment exists for %s.", *name);
6103 return -ENOENT;
6104 }
6105
6106 if (arg_full)
6107 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
6108 else
6109 r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
6110 if (r < 0)
6111 return r;
6112
6113 r = strv_push_pair(paths, new_path, tmp_path);
6114 if (r < 0)
6115 return log_oom();
6116 }
6117
6118 return 0;
6119 }
6120
6121 static int edit(int argc, char *argv[], void *userdata) {
6122 _cleanup_strv_free_ char **names = NULL;
6123 _cleanup_strv_free_ char **paths = NULL;
6124 char **original, **tmp;
6125 sd_bus *bus;
6126 int r;
6127
6128 if (!on_tty()) {
6129 log_error("Cannot edit units if not on a tty.");
6130 return -EINVAL;
6131 }
6132
6133 if (arg_transport != BUS_TRANSPORT_LOCAL) {
6134 log_error("Cannot edit units remotely.");
6135 return -EINVAL;
6136 }
6137
6138 r = acquire_bus(BUS_MANAGER, &bus);
6139 if (r < 0)
6140 return r;
6141
6142 r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
6143 if (r < 0)
6144 return log_error_errno(r, "Failed to expand names: %m");
6145
6146 r = find_paths_to_edit(bus, names, &paths);
6147 if (r < 0)
6148 return r;
6149
6150 if (strv_isempty(paths))
6151 return -ENOENT;
6152
6153 r = run_editor(paths);
6154 if (r < 0)
6155 goto end;
6156
6157 STRV_FOREACH_PAIR(original, tmp, paths) {
6158 /* If the temporary file is empty we ignore it. It's
6159 * useful if the user wants to cancel its modification
6160 */
6161 if (null_or_empty_path(*tmp)) {
6162 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original);
6163 continue;
6164 }
6165
6166 r = rename(*tmp, *original);
6167 if (r < 0) {
6168 r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
6169 goto end;
6170 }
6171 }
6172
6173 r = 0;
6174
6175 if (!arg_no_reload && !install_client_side())
6176 r = daemon_reload(argc, argv, userdata);
6177
6178 end:
6179 STRV_FOREACH_PAIR(original, tmp, paths)
6180 (void) unlink(*tmp);
6181
6182 return r;
6183 }
6184
6185 static void systemctl_help(void) {
6186
6187 pager_open_if_enabled();
6188
6189 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6190 "Query or send control commands to the systemd manager.\n\n"
6191 " -h --help Show this help\n"
6192 " --version Show package version\n"
6193 " --system Connect to system manager\n"
6194 " --user Connect to user service manager\n"
6195 " -H --host=[USER@]HOST\n"
6196 " Operate on remote host\n"
6197 " -M --machine=CONTAINER\n"
6198 " Operate on local container\n"
6199 " -t --type=TYPE List units of a particular type\n"
6200 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6201 " -p --property=NAME Show only properties by this name\n"
6202 " -a --all Show all loaded units/properties, including dead/empty\n"
6203 " ones. To list all units installed on the system, use\n"
6204 " the 'list-unit-files' command instead.\n"
6205 " -l --full Don't ellipsize unit names on output\n"
6206 " -r --recursive Show unit list of host and local containers\n"
6207 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6208 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6209 " queueing a new job\n"
6210 " --show-types When showing sockets, explicitly show their type\n"
6211 " -i --ignore-inhibitors\n"
6212 " When shutting down or sleeping, ignore inhibitors\n"
6213 " --kill-who=WHO Who to send signal to\n"
6214 " -s --signal=SIGNAL Which signal to send\n"
6215 " --now Start or stop unit in addition to enabling or disabling it\n"
6216 " -q --quiet Suppress output\n"
6217 " --no-block Do not wait until operation finished\n"
6218 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6219 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6220 " --no-legend Do not print a legend (column headers and hints)\n"
6221 " --no-pager Do not pipe output into a pager\n"
6222 " --no-ask-password\n"
6223 " Do not ask for system passwords\n"
6224 " --global Enable/disable unit files globally\n"
6225 " --runtime Enable unit files only temporarily until next reboot\n"
6226 " -f --force When enabling unit files, override existing symlinks\n"
6227 " When shutting down, execute action immediately\n"
6228 " --preset-mode= Apply only enable, only disable, or all presets\n"
6229 " --root=PATH Enable unit files in the specified root directory\n"
6230 " -n --lines=INTEGER Number of journal entries to show\n"
6231 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6232 " short-precise, short-monotonic, verbose,\n"
6233 " export, json, json-pretty, json-sse, cat)\n"
6234 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6235 " --plain Print unit dependencies as a list instead of a tree\n\n"
6236 "Unit Commands:\n"
6237 " list-units [PATTERN...] List loaded units\n"
6238 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6239 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6240 " start NAME... Start (activate) one or more units\n"
6241 " stop NAME... Stop (deactivate) one or more units\n"
6242 " reload NAME... Reload one or more units\n"
6243 " restart NAME... Start or restart one or more units\n"
6244 " try-restart NAME... Restart one or more units if active\n"
6245 " reload-or-restart NAME... Reload one or more units if possible,\n"
6246 " otherwise start or restart\n"
6247 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6248 " otherwise restart if active\n"
6249 " isolate NAME Start one unit and stop all others\n"
6250 " kill NAME... Send signal to processes of a unit\n"
6251 " is-active PATTERN... Check whether units are active\n"
6252 " is-failed PATTERN... Check whether units are failed\n"
6253 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6254 " show [PATTERN...|JOB...] Show properties of one or more\n"
6255 " units/jobs or the manager\n"
6256 " cat PATTERN... Show files and drop-ins of one or more units\n"
6257 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6258 " help PATTERN...|PID... Show manual for one or more units\n"
6259 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6260 " units\n"
6261 " list-dependencies [NAME] Recursively show units which are required\n"
6262 " or wanted by this unit or by which this\n"
6263 " unit is required or wanted\n\n"
6264 "Unit File Commands:\n"
6265 " list-unit-files [PATTERN...] List installed unit files\n"
6266 " enable NAME... Enable one or more unit files\n"
6267 " disable NAME... Disable one or more unit files\n"
6268 " reenable NAME... Reenable one or more unit files\n"
6269 " preset NAME... Enable/disable one or more unit files\n"
6270 " based on preset configuration\n"
6271 " preset-all Enable/disable all unit files based on\n"
6272 " preset configuration\n"
6273 " is-enabled NAME... Check whether unit files are enabled\n"
6274 " mask NAME... Mask one or more units\n"
6275 " unmask NAME... Unmask one or more units\n"
6276 " link PATH... Link one or more units files into\n"
6277 " the search path\n"
6278 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6279 " on specified one or more units\n"
6280 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6281 " on specified one or more units\n"
6282 " edit NAME... Edit one or more unit files\n"
6283 " get-default Get the name of the default target\n"
6284 " set-default NAME Set the default target\n\n"
6285 "Machine Commands:\n"
6286 " list-machines [PATTERN...] List local containers and host\n\n"
6287 "Job Commands:\n"
6288 " list-jobs [PATTERN...] List jobs\n"
6289 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6290 "Environment Commands:\n"
6291 " show-environment Dump environment\n"
6292 " set-environment NAME=VALUE... Set one or more environment variables\n"
6293 " unset-environment NAME... Unset one or more environment variables\n"
6294 " import-environment [NAME...] Import all or some environment variables\n\n"
6295 "Manager Lifecycle Commands:\n"
6296 " daemon-reload Reload systemd manager configuration\n"
6297 " daemon-reexec Reexecute systemd manager\n\n"
6298 "System Commands:\n"
6299 " is-system-running Check whether system is fully running\n"
6300 " default Enter system default mode\n"
6301 " rescue Enter system rescue mode\n"
6302 " emergency Enter system emergency mode\n"
6303 " halt Shut down and halt the system\n"
6304 " poweroff Shut down and power-off the system\n"
6305 " reboot [ARG] Shut down and reboot the system\n"
6306 " kexec Shut down and reboot the system with kexec\n"
6307 " exit [EXIT_CODE] Request user instance or container exit\n"
6308 " switch-root ROOT [INIT] Change to a different root file system\n"
6309 " suspend Suspend the system\n"
6310 " hibernate Hibernate the system\n"
6311 " hybrid-sleep Hibernate and suspend the system\n",
6312 program_invocation_short_name);
6313 }
6314
6315 static void halt_help(void) {
6316 printf("%s [OPTIONS...]%s\n\n"
6317 "%s the system.\n\n"
6318 " --help Show this help\n"
6319 " --halt Halt the machine\n"
6320 " -p --poweroff Switch off the machine\n"
6321 " --reboot Reboot the machine\n"
6322 " -f --force Force immediate halt/power-off/reboot\n"
6323 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6324 " -d --no-wtmp Don't write wtmp record\n"
6325 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6326 program_invocation_short_name,
6327 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6328 arg_action == ACTION_REBOOT ? "Reboot" :
6329 arg_action == ACTION_POWEROFF ? "Power off" :
6330 "Halt");
6331 }
6332
6333 static void shutdown_help(void) {
6334 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6335 "Shut down the system.\n\n"
6336 " --help Show this help\n"
6337 " -H --halt Halt the machine\n"
6338 " -P --poweroff Power-off the machine\n"
6339 " -r --reboot Reboot the machine\n"
6340 " -h Equivalent to --poweroff, overridden by --halt\n"
6341 " -k Don't halt/power-off/reboot, just send warnings\n"
6342 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6343 " -c Cancel a pending shutdown\n",
6344 program_invocation_short_name);
6345 }
6346
6347 static void telinit_help(void) {
6348 printf("%s [OPTIONS...] {COMMAND}\n\n"
6349 "Send control commands to the init daemon.\n\n"
6350 " --help Show this help\n"
6351 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6352 "Commands:\n"
6353 " 0 Power-off the machine\n"
6354 " 6 Reboot the machine\n"
6355 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6356 " 1, s, S Enter rescue mode\n"
6357 " q, Q Reload init daemon configuration\n"
6358 " u, U Reexecute init daemon\n",
6359 program_invocation_short_name);
6360 }
6361
6362 static void runlevel_help(void) {
6363 printf("%s [OPTIONS...]\n\n"
6364 "Prints the previous and current runlevel of the init system.\n\n"
6365 " --help Show this help\n",
6366 program_invocation_short_name);
6367 }
6368
6369 static void help_types(void) {
6370 int i;
6371
6372 if (!arg_no_legend)
6373 puts("Available unit types:");
6374 for (i = 0; i < _UNIT_TYPE_MAX; i++)
6375 puts(unit_type_to_string(i));
6376 }
6377
6378 static void help_states(void) {
6379 int i;
6380
6381 if (!arg_no_legend)
6382 puts("Available unit load states:");
6383 for (i = 0; i < _UNIT_LOAD_STATE_MAX; i++)
6384 puts(unit_load_state_to_string(i));
6385
6386 if (!arg_no_legend)
6387 puts("\nAvailable unit active states:");
6388 for (i = 0; i < _UNIT_ACTIVE_STATE_MAX; i++)
6389 puts(unit_active_state_to_string(i));
6390
6391 if (!arg_no_legend)
6392 puts("\nAvailable automount unit substates:");
6393 for (i = 0; i < _AUTOMOUNT_STATE_MAX; i++)
6394 puts(automount_state_to_string(i));
6395
6396 if (!arg_no_legend)
6397 puts("\nAvailable busname unit substates:");
6398 for (i = 0; i < _BUSNAME_STATE_MAX; i++)
6399 puts(busname_state_to_string(i));
6400
6401 if (!arg_no_legend)
6402 puts("\nAvailable device unit substates:");
6403 for (i = 0; i < _DEVICE_STATE_MAX; i++)
6404 puts(device_state_to_string(i));
6405
6406 if (!arg_no_legend)
6407 puts("\nAvailable mount unit substates:");
6408 for (i = 0; i < _MOUNT_STATE_MAX; i++)
6409 puts(mount_state_to_string(i));
6410
6411 if (!arg_no_legend)
6412 puts("\nAvailable path unit substates:");
6413 for (i = 0; i < _PATH_STATE_MAX; i++)
6414 puts(path_state_to_string(i));
6415
6416 if (!arg_no_legend)
6417 puts("\nAvailable scope unit substates:");
6418 for (i = 0; i < _SCOPE_STATE_MAX; i++)
6419 puts(scope_state_to_string(i));
6420
6421 if (!arg_no_legend)
6422 puts("\nAvailable service unit substates:");
6423 for (i = 0; i < _SERVICE_STATE_MAX; i++)
6424 puts(service_state_to_string(i));
6425
6426 if (!arg_no_legend)
6427 puts("\nAvailable slice unit substates:");
6428 for (i = 0; i < _SLICE_STATE_MAX; i++)
6429 puts(slice_state_to_string(i));
6430
6431 if (!arg_no_legend)
6432 puts("\nAvailable socket unit substates:");
6433 for (i = 0; i < _SOCKET_STATE_MAX; i++)
6434 puts(socket_state_to_string(i));
6435
6436 if (!arg_no_legend)
6437 puts("\nAvailable swap unit substates:");
6438 for (i = 0; i < _SWAP_STATE_MAX; i++)
6439 puts(swap_state_to_string(i));
6440
6441 if (!arg_no_legend)
6442 puts("\nAvailable target unit substates:");
6443 for (i = 0; i < _TARGET_STATE_MAX; i++)
6444 puts(target_state_to_string(i));
6445
6446 if (!arg_no_legend)
6447 puts("\nAvailable timer unit substates:");
6448 for (i = 0; i < _TIMER_STATE_MAX; i++)
6449 puts(timer_state_to_string(i));
6450 }
6451
6452 static int systemctl_parse_argv(int argc, char *argv[]) {
6453
6454 enum {
6455 ARG_FAIL = 0x100,
6456 ARG_REVERSE,
6457 ARG_AFTER,
6458 ARG_BEFORE,
6459 ARG_SHOW_TYPES,
6460 ARG_IRREVERSIBLE,
6461 ARG_IGNORE_DEPENDENCIES,
6462 ARG_VERSION,
6463 ARG_USER,
6464 ARG_SYSTEM,
6465 ARG_GLOBAL,
6466 ARG_NO_BLOCK,
6467 ARG_NO_LEGEND,
6468 ARG_NO_PAGER,
6469 ARG_NO_WALL,
6470 ARG_ROOT,
6471 ARG_NO_RELOAD,
6472 ARG_KILL_WHO,
6473 ARG_NO_ASK_PASSWORD,
6474 ARG_FAILED,
6475 ARG_RUNTIME,
6476 ARG_FORCE,
6477 ARG_PLAIN,
6478 ARG_STATE,
6479 ARG_JOB_MODE,
6480 ARG_PRESET_MODE,
6481 ARG_FIRMWARE_SETUP,
6482 ARG_NOW,
6483 ARG_MESSAGE,
6484 };
6485
6486 static const struct option options[] = {
6487 { "help", no_argument, NULL, 'h' },
6488 { "version", no_argument, NULL, ARG_VERSION },
6489 { "type", required_argument, NULL, 't' },
6490 { "property", required_argument, NULL, 'p' },
6491 { "all", no_argument, NULL, 'a' },
6492 { "reverse", no_argument, NULL, ARG_REVERSE },
6493 { "after", no_argument, NULL, ARG_AFTER },
6494 { "before", no_argument, NULL, ARG_BEFORE },
6495 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6496 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6497 { "full", no_argument, NULL, 'l' },
6498 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6499 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6500 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6501 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6502 { "ignore-inhibitors", no_argument, NULL, 'i' },
6503 { "user", no_argument, NULL, ARG_USER },
6504 { "system", no_argument, NULL, ARG_SYSTEM },
6505 { "global", no_argument, NULL, ARG_GLOBAL },
6506 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6507 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6508 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6509 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6510 { "quiet", no_argument, NULL, 'q' },
6511 { "root", required_argument, NULL, ARG_ROOT },
6512 { "force", no_argument, NULL, ARG_FORCE },
6513 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6514 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6515 { "signal", required_argument, NULL, 's' },
6516 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6517 { "host", required_argument, NULL, 'H' },
6518 { "machine", required_argument, NULL, 'M' },
6519 { "runtime", no_argument, NULL, ARG_RUNTIME },
6520 { "lines", required_argument, NULL, 'n' },
6521 { "output", required_argument, NULL, 'o' },
6522 { "plain", no_argument, NULL, ARG_PLAIN },
6523 { "state", required_argument, NULL, ARG_STATE },
6524 { "recursive", no_argument, NULL, 'r' },
6525 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6526 { "firmware-setup", no_argument, NULL, ARG_FIRMWARE_SETUP },
6527 { "now", no_argument, NULL, ARG_NOW },
6528 { "message", required_argument, NULL, ARG_MESSAGE },
6529 {}
6530 };
6531
6532 const char *p;
6533 int c, r;
6534
6535 assert(argc >= 0);
6536 assert(argv);
6537
6538 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6539 arg_ask_password = true;
6540
6541 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6542
6543 switch (c) {
6544
6545 case 'h':
6546 systemctl_help();
6547 return 0;
6548
6549 case ARG_VERSION:
6550 return version();
6551
6552 case 't': {
6553 if (isempty(optarg)) {
6554 log_error("--type requires arguments.");
6555 return -EINVAL;
6556 }
6557
6558 p = optarg;
6559 for(;;) {
6560 _cleanup_free_ char *type = NULL;
6561
6562 r = extract_first_word(&p, &type, ",", 0);
6563 if (r < 0)
6564 return log_error_errno(r, "Failed to parse type: %s", optarg);
6565
6566 if (r == 0)
6567 break;
6568
6569 if (streq(type, "help")) {
6570 help_types();
6571 return 0;
6572 }
6573
6574 if (unit_type_from_string(type) >= 0) {
6575 if (strv_push(&arg_types, type) < 0)
6576 return log_oom();
6577 type = NULL;
6578 continue;
6579 }
6580
6581 /* It's much nicer to use --state= for
6582 * load states, but let's support this
6583 * in --types= too for compatibility
6584 * with old versions */
6585 if (unit_load_state_from_string(type) >= 0) {
6586 if (strv_push(&arg_states, type) < 0)
6587 return log_oom();
6588 type = NULL;
6589 continue;
6590 }
6591
6592 log_error("Unknown unit type or load state '%s'.", type);
6593 log_info("Use -t help to see a list of allowed values.");
6594 return -EINVAL;
6595 }
6596
6597 break;
6598 }
6599
6600 case 'p': {
6601 /* Make sure that if the empty property list
6602 was specified, we won't show any properties. */
6603 if (isempty(optarg) && !arg_properties) {
6604 arg_properties = new0(char*, 1);
6605 if (!arg_properties)
6606 return log_oom();
6607 } else {
6608 p = optarg;
6609 for(;;) {
6610 _cleanup_free_ char *prop = NULL;
6611
6612 r = extract_first_word(&p, &prop, ",", 0);
6613 if (r < 0)
6614 return log_error_errno(r, "Failed to parse property: %s", optarg);
6615
6616 if (r == 0)
6617 break;
6618
6619 if (strv_push(&arg_properties, prop) < 0)
6620 return log_oom();
6621
6622 prop = NULL;
6623 }
6624 }
6625
6626 /* If the user asked for a particular
6627 * property, show it to him, even if it is
6628 * empty. */
6629 arg_all = true;
6630
6631 break;
6632 }
6633
6634 case 'a':
6635 arg_all = true;
6636 break;
6637
6638 case ARG_REVERSE:
6639 arg_dependency = DEPENDENCY_REVERSE;
6640 break;
6641
6642 case ARG_AFTER:
6643 arg_dependency = DEPENDENCY_AFTER;
6644 break;
6645
6646 case ARG_BEFORE:
6647 arg_dependency = DEPENDENCY_BEFORE;
6648 break;
6649
6650 case ARG_SHOW_TYPES:
6651 arg_show_types = true;
6652 break;
6653
6654 case ARG_JOB_MODE:
6655 arg_job_mode = optarg;
6656 break;
6657
6658 case ARG_FAIL:
6659 arg_job_mode = "fail";
6660 break;
6661
6662 case ARG_IRREVERSIBLE:
6663 arg_job_mode = "replace-irreversibly";
6664 break;
6665
6666 case ARG_IGNORE_DEPENDENCIES:
6667 arg_job_mode = "ignore-dependencies";
6668 break;
6669
6670 case ARG_USER:
6671 arg_scope = UNIT_FILE_USER;
6672 break;
6673
6674 case ARG_SYSTEM:
6675 arg_scope = UNIT_FILE_SYSTEM;
6676 break;
6677
6678 case ARG_GLOBAL:
6679 arg_scope = UNIT_FILE_GLOBAL;
6680 break;
6681
6682 case ARG_NO_BLOCK:
6683 arg_no_block = true;
6684 break;
6685
6686 case ARG_NO_LEGEND:
6687 arg_no_legend = true;
6688 break;
6689
6690 case ARG_NO_PAGER:
6691 arg_no_pager = true;
6692 break;
6693
6694 case ARG_NO_WALL:
6695 arg_no_wall = true;
6696 break;
6697
6698 case ARG_ROOT:
6699 r = parse_path_argument_and_warn(optarg, true, &arg_root);
6700 if (r < 0)
6701 return r;
6702 break;
6703
6704 case 'l':
6705 arg_full = true;
6706 break;
6707
6708 case ARG_FAILED:
6709 if (strv_extend(&arg_states, "failed") < 0)
6710 return log_oom();
6711
6712 break;
6713
6714 case 'q':
6715 arg_quiet = true;
6716 break;
6717
6718 case ARG_FORCE:
6719 arg_force ++;
6720 break;
6721
6722 case 'f':
6723 arg_force ++;
6724 break;
6725
6726 case ARG_NO_RELOAD:
6727 arg_no_reload = true;
6728 break;
6729
6730 case ARG_KILL_WHO:
6731 arg_kill_who = optarg;
6732 break;
6733
6734 case 's':
6735 arg_signal = signal_from_string_try_harder(optarg);
6736 if (arg_signal < 0) {
6737 log_error("Failed to parse signal string %s.", optarg);
6738 return -EINVAL;
6739 }
6740 break;
6741
6742 case ARG_NO_ASK_PASSWORD:
6743 arg_ask_password = false;
6744 break;
6745
6746 case 'H':
6747 arg_transport = BUS_TRANSPORT_REMOTE;
6748 arg_host = optarg;
6749 break;
6750
6751 case 'M':
6752 arg_transport = BUS_TRANSPORT_MACHINE;
6753 arg_host = optarg;
6754 break;
6755
6756 case ARG_RUNTIME:
6757 arg_runtime = true;
6758 break;
6759
6760 case 'n':
6761 if (safe_atou(optarg, &arg_lines) < 0) {
6762 log_error("Failed to parse lines '%s'", optarg);
6763 return -EINVAL;
6764 }
6765 break;
6766
6767 case 'o':
6768 arg_output = output_mode_from_string(optarg);
6769 if (arg_output < 0) {
6770 log_error("Unknown output '%s'.", optarg);
6771 return -EINVAL;
6772 }
6773 break;
6774
6775 case 'i':
6776 arg_ignore_inhibitors = true;
6777 break;
6778
6779 case ARG_PLAIN:
6780 arg_plain = true;
6781 break;
6782
6783 case ARG_FIRMWARE_SETUP:
6784 arg_firmware_setup = true;
6785 break;
6786
6787 case ARG_STATE: {
6788 if (isempty(optarg)) {
6789 log_error("--signal requires arguments.");
6790 return -EINVAL;
6791 }
6792
6793 p = optarg;
6794 for(;;) {
6795 _cleanup_free_ char *s = NULL;
6796
6797 r = extract_first_word(&p, &s, ",", 0);
6798 if (r < 0)
6799 return log_error_errno(r, "Failed to parse signal: %s", optarg);
6800
6801 if (r == 0)
6802 break;
6803
6804 if (streq(s, "help")) {
6805 help_states();
6806 return 0;
6807 }
6808
6809 if (strv_push(&arg_states, s) < 0)
6810 return log_oom();
6811
6812 s = NULL;
6813 }
6814 break;
6815 }
6816
6817 case 'r':
6818 if (geteuid() != 0) {
6819 log_error("--recursive requires root privileges.");
6820 return -EPERM;
6821 }
6822
6823 arg_recursive = true;
6824 break;
6825
6826 case ARG_PRESET_MODE:
6827
6828 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6829 if (arg_preset_mode < 0) {
6830 log_error("Failed to parse preset mode: %s.", optarg);
6831 return -EINVAL;
6832 }
6833
6834 break;
6835
6836 case ARG_NOW:
6837 arg_now = true;
6838 break;
6839
6840 case ARG_MESSAGE:
6841 if (strv_extend(&arg_wall, optarg) < 0)
6842 return log_oom();
6843 break;
6844
6845 case '?':
6846 return -EINVAL;
6847
6848 default:
6849 assert_not_reached("Unhandled option");
6850 }
6851
6852 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6853 log_error("Cannot access user instance remotely.");
6854 return -EINVAL;
6855 }
6856
6857 return 1;
6858 }
6859
6860 static int halt_parse_argv(int argc, char *argv[]) {
6861
6862 enum {
6863 ARG_HELP = 0x100,
6864 ARG_HALT,
6865 ARG_REBOOT,
6866 ARG_NO_WALL
6867 };
6868
6869 static const struct option options[] = {
6870 { "help", no_argument, NULL, ARG_HELP },
6871 { "halt", no_argument, NULL, ARG_HALT },
6872 { "poweroff", no_argument, NULL, 'p' },
6873 { "reboot", no_argument, NULL, ARG_REBOOT },
6874 { "force", no_argument, NULL, 'f' },
6875 { "wtmp-only", no_argument, NULL, 'w' },
6876 { "no-wtmp", no_argument, NULL, 'd' },
6877 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6878 {}
6879 };
6880
6881 int c, r, runlevel;
6882
6883 assert(argc >= 0);
6884 assert(argv);
6885
6886 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6887 if (runlevel == '0' || runlevel == '6')
6888 arg_force = 2;
6889
6890 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6891 switch (c) {
6892
6893 case ARG_HELP:
6894 halt_help();
6895 return 0;
6896
6897 case ARG_HALT:
6898 arg_action = ACTION_HALT;
6899 break;
6900
6901 case 'p':
6902 if (arg_action != ACTION_REBOOT)
6903 arg_action = ACTION_POWEROFF;
6904 break;
6905
6906 case ARG_REBOOT:
6907 arg_action = ACTION_REBOOT;
6908 break;
6909
6910 case 'f':
6911 arg_force = 2;
6912 break;
6913
6914 case 'w':
6915 arg_dry = true;
6916 break;
6917
6918 case 'd':
6919 arg_no_wtmp = true;
6920 break;
6921
6922 case ARG_NO_WALL:
6923 arg_no_wall = true;
6924 break;
6925
6926 case 'i':
6927 case 'h':
6928 case 'n':
6929 /* Compatibility nops */
6930 break;
6931
6932 case '?':
6933 return -EINVAL;
6934
6935 default:
6936 assert_not_reached("Unhandled option");
6937 }
6938
6939 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6940 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6941 if (r < 0)
6942 return r;
6943 } else if (optind < argc) {
6944 log_error("Too many arguments.");
6945 return -EINVAL;
6946 }
6947
6948 return 1;
6949 }
6950
6951 static int parse_shutdown_time_spec(const char *t, usec_t *_u) {
6952 assert(t);
6953 assert(_u);
6954
6955 if (streq(t, "now"))
6956 *_u = 0;
6957 else if (!strchr(t, ':')) {
6958 uint64_t u;
6959
6960 if (safe_atou64(t, &u) < 0)
6961 return -EINVAL;
6962
6963 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6964 } else {
6965 char *e = NULL;
6966 long hour, minute;
6967 struct tm tm = {};
6968 time_t s;
6969 usec_t n;
6970
6971 errno = 0;
6972 hour = strtol(t, &e, 10);
6973 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6974 return -EINVAL;
6975
6976 minute = strtol(e+1, &e, 10);
6977 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6978 return -EINVAL;
6979
6980 n = now(CLOCK_REALTIME);
6981 s = (time_t) (n / USEC_PER_SEC);
6982
6983 assert_se(localtime_r(&s, &tm));
6984
6985 tm.tm_hour = (int) hour;
6986 tm.tm_min = (int) minute;
6987 tm.tm_sec = 0;
6988
6989 assert_se(s = mktime(&tm));
6990
6991 *_u = (usec_t) s * USEC_PER_SEC;
6992
6993 while (*_u <= n)
6994 *_u += USEC_PER_DAY;
6995 }
6996
6997 return 0;
6998 }
6999
7000 static int shutdown_parse_argv(int argc, char *argv[]) {
7001
7002 enum {
7003 ARG_HELP = 0x100,
7004 ARG_NO_WALL
7005 };
7006
7007 static const struct option options[] = {
7008 { "help", no_argument, NULL, ARG_HELP },
7009 { "halt", no_argument, NULL, 'H' },
7010 { "poweroff", no_argument, NULL, 'P' },
7011 { "reboot", no_argument, NULL, 'r' },
7012 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
7013 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7014 {}
7015 };
7016
7017 char **wall = NULL;
7018 int c, r;
7019
7020 assert(argc >= 0);
7021 assert(argv);
7022
7023 while ((c = getopt_long(argc, argv, "HPrhkKtafFc", options, NULL)) >= 0)
7024 switch (c) {
7025
7026 case ARG_HELP:
7027 shutdown_help();
7028 return 0;
7029
7030 case 'H':
7031 arg_action = ACTION_HALT;
7032 break;
7033
7034 case 'P':
7035 arg_action = ACTION_POWEROFF;
7036 break;
7037
7038 case 'r':
7039 if (kexec_loaded())
7040 arg_action = ACTION_KEXEC;
7041 else
7042 arg_action = ACTION_REBOOT;
7043 break;
7044
7045 case 'K':
7046 arg_action = ACTION_KEXEC;
7047 break;
7048
7049 case 'h':
7050 if (arg_action != ACTION_HALT)
7051 arg_action = ACTION_POWEROFF;
7052 break;
7053
7054 case 'k':
7055 arg_dry = true;
7056 break;
7057
7058 case ARG_NO_WALL:
7059 arg_no_wall = true;
7060 break;
7061
7062 case 't':
7063 case 'a':
7064 case 'f':
7065 case 'F':
7066 /* Compatibility nops */
7067 break;
7068
7069 case 'c':
7070 arg_action = ACTION_CANCEL_SHUTDOWN;
7071 break;
7072
7073 case '?':
7074 return -EINVAL;
7075
7076 default:
7077 assert_not_reached("Unhandled option");
7078 }
7079
7080 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
7081 r = parse_shutdown_time_spec(argv[optind], &arg_when);
7082 if (r < 0) {
7083 log_error("Failed to parse time specification: %s", argv[optind]);
7084 return r;
7085 }
7086 } else
7087 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
7088
7089 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
7090 /* No time argument for shutdown cancel */
7091 wall = argv + optind;
7092 else if (argc > optind + 1)
7093 /* We skip the time argument */
7094 wall = argv + optind + 1;
7095
7096 if (wall) {
7097 arg_wall = strv_copy(wall);
7098 if (!arg_wall)
7099 return log_oom();
7100 }
7101
7102 optind = argc;
7103
7104 return 1;
7105 }
7106
7107 static int telinit_parse_argv(int argc, char *argv[]) {
7108
7109 enum {
7110 ARG_HELP = 0x100,
7111 ARG_NO_WALL
7112 };
7113
7114 static const struct option options[] = {
7115 { "help", no_argument, NULL, ARG_HELP },
7116 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7117 {}
7118 };
7119
7120 static const struct {
7121 char from;
7122 enum action to;
7123 } table[] = {
7124 { '0', ACTION_POWEROFF },
7125 { '6', ACTION_REBOOT },
7126 { '1', ACTION_RESCUE },
7127 { '2', ACTION_RUNLEVEL2 },
7128 { '3', ACTION_RUNLEVEL3 },
7129 { '4', ACTION_RUNLEVEL4 },
7130 { '5', ACTION_RUNLEVEL5 },
7131 { 's', ACTION_RESCUE },
7132 { 'S', ACTION_RESCUE },
7133 { 'q', ACTION_RELOAD },
7134 { 'Q', ACTION_RELOAD },
7135 { 'u', ACTION_REEXEC },
7136 { 'U', ACTION_REEXEC }
7137 };
7138
7139 unsigned i;
7140 int c;
7141
7142 assert(argc >= 0);
7143 assert(argv);
7144
7145 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7146 switch (c) {
7147
7148 case ARG_HELP:
7149 telinit_help();
7150 return 0;
7151
7152 case ARG_NO_WALL:
7153 arg_no_wall = true;
7154 break;
7155
7156 case '?':
7157 return -EINVAL;
7158
7159 default:
7160 assert_not_reached("Unhandled option");
7161 }
7162
7163 if (optind >= argc) {
7164 log_error("%s: required argument missing.", program_invocation_short_name);
7165 return -EINVAL;
7166 }
7167
7168 if (optind + 1 < argc) {
7169 log_error("Too many arguments.");
7170 return -EINVAL;
7171 }
7172
7173 if (strlen(argv[optind]) != 1) {
7174 log_error("Expected single character argument.");
7175 return -EINVAL;
7176 }
7177
7178 for (i = 0; i < ELEMENTSOF(table); i++)
7179 if (table[i].from == argv[optind][0])
7180 break;
7181
7182 if (i >= ELEMENTSOF(table)) {
7183 log_error("Unknown command '%s'.", argv[optind]);
7184 return -EINVAL;
7185 }
7186
7187 arg_action = table[i].to;
7188
7189 optind ++;
7190
7191 return 1;
7192 }
7193
7194 static int runlevel_parse_argv(int argc, char *argv[]) {
7195
7196 enum {
7197 ARG_HELP = 0x100,
7198 };
7199
7200 static const struct option options[] = {
7201 { "help", no_argument, NULL, ARG_HELP },
7202 {}
7203 };
7204
7205 int c;
7206
7207 assert(argc >= 0);
7208 assert(argv);
7209
7210 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7211 switch (c) {
7212
7213 case ARG_HELP:
7214 runlevel_help();
7215 return 0;
7216
7217 case '?':
7218 return -EINVAL;
7219
7220 default:
7221 assert_not_reached("Unhandled option");
7222 }
7223
7224 if (optind < argc) {
7225 log_error("Too many arguments.");
7226 return -EINVAL;
7227 }
7228
7229 return 1;
7230 }
7231
7232 static int parse_argv(int argc, char *argv[]) {
7233 assert(argc >= 0);
7234 assert(argv);
7235
7236 if (program_invocation_short_name) {
7237
7238 if (strstr(program_invocation_short_name, "halt")) {
7239 arg_action = ACTION_HALT;
7240 return halt_parse_argv(argc, argv);
7241 } else if (strstr(program_invocation_short_name, "poweroff")) {
7242 arg_action = ACTION_POWEROFF;
7243 return halt_parse_argv(argc, argv);
7244 } else if (strstr(program_invocation_short_name, "reboot")) {
7245 if (kexec_loaded())
7246 arg_action = ACTION_KEXEC;
7247 else
7248 arg_action = ACTION_REBOOT;
7249 return halt_parse_argv(argc, argv);
7250 } else if (strstr(program_invocation_short_name, "shutdown")) {
7251 arg_action = ACTION_POWEROFF;
7252 return shutdown_parse_argv(argc, argv);
7253 } else if (strstr(program_invocation_short_name, "init")) {
7254
7255 if (sd_booted() > 0) {
7256 arg_action = _ACTION_INVALID;
7257 return telinit_parse_argv(argc, argv);
7258 } else {
7259 /* Hmm, so some other init system is
7260 * running, we need to forward this
7261 * request to it. For now we simply
7262 * guess that it is Upstart. */
7263
7264 execv(TELINIT, argv);
7265
7266 log_error("Couldn't find an alternative telinit implementation to spawn.");
7267 return -EIO;
7268 }
7269
7270 } else if (strstr(program_invocation_short_name, "runlevel")) {
7271 arg_action = ACTION_RUNLEVEL;
7272 return runlevel_parse_argv(argc, argv);
7273 }
7274 }
7275
7276 arg_action = ACTION_SYSTEMCTL;
7277 return systemctl_parse_argv(argc, argv);
7278 }
7279
7280 _pure_ static int action_to_runlevel(void) {
7281
7282 static const char table[_ACTION_MAX] = {
7283 [ACTION_HALT] = '0',
7284 [ACTION_POWEROFF] = '0',
7285 [ACTION_REBOOT] = '6',
7286 [ACTION_RUNLEVEL2] = '2',
7287 [ACTION_RUNLEVEL3] = '3',
7288 [ACTION_RUNLEVEL4] = '4',
7289 [ACTION_RUNLEVEL5] = '5',
7290 [ACTION_RESCUE] = '1'
7291 };
7292
7293 assert(arg_action < _ACTION_MAX);
7294
7295 return table[arg_action];
7296 }
7297
7298 static int talk_initctl(void) {
7299 #ifdef HAVE_SYSV_COMPAT
7300 struct init_request request = {
7301 .magic = INIT_MAGIC,
7302 .sleeptime = 0,
7303 .cmd = INIT_CMD_RUNLVL
7304 };
7305
7306 _cleanup_close_ int fd = -1;
7307 char rl;
7308 int r;
7309
7310 rl = action_to_runlevel();
7311 if (!rl)
7312 return 0;
7313
7314 request.runlevel = rl;
7315
7316 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7317 if (fd < 0) {
7318 if (errno == ENOENT)
7319 return 0;
7320
7321 return log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7322 }
7323
7324 r = loop_write(fd, &request, sizeof(request), false);
7325 if (r < 0)
7326 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7327
7328 return 1;
7329 #else
7330 return 0;
7331 #endif
7332 }
7333
7334 static int systemctl_main(int argc, char *argv[]) {
7335
7336 static const Verb verbs[] = {
7337 { "list-units", VERB_ANY, VERB_ANY, VERB_DEFAULT, list_units },
7338 { "list-unit-files", VERB_ANY, VERB_ANY, 0, list_unit_files },
7339 { "list-sockets", VERB_ANY, VERB_ANY, 0, list_sockets },
7340 { "list-timers", VERB_ANY, VERB_ANY, 0, list_timers },
7341 { "list-jobs", VERB_ANY, VERB_ANY, 0, list_jobs },
7342 { "list-machines", VERB_ANY, VERB_ANY, 0, list_machines },
7343 { "clear-jobs", VERB_ANY, 1, 0, daemon_reload },
7344 { "cancel", VERB_ANY, VERB_ANY, 0, cancel_job },
7345 { "start", 2, VERB_ANY, 0, start_unit },
7346 { "stop", 2, VERB_ANY, 0, start_unit },
7347 { "condstop", 2, VERB_ANY, 0, start_unit }, /* For compatibility with ALTLinux */
7348 { "reload", 2, VERB_ANY, 0, start_unit },
7349 { "restart", 2, VERB_ANY, 0, start_unit },
7350 { "try-restart", 2, VERB_ANY, 0, start_unit },
7351 { "reload-or-restart", 2, VERB_ANY, 0, start_unit },
7352 { "reload-or-try-restart", 2, VERB_ANY, 0, start_unit },
7353 { "force-reload", 2, VERB_ANY, 0, start_unit }, /* For compatibility with SysV */
7354 { "condreload", 2, VERB_ANY, 0, start_unit }, /* For compatibility with ALTLinux */
7355 { "condrestart", 2, VERB_ANY, 0, start_unit }, /* For compatibility with RH */
7356 { "isolate", 2, 2, 0, start_unit },
7357 { "kill", 2, VERB_ANY, 0, kill_unit },
7358 { "is-active", 2, VERB_ANY, 0, check_unit_active },
7359 { "check", 2, VERB_ANY, 0, check_unit_active },
7360 { "is-failed", 2, VERB_ANY, 0, check_unit_failed },
7361 { "show", VERB_ANY, VERB_ANY, 0, show },
7362 { "cat", 2, VERB_ANY, 0, cat },
7363 { "status", VERB_ANY, VERB_ANY, 0, show },
7364 { "help", VERB_ANY, VERB_ANY, 0, show },
7365 { "daemon-reload", VERB_ANY, 1, 0, daemon_reload },
7366 { "daemon-reexec", VERB_ANY, 1, 0, daemon_reload },
7367 { "show-environment", VERB_ANY, 1, 0, show_environment },
7368 { "set-environment", 2, VERB_ANY, 0, set_environment },
7369 { "unset-environment", 2, VERB_ANY, 0, set_environment },
7370 { "import-environment", VERB_ANY, VERB_ANY, 0, import_environment},
7371 { "halt", VERB_ANY, 1, 0, start_special },
7372 { "poweroff", VERB_ANY, 1, 0, start_special },
7373 { "reboot", VERB_ANY, 2, 0, start_special },
7374 { "kexec", VERB_ANY, 1, 0, start_special },
7375 { "suspend", VERB_ANY, 1, 0, start_special },
7376 { "hibernate", VERB_ANY, 1, 0, start_special },
7377 { "hybrid-sleep", VERB_ANY, 1, 0, start_special },
7378 { "default", VERB_ANY, 1, 0, start_special },
7379 { "rescue", VERB_ANY, 1, 0, start_special },
7380 { "emergency", VERB_ANY, 1, 0, start_special },
7381 { "exit", VERB_ANY, 2, 0, start_special },
7382 { "reset-failed", VERB_ANY, VERB_ANY, 0, reset_failed },
7383 { "enable", 2, VERB_ANY, 0, enable_unit },
7384 { "disable", 2, VERB_ANY, 0, enable_unit },
7385 { "is-enabled", 2, VERB_ANY, 0, unit_is_enabled },
7386 { "reenable", 2, VERB_ANY, 0, enable_unit },
7387 { "preset", 2, VERB_ANY, 0, enable_unit },
7388 { "preset-all", VERB_ANY, 1, 0, preset_all },
7389 { "mask", 2, VERB_ANY, 0, enable_unit },
7390 { "unmask", 2, VERB_ANY, 0, enable_unit },
7391 { "link", 2, VERB_ANY, 0, enable_unit },
7392 { "switch-root", 2, VERB_ANY, 0, switch_root },
7393 { "list-dependencies", VERB_ANY, 2, 0, list_dependencies },
7394 { "set-default", 2, 2, 0, set_default },
7395 { "get-default", VERB_ANY, 1, 0, get_default, },
7396 { "set-property", 3, VERB_ANY, 0, set_property },
7397 { "is-system-running", VERB_ANY, 1, 0, is_system_running },
7398 { "add-wants", 3, VERB_ANY, 0, add_dependency },
7399 { "add-requires", 3, VERB_ANY, 0, add_dependency },
7400 { "edit", 2, VERB_ANY, 0, edit },
7401 {}
7402 };
7403
7404 return dispatch_verb(argc, argv, verbs, NULL);
7405 }
7406
7407 static int reload_with_fallback(void) {
7408
7409 /* First, try systemd via D-Bus. */
7410 if (daemon_reload(0, NULL, NULL) >= 0)
7411 return 0;
7412
7413 /* Nothing else worked, so let's try signals */
7414 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7415
7416 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7417 return log_error_errno(errno, "kill() failed: %m");
7418
7419 return 0;
7420 }
7421
7422 static int start_with_fallback(void) {
7423
7424 /* First, try systemd via D-Bus. */
7425 if (start_unit(0, NULL, NULL) >= 0)
7426 return 0;
7427
7428 /* Nothing else worked, so let's try
7429 * /dev/initctl */
7430 if (talk_initctl() > 0)
7431 return 0;
7432
7433 log_error("Failed to talk to init daemon.");
7434 return -EIO;
7435 }
7436
7437 static int halt_now(enum action a) {
7438
7439 /* The kernel will automaticall flush ATA disks and suchlike
7440 * on reboot(), but the file systems need to be synce'd
7441 * explicitly in advance. */
7442 (void) sync();
7443
7444 /* Make sure C-A-D is handled by the kernel from this point
7445 * on... */
7446 (void) reboot(RB_ENABLE_CAD);
7447
7448 switch (a) {
7449
7450 case ACTION_HALT:
7451 log_info("Halting.");
7452 (void) reboot(RB_HALT_SYSTEM);
7453 return -errno;
7454
7455 case ACTION_POWEROFF:
7456 log_info("Powering off.");
7457 (void) reboot(RB_POWER_OFF);
7458 return -errno;
7459
7460 case ACTION_KEXEC:
7461 case ACTION_REBOOT: {
7462 _cleanup_free_ char *param = NULL;
7463
7464 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
7465 log_info("Rebooting with argument '%s'.", param);
7466 (void) syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param);
7467 }
7468
7469 log_info("Rebooting.");
7470 (void) reboot(RB_AUTOBOOT);
7471 return -errno;
7472 }
7473
7474 default:
7475 assert_not_reached("Unknown action.");
7476 }
7477 }
7478
7479 static int logind_schedule_shutdown(void) {
7480
7481 #ifdef HAVE_LOGIND
7482 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
7483 char date[FORMAT_TIMESTAMP_MAX];
7484 const char *action;
7485 sd_bus *bus;
7486 int r;
7487
7488 (void) logind_set_wall_message();
7489
7490 r = acquire_bus(BUS_FULL, &bus);
7491 if (r < 0)
7492 return r;
7493
7494 switch (arg_action) {
7495 case ACTION_HALT:
7496 action = "halt";
7497 break;
7498 case ACTION_POWEROFF:
7499 action = "poweroff";
7500 break;
7501 case ACTION_KEXEC:
7502 action = "kexec";
7503 break;
7504 case ACTION_EXIT:
7505 action = "exit";
7506 break;
7507 case ACTION_REBOOT:
7508 default:
7509 action = "reboot";
7510 break;
7511 }
7512
7513 if (arg_dry)
7514 action = strjoina("dry-", action);
7515
7516 r = sd_bus_call_method(
7517 bus,
7518 "org.freedesktop.login1",
7519 "/org/freedesktop/login1",
7520 "org.freedesktop.login1.Manager",
7521 "ScheduleShutdown",
7522 &error,
7523 NULL,
7524 "st",
7525 action,
7526 arg_when);
7527 if (r < 0)
7528 return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r));
7529
7530 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
7531 return 0;
7532 #else
7533 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7534 return -ENOSYS;
7535 #endif
7536 }
7537
7538 static int halt_main(void) {
7539 int r;
7540
7541 r = logind_check_inhibitors(arg_action);
7542 if (r < 0)
7543 return r;
7544
7545 if (arg_when > 0)
7546 return logind_schedule_shutdown();
7547
7548 if (geteuid() != 0) {
7549 if (arg_dry || arg_force > 0) {
7550 log_error("Must be root.");
7551 return -EPERM;
7552 }
7553
7554 /* Try logind if we are a normal user and no special
7555 * mode applies. Maybe PolicyKit allows us to shutdown
7556 * the machine. */
7557 if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT)) {
7558 r = logind_reboot(arg_action);
7559 if (r >= 0)
7560 return r;
7561 if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
7562 /* requested operation is not
7563 * supported on the local system or
7564 * already in progress */
7565 return r;
7566 /* on all other errors, try low-level operation */
7567 }
7568 }
7569
7570 if (!arg_dry && !arg_force)
7571 return start_with_fallback();
7572
7573 assert(geteuid() == 0);
7574
7575 if (!arg_no_wtmp) {
7576 if (sd_booted() > 0)
7577 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7578 else {
7579 r = utmp_put_shutdown();
7580 if (r < 0)
7581 log_warning_errno(r, "Failed to write utmp record: %m");
7582 }
7583 }
7584
7585 if (arg_dry)
7586 return 0;
7587
7588 r = halt_now(arg_action);
7589 return log_error_errno(r, "Failed to reboot: %m");
7590 }
7591
7592 static int runlevel_main(void) {
7593 int r, runlevel, previous;
7594
7595 r = utmp_get_runlevel(&runlevel, &previous);
7596 if (r < 0) {
7597 puts("unknown");
7598 return r;
7599 }
7600
7601 printf("%c %c\n",
7602 previous <= 0 ? 'N' : previous,
7603 runlevel <= 0 ? 'N' : runlevel);
7604
7605 return 0;
7606 }
7607
7608 static int logind_cancel_shutdown(void) {
7609 #ifdef HAVE_LOGIND
7610 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
7611 sd_bus *bus;
7612 int r;
7613
7614 r = acquire_bus(BUS_FULL, &bus);
7615 if (r < 0)
7616 return r;
7617
7618 (void) logind_set_wall_message();
7619
7620 r = sd_bus_call_method(
7621 bus,
7622 "org.freedesktop.login1",
7623 "/org/freedesktop/login1",
7624 "org.freedesktop.login1.Manager",
7625 "CancelScheduledShutdown",
7626 &error,
7627 NULL, NULL);
7628 if (r < 0)
7629 return log_warning_errno(r, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error, r));
7630
7631 return 0;
7632 #else
7633 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7634 return -ENOSYS;
7635 #endif
7636 }
7637
7638 int main(int argc, char*argv[]) {
7639 int r;
7640
7641 setlocale(LC_ALL, "");
7642 log_parse_environment();
7643 log_open();
7644
7645 /* Explicitly not on_tty() to avoid setting cached value.
7646 * This becomes relevant for piping output which might be
7647 * ellipsized. */
7648 original_stdout_is_tty = isatty(STDOUT_FILENO);
7649
7650 r = parse_argv(argc, argv);
7651 if (r <= 0)
7652 goto finish;
7653
7654 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7655 log_info("Running in chroot, ignoring request.");
7656 r = 0;
7657 goto finish;
7658 }
7659
7660 /* systemctl_main() will print an error message for the bus
7661 * connection, but only if it needs to */
7662
7663 switch (arg_action) {
7664
7665 case ACTION_SYSTEMCTL:
7666 r = systemctl_main(argc, argv);
7667 break;
7668
7669 case ACTION_HALT:
7670 case ACTION_POWEROFF:
7671 case ACTION_REBOOT:
7672 case ACTION_KEXEC:
7673 r = halt_main();
7674 break;
7675
7676 case ACTION_RUNLEVEL2:
7677 case ACTION_RUNLEVEL3:
7678 case ACTION_RUNLEVEL4:
7679 case ACTION_RUNLEVEL5:
7680 case ACTION_RESCUE:
7681 case ACTION_EMERGENCY:
7682 case ACTION_DEFAULT:
7683 r = start_with_fallback();
7684 break;
7685
7686 case ACTION_RELOAD:
7687 case ACTION_REEXEC:
7688 r = reload_with_fallback();
7689 break;
7690
7691 case ACTION_CANCEL_SHUTDOWN:
7692 r = logind_cancel_shutdown();
7693 break;
7694
7695 case ACTION_RUNLEVEL:
7696 r = runlevel_main();
7697 break;
7698
7699 case _ACTION_INVALID:
7700 default:
7701 assert_not_reached("Unknown action");
7702 }
7703
7704 finish:
7705 pager_close();
7706 ask_password_agent_close();
7707 polkit_agent_close();
7708
7709 strv_free(arg_types);
7710 strv_free(arg_states);
7711 strv_free(arg_properties);
7712
7713 strv_free(arg_wall);
7714 free(arg_root);
7715
7716 release_busses();
7717
7718 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
7719
7720 return r < 0 ? EXIT_FAILURE : r;
7721 }