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