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