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