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