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