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