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