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