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