]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/systemctl/systemctl.c
build-sys: use #if Y instead of #ifdef Y everywhere
[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 #if 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 #if 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 #if 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_is_valid((pid_t) pid)) {
3379 log_error("Invalid PID %" PRIu32 ".", pid);
3380 return -ERANGE;
3381 }
3382
3383 if (!strv_contains(sv,
3384 IN_SET(a,
3385 ACTION_HALT,
3386 ACTION_POWEROFF,
3387 ACTION_REBOOT,
3388 ACTION_KEXEC) ? "shutdown" : "sleep"))
3389 continue;
3390
3391 get_process_comm(pid, &comm);
3392 user = uid_to_name(uid);
3393
3394 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
3395 who, (pid_t) pid, strna(comm), strna(user), why);
3396
3397 c++;
3398 }
3399 if (r < 0)
3400 return bus_log_parse_error(r);
3401
3402 r = sd_bus_message_exit_container(reply);
3403 if (r < 0)
3404 return bus_log_parse_error(r);
3405
3406 /* Check for current sessions */
3407 sd_get_sessions(&sessions);
3408 STRV_FOREACH(s, sessions) {
3409 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
3410
3411 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
3412 continue;
3413
3414 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
3415 continue;
3416
3417 if (sd_session_get_type(*s, &type) < 0 || !STR_IN_SET(type, "x11", "tty"))
3418 continue;
3419
3420 sd_session_get_tty(*s, &tty);
3421 sd_session_get_seat(*s, &seat);
3422 sd_session_get_service(*s, &service);
3423 user = uid_to_name(uid);
3424
3425 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
3426 c++;
3427 }
3428
3429 if (c <= 0)
3430 return 0;
3431
3432 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3433 action_table[a].verb);
3434
3435 return -EPERM;
3436 #else
3437 return 0;
3438 #endif
3439 }
3440
3441 static int logind_prepare_firmware_setup(void) {
3442 #if ENABLE_LOGIND
3443 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3444 sd_bus *bus;
3445 int r;
3446
3447 r = acquire_bus(BUS_FULL, &bus);
3448 if (r < 0)
3449 return r;
3450
3451 r = sd_bus_call_method(
3452 bus,
3453 "org.freedesktop.login1",
3454 "/org/freedesktop/login1",
3455 "org.freedesktop.login1.Manager",
3456 "SetRebootToFirmwareSetup",
3457 &error,
3458 NULL,
3459 "b", true);
3460 if (r < 0)
3461 return log_error_errno(r, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error, r));
3462
3463 return 0;
3464 #else
3465 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3466 return -ENOSYS;
3467 #endif
3468 }
3469
3470 static int prepare_firmware_setup(void) {
3471 int r;
3472
3473 if (!arg_firmware_setup)
3474 return 0;
3475
3476 if (arg_transport == BUS_TRANSPORT_LOCAL) {
3477
3478 r = efi_set_reboot_to_firmware(true);
3479 if (r < 0)
3480 log_debug_errno(r, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3481 else
3482 return r;
3483 }
3484
3485 return logind_prepare_firmware_setup();
3486 }
3487
3488 static int set_exit_code(uint8_t code) {
3489 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3490 sd_bus *bus;
3491 int r;
3492
3493 r = acquire_bus(BUS_MANAGER, &bus);
3494 if (r < 0)
3495 return r;
3496
3497 r = sd_bus_call_method(
3498 bus,
3499 "org.freedesktop.systemd1",
3500 "/org/freedesktop/systemd1",
3501 "org.freedesktop.systemd1.Manager",
3502 "SetExitCode",
3503 &error,
3504 NULL,
3505 "y", code);
3506 if (r < 0)
3507 return log_error_errno(r, "Failed to set exit code: %s", bus_error_message(&error, r));
3508
3509 return 0;
3510 }
3511
3512 static int start_special(int argc, char *argv[], void *userdata) {
3513 enum action a;
3514 int r;
3515 bool termination_action; /* an action that terminates the manager,
3516 * can be performed also by signal. */
3517
3518 assert(argv);
3519
3520 a = verb_to_action(argv[0]);
3521
3522 r = logind_check_inhibitors(a);
3523 if (r < 0)
3524 return r;
3525
3526 if (arg_force >= 2 && geteuid() != 0) {
3527 log_error("Must be root.");
3528 return -EPERM;
3529 }
3530
3531 r = prepare_firmware_setup();
3532 if (r < 0)
3533 return r;
3534
3535 if (a == ACTION_REBOOT && argc > 1) {
3536 r = update_reboot_parameter_and_warn(argv[1]);
3537 if (r < 0)
3538 return r;
3539
3540 } else if (a == ACTION_EXIT && argc > 1) {
3541 uint8_t code;
3542
3543 /* If the exit code is not given on the command line,
3544 * don't reset it to zero: just keep it as it might
3545 * have been set previously. */
3546
3547 r = safe_atou8(argv[1], &code);
3548 if (r < 0)
3549 return log_error_errno(r, "Invalid exit code.");
3550
3551 r = set_exit_code(code);
3552 if (r < 0)
3553 return r;
3554 }
3555
3556 termination_action = IN_SET(a,
3557 ACTION_HALT,
3558 ACTION_POWEROFF,
3559 ACTION_REBOOT);
3560 if (termination_action && arg_force >= 2)
3561 return halt_now(a);
3562
3563 if (arg_force >= 1 &&
3564 (termination_action || IN_SET(a, ACTION_KEXEC, ACTION_EXIT)))
3565 r = trivial_method(argc, argv, userdata);
3566 else {
3567 /* First try logind, to allow authentication with polkit */
3568 if (IN_SET(a,
3569 ACTION_POWEROFF,
3570 ACTION_REBOOT,
3571 ACTION_SUSPEND,
3572 ACTION_HIBERNATE,
3573 ACTION_HYBRID_SLEEP)) {
3574
3575 r = logind_reboot(a);
3576 if (r >= 0)
3577 return r;
3578 if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
3579 /* requested operation is not supported or already in progress */
3580 return r;
3581
3582 /* On all other errors, try low-level operation */
3583 }
3584
3585 r = start_unit(argc, argv, userdata);
3586 }
3587
3588 if (termination_action && arg_force < 2 &&
3589 IN_SET(r, -ENOENT, -ETIMEDOUT))
3590 log_notice("It is possible to perform action directly, see discussion of --force --force in man:systemctl(1).");
3591
3592 return r;
3593 }
3594
3595 static int start_system_special(int argc, char *argv[], void *userdata) {
3596 /* Like start_special above, but raises an error when running in user mode */
3597
3598 if (arg_scope != UNIT_FILE_SYSTEM) {
3599 log_error("Bad action for %s mode.",
3600 arg_scope == UNIT_FILE_GLOBAL ? "--global" : "--user");
3601 return -EINVAL;
3602 }
3603
3604 return start_special(argc, argv, userdata);
3605 }
3606
3607 static int check_unit_generic(int code, const UnitActiveState good_states[], int nb_states, char **args) {
3608 _cleanup_strv_free_ char **names = NULL;
3609 UnitActiveState active_state;
3610 sd_bus *bus;
3611 char **name;
3612 int r, i;
3613 bool found = false;
3614
3615 r = acquire_bus(BUS_MANAGER, &bus);
3616 if (r < 0)
3617 return r;
3618
3619 r = expand_names(bus, args, NULL, &names);
3620 if (r < 0)
3621 return log_error_errno(r, "Failed to expand names: %m");
3622
3623 STRV_FOREACH(name, names) {
3624 r = get_state_one_unit(bus, *name, &active_state);
3625 if (r < 0)
3626 return r;
3627
3628 if (!arg_quiet)
3629 puts(unit_active_state_to_string(active_state));
3630
3631 for (i = 0; i < nb_states; ++i)
3632 if (good_states[i] == active_state)
3633 found = true;
3634 }
3635
3636 /* use the given return code for the case that we won't find
3637 * any unit which matches the list */
3638 return found ? 0 : code;
3639 }
3640
3641 static int check_unit_active(int argc, char *argv[], void *userdata) {
3642 const UnitActiveState states[] = { UNIT_ACTIVE, UNIT_RELOADING };
3643 /* According to LSB: 3, "program is not running" */
3644 return check_unit_generic(EXIT_PROGRAM_NOT_RUNNING, states, ELEMENTSOF(states), strv_skip(argv, 1));
3645 }
3646
3647 static int check_unit_failed(int argc, char *argv[], void *userdata) {
3648 const UnitActiveState states[] = { UNIT_FAILED };
3649 return check_unit_generic(EXIT_PROGRAM_DEAD_AND_PID_EXISTS, states, ELEMENTSOF(states), strv_skip(argv, 1));
3650 }
3651
3652 static int kill_unit(int argc, char *argv[], void *userdata) {
3653 _cleanup_strv_free_ char **names = NULL;
3654 char *kill_who = NULL, **name;
3655 sd_bus *bus;
3656 int r, q;
3657
3658 r = acquire_bus(BUS_MANAGER, &bus);
3659 if (r < 0)
3660 return r;
3661
3662 polkit_agent_open_if_enabled();
3663
3664 if (!arg_kill_who)
3665 arg_kill_who = "all";
3666
3667 /* --fail was specified */
3668 if (streq(arg_job_mode, "fail"))
3669 kill_who = strjoina(arg_kill_who, "-fail");
3670
3671 r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
3672 if (r < 0)
3673 return log_error_errno(r, "Failed to expand names: %m");
3674
3675 STRV_FOREACH(name, names) {
3676 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3677
3678 q = sd_bus_call_method(
3679 bus,
3680 "org.freedesktop.systemd1",
3681 "/org/freedesktop/systemd1",
3682 "org.freedesktop.systemd1.Manager",
3683 "KillUnit",
3684 &error,
3685 NULL,
3686 "ssi", *name, kill_who ? kill_who : arg_kill_who, arg_signal);
3687 if (q < 0) {
3688 log_error_errno(q, "Failed to kill unit %s: %s", *name, bus_error_message(&error, q));
3689 if (r == 0)
3690 r = q;
3691 }
3692 }
3693
3694 return r;
3695 }
3696
3697 typedef struct ExecStatusInfo {
3698 char *name;
3699
3700 char *path;
3701 char **argv;
3702
3703 bool ignore;
3704
3705 usec_t start_timestamp;
3706 usec_t exit_timestamp;
3707 pid_t pid;
3708 int code;
3709 int status;
3710
3711 LIST_FIELDS(struct ExecStatusInfo, exec);
3712 } ExecStatusInfo;
3713
3714 static void exec_status_info_free(ExecStatusInfo *i) {
3715 assert(i);
3716
3717 free(i->name);
3718 free(i->path);
3719 strv_free(i->argv);
3720 free(i);
3721 }
3722
3723 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3724 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3725 const char *path;
3726 uint32_t pid;
3727 int32_t code, status;
3728 int ignore, r;
3729
3730 assert(m);
3731 assert(i);
3732
3733 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3734 if (r < 0)
3735 return bus_log_parse_error(r);
3736 else if (r == 0)
3737 return 0;
3738
3739 r = sd_bus_message_read(m, "s", &path);
3740 if (r < 0)
3741 return bus_log_parse_error(r);
3742
3743 i->path = strdup(path);
3744 if (!i->path)
3745 return log_oom();
3746
3747 r = sd_bus_message_read_strv(m, &i->argv);
3748 if (r < 0)
3749 return bus_log_parse_error(r);
3750
3751 r = sd_bus_message_read(m,
3752 "bttttuii",
3753 &ignore,
3754 &start_timestamp, &start_timestamp_monotonic,
3755 &exit_timestamp, &exit_timestamp_monotonic,
3756 &pid,
3757 &code, &status);
3758 if (r < 0)
3759 return bus_log_parse_error(r);
3760
3761 i->ignore = ignore;
3762 i->start_timestamp = (usec_t) start_timestamp;
3763 i->exit_timestamp = (usec_t) exit_timestamp;
3764 i->pid = (pid_t) pid;
3765 i->code = code;
3766 i->status = status;
3767
3768 r = sd_bus_message_exit_container(m);
3769 if (r < 0)
3770 return bus_log_parse_error(r);
3771
3772 return 1;
3773 }
3774
3775 typedef struct UnitCondition {
3776 char *name;
3777 char *param;
3778 bool trigger;
3779 bool negate;
3780 int tristate;
3781
3782 LIST_FIELDS(struct UnitCondition, conditions);
3783 } UnitCondition;
3784
3785 static void unit_condition_free(UnitCondition *c) {
3786 if (!c)
3787 return;
3788
3789 free(c->name);
3790 free(c->param);
3791 free(c);
3792 }
3793
3794 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitCondition*, unit_condition_free);
3795
3796 typedef struct UnitStatusInfo {
3797 const char *id;
3798 const char *load_state;
3799 const char *active_state;
3800 const char *sub_state;
3801 const char *unit_file_state;
3802 const char *unit_file_preset;
3803
3804 const char *description;
3805 const char *following;
3806
3807 char **documentation;
3808
3809 const char *fragment_path;
3810 const char *source_path;
3811 const char *control_group;
3812
3813 char **dropin_paths;
3814
3815 const char *load_error;
3816 const char *result;
3817
3818 usec_t inactive_exit_timestamp;
3819 usec_t inactive_exit_timestamp_monotonic;
3820 usec_t active_enter_timestamp;
3821 usec_t active_exit_timestamp;
3822 usec_t inactive_enter_timestamp;
3823
3824 bool need_daemon_reload;
3825 bool transient;
3826
3827 /* Service */
3828 pid_t main_pid;
3829 pid_t control_pid;
3830 const char *status_text;
3831 const char *pid_file;
3832 bool running:1;
3833 int status_errno;
3834
3835 usec_t start_timestamp;
3836 usec_t exit_timestamp;
3837
3838 int exit_code, exit_status;
3839
3840 usec_t condition_timestamp;
3841 bool condition_result;
3842 LIST_HEAD(UnitCondition, conditions);
3843
3844 usec_t assert_timestamp;
3845 bool assert_result;
3846 bool failed_assert_trigger;
3847 bool failed_assert_negate;
3848 const char *failed_assert;
3849 const char *failed_assert_parameter;
3850 usec_t next_elapse_real;
3851 usec_t next_elapse_monotonic;
3852
3853 /* Socket */
3854 unsigned n_accepted;
3855 unsigned n_connections;
3856 bool accept;
3857
3858 /* Pairs of type, path */
3859 char **listen;
3860
3861 /* Device */
3862 const char *sysfs_path;
3863
3864 /* Mount, Automount */
3865 const char *where;
3866
3867 /* Swap */
3868 const char *what;
3869
3870 /* CGroup */
3871 uint64_t memory_current;
3872 uint64_t memory_low;
3873 uint64_t memory_high;
3874 uint64_t memory_max;
3875 uint64_t memory_swap_max;
3876 uint64_t memory_limit;
3877 uint64_t cpu_usage_nsec;
3878 uint64_t tasks_current;
3879 uint64_t tasks_max;
3880
3881 uint64_t ip_ingress_bytes;
3882 uint64_t ip_egress_bytes;
3883
3884 LIST_HEAD(ExecStatusInfo, exec);
3885 } UnitStatusInfo;
3886
3887 static void unit_status_info_free(UnitStatusInfo *info) {
3888 ExecStatusInfo *p;
3889 UnitCondition *c;
3890
3891 strv_free(info->documentation);
3892 strv_free(info->dropin_paths);
3893 strv_free(info->listen);
3894
3895 while ((c = info->conditions)) {
3896 LIST_REMOVE(conditions, info->conditions, c);
3897 unit_condition_free(c);
3898 }
3899
3900 while ((p = info->exec)) {
3901 LIST_REMOVE(exec, info->exec, p);
3902 exec_status_info_free(p);
3903 }
3904 }
3905
3906 static void print_status_info(
3907 sd_bus *bus,
3908 UnitStatusInfo *i,
3909 bool *ellipsized) {
3910
3911 ExecStatusInfo *p;
3912 const char *active_on, *active_off, *on, *off, *ss;
3913 usec_t timestamp;
3914 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3915 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3916 const char *path;
3917 char **t, **t2;
3918 int r;
3919
3920 assert(i);
3921
3922 /* This shows pretty information about a unit. See
3923 * print_property() for a low-level property printer */
3924
3925 if (streq_ptr(i->active_state, "failed")) {
3926 active_on = ansi_highlight_red();
3927 active_off = ansi_normal();
3928 } else if (STRPTR_IN_SET(i->active_state, "active", "reloading")) {
3929 active_on = ansi_highlight_green();
3930 active_off = ansi_normal();
3931 } else
3932 active_on = active_off = "";
3933
3934 printf("%s%s%s %s", active_on, special_glyph(BLACK_CIRCLE), active_off, strna(i->id));
3935
3936 if (i->description && !streq_ptr(i->id, i->description))
3937 printf(" - %s", i->description);
3938
3939 printf("\n");
3940
3941 if (i->following)
3942 printf(" Follow: unit currently follows state of %s\n", i->following);
3943
3944 if (streq_ptr(i->load_state, "error")) {
3945 on = ansi_highlight_red();
3946 off = ansi_normal();
3947 } else
3948 on = off = "";
3949
3950 path = i->source_path ? i->source_path : i->fragment_path;
3951
3952 if (i->load_error != 0)
3953 printf(" Loaded: %s%s%s (Reason: %s)\n",
3954 on, strna(i->load_state), off, i->load_error);
3955 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3956 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3957 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3958 else if (path && !isempty(i->unit_file_state))
3959 printf(" Loaded: %s%s%s (%s; %s)\n",
3960 on, strna(i->load_state), off, path, i->unit_file_state);
3961 else if (path)
3962 printf(" Loaded: %s%s%s (%s)\n",
3963 on, strna(i->load_state), off, path);
3964 else
3965 printf(" Loaded: %s%s%s\n",
3966 on, strna(i->load_state), off);
3967
3968 if (i->transient)
3969 printf("Transient: yes\n");
3970
3971 if (!strv_isempty(i->dropin_paths)) {
3972 _cleanup_free_ char *dir = NULL;
3973 bool last = false;
3974 char ** dropin;
3975
3976 STRV_FOREACH(dropin, i->dropin_paths) {
3977 if (! dir || last) {
3978 printf(dir ? " " : " Drop-In: ");
3979
3980 dir = mfree(dir);
3981
3982 dir = dirname_malloc(*dropin);
3983 if (!dir) {
3984 log_oom();
3985 return;
3986 }
3987
3988 printf("%s\n %s", dir,
3989 special_glyph(TREE_RIGHT));
3990 }
3991
3992 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3993
3994 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3995 }
3996 }
3997
3998 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3999 if (ss)
4000 printf(" Active: %s%s (%s)%s",
4001 active_on, strna(i->active_state), ss, active_off);
4002 else
4003 printf(" Active: %s%s%s",
4004 active_on, strna(i->active_state), active_off);
4005
4006 if (!isempty(i->result) && !streq(i->result, "success"))
4007 printf(" (Result: %s)", i->result);
4008
4009 timestamp = STRPTR_IN_SET(i->active_state, "active", "reloading") ? i->active_enter_timestamp :
4010 STRPTR_IN_SET(i->active_state, "inactive", "failed") ? i->inactive_enter_timestamp :
4011 STRPTR_IN_SET(i->active_state, "activating") ? i->inactive_exit_timestamp :
4012 i->active_exit_timestamp;
4013
4014 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
4015 s2 = format_timestamp(since2, sizeof(since2), timestamp);
4016
4017 if (s1)
4018 printf(" since %s; %s\n", s2, s1);
4019 else if (s2)
4020 printf(" since %s\n", s2);
4021 else
4022 printf("\n");
4023
4024 if (endswith(i->id, ".timer")) {
4025 char tstamp1[FORMAT_TIMESTAMP_RELATIVE_MAX],
4026 tstamp2[FORMAT_TIMESTAMP_MAX];
4027 char *next_rel_time, *next_time;
4028 dual_timestamp nw, next = {i->next_elapse_real,
4029 i->next_elapse_monotonic};
4030 usec_t next_elapse;
4031
4032 printf(" Trigger: ");
4033
4034 dual_timestamp_get(&nw);
4035 next_elapse = calc_next_elapse(&nw, &next);
4036 next_rel_time = format_timestamp_relative(tstamp1,
4037 sizeof(tstamp1),
4038 next_elapse);
4039 next_time = format_timestamp(tstamp2,
4040 sizeof(tstamp2),
4041 next_elapse);
4042
4043 if (next_time && next_rel_time)
4044 printf("%s; %s\n", next_time, next_rel_time);
4045 else
4046 printf("n/a\n");
4047 }
4048
4049 if (!i->condition_result && i->condition_timestamp > 0) {
4050 UnitCondition *c;
4051 int n = 0;
4052
4053 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
4054 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
4055
4056 printf("Condition: start %scondition failed%s at %s%s%s\n",
4057 ansi_highlight_yellow(), ansi_normal(),
4058 s2, s1 ? "; " : "", strempty(s1));
4059
4060 LIST_FOREACH(conditions, c, i->conditions)
4061 if (c->tristate < 0)
4062 n++;
4063
4064 LIST_FOREACH(conditions, c, i->conditions)
4065 if (c->tristate < 0)
4066 printf(" %s %s=%s%s%s was not met\n",
4067 --n ? special_glyph(TREE_BRANCH) : special_glyph(TREE_RIGHT),
4068 c->name,
4069 c->trigger ? "|" : "",
4070 c->negate ? "!" : "",
4071 c->param);
4072 }
4073
4074 if (!i->assert_result && i->assert_timestamp > 0) {
4075 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
4076 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
4077
4078 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
4079 ansi_highlight_red(), ansi_normal(),
4080 s2, s1 ? "; " : "", strempty(s1));
4081 if (i->failed_assert_trigger)
4082 printf(" none of the trigger assertions were met\n");
4083 else if (i->failed_assert)
4084 printf(" %s=%s%s was not met\n",
4085 i->failed_assert,
4086 i->failed_assert_negate ? "!" : "",
4087 i->failed_assert_parameter);
4088 }
4089
4090 if (i->sysfs_path)
4091 printf(" Device: %s\n", i->sysfs_path);
4092 if (i->where)
4093 printf(" Where: %s\n", i->where);
4094 if (i->what)
4095 printf(" What: %s\n", i->what);
4096
4097 STRV_FOREACH(t, i->documentation)
4098 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
4099
4100 STRV_FOREACH_PAIR(t, t2, i->listen)
4101 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
4102
4103 if (i->accept)
4104 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
4105
4106 LIST_FOREACH(exec, p, i->exec) {
4107 _cleanup_free_ char *argv = NULL;
4108 bool good;
4109
4110 /* Only show exited processes here */
4111 if (p->code == 0)
4112 continue;
4113
4114 argv = strv_join(p->argv, " ");
4115 printf(" Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
4116
4117 good = is_clean_exit(p->code, p->status, EXIT_CLEAN_DAEMON, NULL);
4118 if (!good) {
4119 on = ansi_highlight_red();
4120 off = ansi_normal();
4121 } else
4122 on = off = "";
4123
4124 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
4125
4126 if (p->code == CLD_EXITED) {
4127 const char *c;
4128
4129 printf("status=%i", p->status);
4130
4131 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
4132 if (c)
4133 printf("/%s", c);
4134
4135 } else
4136 printf("signal=%s", signal_to_string(p->status));
4137
4138 printf(")%s\n", off);
4139
4140 if (i->main_pid == p->pid &&
4141 i->start_timestamp == p->start_timestamp &&
4142 i->exit_timestamp == p->start_timestamp)
4143 /* Let's not show this twice */
4144 i->main_pid = 0;
4145
4146 if (p->pid == i->control_pid)
4147 i->control_pid = 0;
4148 }
4149
4150 if (i->main_pid > 0 || i->control_pid > 0) {
4151 if (i->main_pid > 0) {
4152 printf(" Main PID: "PID_FMT, i->main_pid);
4153
4154 if (i->running) {
4155 _cleanup_free_ char *comm = NULL;
4156 (void) get_process_comm(i->main_pid, &comm);
4157 if (comm)
4158 printf(" (%s)", comm);
4159 } else if (i->exit_code > 0) {
4160 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
4161
4162 if (i->exit_code == CLD_EXITED) {
4163 const char *c;
4164
4165 printf("status=%i", i->exit_status);
4166
4167 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
4168 if (c)
4169 printf("/%s", c);
4170
4171 } else
4172 printf("signal=%s", signal_to_string(i->exit_status));
4173 printf(")");
4174 }
4175 }
4176
4177 if (i->control_pid > 0) {
4178 _cleanup_free_ char *c = NULL;
4179
4180 if (i->main_pid > 0)
4181 fputs("; Control PID: ", stdout);
4182 else
4183 fputs("Cntrl PID: ", stdout); /* if first in column, abbreviated so it fits alignment */
4184
4185 printf(PID_FMT, i->control_pid);
4186
4187 (void) get_process_comm(i->control_pid, &c);
4188 if (c)
4189 printf(" (%s)", c);
4190 }
4191
4192 printf("\n");
4193 }
4194
4195 if (i->status_text)
4196 printf(" Status: \"%s\"\n", i->status_text);
4197 if (i->status_errno > 0)
4198 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
4199
4200 if (i->ip_ingress_bytes != (uint64_t) -1 && i->ip_egress_bytes != (uint64_t) -1) {
4201 char buf_in[FORMAT_BYTES_MAX], buf_out[FORMAT_BYTES_MAX];
4202
4203 printf(" IP: %s in, %s out\n",
4204 format_bytes(buf_in, sizeof(buf_in), i->ip_ingress_bytes),
4205 format_bytes(buf_out, sizeof(buf_out), i->ip_egress_bytes));
4206 }
4207
4208 if (i->tasks_current != (uint64_t) -1) {
4209 printf(" Tasks: %" PRIu64, i->tasks_current);
4210
4211 if (i->tasks_max != (uint64_t) -1)
4212 printf(" (limit: %" PRIu64 ")\n", i->tasks_max);
4213 else
4214 printf("\n");
4215 }
4216
4217 if (i->memory_current != (uint64_t) -1) {
4218 char buf[FORMAT_BYTES_MAX];
4219
4220 printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
4221
4222 if (i->memory_low > 0 || i->memory_high != CGROUP_LIMIT_MAX ||
4223 i->memory_max != CGROUP_LIMIT_MAX || i->memory_swap_max != CGROUP_LIMIT_MAX ||
4224 i->memory_limit != CGROUP_LIMIT_MAX) {
4225 const char *prefix = "";
4226
4227 printf(" (");
4228 if (i->memory_low > 0) {
4229 printf("%slow: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_low));
4230 prefix = " ";
4231 }
4232 if (i->memory_high != CGROUP_LIMIT_MAX) {
4233 printf("%shigh: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_high));
4234 prefix = " ";
4235 }
4236 if (i->memory_max != CGROUP_LIMIT_MAX) {
4237 printf("%smax: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_max));
4238 prefix = " ";
4239 }
4240 if (i->memory_swap_max != CGROUP_LIMIT_MAX) {
4241 printf("%sswap max: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_swap_max));
4242 prefix = " ";
4243 }
4244 if (i->memory_limit != CGROUP_LIMIT_MAX) {
4245 printf("%slimit: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_limit));
4246 prefix = " ";
4247 }
4248 printf(")");
4249 }
4250 printf("\n");
4251 }
4252
4253 if (i->cpu_usage_nsec != (uint64_t) -1) {
4254 char buf[FORMAT_TIMESPAN_MAX];
4255 printf(" CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
4256 }
4257
4258 if (i->control_group) {
4259 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4260 static const char prefix[] = " ";
4261 unsigned c;
4262
4263 printf(" CGroup: %s\n", i->control_group);
4264
4265 c = columns();
4266 if (c > sizeof(prefix) - 1)
4267 c -= sizeof(prefix) - 1;
4268 else
4269 c = 0;
4270
4271 r = unit_show_processes(bus, i->id, i->control_group, prefix, c, get_output_flags(), &error);
4272 if (r == -EBADR) {
4273 unsigned k = 0;
4274 pid_t extra[2];
4275
4276 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
4277
4278 if (i->main_pid > 0)
4279 extra[k++] = i->main_pid;
4280
4281 if (i->control_pid > 0)
4282 extra[k++] = i->control_pid;
4283
4284 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, extra, k, get_output_flags());
4285 } else if (r < 0)
4286 log_warning_errno(r, "Failed to dump process list, ignoring: %s", bus_error_message(&error, r));
4287 }
4288
4289 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL)
4290 show_journal_by_unit(
4291 stdout,
4292 i->id,
4293 arg_output,
4294 0,
4295 i->inactive_exit_timestamp_monotonic,
4296 arg_lines,
4297 getuid(),
4298 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
4299 SD_JOURNAL_LOCAL_ONLY,
4300 arg_scope == UNIT_FILE_SYSTEM,
4301 ellipsized);
4302
4303 if (i->need_daemon_reload)
4304 warn_unit_file_changed(i->id);
4305 }
4306
4307 static void show_unit_help(UnitStatusInfo *i) {
4308 char **p;
4309
4310 assert(i);
4311
4312 if (!i->documentation) {
4313 log_info("Documentation for %s not known.", i->id);
4314 return;
4315 }
4316
4317 STRV_FOREACH(p, i->documentation)
4318 if (startswith(*p, "man:"))
4319 show_man_page(*p + 4, false);
4320 else
4321 log_info("Can't show: %s", *p);
4322 }
4323
4324 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
4325 int r;
4326
4327 assert(name);
4328 assert(m);
4329 assert(i);
4330
4331 switch (contents[0]) {
4332
4333 case SD_BUS_TYPE_STRING: {
4334 const char *s;
4335
4336 r = sd_bus_message_read(m, "s", &s);
4337 if (r < 0)
4338 return bus_log_parse_error(r);
4339
4340 if (!isempty(s)) {
4341 if (streq(name, "Id"))
4342 i->id = s;
4343 else if (streq(name, "LoadState"))
4344 i->load_state = s;
4345 else if (streq(name, "ActiveState"))
4346 i->active_state = s;
4347 else if (streq(name, "SubState"))
4348 i->sub_state = s;
4349 else if (streq(name, "Description"))
4350 i->description = s;
4351 else if (streq(name, "FragmentPath"))
4352 i->fragment_path = s;
4353 else if (streq(name, "SourcePath"))
4354 i->source_path = s;
4355 #ifndef NOLEGACY
4356 else if (streq(name, "DefaultControlGroup")) {
4357 const char *e;
4358 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
4359 if (e)
4360 i->control_group = e;
4361 }
4362 #endif
4363 else if (streq(name, "ControlGroup"))
4364 i->control_group = s;
4365 else if (streq(name, "StatusText"))
4366 i->status_text = s;
4367 else if (streq(name, "PIDFile"))
4368 i->pid_file = s;
4369 else if (streq(name, "SysFSPath"))
4370 i->sysfs_path = s;
4371 else if (streq(name, "Where"))
4372 i->where = s;
4373 else if (streq(name, "What"))
4374 i->what = s;
4375 else if (streq(name, "Following"))
4376 i->following = s;
4377 else if (streq(name, "UnitFileState"))
4378 i->unit_file_state = s;
4379 else if (streq(name, "UnitFilePreset"))
4380 i->unit_file_preset = s;
4381 else if (streq(name, "Result"))
4382 i->result = s;
4383 }
4384
4385 break;
4386 }
4387
4388 case SD_BUS_TYPE_BOOLEAN: {
4389 int b;
4390
4391 r = sd_bus_message_read(m, "b", &b);
4392 if (r < 0)
4393 return bus_log_parse_error(r);
4394
4395 if (streq(name, "Accept"))
4396 i->accept = b;
4397 else if (streq(name, "NeedDaemonReload"))
4398 i->need_daemon_reload = b;
4399 else if (streq(name, "ConditionResult"))
4400 i->condition_result = b;
4401 else if (streq(name, "AssertResult"))
4402 i->assert_result = b;
4403 else if (streq(name, "Transient"))
4404 i->transient = b;
4405
4406 break;
4407 }
4408
4409 case SD_BUS_TYPE_UINT32: {
4410 uint32_t u;
4411
4412 r = sd_bus_message_read(m, "u", &u);
4413 if (r < 0)
4414 return bus_log_parse_error(r);
4415
4416 if (streq(name, "MainPID")) {
4417 if (u > 0) {
4418 i->main_pid = (pid_t) u;
4419 i->running = true;
4420 }
4421 } else if (streq(name, "ControlPID"))
4422 i->control_pid = (pid_t) u;
4423 else if (streq(name, "ExecMainPID")) {
4424 if (u > 0)
4425 i->main_pid = (pid_t) u;
4426 } else if (streq(name, "NAccepted"))
4427 i->n_accepted = u;
4428 else if (streq(name, "NConnections"))
4429 i->n_connections = u;
4430
4431 break;
4432 }
4433
4434 case SD_BUS_TYPE_INT32: {
4435 int32_t j;
4436
4437 r = sd_bus_message_read(m, "i", &j);
4438 if (r < 0)
4439 return bus_log_parse_error(r);
4440
4441 if (streq(name, "ExecMainCode"))
4442 i->exit_code = (int) j;
4443 else if (streq(name, "ExecMainStatus"))
4444 i->exit_status = (int) j;
4445 else if (streq(name, "StatusErrno"))
4446 i->status_errno = (int) j;
4447
4448 break;
4449 }
4450
4451 case SD_BUS_TYPE_UINT64: {
4452 uint64_t u;
4453
4454 r = sd_bus_message_read(m, "t", &u);
4455 if (r < 0)
4456 return bus_log_parse_error(r);
4457
4458 if (streq(name, "ExecMainStartTimestamp"))
4459 i->start_timestamp = (usec_t) u;
4460 else if (streq(name, "ExecMainExitTimestamp"))
4461 i->exit_timestamp = (usec_t) u;
4462 else if (streq(name, "ActiveEnterTimestamp"))
4463 i->active_enter_timestamp = (usec_t) u;
4464 else if (streq(name, "InactiveEnterTimestamp"))
4465 i->inactive_enter_timestamp = (usec_t) u;
4466 else if (streq(name, "InactiveExitTimestamp"))
4467 i->inactive_exit_timestamp = (usec_t) u;
4468 else if (streq(name, "InactiveExitTimestampMonotonic"))
4469 i->inactive_exit_timestamp_monotonic = (usec_t) u;
4470 else if (streq(name, "ActiveExitTimestamp"))
4471 i->active_exit_timestamp = (usec_t) u;
4472 else if (streq(name, "ConditionTimestamp"))
4473 i->condition_timestamp = (usec_t) u;
4474 else if (streq(name, "AssertTimestamp"))
4475 i->assert_timestamp = (usec_t) u;
4476 else if (streq(name, "MemoryCurrent"))
4477 i->memory_current = u;
4478 else if (streq(name, "MemoryLow"))
4479 i->memory_low = u;
4480 else if (streq(name, "MemoryHigh"))
4481 i->memory_high = u;
4482 else if (streq(name, "MemoryMax"))
4483 i->memory_max = u;
4484 else if (streq(name, "MemorySwapMax"))
4485 i->memory_swap_max = u;
4486 else if (streq(name, "MemoryLimit"))
4487 i->memory_limit = u;
4488 else if (streq(name, "TasksCurrent"))
4489 i->tasks_current = u;
4490 else if (streq(name, "TasksMax"))
4491 i->tasks_max = u;
4492 else if (streq(name, "CPUUsageNSec"))
4493 i->cpu_usage_nsec = u;
4494 else if (streq(name, "NextElapseUSecMonotonic"))
4495 i->next_elapse_monotonic = u;
4496 else if (streq(name, "NextElapseUSecRealtime"))
4497 i->next_elapse_real = u;
4498 else if (streq(name, "IPIngressBytes"))
4499 i->ip_ingress_bytes = u;
4500 else if (streq(name, "IPEgressBytes"))
4501 i->ip_egress_bytes = u;
4502
4503 break;
4504 }
4505
4506 case SD_BUS_TYPE_ARRAY:
4507
4508 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4509 _cleanup_free_ ExecStatusInfo *info = NULL;
4510
4511 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4512 if (r < 0)
4513 return bus_log_parse_error(r);
4514
4515 info = new0(ExecStatusInfo, 1);
4516 if (!info)
4517 return log_oom();
4518
4519 while ((r = exec_status_info_deserialize(m, info)) > 0) {
4520
4521 info->name = strdup(name);
4522 if (!info->name)
4523 return log_oom();
4524
4525 LIST_PREPEND(exec, i->exec, info);
4526
4527 info = new0(ExecStatusInfo, 1);
4528 if (!info)
4529 return log_oom();
4530 }
4531
4532 if (r < 0)
4533 return bus_log_parse_error(r);
4534
4535 r = sd_bus_message_exit_container(m);
4536 if (r < 0)
4537 return bus_log_parse_error(r);
4538
4539 return 0;
4540
4541 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4542 const char *type, *path;
4543
4544 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4545 if (r < 0)
4546 return bus_log_parse_error(r);
4547
4548 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
4549
4550 r = strv_extend(&i->listen, type);
4551 if (r < 0)
4552 return r;
4553
4554 r = strv_extend(&i->listen, path);
4555 if (r < 0)
4556 return r;
4557 }
4558 if (r < 0)
4559 return bus_log_parse_error(r);
4560
4561 r = sd_bus_message_exit_container(m);
4562 if (r < 0)
4563 return bus_log_parse_error(r);
4564
4565 return 0;
4566
4567 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
4568
4569 r = sd_bus_message_read_strv(m, &i->dropin_paths);
4570 if (r < 0)
4571 return bus_log_parse_error(r);
4572
4573 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
4574
4575 r = sd_bus_message_read_strv(m, &i->documentation);
4576 if (r < 0)
4577 return bus_log_parse_error(r);
4578
4579 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
4580 const char *cond, *param;
4581 int trigger, negate;
4582 int32_t state;
4583
4584 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
4585 if (r < 0)
4586 return bus_log_parse_error(r);
4587
4588 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
4589 _cleanup_(unit_condition_freep) UnitCondition *c = NULL;
4590
4591 log_debug("%s trigger=%d negate=%d %s →%d", cond, trigger, negate, param, state);
4592
4593 c = new0(UnitCondition, 1);
4594 if (!c)
4595 return log_oom();
4596
4597 c->name = strdup(cond);
4598 c->param = strdup(param);
4599 if (!c->name || !c->param)
4600 return log_oom();
4601
4602 c->trigger = trigger;
4603 c->negate = negate;
4604 c->tristate = state;
4605
4606 LIST_PREPEND(conditions, i->conditions, c);
4607 c = NULL;
4608 }
4609 if (r < 0)
4610 return bus_log_parse_error(r);
4611
4612 r = sd_bus_message_exit_container(m);
4613 if (r < 0)
4614 return bus_log_parse_error(r);
4615
4616 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
4617 const char *cond, *param;
4618 int trigger, negate;
4619 int32_t state;
4620
4621 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
4622 if (r < 0)
4623 return bus_log_parse_error(r);
4624
4625 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
4626 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
4627 if (state < 0 && (!trigger || !i->failed_assert)) {
4628 i->failed_assert = cond;
4629 i->failed_assert_trigger = trigger;
4630 i->failed_assert_negate = negate;
4631 i->failed_assert_parameter = param;
4632 }
4633 }
4634 if (r < 0)
4635 return bus_log_parse_error(r);
4636
4637 r = sd_bus_message_exit_container(m);
4638 if (r < 0)
4639 return bus_log_parse_error(r);
4640
4641 } else
4642 goto skip;
4643
4644 break;
4645
4646 case SD_BUS_TYPE_STRUCT_BEGIN:
4647
4648 if (streq(name, "LoadError")) {
4649 const char *n, *message;
4650
4651 r = sd_bus_message_read(m, "(ss)", &n, &message);
4652 if (r < 0)
4653 return bus_log_parse_error(r);
4654
4655 if (!isempty(message))
4656 i->load_error = message;
4657 } else
4658 goto skip;
4659
4660 break;
4661
4662 default:
4663 goto skip;
4664 }
4665
4666 return 0;
4667
4668 skip:
4669 r = sd_bus_message_skip(m, contents);
4670 if (r < 0)
4671 return bus_log_parse_error(r);
4672
4673 return 0;
4674 }
4675
4676 #define print_prop(name, fmt, ...) \
4677 do { \
4678 if (arg_value) \
4679 printf(fmt "\n", __VA_ARGS__); \
4680 else \
4681 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4682 } while(0)
4683
4684 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
4685 int r;
4686
4687 assert(name);
4688 assert(m);
4689
4690 /* This is a low-level property printer, see
4691 * print_status_info() for the nicer output */
4692
4693 if (arg_properties && !strv_find(arg_properties, name)) {
4694 /* skip what we didn't read */
4695 r = sd_bus_message_skip(m, contents);
4696 return r;
4697 }
4698
4699 switch (contents[0]) {
4700
4701 case SD_BUS_TYPE_STRUCT_BEGIN:
4702
4703 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
4704 uint32_t u;
4705
4706 r = sd_bus_message_read(m, "(uo)", &u, NULL);
4707 if (r < 0)
4708 return bus_log_parse_error(r);
4709
4710 if (u > 0)
4711 print_prop(name, "%"PRIu32, u);
4712 else if (arg_all)
4713 print_prop(name, "%s", "");
4714
4715 return 0;
4716
4717 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
4718 const char *s;
4719
4720 r = sd_bus_message_read(m, "(so)", &s, NULL);
4721 if (r < 0)
4722 return bus_log_parse_error(r);
4723
4724 if (arg_all || !isempty(s))
4725 print_prop(name, "%s", s);
4726
4727 return 0;
4728
4729 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
4730 const char *a = NULL, *b = NULL;
4731
4732 r = sd_bus_message_read(m, "(ss)", &a, &b);
4733 if (r < 0)
4734 return bus_log_parse_error(r);
4735
4736 if (arg_all || !isempty(a) || !isempty(b))
4737 print_prop(name, "%s \"%s\"", strempty(a), strempty(b));
4738
4739 return 0;
4740 } else if (streq_ptr(name, "SystemCallFilter")) {
4741 _cleanup_strv_free_ char **l = NULL;
4742 int whitelist;
4743
4744 r = sd_bus_message_enter_container(m, 'r', "bas");
4745 if (r < 0)
4746 return bus_log_parse_error(r);
4747
4748 r = sd_bus_message_read(m, "b", &whitelist);
4749 if (r < 0)
4750 return bus_log_parse_error(r);
4751
4752 r = sd_bus_message_read_strv(m, &l);
4753 if (r < 0)
4754 return bus_log_parse_error(r);
4755
4756 r = sd_bus_message_exit_container(m);
4757 if (r < 0)
4758 return bus_log_parse_error(r);
4759
4760 if (arg_all || whitelist || !strv_isempty(l)) {
4761 bool first = true;
4762 char **i;
4763
4764 if (!arg_value) {
4765 fputs(name, stdout);
4766 fputc('=', stdout);
4767 }
4768
4769 if (!whitelist)
4770 fputc('~', stdout);
4771
4772 STRV_FOREACH(i, l) {
4773 if (first)
4774 first = false;
4775 else
4776 fputc(' ', stdout);
4777
4778 fputs(*i, stdout);
4779 }
4780 fputc('\n', stdout);
4781 }
4782
4783 return 0;
4784 }
4785
4786 break;
4787
4788 case SD_BUS_TYPE_ARRAY:
4789
4790 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4791 const char *path;
4792 int ignore;
4793
4794 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4795 if (r < 0)
4796 return bus_log_parse_error(r);
4797
4798 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4799 print_prop("EnvironmentFile", "%s (ignore_errors=%s)", path, yes_no(ignore));
4800
4801 if (r < 0)
4802 return bus_log_parse_error(r);
4803
4804 r = sd_bus_message_exit_container(m);
4805 if (r < 0)
4806 return bus_log_parse_error(r);
4807
4808 return 0;
4809
4810 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4811 const char *type, *path;
4812
4813 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4814 if (r < 0)
4815 return bus_log_parse_error(r);
4816
4817 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4818 print_prop(type, "%s", path);
4819 if (r < 0)
4820 return bus_log_parse_error(r);
4821
4822 r = sd_bus_message_exit_container(m);
4823 if (r < 0)
4824 return bus_log_parse_error(r);
4825
4826 return 0;
4827
4828 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4829 const char *type, *path;
4830
4831 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4832 if (r < 0)
4833 return bus_log_parse_error(r);
4834
4835 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4836 if (arg_value)
4837 puts(path);
4838 else
4839 printf("Listen%s=%s\n", type, path);
4840 if (r < 0)
4841 return bus_log_parse_error(r);
4842
4843 r = sd_bus_message_exit_container(m);
4844 if (r < 0)
4845 return bus_log_parse_error(r);
4846
4847 return 0;
4848
4849 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4850 const char *base;
4851 uint64_t value, next_elapse;
4852
4853 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4854 if (r < 0)
4855 return bus_log_parse_error(r);
4856
4857 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4858 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4859
4860 print_prop(base, "{ value=%s ; next_elapse=%s }",
4861 format_timespan(timespan1, sizeof(timespan1), value, 0),
4862 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4863 }
4864 if (r < 0)
4865 return bus_log_parse_error(r);
4866
4867 r = sd_bus_message_exit_container(m);
4868 if (r < 0)
4869 return bus_log_parse_error(r);
4870
4871 return 0;
4872
4873 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4874 ExecStatusInfo info = {};
4875
4876 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4877 if (r < 0)
4878 return bus_log_parse_error(r);
4879
4880 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4881 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4882 _cleanup_free_ char *tt;
4883
4884 tt = strv_join(info.argv, " ");
4885
4886 print_prop(name,
4887 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }",
4888 strna(info.path),
4889 strna(tt),
4890 yes_no(info.ignore),
4891 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4892 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4893 info.pid,
4894 sigchld_code_to_string(info.code),
4895 info.status,
4896 info.code == CLD_EXITED ? "" : "/",
4897 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4898
4899 free(info.path);
4900 strv_free(info.argv);
4901 zero(info);
4902 }
4903
4904 r = sd_bus_message_exit_container(m);
4905 if (r < 0)
4906 return bus_log_parse_error(r);
4907
4908 return 0;
4909
4910 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4911 const char *path, *rwm;
4912
4913 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4914 if (r < 0)
4915 return bus_log_parse_error(r);
4916
4917 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4918 print_prop(name, "%s %s", strna(path), strna(rwm));
4919 if (r < 0)
4920 return bus_log_parse_error(r);
4921
4922 r = sd_bus_message_exit_container(m);
4923 if (r < 0)
4924 return bus_log_parse_error(r);
4925
4926 return 0;
4927
4928 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN &&
4929 STR_IN_SET(name, "IODeviceWeight", "BlockIODeviceWeight")) {
4930 const char *path;
4931 uint64_t weight;
4932
4933 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4934 if (r < 0)
4935 return bus_log_parse_error(r);
4936
4937 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4938 print_prop(name, "%s %"PRIu64, strna(path), weight);
4939 if (r < 0)
4940 return bus_log_parse_error(r);
4941
4942 r = sd_bus_message_exit_container(m);
4943 if (r < 0)
4944 return bus_log_parse_error(r);
4945
4946 return 0;
4947
4948 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN &&
4949 (cgroup_io_limit_type_from_string(name) >= 0 ||
4950 STR_IN_SET(name, "BlockIOReadBandwidth", "BlockIOWriteBandwidth"))) {
4951 const char *path;
4952 uint64_t bandwidth;
4953
4954 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4955 if (r < 0)
4956 return bus_log_parse_error(r);
4957
4958 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4959 print_prop(name, "%s %"PRIu64, strna(path), bandwidth);
4960 if (r < 0)
4961 return bus_log_parse_error(r);
4962
4963 r = sd_bus_message_exit_container(m);
4964 if (r < 0)
4965 return bus_log_parse_error(r);
4966
4967 return 0;
4968 }
4969
4970 break;
4971 }
4972
4973 r = bus_print_property(name, m, arg_value, arg_all);
4974 if (r < 0)
4975 return bus_log_parse_error(r);
4976
4977 if (r == 0) {
4978 r = sd_bus_message_skip(m, contents);
4979 if (r < 0)
4980 return bus_log_parse_error(r);
4981
4982 if (arg_all)
4983 printf("%s=[unprintable]\n", name);
4984 }
4985
4986 return 0;
4987 }
4988
4989 static int show_one(
4990 const char *verb,
4991 sd_bus *bus,
4992 const char *path,
4993 const char *unit,
4994 bool show_properties,
4995 bool *new_line,
4996 bool *ellipsized) {
4997
4998 static const struct bus_properties_map property_map[] = {
4999 { "LoadState", "s", map_string_no_copy, offsetof(UnitStatusInfo, load_state) },
5000 { "ActiveState", "s", map_string_no_copy, offsetof(UnitStatusInfo, active_state) },
5001 {}
5002 };
5003
5004 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
5005 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5006 _cleanup_set_free_ Set *found_properties = NULL;
5007 _cleanup_(unit_status_info_free) UnitStatusInfo info = {
5008 .memory_current = (uint64_t) -1,
5009 .memory_high = CGROUP_LIMIT_MAX,
5010 .memory_max = CGROUP_LIMIT_MAX,
5011 .memory_swap_max = CGROUP_LIMIT_MAX,
5012 .memory_limit = (uint64_t) -1,
5013 .cpu_usage_nsec = (uint64_t) -1,
5014 .tasks_current = (uint64_t) -1,
5015 .tasks_max = (uint64_t) -1,
5016 .ip_ingress_bytes = (uint64_t) -1,
5017 .ip_egress_bytes = (uint64_t) -1,
5018 };
5019 int r;
5020
5021 assert(path);
5022 assert(new_line);
5023
5024 log_debug("Showing one %s", path);
5025
5026 r = sd_bus_call_method(
5027 bus,
5028 "org.freedesktop.systemd1",
5029 path,
5030 "org.freedesktop.DBus.Properties",
5031 "GetAll",
5032 &error,
5033 &reply,
5034 "s", "");
5035 if (r < 0)
5036 return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
5037
5038 if (unit) {
5039 r = bus_message_map_all_properties(reply, property_map, &error, &info);
5040 if (r < 0)
5041 return log_error_errno(r, "Failed to map properties: %s", bus_error_message(&error, r));
5042
5043 if (streq_ptr(info.load_state, "not-found") && streq_ptr(info.active_state, "inactive")) {
5044 log_full(streq(verb, "status") ? LOG_ERR : LOG_DEBUG,
5045 "Unit %s could not be found.", unit);
5046
5047 if (streq(verb, "status"))
5048 return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN;
5049
5050 if (!streq(verb, "show"))
5051 return -ENOENT;
5052 }
5053
5054 r = sd_bus_message_rewind(reply, true);
5055 if (r < 0)
5056 return log_error_errno(r, "Failed to rewind: %s", bus_error_message(&error, r));
5057 }
5058
5059 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
5060 if (r < 0)
5061 return bus_log_parse_error(r);
5062
5063 if (*new_line)
5064 printf("\n");
5065
5066 *new_line = true;
5067
5068 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
5069 const char *name, *contents;
5070
5071 r = sd_bus_message_read(reply, "s", &name);
5072 if (r < 0)
5073 return bus_log_parse_error(r);
5074
5075 r = sd_bus_message_peek_type(reply, NULL, &contents);
5076 if (r < 0)
5077 return bus_log_parse_error(r);
5078
5079 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
5080 if (r < 0)
5081 return bus_log_parse_error(r);
5082
5083 if (show_properties) {
5084 r = set_ensure_allocated(&found_properties, &string_hash_ops);
5085 if (r < 0)
5086 return log_oom();
5087
5088 r = set_put(found_properties, name);
5089 if (r < 0 && r != EEXIST)
5090 return log_oom();
5091
5092 r = print_property(name, reply, contents);
5093 } else
5094 r = status_property(name, reply, &info, contents);
5095 if (r < 0)
5096 return r;
5097
5098 r = sd_bus_message_exit_container(reply);
5099 if (r < 0)
5100 return bus_log_parse_error(r);
5101
5102 r = sd_bus_message_exit_container(reply);
5103 if (r < 0)
5104 return bus_log_parse_error(r);
5105 }
5106 if (r < 0)
5107 return bus_log_parse_error(r);
5108
5109 r = sd_bus_message_exit_container(reply);
5110 if (r < 0)
5111 return bus_log_parse_error(r);
5112
5113 r = 0;
5114 if (show_properties) {
5115 char **pp;
5116
5117 STRV_FOREACH(pp, arg_properties)
5118 if (!set_contains(found_properties, *pp))
5119 log_debug("Property %s does not exist.", *pp);
5120
5121 } else if (streq(verb, "help"))
5122 show_unit_help(&info);
5123 else if (streq(verb, "status")) {
5124 print_status_info(bus, &info, ellipsized);
5125
5126 if (info.active_state && !STR_IN_SET(info.active_state, "active", "reloading"))
5127 r = EXIT_PROGRAM_NOT_RUNNING;
5128 else
5129 r = EXIT_PROGRAM_RUNNING_OR_SERVICE_OK;
5130 }
5131
5132 return r;
5133 }
5134
5135 static int get_unit_dbus_path_by_pid(
5136 sd_bus *bus,
5137 uint32_t pid,
5138 char **unit) {
5139
5140 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5141 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
5142 char *u;
5143 int r;
5144
5145 r = sd_bus_call_method(
5146 bus,
5147 "org.freedesktop.systemd1",
5148 "/org/freedesktop/systemd1",
5149 "org.freedesktop.systemd1.Manager",
5150 "GetUnitByPID",
5151 &error,
5152 &reply,
5153 "u", pid);
5154 if (r < 0)
5155 return log_error_errno(r, "Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
5156
5157 r = sd_bus_message_read(reply, "o", &u);
5158 if (r < 0)
5159 return bus_log_parse_error(r);
5160
5161 u = strdup(u);
5162 if (!u)
5163 return log_oom();
5164
5165 *unit = u;
5166 return 0;
5167 }
5168
5169 static int show_all(
5170 const char* verb,
5171 sd_bus *bus,
5172 bool show_properties,
5173 bool *new_line,
5174 bool *ellipsized) {
5175
5176 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
5177 _cleanup_free_ UnitInfo *unit_infos = NULL;
5178 const UnitInfo *u;
5179 unsigned c;
5180 int r, ret = 0;
5181
5182 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
5183 if (r < 0)
5184 return r;
5185
5186 pager_open(arg_no_pager, false);
5187
5188 c = (unsigned) r;
5189
5190 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
5191
5192 for (u = unit_infos; u < unit_infos + c; u++) {
5193 _cleanup_free_ char *p = NULL;
5194
5195 p = unit_dbus_path_from_name(u->id);
5196 if (!p)
5197 return log_oom();
5198
5199 r = show_one(verb, bus, p, u->id, show_properties, new_line, ellipsized);
5200 if (r < 0)
5201 return r;
5202 else if (r > 0 && ret == 0)
5203 ret = r;
5204 }
5205
5206 return ret;
5207 }
5208
5209 static int show_system_status(sd_bus *bus) {
5210 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
5211 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5212 _cleanup_(machine_info_clear) struct machine_info mi = {};
5213 _cleanup_free_ char *hn = NULL;
5214 const char *on, *off;
5215 int r;
5216
5217 hn = gethostname_malloc();
5218 if (!hn)
5219 return log_oom();
5220
5221 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &error, &mi);
5222 if (r < 0)
5223 return log_error_errno(r, "Failed to read server status: %s", bus_error_message(&error, r));
5224
5225 if (streq_ptr(mi.state, "degraded")) {
5226 on = ansi_highlight_red();
5227 off = ansi_normal();
5228 } else if (!streq_ptr(mi.state, "running")) {
5229 on = ansi_highlight_yellow();
5230 off = ansi_normal();
5231 } else
5232 on = off = "";
5233
5234 printf("%s%s%s %s\n", on, special_glyph(BLACK_CIRCLE), off, arg_host ? arg_host : hn);
5235
5236 printf(" State: %s%s%s\n",
5237 on, strna(mi.state), off);
5238
5239 printf(" Jobs: %" PRIu32 " queued\n", mi.n_jobs);
5240 printf(" Failed: %" PRIu32 " units\n", mi.n_failed_units);
5241
5242 printf(" Since: %s; %s\n",
5243 format_timestamp(since2, sizeof(since2), mi.timestamp),
5244 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
5245
5246 printf(" CGroup: %s\n", mi.control_group ?: "/");
5247 if (IN_SET(arg_transport,
5248 BUS_TRANSPORT_LOCAL,
5249 BUS_TRANSPORT_MACHINE)) {
5250 static const char prefix[] = " ";
5251 unsigned c;
5252
5253 c = columns();
5254 if (c > sizeof(prefix) - 1)
5255 c -= sizeof(prefix) - 1;
5256 else
5257 c = 0;
5258
5259 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, get_output_flags());
5260 }
5261
5262 return 0;
5263 }
5264
5265 static int show(int argc, char *argv[], void *userdata) {
5266 bool show_properties, show_status, show_help, new_line = false;
5267 bool ellipsized = false;
5268 int r, ret = 0;
5269 sd_bus *bus;
5270
5271 assert(argv);
5272
5273 show_properties = streq(argv[0], "show");
5274 show_status = streq(argv[0], "status");
5275 show_help = streq(argv[0], "help");
5276
5277 if (show_help && argc <= 1) {
5278 log_error("This command expects one or more unit names. Did you mean --help?");
5279 return -EINVAL;
5280 }
5281
5282 r = acquire_bus(BUS_MANAGER, &bus);
5283 if (r < 0)
5284 return r;
5285
5286 pager_open(arg_no_pager, false);
5287
5288 if (show_status)
5289 /* Increase max number of open files to 16K if we can, we
5290 * might needs this when browsing journal files, which might
5291 * be split up into many files. */
5292 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
5293
5294 /* If no argument is specified inspect the manager itself */
5295 if (show_properties && argc <= 1)
5296 return show_one(argv[0], bus, "/org/freedesktop/systemd1", NULL, show_properties, &new_line, &ellipsized);
5297
5298 if (show_status && argc <= 1) {
5299
5300 show_system_status(bus);
5301 new_line = true;
5302
5303 if (arg_all)
5304 ret = show_all(argv[0], bus, false, &new_line, &ellipsized);
5305 } else {
5306 _cleanup_free_ char **patterns = NULL;
5307 char **name;
5308
5309 STRV_FOREACH(name, strv_skip(argv, 1)) {
5310 _cleanup_free_ char *path = NULL, *unit = NULL;
5311 uint32_t id;
5312
5313 if (safe_atou32(*name, &id) < 0) {
5314 if (strv_push(&patterns, *name) < 0)
5315 return log_oom();
5316
5317 continue;
5318 } else if (show_properties) {
5319 /* Interpret as job id */
5320 if (asprintf(&path, "/org/freedesktop/systemd1/job/%u", id) < 0)
5321 return log_oom();
5322
5323 } else {
5324 /* Interpret as PID */
5325 r = get_unit_dbus_path_by_pid(bus, id, &path);
5326 if (r < 0) {
5327 ret = r;
5328 continue;
5329 }
5330
5331 r = unit_name_from_dbus_path(path, &unit);
5332 if (r < 0)
5333 return log_oom();
5334 }
5335
5336 r = show_one(argv[0], bus, path, unit, show_properties, &new_line, &ellipsized);
5337 if (r < 0)
5338 return r;
5339 else if (r > 0 && ret == 0)
5340 ret = r;
5341 }
5342
5343 if (!strv_isempty(patterns)) {
5344 _cleanup_strv_free_ char **names = NULL;
5345
5346 r = expand_names(bus, patterns, NULL, &names);
5347 if (r < 0)
5348 return log_error_errno(r, "Failed to expand names: %m");
5349
5350 STRV_FOREACH(name, names) {
5351 _cleanup_free_ char *path;
5352
5353 path = unit_dbus_path_from_name(*name);
5354 if (!path)
5355 return log_oom();
5356
5357 r = show_one(argv[0], bus, path, *name, show_properties, &new_line, &ellipsized);
5358 if (r < 0)
5359 return r;
5360 if (r > 0 && ret == 0)
5361 ret = r;
5362 }
5363 }
5364 }
5365
5366 if (ellipsized && !arg_quiet)
5367 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
5368
5369 return ret;
5370 }
5371
5372 static int cat_file(const char *filename, bool newline) {
5373 _cleanup_close_ int fd;
5374
5375 fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
5376 if (fd < 0)
5377 return -errno;
5378
5379 printf("%s%s# %s%s\n",
5380 newline ? "\n" : "",
5381 ansi_highlight_blue(),
5382 filename,
5383 ansi_normal());
5384 fflush(stdout);
5385
5386 return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, 0);
5387 }
5388
5389 static int cat(int argc, char *argv[], void *userdata) {
5390 _cleanup_lookup_paths_free_ LookupPaths lp = {};
5391 _cleanup_strv_free_ char **names = NULL;
5392 char **name;
5393 sd_bus *bus;
5394 bool first = true;
5395 int r;
5396
5397 if (arg_transport != BUS_TRANSPORT_LOCAL) {
5398 log_error("Cannot remotely cat units.");
5399 return -EINVAL;
5400 }
5401
5402 r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
5403 if (r < 0)
5404 return log_error_errno(r, "Failed to determine unit paths: %m");
5405
5406 r = acquire_bus(BUS_MANAGER, &bus);
5407 if (r < 0)
5408 return r;
5409
5410 r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
5411 if (r < 0)
5412 return log_error_errno(r, "Failed to expand names: %m");
5413
5414 pager_open(arg_no_pager, false);
5415
5416 STRV_FOREACH(name, names) {
5417 _cleanup_free_ char *fragment_path = NULL;
5418 _cleanup_strv_free_ char **dropin_paths = NULL;
5419 char **path;
5420
5421 r = unit_find_paths(bus, *name, &lp, &fragment_path, &dropin_paths);
5422 if (r < 0)
5423 return r;
5424 else if (r == 0)
5425 return -ENOENT;
5426
5427 if (first)
5428 first = false;
5429 else
5430 puts("");
5431
5432 if (need_daemon_reload(bus, *name) > 0) /* ignore errors (<0), this is informational output */
5433 fprintf(stderr,
5434 "%s# Warning: %s changed on disk, the version systemd has loaded is outdated.\n"
5435 "%s# This output shows the current version of the unit's original fragment and drop-in files.\n"
5436 "%s# If fragments or drop-ins were added or removed, they are not properly reflected in this output.\n"
5437 "%s# Run 'systemctl%s daemon-reload' to reload units.%s\n",
5438 ansi_highlight_red(),
5439 *name,
5440 ansi_highlight_red(),
5441 ansi_highlight_red(),
5442 ansi_highlight_red(),
5443 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user",
5444 ansi_normal());
5445
5446 if (fragment_path) {
5447 r = cat_file(fragment_path, false);
5448 if (r < 0)
5449 return log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
5450 }
5451
5452 STRV_FOREACH(path, dropin_paths) {
5453 r = cat_file(*path, path == dropin_paths);
5454 if (r < 0)
5455 return log_warning_errno(r, "Failed to cat %s: %m", *path);
5456 }
5457 }
5458
5459 return 0;
5460 }
5461
5462 static int set_property(int argc, char *argv[], void *userdata) {
5463 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
5464 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5465 _cleanup_free_ char *n = NULL;
5466 sd_bus *bus;
5467 int r;
5468
5469 r = acquire_bus(BUS_MANAGER, &bus);
5470 if (r < 0)
5471 return r;
5472
5473 polkit_agent_open_if_enabled();
5474
5475 r = sd_bus_message_new_method_call(
5476 bus,
5477 &m,
5478 "org.freedesktop.systemd1",
5479 "/org/freedesktop/systemd1",
5480 "org.freedesktop.systemd1.Manager",
5481 "SetUnitProperties");
5482 if (r < 0)
5483 return bus_log_create_error(r);
5484
5485 r = unit_name_mangle(argv[1], UNIT_NAME_NOGLOB, &n);
5486 if (r < 0)
5487 return log_error_errno(r, "Failed to mangle unit name: %m");
5488
5489 r = sd_bus_message_append(m, "sb", n, arg_runtime);
5490 if (r < 0)
5491 return bus_log_create_error(r);
5492
5493 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
5494 if (r < 0)
5495 return bus_log_create_error(r);
5496
5497 r = bus_append_unit_property_assignment_many(m, strv_skip(argv, 2));
5498 if (r < 0)
5499 return r;
5500
5501 r = sd_bus_message_close_container(m);
5502 if (r < 0)
5503 return bus_log_create_error(r);
5504
5505 r = sd_bus_call(bus, m, 0, &error, NULL);
5506 if (r < 0)
5507 return log_error_errno(r, "Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
5508
5509 return 0;
5510 }
5511
5512 static int daemon_reload(int argc, char *argv[], void *userdata) {
5513 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5514 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
5515 const char *method;
5516 sd_bus *bus;
5517 int r;
5518
5519 r = acquire_bus(BUS_MANAGER, &bus);
5520 if (r < 0)
5521 return r;
5522
5523 polkit_agent_open_if_enabled();
5524
5525 switch (arg_action) {
5526
5527 case ACTION_RELOAD:
5528 method = "Reload";
5529 break;
5530
5531 case ACTION_REEXEC:
5532 method = "Reexecute";
5533 break;
5534
5535 case ACTION_SYSTEMCTL:
5536 method = streq(argv[0], "daemon-reexec") ? "Reexecute" :
5537 /* "daemon-reload" */ "Reload";
5538 break;
5539
5540 default:
5541 assert_not_reached("Unexpected action");
5542 }
5543
5544 r = sd_bus_message_new_method_call(
5545 bus,
5546 &m,
5547 "org.freedesktop.systemd1",
5548 "/org/freedesktop/systemd1",
5549 "org.freedesktop.systemd1.Manager",
5550 method);
5551 if (r < 0)
5552 return bus_log_create_error(r);
5553
5554 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
5555 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
5556 * their timeout, and for everything else there's the same time budget in place. */
5557
5558 r = sd_bus_call(bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL);
5559
5560 /* On reexecution, we expect a disconnect, not a reply */
5561 if (IN_SET(r, -ETIMEDOUT, -ECONNRESET) && streq(method, "Reexecute"))
5562 r = 0;
5563
5564 if (r < 0 && arg_action == ACTION_SYSTEMCTL)
5565 return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
5566
5567 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5568 * old ways of doing things, hence don't log any error in that case here. */
5569
5570 return r < 0 ? r : 0;
5571 }
5572
5573 static int trivial_method(int argc, char *argv[], void *userdata) {
5574 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5575 const char *method;
5576 sd_bus *bus;
5577 int r;
5578
5579 r = acquire_bus(BUS_MANAGER, &bus);
5580 if (r < 0)
5581 return r;
5582
5583 polkit_agent_open_if_enabled();
5584
5585 method =
5586 streq(argv[0], "clear-jobs") ||
5587 streq(argv[0], "cancel") ? "ClearJobs" :
5588 streq(argv[0], "reset-failed") ? "ResetFailed" :
5589 streq(argv[0], "halt") ? "Halt" :
5590 streq(argv[0], "reboot") ? "Reboot" :
5591 streq(argv[0], "kexec") ? "KExec" :
5592 streq(argv[0], "exit") ? "Exit" :
5593 /* poweroff */ "PowerOff";
5594
5595 r = sd_bus_call_method(
5596 bus,
5597 "org.freedesktop.systemd1",
5598 "/org/freedesktop/systemd1",
5599 "org.freedesktop.systemd1.Manager",
5600 method,
5601 &error,
5602 NULL,
5603 NULL);
5604 if (r < 0 && arg_action == ACTION_SYSTEMCTL)
5605 return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
5606
5607 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5608 * old ways of doing things, hence don't log any error in that case here. */
5609
5610 return r < 0 ? r : 0;
5611 }
5612
5613 static int reset_failed(int argc, char *argv[], void *userdata) {
5614 _cleanup_strv_free_ char **names = NULL;
5615 sd_bus *bus;
5616 char **name;
5617 int r, q;
5618
5619 if (argc <= 1)
5620 return trivial_method(argc, argv, userdata);
5621
5622 r = acquire_bus(BUS_MANAGER, &bus);
5623 if (r < 0)
5624 return r;
5625
5626 polkit_agent_open_if_enabled();
5627
5628 r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
5629 if (r < 0)
5630 return log_error_errno(r, "Failed to expand names: %m");
5631
5632 STRV_FOREACH(name, names) {
5633 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5634
5635 q = sd_bus_call_method(
5636 bus,
5637 "org.freedesktop.systemd1",
5638 "/org/freedesktop/systemd1",
5639 "org.freedesktop.systemd1.Manager",
5640 "ResetFailedUnit",
5641 &error,
5642 NULL,
5643 "s", *name);
5644 if (q < 0) {
5645 log_error_errno(q, "Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
5646 if (r == 0)
5647 r = q;
5648 }
5649 }
5650
5651 return r;
5652 }
5653
5654 static int print_variable(const char *s) {
5655 const char *sep;
5656 _cleanup_free_ char *esc = NULL;
5657
5658 sep = strchr(s, '=');
5659 if (!sep) {
5660 log_error("Invalid environment block");
5661 return -EUCLEAN;
5662 }
5663
5664 esc = shell_maybe_quote(sep + 1, ESCAPE_POSIX);
5665 if (!esc)
5666 return log_oom();
5667
5668 printf("%.*s=%s\n", (int)(sep-s), s, esc);
5669 return 0;
5670 }
5671
5672 static int show_environment(int argc, char *argv[], void *userdata) {
5673 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5674 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
5675 const char *text;
5676 sd_bus *bus;
5677 int r;
5678
5679 r = acquire_bus(BUS_MANAGER, &bus);
5680 if (r < 0)
5681 return r;
5682
5683 pager_open(arg_no_pager, false);
5684
5685 r = sd_bus_get_property(
5686 bus,
5687 "org.freedesktop.systemd1",
5688 "/org/freedesktop/systemd1",
5689 "org.freedesktop.systemd1.Manager",
5690 "Environment",
5691 &error,
5692 &reply,
5693 "as");
5694 if (r < 0)
5695 return log_error_errno(r, "Failed to get environment: %s", bus_error_message(&error, r));
5696
5697 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
5698 if (r < 0)
5699 return bus_log_parse_error(r);
5700
5701 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0) {
5702 r = print_variable(text);
5703 if (r < 0)
5704 return r;
5705 }
5706 if (r < 0)
5707 return bus_log_parse_error(r);
5708
5709 r = sd_bus_message_exit_container(reply);
5710 if (r < 0)
5711 return bus_log_parse_error(r);
5712
5713 return 0;
5714 }
5715
5716 static int switch_root(int argc, char *argv[], void *userdata) {
5717 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5718 _cleanup_free_ char *cmdline_init = NULL;
5719 const char *root, *init;
5720 sd_bus *bus;
5721 int r;
5722
5723 if (arg_transport != BUS_TRANSPORT_LOCAL) {
5724 log_error("Cannot switch root remotely.");
5725 return -EINVAL;
5726 }
5727
5728 if (argc < 2 || argc > 3) {
5729 log_error("Wrong number of arguments.");
5730 return -EINVAL;
5731 }
5732
5733 root = argv[1];
5734
5735 if (argc >= 3)
5736 init = argv[2];
5737 else {
5738 r = parse_env_file("/proc/cmdline", WHITESPACE,
5739 "init", &cmdline_init,
5740 NULL);
5741 if (r < 0)
5742 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
5743
5744 init = cmdline_init;
5745 }
5746
5747 init = empty_to_null(init);
5748 if (init) {
5749 const char *root_systemd_path = NULL, *root_init_path = NULL;
5750
5751 root_systemd_path = strjoina(root, "/" SYSTEMD_BINARY_PATH);
5752 root_init_path = strjoina(root, "/", init);
5753
5754 /* If the passed init is actually the same as the
5755 * systemd binary, then let's suppress it. */
5756 if (files_same(root_init_path, root_systemd_path, 0) > 0)
5757 init = NULL;
5758 }
5759
5760 /* Instruct PID1 to exclude us from its killing spree applied during
5761 * the transition. Otherwise we would exit with a failure status even
5762 * though the switch to the new root has succeed. */
5763 argv_cmdline[0] = '@';
5764
5765 r = acquire_bus(BUS_MANAGER, &bus);
5766 if (r < 0)
5767 return r;
5768
5769 /* If we are slow to exit after the root switch, the new systemd instance
5770 * will send us a signal to terminate. Just ignore it and exit normally.
5771 * This way the unit does not end up as failed.
5772 */
5773 r = ignore_signals(SIGTERM, -1);
5774 if (r < 0)
5775 log_warning_errno(r, "Failed to change disposition of SIGTERM to ignore: %m");
5776
5777 log_debug("Switching root - root: %s; init: %s", root, strna(init));
5778
5779 r = sd_bus_call_method(
5780 bus,
5781 "org.freedesktop.systemd1",
5782 "/org/freedesktop/systemd1",
5783 "org.freedesktop.systemd1.Manager",
5784 "SwitchRoot",
5785 &error,
5786 NULL,
5787 "ss", root, init);
5788 if (r < 0) {
5789 (void) default_signals(SIGTERM, -1);
5790
5791 return log_error_errno(r, "Failed to switch root: %s", bus_error_message(&error, r));
5792 }
5793
5794 return 0;
5795 }
5796
5797 static int set_environment(int argc, char *argv[], void *userdata) {
5798 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5799 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
5800 const char *method;
5801 sd_bus *bus;
5802 int r;
5803
5804 assert(argc > 1);
5805 assert(argv);
5806
5807 r = acquire_bus(BUS_MANAGER, &bus);
5808 if (r < 0)
5809 return r;
5810
5811 polkit_agent_open_if_enabled();
5812
5813 method = streq(argv[0], "set-environment")
5814 ? "SetEnvironment"
5815 : "UnsetEnvironment";
5816
5817 r = sd_bus_message_new_method_call(
5818 bus,
5819 &m,
5820 "org.freedesktop.systemd1",
5821 "/org/freedesktop/systemd1",
5822 "org.freedesktop.systemd1.Manager",
5823 method);
5824 if (r < 0)
5825 return bus_log_create_error(r);
5826
5827 r = sd_bus_message_append_strv(m, strv_skip(argv, 1));
5828 if (r < 0)
5829 return bus_log_create_error(r);
5830
5831 r = sd_bus_call(bus, m, 0, &error, NULL);
5832 if (r < 0)
5833 return log_error_errno(r, "Failed to set environment: %s", bus_error_message(&error, r));
5834
5835 return 0;
5836 }
5837
5838 static int import_environment(int argc, char *argv[], void *userdata) {
5839 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5840 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
5841 sd_bus *bus;
5842 int r;
5843
5844 r = acquire_bus(BUS_MANAGER, &bus);
5845 if (r < 0)
5846 return r;
5847
5848 polkit_agent_open_if_enabled();
5849
5850 r = sd_bus_message_new_method_call(
5851 bus,
5852 &m,
5853 "org.freedesktop.systemd1",
5854 "/org/freedesktop/systemd1",
5855 "org.freedesktop.systemd1.Manager",
5856 "SetEnvironment");
5857 if (r < 0)
5858 return bus_log_create_error(r);
5859
5860 if (argc < 2)
5861 r = sd_bus_message_append_strv(m, environ);
5862 else {
5863 char **a, **b;
5864
5865 r = sd_bus_message_open_container(m, 'a', "s");
5866 if (r < 0)
5867 return bus_log_create_error(r);
5868
5869 STRV_FOREACH(a, strv_skip(argv, 1)) {
5870
5871 if (!env_name_is_valid(*a)) {
5872 log_error("Not a valid environment variable name: %s", *a);
5873 return -EINVAL;
5874 }
5875
5876 STRV_FOREACH(b, environ) {
5877 const char *eq;
5878
5879 eq = startswith(*b, *a);
5880 if (eq && *eq == '=') {
5881
5882 r = sd_bus_message_append(m, "s", *b);
5883 if (r < 0)
5884 return bus_log_create_error(r);
5885
5886 break;
5887 }
5888 }
5889 }
5890
5891 r = sd_bus_message_close_container(m);
5892 }
5893 if (r < 0)
5894 return bus_log_create_error(r);
5895
5896 r = sd_bus_call(bus, m, 0, &error, NULL);
5897 if (r < 0)
5898 return log_error_errno(r, "Failed to import environment: %s", bus_error_message(&error, r));
5899
5900 return 0;
5901 }
5902
5903 static int enable_sysv_units(const char *verb, char **args) {
5904 int r = 0;
5905
5906 #if HAVE_SYSV_COMPAT
5907 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5908 unsigned f = 0;
5909
5910 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5911
5912 if (arg_scope != UNIT_FILE_SYSTEM)
5913 return 0;
5914
5915 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5916 return 0;
5917
5918 if (!STR_IN_SET(verb,
5919 "enable",
5920 "disable",
5921 "is-enabled"))
5922 return 0;
5923
5924 r = lookup_paths_init(&paths, arg_scope, LOOKUP_PATHS_EXCLUDE_GENERATED, arg_root);
5925 if (r < 0)
5926 return r;
5927
5928 r = 0;
5929 while (args[f]) {
5930
5931 const char *argv[] = {
5932 ROOTLIBEXECDIR "/systemd-sysv-install",
5933 NULL,
5934 NULL,
5935 NULL,
5936 NULL,
5937 };
5938
5939 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5940 bool found_native = false, found_sysv;
5941 siginfo_t status;
5942 const char *name;
5943 unsigned c = 1;
5944 pid_t pid;
5945 int j;
5946
5947 name = args[f++];
5948
5949 if (!endswith(name, ".service"))
5950 continue;
5951
5952 if (path_is_absolute(name))
5953 continue;
5954
5955 j = unit_file_exists(arg_scope, &paths, name);
5956 if (j < 0 && !IN_SET(j, -ELOOP, -ERFKILL, -EADDRNOTAVAIL))
5957 return log_error_errno(j, "Failed to lookup unit file state: %m");
5958 found_native = j != 0;
5959
5960 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5961 * prefer the native unit */
5962 if (found_native && streq(verb, "is-enabled"))
5963 continue;
5964
5965 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5966 if (!p)
5967 return log_oom();
5968
5969 p[strlen(p) - strlen(".service")] = 0;
5970 found_sysv = access(p, F_OK) >= 0;
5971 if (!found_sysv)
5972 continue;
5973
5974 if (!arg_quiet) {
5975 if (found_native)
5976 log_info("Synchronizing state of %s with SysV service script with %s.", name, argv[0]);
5977 else
5978 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name);
5979 }
5980
5981 if (!isempty(arg_root))
5982 argv[c++] = q = strappend("--root=", arg_root);
5983
5984 argv[c++] = verb;
5985 argv[c++] = basename(p);
5986 argv[c] = NULL;
5987
5988 l = strv_join((char**)argv, " ");
5989 if (!l)
5990 return log_oom();
5991
5992 if (!arg_quiet)
5993 log_info("Executing: %s", l);
5994
5995 pid = fork();
5996 if (pid < 0)
5997 return log_error_errno(errno, "Failed to fork: %m");
5998 else if (pid == 0) {
5999 /* Child */
6000
6001 (void) reset_all_signal_handlers();
6002 (void) reset_signal_mask();
6003
6004 execv(argv[0], (char**) argv);
6005 log_error_errno(errno, "Failed to execute %s: %m", argv[0]);
6006 _exit(EXIT_FAILURE);
6007 }
6008
6009 j = wait_for_terminate(pid, &status);
6010 if (j < 0)
6011 return log_error_errno(j, "Failed to wait for child: %m");
6012
6013 if (status.si_code == CLD_EXITED) {
6014 if (streq(verb, "is-enabled")) {
6015 if (status.si_status == 0) {
6016 if (!arg_quiet)
6017 puts("enabled");
6018 r = 1;
6019 } else {
6020 if (!arg_quiet)
6021 puts("disabled");
6022 }
6023
6024 } else if (status.si_status != 0)
6025 return -EBADE; /* We don't warn here, under the assumption the script already showed an explanation */
6026 } else {
6027 log_error("Unexpected waitid() result.");
6028 return -EPROTO;
6029 }
6030
6031 if (found_native)
6032 continue;
6033
6034 /* Remove this entry, so that we don't try enabling it as native unit */
6035 assert(f > 0);
6036 f--;
6037 assert(args[f] == name);
6038 strv_remove(args, name);
6039 }
6040
6041 #endif
6042 return r;
6043 }
6044
6045 static int mangle_names(char **original_names, char ***mangled_names) {
6046 char **i, **l, **name;
6047 int r;
6048
6049 l = i = new(char*, strv_length(original_names) + 1);
6050 if (!l)
6051 return log_oom();
6052
6053 STRV_FOREACH(name, original_names) {
6054
6055 /* When enabling units qualified path names are OK,
6056 * too, hence allow them explicitly. */
6057
6058 if (is_path(*name)) {
6059 *i = strdup(*name);
6060 if (!*i) {
6061 strv_free(l);
6062 return log_oom();
6063 }
6064 } else {
6065 r = unit_name_mangle(*name, UNIT_NAME_NOGLOB, i);
6066 if (r < 0) {
6067 *i = NULL;
6068 strv_free(l);
6069 return log_error_errno(r, "Failed to mangle unit name: %m");
6070 }
6071 }
6072
6073 i++;
6074 }
6075
6076 *i = NULL;
6077 *mangled_names = l;
6078
6079 return 0;
6080 }
6081
6082 static int normalize_filenames(char **names) {
6083 char **u;
6084 int r;
6085
6086 STRV_FOREACH(u, names)
6087 if (!path_is_absolute(*u)) {
6088 char* normalized_path;
6089
6090 if (!isempty(arg_root)) {
6091 log_error("Non-absolute paths are not allowed when --root is used: %s", *u);
6092 return -EINVAL;
6093 }
6094
6095 if (!strchr(*u,'/')) {
6096 log_error("Link argument does contain at least one directory separator: %s", *u);
6097 return -EINVAL;
6098 }
6099
6100 r = path_make_absolute_cwd(*u, &normalized_path);
6101 if (r < 0)
6102 return r;
6103
6104 free_and_replace(*u, normalized_path);
6105 }
6106
6107 return 0;
6108 }
6109
6110 static int normalize_names(char **names, bool warn_if_path) {
6111 char **u;
6112 bool was_path = false;
6113
6114 STRV_FOREACH(u, names) {
6115 int r;
6116
6117 if (!is_path(*u))
6118 continue;
6119
6120 r = free_and_strdup(u, basename(*u));
6121 if (r < 0)
6122 return log_error_errno(r, "Failed to normalize unit file path: %m");
6123
6124 was_path = true;
6125 }
6126
6127 if (warn_if_path && was_path)
6128 log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
6129
6130 return 0;
6131 }
6132
6133 static int unit_exists(LookupPaths *lp, const char *unit) {
6134 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
6135 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6136 _cleanup_free_ char *path = NULL;
6137 static const struct bus_properties_map property_map[] = {
6138 { "LoadState", "s", map_string_no_copy, offsetof(UnitStatusInfo, load_state) },
6139 { "ActiveState", "s", map_string_no_copy, offsetof(UnitStatusInfo, active_state)},
6140 {},
6141 };
6142 UnitStatusInfo info = {};
6143 sd_bus *bus;
6144 int r;
6145
6146 if (unit_name_is_valid(unit, UNIT_NAME_TEMPLATE))
6147 return unit_find_template_path(unit, lp, NULL, NULL);
6148
6149 path = unit_dbus_path_from_name(unit);
6150 if (!path)
6151 return log_oom();
6152
6153 r = acquire_bus(BUS_MANAGER, &bus);
6154 if (r < 0)
6155 return r;
6156
6157 r = sd_bus_call_method(
6158 bus,
6159 "org.freedesktop.systemd1",
6160 path,
6161 "org.freedesktop.DBus.Properties",
6162 "GetAll",
6163 &error,
6164 &reply,
6165 "s", "");
6166 if (r < 0)
6167 return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
6168
6169 r = bus_message_map_all_properties(reply, property_map, &error, &info);
6170 if (r < 0)
6171 return log_error_errno(r, "Failed to map properties: %s", bus_error_message(&error, r));
6172
6173 return !streq_ptr(info.load_state, "not-found") || !streq_ptr(info.active_state, "inactive");
6174 }
6175
6176 static int enable_unit(int argc, char *argv[], void *userdata) {
6177 _cleanup_strv_free_ char **names = NULL;
6178 const char *verb = argv[0];
6179 UnitFileChange *changes = NULL;
6180 unsigned n_changes = 0;
6181 int carries_install_info = -1;
6182 bool ignore_carries_install_info = arg_quiet;
6183 int r;
6184
6185 if (!argv[1])
6186 return 0;
6187
6188 r = mangle_names(strv_skip(argv, 1), &names);
6189 if (r < 0)
6190 return r;
6191
6192 r = enable_sysv_units(verb, names);
6193 if (r < 0)
6194 return r;
6195
6196 /* If the operation was fully executed by the SysV compat, let's finish early */
6197 if (strv_isempty(names)) {
6198 if (arg_no_reload || install_client_side())
6199 return 0;
6200 return daemon_reload(argc, argv, userdata);
6201 }
6202
6203 if (streq(verb, "disable")) {
6204 r = normalize_names(names, true);
6205 if (r < 0)
6206 return r;
6207 }
6208
6209 if (streq(verb, "link")) {
6210 r = normalize_filenames(names);
6211 if (r < 0)
6212 return r;
6213 }
6214
6215 if (install_client_side()) {
6216 UnitFileFlags flags;
6217
6218 flags = args_to_flags();
6219 if (streq(verb, "enable")) {
6220 r = unit_file_enable(arg_scope, flags, arg_root, names, &changes, &n_changes);
6221 carries_install_info = r;
6222 } else if (streq(verb, "disable"))
6223 r = unit_file_disable(arg_scope, flags, arg_root, names, &changes, &n_changes);
6224 else if (streq(verb, "reenable")) {
6225 r = unit_file_reenable(arg_scope, flags, arg_root, names, &changes, &n_changes);
6226 carries_install_info = r;
6227 } else if (streq(verb, "link"))
6228 r = unit_file_link(arg_scope, flags, arg_root, names, &changes, &n_changes);
6229 else if (streq(verb, "preset")) {
6230 r = unit_file_preset(arg_scope, flags, arg_root, names, arg_preset_mode, &changes, &n_changes);
6231 } else if (streq(verb, "mask"))
6232 r = unit_file_mask(arg_scope, flags, arg_root, names, &changes, &n_changes);
6233 else if (streq(verb, "unmask"))
6234 r = unit_file_unmask(arg_scope, flags, arg_root, names, &changes, &n_changes);
6235 else if (streq(verb, "revert"))
6236 r = unit_file_revert(arg_scope, arg_root, names, &changes, &n_changes);
6237 else
6238 assert_not_reached("Unknown verb");
6239
6240 unit_file_dump_changes(r, verb, changes, n_changes, arg_quiet);
6241 if (r < 0)
6242 goto finish;
6243 r = 0;
6244 } else {
6245 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
6246 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6247 bool expect_carries_install_info = false;
6248 bool send_runtime = true, send_force = true, send_preset_mode = false;
6249 const char *method;
6250 sd_bus *bus;
6251
6252 if (STR_IN_SET(verb, "mask", "unmask")) {
6253 char **name;
6254 _cleanup_lookup_paths_free_ LookupPaths lp = {};
6255
6256 r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
6257 if (r < 0)
6258 return r;
6259
6260 STRV_FOREACH(name, names) {
6261 r = unit_exists(&lp, *name);
6262 if (r < 0)
6263 return r;
6264 if (r == 0)
6265 log_notice("Unit %s does not exist, proceeding anyway.", *names);
6266 }
6267 }
6268
6269 r = acquire_bus(BUS_MANAGER, &bus);
6270 if (r < 0)
6271 return r;
6272
6273 polkit_agent_open_if_enabled();
6274
6275 if (streq(verb, "enable")) {
6276 method = "EnableUnitFiles";
6277 expect_carries_install_info = true;
6278 } else if (streq(verb, "disable")) {
6279 method = "DisableUnitFiles";
6280 send_force = false;
6281 } else if (streq(verb, "reenable")) {
6282 method = "ReenableUnitFiles";
6283 expect_carries_install_info = true;
6284 } else if (streq(verb, "link"))
6285 method = "LinkUnitFiles";
6286 else if (streq(verb, "preset")) {
6287
6288 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
6289 method = "PresetUnitFilesWithMode";
6290 send_preset_mode = true;
6291 } else
6292 method = "PresetUnitFiles";
6293
6294 expect_carries_install_info = true;
6295 ignore_carries_install_info = true;
6296 } else if (streq(verb, "mask"))
6297 method = "MaskUnitFiles";
6298 else if (streq(verb, "unmask")) {
6299 method = "UnmaskUnitFiles";
6300 send_force = false;
6301 } else if (streq(verb, "revert")) {
6302 method = "RevertUnitFiles";
6303 send_runtime = send_force = false;
6304 } else
6305 assert_not_reached("Unknown verb");
6306
6307 r = sd_bus_message_new_method_call(
6308 bus,
6309 &m,
6310 "org.freedesktop.systemd1",
6311 "/org/freedesktop/systemd1",
6312 "org.freedesktop.systemd1.Manager",
6313 method);
6314 if (r < 0)
6315 return bus_log_create_error(r);
6316
6317 r = sd_bus_message_append_strv(m, names);
6318 if (r < 0)
6319 return bus_log_create_error(r);
6320
6321 if (send_preset_mode) {
6322 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
6323 if (r < 0)
6324 return bus_log_create_error(r);
6325 }
6326
6327 if (send_runtime) {
6328 r = sd_bus_message_append(m, "b", arg_runtime);
6329 if (r < 0)
6330 return bus_log_create_error(r);
6331 }
6332
6333 if (send_force) {
6334 r = sd_bus_message_append(m, "b", arg_force);
6335 if (r < 0)
6336 return bus_log_create_error(r);
6337 }
6338
6339 r = sd_bus_call(bus, m, 0, &error, &reply);
6340 if (r < 0)
6341 return log_error_errno(r, "Failed to %s unit: %s", verb, bus_error_message(&error, r));
6342
6343 if (expect_carries_install_info) {
6344 r = sd_bus_message_read(reply, "b", &carries_install_info);
6345 if (r < 0)
6346 return bus_log_parse_error(r);
6347 }
6348
6349 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
6350 if (r < 0)
6351 goto finish;
6352
6353 /* Try to reload if enabled */
6354 if (!arg_no_reload)
6355 r = daemon_reload(argc, argv, userdata);
6356 else
6357 r = 0;
6358 }
6359
6360 if (carries_install_info == 0 && !ignore_carries_install_info)
6361 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
6362 "settings in the [Install] section, and DefaultInstance for template units).\n"
6363 "This means they are not meant to be enabled using systemctl.\n"
6364 "Possible reasons for having this kind of units are:\n"
6365 "1) A unit may be statically enabled by being symlinked from another unit's\n"
6366 " .wants/ or .requires/ directory.\n"
6367 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
6368 " a requirement dependency on it.\n"
6369 "3) A unit may be started when needed via activation (socket, path, timer,\n"
6370 " D-Bus, udev, scripted systemctl call, ...).\n"
6371 "4) In case of template units, the unit is meant to be enabled with some\n"
6372 " instance name specified.");
6373
6374 if (arg_now && STR_IN_SET(argv[0], "enable", "disable", "mask")) {
6375 sd_bus *bus;
6376 unsigned len, i;
6377
6378 r = acquire_bus(BUS_MANAGER, &bus);
6379 if (r < 0)
6380 goto finish;
6381
6382 len = strv_length(names);
6383 {
6384 char *new_args[len + 2];
6385
6386 new_args[0] = (char*) (streq(argv[0], "enable") ? "start" : "stop");
6387 for (i = 0; i < len; i++)
6388 new_args[i + 1] = basename(names[i]);
6389 new_args[i + 1] = NULL;
6390
6391 r = start_unit(len + 1, new_args, userdata);
6392 }
6393 }
6394
6395 finish:
6396 unit_file_changes_free(changes, n_changes);
6397
6398 return r;
6399 }
6400
6401 static int add_dependency(int argc, char *argv[], void *userdata) {
6402 _cleanup_strv_free_ char **names = NULL;
6403 _cleanup_free_ char *target = NULL;
6404 const char *verb = argv[0];
6405 UnitFileChange *changes = NULL;
6406 unsigned n_changes = 0;
6407 UnitDependency dep;
6408 int r = 0;
6409
6410 if (!argv[1])
6411 return 0;
6412
6413 r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".target", &target);
6414 if (r < 0)
6415 return log_error_errno(r, "Failed to mangle unit name: %m");
6416
6417 r = mangle_names(strv_skip(argv, 2), &names);
6418 if (r < 0)
6419 return r;
6420
6421 if (streq(verb, "add-wants"))
6422 dep = UNIT_WANTS;
6423 else if (streq(verb, "add-requires"))
6424 dep = UNIT_REQUIRES;
6425 else
6426 assert_not_reached("Unknown verb");
6427
6428 if (install_client_side()) {
6429 r = unit_file_add_dependency(arg_scope, args_to_flags(), arg_root, names, target, dep, &changes, &n_changes);
6430 unit_file_dump_changes(r, "add dependency on", changes, n_changes, arg_quiet);
6431
6432 if (r > 0)
6433 r = 0;
6434 } else {
6435 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
6436 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6437 sd_bus *bus;
6438
6439 r = acquire_bus(BUS_MANAGER, &bus);
6440 if (r < 0)
6441 return r;
6442
6443 polkit_agent_open_if_enabled();
6444
6445 r = sd_bus_message_new_method_call(
6446 bus,
6447 &m,
6448 "org.freedesktop.systemd1",
6449 "/org/freedesktop/systemd1",
6450 "org.freedesktop.systemd1.Manager",
6451 "AddDependencyUnitFiles");
6452 if (r < 0)
6453 return bus_log_create_error(r);
6454
6455 r = sd_bus_message_append_strv(m, names);
6456 if (r < 0)
6457 return bus_log_create_error(r);
6458
6459 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
6460 if (r < 0)
6461 return bus_log_create_error(r);
6462
6463 r = sd_bus_call(bus, m, 0, &error, &reply);
6464 if (r < 0)
6465 return log_error_errno(r, "Failed to add dependency: %s", bus_error_message(&error, r));
6466
6467 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
6468 if (r < 0)
6469 goto finish;
6470
6471 if (arg_no_reload) {
6472 r = 0;
6473 goto finish;
6474 }
6475
6476 r = daemon_reload(argc, argv, userdata);
6477 }
6478
6479 finish:
6480 unit_file_changes_free(changes, n_changes);
6481
6482 return r;
6483 }
6484
6485 static int preset_all(int argc, char *argv[], void *userdata) {
6486 UnitFileChange *changes = NULL;
6487 unsigned n_changes = 0;
6488 int r;
6489
6490 if (install_client_side()) {
6491 r = unit_file_preset_all(arg_scope, args_to_flags(), arg_root, arg_preset_mode, &changes, &n_changes);
6492 unit_file_dump_changes(r, "preset", changes, n_changes, arg_quiet);
6493
6494 if (r > 0)
6495 r = 0;
6496 } else {
6497 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6498 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
6499 sd_bus *bus;
6500
6501 r = acquire_bus(BUS_MANAGER, &bus);
6502 if (r < 0)
6503 return r;
6504
6505 polkit_agent_open_if_enabled();
6506
6507 r = sd_bus_call_method(
6508 bus,
6509 "org.freedesktop.systemd1",
6510 "/org/freedesktop/systemd1",
6511 "org.freedesktop.systemd1.Manager",
6512 "PresetAllUnitFiles",
6513 &error,
6514 &reply,
6515 "sbb",
6516 unit_file_preset_mode_to_string(arg_preset_mode),
6517 arg_runtime,
6518 arg_force);
6519 if (r < 0)
6520 return log_error_errno(r, "Failed to preset all units: %s", bus_error_message(&error, r));
6521
6522 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
6523 if (r < 0)
6524 goto finish;
6525
6526 if (arg_no_reload) {
6527 r = 0;
6528 goto finish;
6529 }
6530
6531 r = daemon_reload(argc, argv, userdata);
6532 }
6533
6534 finish:
6535 unit_file_changes_free(changes, n_changes);
6536
6537 return r;
6538 }
6539
6540 static int show_installation_targets_client_side(const char *name) {
6541 UnitFileChange *changes = NULL;
6542 unsigned n_changes = 0, i;
6543 UnitFileFlags flags;
6544 char **p;
6545 int r;
6546
6547 p = STRV_MAKE(name);
6548 flags = UNIT_FILE_DRY_RUN |
6549 (arg_runtime ? UNIT_FILE_RUNTIME : 0);
6550
6551 r = unit_file_disable(UNIT_FILE_SYSTEM, flags, NULL, p, &changes, &n_changes);
6552 if (r < 0)
6553 return log_error_errno(r, "Failed to get file links for %s: %m", name);
6554
6555 for (i = 0; i < n_changes; i++)
6556 if (changes[i].type == UNIT_FILE_UNLINK)
6557 printf(" %s\n", changes[i].path);
6558
6559 return 0;
6560 }
6561
6562 static int show_installation_targets(sd_bus *bus, const char *name) {
6563 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
6564 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6565 const char *link;
6566 int r;
6567
6568 r = sd_bus_call_method(
6569 bus,
6570 "org.freedesktop.systemd1",
6571 "/org/freedesktop/systemd1",
6572 "org.freedesktop.systemd1.Manager",
6573 "GetUnitFileLinks",
6574 &error,
6575 &reply,
6576 "sb", name, arg_runtime);
6577 if (r < 0)
6578 return log_error_errno(r, "Failed to get unit file links for %s: %s", name, bus_error_message(&error, r));
6579
6580 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
6581 if (r < 0)
6582 return bus_log_parse_error(r);
6583
6584 while ((r = sd_bus_message_read(reply, "s", &link)) > 0)
6585 printf(" %s\n", link);
6586
6587 if (r < 0)
6588 return bus_log_parse_error(r);
6589
6590 r = sd_bus_message_exit_container(reply);
6591 if (r < 0)
6592 return bus_log_parse_error(r);
6593
6594 return 0;
6595 }
6596
6597 static int unit_is_enabled(int argc, char *argv[], void *userdata) {
6598
6599 _cleanup_strv_free_ char **names = NULL;
6600 bool enabled;
6601 char **name;
6602 int r;
6603
6604 r = mangle_names(strv_skip(argv, 1), &names);
6605 if (r < 0)
6606 return r;
6607
6608 r = enable_sysv_units(argv[0], names);
6609 if (r < 0)
6610 return r;
6611
6612 enabled = r > 0;
6613
6614 if (install_client_side()) {
6615 STRV_FOREACH(name, names) {
6616 UnitFileState state;
6617
6618 r = unit_file_get_state(arg_scope, arg_root, *name, &state);
6619 if (r < 0)
6620 return log_error_errno(r, "Failed to get unit file state for %s: %m", *name);
6621
6622 if (IN_SET(state,
6623 UNIT_FILE_ENABLED,
6624 UNIT_FILE_ENABLED_RUNTIME,
6625 UNIT_FILE_STATIC,
6626 UNIT_FILE_INDIRECT,
6627 UNIT_FILE_GENERATED))
6628 enabled = true;
6629
6630 if (!arg_quiet) {
6631 puts(unit_file_state_to_string(state));
6632 if (arg_full) {
6633 r = show_installation_targets_client_side(*name);
6634 if (r < 0)
6635 return r;
6636 }
6637 }
6638 }
6639
6640 r = 0;
6641 } else {
6642 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6643 sd_bus *bus;
6644
6645 r = acquire_bus(BUS_MANAGER, &bus);
6646 if (r < 0)
6647 return r;
6648
6649 STRV_FOREACH(name, names) {
6650 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
6651 const char *s;
6652
6653 r = sd_bus_call_method(
6654 bus,
6655 "org.freedesktop.systemd1",
6656 "/org/freedesktop/systemd1",
6657 "org.freedesktop.systemd1.Manager",
6658 "GetUnitFileState",
6659 &error,
6660 &reply,
6661 "s", *name);
6662 if (r < 0)
6663 return log_error_errno(r, "Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
6664
6665 r = sd_bus_message_read(reply, "s", &s);
6666 if (r < 0)
6667 return bus_log_parse_error(r);
6668
6669 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect", "generated"))
6670 enabled = true;
6671
6672 if (!arg_quiet) {
6673 puts(s);
6674 if (arg_full) {
6675 r = show_installation_targets(bus, *name);
6676 if (r < 0)
6677 return r;
6678 }
6679 }
6680 }
6681 }
6682
6683 return enabled ? EXIT_SUCCESS : EXIT_FAILURE;
6684 }
6685
6686 static int is_system_running(int argc, char *argv[], void *userdata) {
6687 _cleanup_free_ char *state = NULL;
6688 sd_bus *bus;
6689 int r;
6690
6691 if (running_in_chroot() > 0 || (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted())) {
6692 if (!arg_quiet)
6693 puts("offline");
6694 return EXIT_FAILURE;
6695 }
6696
6697 r = acquire_bus(BUS_MANAGER, &bus);
6698 if (r < 0)
6699 return r;
6700
6701 r = sd_bus_get_property_string(
6702 bus,
6703 "org.freedesktop.systemd1",
6704 "/org/freedesktop/systemd1",
6705 "org.freedesktop.systemd1.Manager",
6706 "SystemState",
6707 NULL,
6708 &state);
6709 if (r < 0) {
6710 if (!arg_quiet)
6711 puts("unknown");
6712 return 0;
6713 }
6714
6715 if (!arg_quiet)
6716 puts(state);
6717
6718 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
6719 }
6720
6721 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
6722 _cleanup_free_ char *t = NULL;
6723 int r;
6724
6725 assert(new_path);
6726 assert(original_path);
6727 assert(ret_tmp_fn);
6728
6729 r = tempfn_random(new_path, NULL, &t);
6730 if (r < 0)
6731 return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
6732
6733 r = mkdir_parents(new_path, 0755);
6734 if (r < 0)
6735 return log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
6736
6737 r = copy_file(original_path, t, 0, 0644, 0, COPY_REFLINK);
6738 if (r == -ENOENT) {
6739
6740 r = touch(t);
6741 if (r < 0)
6742 return log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
6743
6744 } else if (r < 0)
6745 return log_error_errno(r, "Failed to create temporary file for \"%s\": %m", new_path);
6746
6747 *ret_tmp_fn = t;
6748 t = NULL;
6749
6750 return 0;
6751 }
6752
6753 static int get_file_to_edit(
6754 const LookupPaths *paths,
6755 const char *name,
6756 char **ret_path) {
6757
6758 _cleanup_free_ char *path = NULL, *run = NULL;
6759
6760 assert(name);
6761 assert(ret_path);
6762
6763 path = strjoin(paths->persistent_config, "/", name);
6764 if (!path)
6765 return log_oom();
6766
6767 if (arg_runtime) {
6768 run = strjoin(paths->runtime_config, "/", name);
6769 if (!run)
6770 return log_oom();
6771 }
6772
6773 if (arg_runtime) {
6774 if (access(path, F_OK) >= 0) {
6775 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path);
6776 return -EEXIST;
6777 }
6778
6779 *ret_path = run;
6780 run = NULL;
6781 } else {
6782 *ret_path = path;
6783 path = NULL;
6784 }
6785
6786 return 0;
6787 }
6788
6789 static int unit_file_create_new(
6790 const LookupPaths *paths,
6791 const char *unit_name,
6792 const char *suffix,
6793 char **ret_new_path,
6794 char **ret_tmp_path) {
6795
6796 char *tmp_new_path, *tmp_tmp_path, *ending;
6797 int r;
6798
6799 assert(unit_name);
6800 assert(ret_new_path);
6801 assert(ret_tmp_path);
6802
6803 ending = strjoina(unit_name, suffix);
6804 r = get_file_to_edit(paths, ending, &tmp_new_path);
6805 if (r < 0)
6806 return r;
6807
6808 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
6809 if (r < 0) {
6810 free(tmp_new_path);
6811 return r;
6812 }
6813
6814 *ret_new_path = tmp_new_path;
6815 *ret_tmp_path = tmp_tmp_path;
6816
6817 return 0;
6818 }
6819
6820 static int unit_file_create_copy(
6821 const LookupPaths *paths,
6822 const char *unit_name,
6823 const char *fragment_path,
6824 char **ret_new_path,
6825 char **ret_tmp_path) {
6826
6827 char *tmp_new_path, *tmp_tmp_path;
6828 int r;
6829
6830 assert(fragment_path);
6831 assert(unit_name);
6832 assert(ret_new_path);
6833 assert(ret_tmp_path);
6834
6835 r = get_file_to_edit(paths, unit_name, &tmp_new_path);
6836 if (r < 0)
6837 return r;
6838
6839 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
6840 char response;
6841
6842 r = ask_char(&response, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path, fragment_path);
6843 if (r < 0) {
6844 free(tmp_new_path);
6845 return r;
6846 }
6847 if (response != 'y') {
6848 log_warning("%s ignored", unit_name);
6849 free(tmp_new_path);
6850 return -EKEYREJECTED;
6851 }
6852 }
6853
6854 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
6855 if (r < 0) {
6856 free(tmp_new_path);
6857 return r;
6858 }
6859
6860 *ret_new_path = tmp_new_path;
6861 *ret_tmp_path = tmp_tmp_path;
6862
6863 return 0;
6864 }
6865
6866 static int run_editor(char **paths) {
6867 pid_t pid;
6868 int r;
6869
6870 assert(paths);
6871
6872 pid = fork();
6873 if (pid < 0)
6874 return log_error_errno(errno, "Failed to fork: %m");
6875
6876 if (pid == 0) {
6877 const char **args;
6878 char *editor, **editor_args = NULL;
6879 char **tmp_path, **original_path, *p;
6880 unsigned n_editor_args = 0, i = 1;
6881 size_t argc;
6882
6883 (void) reset_all_signal_handlers();
6884 (void) reset_signal_mask();
6885
6886 argc = strv_length(paths)/2 + 1;
6887
6888 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6889 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6890 * we try to execute well known editors
6891 */
6892 editor = getenv("SYSTEMD_EDITOR");
6893 if (!editor)
6894 editor = getenv("EDITOR");
6895 if (!editor)
6896 editor = getenv("VISUAL");
6897
6898 if (!isempty(editor)) {
6899 editor_args = strv_split(editor, WHITESPACE);
6900 if (!editor_args) {
6901 (void) log_oom();
6902 _exit(EXIT_FAILURE);
6903 }
6904 n_editor_args = strv_length(editor_args);
6905 argc += n_editor_args - 1;
6906 }
6907 args = newa(const char*, argc + 1);
6908
6909 if (n_editor_args > 0) {
6910 args[0] = editor_args[0];
6911 for (; i < n_editor_args; i++)
6912 args[i] = editor_args[i];
6913 }
6914
6915 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
6916 args[i] = *tmp_path;
6917 i++;
6918 }
6919 args[i] = NULL;
6920
6921 if (n_editor_args > 0)
6922 execvp(args[0], (char* const*) args);
6923
6924 FOREACH_STRING(p, "editor", "nano", "vim", "vi") {
6925 args[0] = p;
6926 execvp(p, (char* const*) args);
6927 /* We do not fail if the editor doesn't exist
6928 * because we want to try each one of them before
6929 * failing.
6930 */
6931 if (errno != ENOENT) {
6932 log_error_errno(errno, "Failed to execute %s: %m", editor);
6933 _exit(EXIT_FAILURE);
6934 }
6935 }
6936
6937 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6938 _exit(EXIT_FAILURE);
6939 }
6940
6941 r = wait_for_terminate_and_warn("editor", pid, true);
6942 if (r < 0)
6943 return log_error_errno(r, "Failed to wait for child: %m");
6944
6945 return 0;
6946 }
6947
6948 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
6949 _cleanup_lookup_paths_free_ LookupPaths lp = {};
6950 char **name;
6951 int r;
6952
6953 assert(names);
6954 assert(paths);
6955
6956 r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
6957 if (r < 0)
6958 return r;
6959
6960 STRV_FOREACH(name, names) {
6961 _cleanup_free_ char *path = NULL, *new_path = NULL, *tmp_path = NULL, *tmp_name = NULL;
6962 const char *unit_name;
6963
6964 r = unit_find_paths(bus, *name, &lp, &path, NULL);
6965 if (r < 0)
6966 return r;
6967
6968 if (r == 0) {
6969 assert(!path);
6970
6971 if (!arg_force) {
6972 log_error("Run 'systemctl edit%s --force %s' to create a new unit.",
6973 arg_scope == UNIT_FILE_GLOBAL ? " --global" :
6974 arg_scope == UNIT_FILE_USER ? " --user" : "",
6975 *name);
6976 return -ENOENT;
6977 }
6978
6979 /* Create a new unit from scratch */
6980 unit_name = *name;
6981 r = unit_file_create_new(&lp, unit_name,
6982 arg_full ? NULL : ".d/override.conf",
6983 &new_path, &tmp_path);
6984 } else {
6985 assert(path);
6986
6987 unit_name = basename(path);
6988 /* We follow unit aliases, but we need to propagate the instance */
6989 if (unit_name_is_valid(*name, UNIT_NAME_INSTANCE) &&
6990 unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) {
6991 _cleanup_free_ char *instance = NULL;
6992
6993 r = unit_name_to_instance(*name, &instance);
6994 if (r < 0)
6995 return r;
6996
6997 r = unit_name_replace_instance(unit_name, instance, &tmp_name);
6998 if (r < 0)
6999 return r;
7000
7001 unit_name = tmp_name;
7002 }
7003
7004 if (arg_full)
7005 r = unit_file_create_copy(&lp, unit_name, path, &new_path, &tmp_path);
7006 else
7007 r = unit_file_create_new(&lp, unit_name, ".d/override.conf", &new_path, &tmp_path);
7008 }
7009 if (r < 0)
7010 return r;
7011
7012 r = strv_push_pair(paths, new_path, tmp_path);
7013 if (r < 0)
7014 return log_oom();
7015 new_path = tmp_path = NULL;
7016 }
7017
7018 return 0;
7019 }
7020
7021 static int edit(int argc, char *argv[], void *userdata) {
7022 _cleanup_strv_free_ char **names = NULL;
7023 _cleanup_strv_free_ char **paths = NULL;
7024 char **original, **tmp;
7025 sd_bus *bus;
7026 int r;
7027
7028 if (!on_tty()) {
7029 log_error("Cannot edit units if not on a tty.");
7030 return -EINVAL;
7031 }
7032
7033 if (arg_transport != BUS_TRANSPORT_LOCAL) {
7034 log_error("Cannot edit units remotely.");
7035 return -EINVAL;
7036 }
7037
7038 r = acquire_bus(BUS_MANAGER, &bus);
7039 if (r < 0)
7040 return r;
7041
7042 r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
7043 if (r < 0)
7044 return log_error_errno(r, "Failed to expand names: %m");
7045
7046 r = find_paths_to_edit(bus, names, &paths);
7047 if (r < 0)
7048 return r;
7049
7050 if (strv_isempty(paths))
7051 return -ENOENT;
7052
7053 r = run_editor(paths);
7054 if (r < 0)
7055 goto end;
7056
7057 STRV_FOREACH_PAIR(original, tmp, paths) {
7058 /* If the temporary file is empty we ignore it. It's
7059 * useful if the user wants to cancel its modification
7060 */
7061 if (null_or_empty_path(*tmp)) {
7062 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original);
7063 continue;
7064 }
7065
7066 r = rename(*tmp, *original);
7067 if (r < 0) {
7068 r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
7069 goto end;
7070 }
7071 }
7072
7073 r = 0;
7074
7075 if (!arg_no_reload && !install_client_side())
7076 r = daemon_reload(argc, argv, userdata);
7077
7078 end:
7079 STRV_FOREACH_PAIR(original, tmp, paths) {
7080 (void) unlink(*tmp);
7081
7082 /* Removing empty dropin dirs */
7083 if (!arg_full) {
7084 _cleanup_free_ char *dir;
7085
7086 dir = dirname_malloc(*original);
7087 if (!dir)
7088 return log_oom();
7089
7090 /* no need to check if the dir is empty, rmdir
7091 * does nothing if it is not the case.
7092 */
7093 (void) rmdir(dir);
7094 }
7095 }
7096
7097 return r;
7098 }
7099
7100 static void systemctl_help(void) {
7101
7102 pager_open(arg_no_pager, false);
7103
7104 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
7105 "Query or send control commands to the systemd manager.\n\n"
7106 " -h --help Show this help\n"
7107 " --version Show package version\n"
7108 " --system Connect to system manager\n"
7109 " --user Connect to user service manager\n"
7110 " -H --host=[USER@]HOST\n"
7111 " Operate on remote host\n"
7112 " -M --machine=CONTAINER\n"
7113 " Operate on local container\n"
7114 " -t --type=TYPE List units of a particular type\n"
7115 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
7116 " -p --property=NAME Show only properties by this name\n"
7117 " -a --all Show all properties/all units currently in memory,\n"
7118 " including dead/empty ones. To list all units installed on\n"
7119 " the system, use the 'list-unit-files' command instead.\n"
7120 " --failed Same as --state=failed\n"
7121 " -l --full Don't ellipsize unit names on output\n"
7122 " -r --recursive Show unit list of host and local containers\n"
7123 " --reverse Show reverse dependencies with 'list-dependencies'\n"
7124 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
7125 " queueing a new job\n"
7126 " --show-types When showing sockets, explicitly show their type\n"
7127 " --value When showing properties, only print the value\n"
7128 " -i --ignore-inhibitors\n"
7129 " When shutting down or sleeping, ignore inhibitors\n"
7130 " --kill-who=WHO Who to send signal to\n"
7131 " -s --signal=SIGNAL Which signal to send\n"
7132 " --now Start or stop unit in addition to enabling or disabling it\n"
7133 " -q --quiet Suppress output\n"
7134 " --wait For (re)start, wait until service stopped again\n"
7135 " --no-block Do not wait until operation finished\n"
7136 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7137 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
7138 " --no-legend Do not print a legend (column headers and hints)\n"
7139 " --no-pager Do not pipe output into a pager\n"
7140 " --no-ask-password\n"
7141 " Do not ask for system passwords\n"
7142 " --global Enable/disable unit files globally\n"
7143 " --runtime Enable unit files only temporarily until next reboot\n"
7144 " -f --force When enabling unit files, override existing symlinks\n"
7145 " When shutting down, execute action immediately\n"
7146 " --preset-mode= Apply only enable, only disable, or all presets\n"
7147 " --root=PATH Enable unit files in the specified root directory\n"
7148 " -n --lines=INTEGER Number of journal entries to show\n"
7149 " -o --output=STRING Change journal output mode (short, short-precise,\n"
7150 " short-iso, short-iso-precise, short-full,\n"
7151 " short-monotonic, short-unix,\n"
7152 " verbose, export, json, json-pretty, json-sse, cat)\n"
7153 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
7154 " --plain Print unit dependencies as a list instead of a tree\n\n"
7155 "Unit Commands:\n"
7156 " list-units [PATTERN...] List units currently in memory\n"
7157 " list-sockets [PATTERN...] List socket units currently in memory, ordered\n"
7158 " by address\n"
7159 " list-timers [PATTERN...] List timer units currently in memory, ordered\n"
7160 " by next elapse\n"
7161 " start NAME... Start (activate) one or more units\n"
7162 " stop NAME... Stop (deactivate) one or more units\n"
7163 " reload NAME... Reload one or more units\n"
7164 " restart NAME... Start or restart one or more units\n"
7165 " try-restart NAME... Restart one or more units if active\n"
7166 " reload-or-restart NAME... Reload one or more units if possible,\n"
7167 " otherwise start or restart\n"
7168 " try-reload-or-restart NAME... If active, reload one or more units,\n"
7169 " if supported, otherwise restart\n"
7170 " isolate NAME Start one unit and stop all others\n"
7171 " kill NAME... Send signal to processes of a unit\n"
7172 " is-active PATTERN... Check whether units are active\n"
7173 " is-failed PATTERN... Check whether units are failed\n"
7174 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
7175 " show [PATTERN...|JOB...] Show properties of one or more\n"
7176 " units/jobs or the manager\n"
7177 " cat PATTERN... Show files and drop-ins of one or more units\n"
7178 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
7179 " help PATTERN...|PID... Show manual for one or more units\n"
7180 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
7181 " units\n"
7182 " list-dependencies [NAME] Recursively show units which are required\n"
7183 " or wanted by this unit or by which this\n"
7184 " unit is required or wanted\n\n"
7185 "Unit File Commands:\n"
7186 " list-unit-files [PATTERN...] List installed unit files\n"
7187 " enable [NAME...|PATH...] Enable one or more unit files\n"
7188 " disable NAME... Disable one or more unit files\n"
7189 " reenable NAME... Reenable one or more unit files\n"
7190 " preset NAME... Enable/disable one or more unit files\n"
7191 " based on preset configuration\n"
7192 " preset-all Enable/disable all unit files based on\n"
7193 " preset configuration\n"
7194 " is-enabled NAME... Check whether unit files are enabled\n"
7195 " mask NAME... Mask one or more units\n"
7196 " unmask NAME... Unmask one or more units\n"
7197 " link PATH... Link one or more units files into\n"
7198 " the search path\n"
7199 " revert NAME... Revert one or more unit files to vendor\n"
7200 " version\n"
7201 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
7202 " on specified one or more units\n"
7203 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
7204 " on specified one or more units\n"
7205 " edit NAME... Edit one or more unit files\n"
7206 " get-default Get the name of the default target\n"
7207 " set-default NAME Set the default target\n\n"
7208 "Machine Commands:\n"
7209 " list-machines [PATTERN...] List local containers and host\n\n"
7210 "Job Commands:\n"
7211 " list-jobs [PATTERN...] List jobs\n"
7212 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
7213 "Environment Commands:\n"
7214 " show-environment Dump environment\n"
7215 " set-environment NAME=VALUE... Set one or more environment variables\n"
7216 " unset-environment NAME... Unset one or more environment variables\n"
7217 " import-environment [NAME...] Import all or some environment variables\n\n"
7218 "Manager Lifecycle Commands:\n"
7219 " daemon-reload Reload systemd manager configuration\n"
7220 " daemon-reexec Reexecute systemd manager\n\n"
7221 "System Commands:\n"
7222 " is-system-running Check whether system is fully running\n"
7223 " default Enter system default mode\n"
7224 " rescue Enter system rescue mode\n"
7225 " emergency Enter system emergency mode\n"
7226 " halt Shut down and halt the system\n"
7227 " poweroff Shut down and power-off the system\n"
7228 " reboot [ARG] Shut down and reboot the system\n"
7229 " kexec Shut down and reboot the system with kexec\n"
7230 " exit [EXIT_CODE] Request user instance or container exit\n"
7231 " switch-root ROOT [INIT] Change to a different root file system\n"
7232 " suspend Suspend the system\n"
7233 " hibernate Hibernate the system\n"
7234 " hybrid-sleep Hibernate and suspend the system\n",
7235 program_invocation_short_name);
7236 }
7237
7238 static void halt_help(void) {
7239 printf("%s [OPTIONS...]%s\n\n"
7240 "%s the system.\n\n"
7241 " --help Show this help\n"
7242 " --halt Halt the machine\n"
7243 " -p --poweroff Switch off the machine\n"
7244 " --reboot Reboot the machine\n"
7245 " -f --force Force immediate halt/power-off/reboot\n"
7246 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
7247 " -d --no-wtmp Don't write wtmp record\n"
7248 " --no-wall Don't send wall message before halt/power-off/reboot\n",
7249 program_invocation_short_name,
7250 arg_action == ACTION_REBOOT ? " [ARG]" : "",
7251 arg_action == ACTION_REBOOT ? "Reboot" :
7252 arg_action == ACTION_POWEROFF ? "Power off" :
7253 "Halt");
7254 }
7255
7256 static void shutdown_help(void) {
7257 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
7258 "Shut down the system.\n\n"
7259 " --help Show this help\n"
7260 " -H --halt Halt the machine\n"
7261 " -P --poweroff Power-off the machine\n"
7262 " -r --reboot Reboot the machine\n"
7263 " -h Equivalent to --poweroff, overridden by --halt\n"
7264 " -k Don't halt/power-off/reboot, just send warnings\n"
7265 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7266 " -c Cancel a pending shutdown\n",
7267 program_invocation_short_name);
7268 }
7269
7270 static void telinit_help(void) {
7271 printf("%s [OPTIONS...] {COMMAND}\n\n"
7272 "Send control commands to the init daemon.\n\n"
7273 " --help Show this help\n"
7274 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
7275 "Commands:\n"
7276 " 0 Power-off the machine\n"
7277 " 6 Reboot the machine\n"
7278 " 2, 3, 4, 5 Start runlevelX.target unit\n"
7279 " 1, s, S Enter rescue mode\n"
7280 " q, Q Reload init daemon configuration\n"
7281 " u, U Reexecute init daemon\n",
7282 program_invocation_short_name);
7283 }
7284
7285 static void runlevel_help(void) {
7286 printf("%s [OPTIONS...]\n\n"
7287 "Prints the previous and current runlevel of the init system.\n\n"
7288 " --help Show this help\n",
7289 program_invocation_short_name);
7290 }
7291
7292 static void help_types(void) {
7293 int i;
7294
7295 if (!arg_no_legend)
7296 puts("Available unit types:");
7297 for (i = 0; i < _UNIT_TYPE_MAX; i++)
7298 puts(unit_type_to_string(i));
7299 }
7300
7301 static void help_states(void) {
7302 int i;
7303
7304 if (!arg_no_legend)
7305 puts("Available unit load states:");
7306 for (i = 0; i < _UNIT_LOAD_STATE_MAX; i++)
7307 puts(unit_load_state_to_string(i));
7308
7309 if (!arg_no_legend)
7310 puts("\nAvailable unit active states:");
7311 for (i = 0; i < _UNIT_ACTIVE_STATE_MAX; i++)
7312 puts(unit_active_state_to_string(i));
7313
7314 if (!arg_no_legend)
7315 puts("\nAvailable automount unit substates:");
7316 for (i = 0; i < _AUTOMOUNT_STATE_MAX; i++)
7317 puts(automount_state_to_string(i));
7318
7319 if (!arg_no_legend)
7320 puts("\nAvailable device unit substates:");
7321 for (i = 0; i < _DEVICE_STATE_MAX; i++)
7322 puts(device_state_to_string(i));
7323
7324 if (!arg_no_legend)
7325 puts("\nAvailable mount unit substates:");
7326 for (i = 0; i < _MOUNT_STATE_MAX; i++)
7327 puts(mount_state_to_string(i));
7328
7329 if (!arg_no_legend)
7330 puts("\nAvailable path unit substates:");
7331 for (i = 0; i < _PATH_STATE_MAX; i++)
7332 puts(path_state_to_string(i));
7333
7334 if (!arg_no_legend)
7335 puts("\nAvailable scope unit substates:");
7336 for (i = 0; i < _SCOPE_STATE_MAX; i++)
7337 puts(scope_state_to_string(i));
7338
7339 if (!arg_no_legend)
7340 puts("\nAvailable service unit substates:");
7341 for (i = 0; i < _SERVICE_STATE_MAX; i++)
7342 puts(service_state_to_string(i));
7343
7344 if (!arg_no_legend)
7345 puts("\nAvailable slice unit substates:");
7346 for (i = 0; i < _SLICE_STATE_MAX; i++)
7347 puts(slice_state_to_string(i));
7348
7349 if (!arg_no_legend)
7350 puts("\nAvailable socket unit substates:");
7351 for (i = 0; i < _SOCKET_STATE_MAX; i++)
7352 puts(socket_state_to_string(i));
7353
7354 if (!arg_no_legend)
7355 puts("\nAvailable swap unit substates:");
7356 for (i = 0; i < _SWAP_STATE_MAX; i++)
7357 puts(swap_state_to_string(i));
7358
7359 if (!arg_no_legend)
7360 puts("\nAvailable target unit substates:");
7361 for (i = 0; i < _TARGET_STATE_MAX; i++)
7362 puts(target_state_to_string(i));
7363
7364 if (!arg_no_legend)
7365 puts("\nAvailable timer unit substates:");
7366 for (i = 0; i < _TIMER_STATE_MAX; i++)
7367 puts(timer_state_to_string(i));
7368 }
7369
7370 static int systemctl_parse_argv(int argc, char *argv[]) {
7371
7372 enum {
7373 ARG_FAIL = 0x100,
7374 ARG_REVERSE,
7375 ARG_AFTER,
7376 ARG_BEFORE,
7377 ARG_SHOW_TYPES,
7378 ARG_IRREVERSIBLE,
7379 ARG_IGNORE_DEPENDENCIES,
7380 ARG_VALUE,
7381 ARG_VERSION,
7382 ARG_USER,
7383 ARG_SYSTEM,
7384 ARG_GLOBAL,
7385 ARG_NO_BLOCK,
7386 ARG_NO_LEGEND,
7387 ARG_NO_PAGER,
7388 ARG_NO_WALL,
7389 ARG_ROOT,
7390 ARG_NO_RELOAD,
7391 ARG_KILL_WHO,
7392 ARG_NO_ASK_PASSWORD,
7393 ARG_FAILED,
7394 ARG_RUNTIME,
7395 ARG_FORCE,
7396 ARG_PLAIN,
7397 ARG_STATE,
7398 ARG_JOB_MODE,
7399 ARG_PRESET_MODE,
7400 ARG_FIRMWARE_SETUP,
7401 ARG_NOW,
7402 ARG_MESSAGE,
7403 ARG_WAIT,
7404 };
7405
7406 static const struct option options[] = {
7407 { "help", no_argument, NULL, 'h' },
7408 { "version", no_argument, NULL, ARG_VERSION },
7409 { "type", required_argument, NULL, 't' },
7410 { "property", required_argument, NULL, 'p' },
7411 { "all", no_argument, NULL, 'a' },
7412 { "reverse", no_argument, NULL, ARG_REVERSE },
7413 { "after", no_argument, NULL, ARG_AFTER },
7414 { "before", no_argument, NULL, ARG_BEFORE },
7415 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
7416 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
7417 { "full", no_argument, NULL, 'l' },
7418 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
7419 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
7420 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
7421 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
7422 { "ignore-inhibitors", no_argument, NULL, 'i' },
7423 { "value", no_argument, NULL, ARG_VALUE },
7424 { "user", no_argument, NULL, ARG_USER },
7425 { "system", no_argument, NULL, ARG_SYSTEM },
7426 { "global", no_argument, NULL, ARG_GLOBAL },
7427 { "wait", no_argument, NULL, ARG_WAIT },
7428 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
7429 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
7430 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
7431 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7432 { "quiet", no_argument, NULL, 'q' },
7433 { "root", required_argument, NULL, ARG_ROOT },
7434 { "force", no_argument, NULL, ARG_FORCE },
7435 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
7436 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
7437 { "signal", required_argument, NULL, 's' },
7438 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
7439 { "host", required_argument, NULL, 'H' },
7440 { "machine", required_argument, NULL, 'M' },
7441 { "runtime", no_argument, NULL, ARG_RUNTIME },
7442 { "lines", required_argument, NULL, 'n' },
7443 { "output", required_argument, NULL, 'o' },
7444 { "plain", no_argument, NULL, ARG_PLAIN },
7445 { "state", required_argument, NULL, ARG_STATE },
7446 { "recursive", no_argument, NULL, 'r' },
7447 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
7448 { "firmware-setup", no_argument, NULL, ARG_FIRMWARE_SETUP },
7449 { "now", no_argument, NULL, ARG_NOW },
7450 { "message", required_argument, NULL, ARG_MESSAGE },
7451 {}
7452 };
7453
7454 const char *p;
7455 int c, r;
7456
7457 assert(argc >= 0);
7458 assert(argv);
7459
7460 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
7461 arg_ask_password = true;
7462
7463 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
7464
7465 switch (c) {
7466
7467 case 'h':
7468 systemctl_help();
7469 return 0;
7470
7471 case ARG_VERSION:
7472 return version();
7473
7474 case 't': {
7475 if (isempty(optarg)) {
7476 log_error("--type= requires arguments.");
7477 return -EINVAL;
7478 }
7479
7480 for (p = optarg;;) {
7481 _cleanup_free_ char *type = NULL;
7482
7483 r = extract_first_word(&p, &type, ",", 0);
7484 if (r < 0)
7485 return log_error_errno(r, "Failed to parse type: %s", optarg);
7486 if (r == 0)
7487 break;
7488
7489 if (streq(type, "help")) {
7490 help_types();
7491 return 0;
7492 }
7493
7494 if (unit_type_from_string(type) >= 0) {
7495 if (strv_push(&arg_types, type) < 0)
7496 return log_oom();
7497 type = NULL;
7498 continue;
7499 }
7500
7501 /* It's much nicer to use --state= for
7502 * load states, but let's support this
7503 * in --types= too for compatibility
7504 * with old versions */
7505 if (unit_load_state_from_string(type) >= 0) {
7506 if (strv_push(&arg_states, type) < 0)
7507 return log_oom();
7508 type = NULL;
7509 continue;
7510 }
7511
7512 log_error("Unknown unit type or load state '%s'.", type);
7513 log_info("Use -t help to see a list of allowed values.");
7514 return -EINVAL;
7515 }
7516
7517 break;
7518 }
7519
7520 case 'p': {
7521 /* Make sure that if the empty property list
7522 was specified, we won't show any properties. */
7523 if (isempty(optarg) && !arg_properties) {
7524 arg_properties = new0(char*, 1);
7525 if (!arg_properties)
7526 return log_oom();
7527 } else
7528 for (p = optarg;;) {
7529 _cleanup_free_ char *prop = NULL;
7530
7531 r = extract_first_word(&p, &prop, ",", 0);
7532 if (r < 0)
7533 return log_error_errno(r, "Failed to parse property: %s", optarg);
7534 if (r == 0)
7535 break;
7536
7537 if (strv_push(&arg_properties, prop) < 0)
7538 return log_oom();
7539
7540 prop = NULL;
7541 }
7542
7543 /* If the user asked for a particular
7544 * property, show it to him, even if it is
7545 * empty. */
7546 arg_all = true;
7547
7548 break;
7549 }
7550
7551 case 'a':
7552 arg_all = true;
7553 break;
7554
7555 case ARG_REVERSE:
7556 arg_dependency = DEPENDENCY_REVERSE;
7557 break;
7558
7559 case ARG_AFTER:
7560 arg_dependency = DEPENDENCY_AFTER;
7561 arg_jobs_after = true;
7562 break;
7563
7564 case ARG_BEFORE:
7565 arg_dependency = DEPENDENCY_BEFORE;
7566 arg_jobs_before = true;
7567 break;
7568
7569 case ARG_SHOW_TYPES:
7570 arg_show_types = true;
7571 break;
7572
7573 case ARG_VALUE:
7574 arg_value = true;
7575 break;
7576
7577 case ARG_JOB_MODE:
7578 arg_job_mode = optarg;
7579 break;
7580
7581 case ARG_FAIL:
7582 arg_job_mode = "fail";
7583 break;
7584
7585 case ARG_IRREVERSIBLE:
7586 arg_job_mode = "replace-irreversibly";
7587 break;
7588
7589 case ARG_IGNORE_DEPENDENCIES:
7590 arg_job_mode = "ignore-dependencies";
7591 break;
7592
7593 case ARG_USER:
7594 arg_scope = UNIT_FILE_USER;
7595 break;
7596
7597 case ARG_SYSTEM:
7598 arg_scope = UNIT_FILE_SYSTEM;
7599 break;
7600
7601 case ARG_GLOBAL:
7602 arg_scope = UNIT_FILE_GLOBAL;
7603 break;
7604
7605 case ARG_WAIT:
7606 arg_wait = true;
7607 break;
7608
7609 case ARG_NO_BLOCK:
7610 arg_no_block = true;
7611 break;
7612
7613 case ARG_NO_LEGEND:
7614 arg_no_legend = true;
7615 break;
7616
7617 case ARG_NO_PAGER:
7618 arg_no_pager = true;
7619 break;
7620
7621 case ARG_NO_WALL:
7622 arg_no_wall = true;
7623 break;
7624
7625 case ARG_ROOT:
7626 r = parse_path_argument_and_warn(optarg, false, &arg_root);
7627 if (r < 0)
7628 return r;
7629 break;
7630
7631 case 'l':
7632 arg_full = true;
7633 break;
7634
7635 case ARG_FAILED:
7636 if (strv_extend(&arg_states, "failed") < 0)
7637 return log_oom();
7638
7639 break;
7640
7641 case 'q':
7642 arg_quiet = true;
7643 break;
7644
7645 case ARG_FORCE:
7646 arg_force++;
7647 break;
7648
7649 case 'f':
7650 arg_force++;
7651 break;
7652
7653 case ARG_NO_RELOAD:
7654 arg_no_reload = true;
7655 break;
7656
7657 case ARG_KILL_WHO:
7658 arg_kill_who = optarg;
7659 break;
7660
7661 case 's':
7662 arg_signal = signal_from_string_try_harder(optarg);
7663 if (arg_signal < 0) {
7664 log_error("Failed to parse signal string %s.", optarg);
7665 return -EINVAL;
7666 }
7667 break;
7668
7669 case ARG_NO_ASK_PASSWORD:
7670 arg_ask_password = false;
7671 break;
7672
7673 case 'H':
7674 arg_transport = BUS_TRANSPORT_REMOTE;
7675 arg_host = optarg;
7676 break;
7677
7678 case 'M':
7679 arg_transport = BUS_TRANSPORT_MACHINE;
7680 arg_host = optarg;
7681 break;
7682
7683 case ARG_RUNTIME:
7684 arg_runtime = true;
7685 break;
7686
7687 case 'n':
7688 if (safe_atou(optarg, &arg_lines) < 0) {
7689 log_error("Failed to parse lines '%s'", optarg);
7690 return -EINVAL;
7691 }
7692 break;
7693
7694 case 'o':
7695 arg_output = output_mode_from_string(optarg);
7696 if (arg_output < 0) {
7697 log_error("Unknown output '%s'.", optarg);
7698 return -EINVAL;
7699 }
7700 break;
7701
7702 case 'i':
7703 arg_ignore_inhibitors = true;
7704 break;
7705
7706 case ARG_PLAIN:
7707 arg_plain = true;
7708 break;
7709
7710 case ARG_FIRMWARE_SETUP:
7711 arg_firmware_setup = true;
7712 break;
7713
7714 case ARG_STATE: {
7715 if (isempty(optarg)) {
7716 log_error("--state= requires arguments.");
7717 return -EINVAL;
7718 }
7719
7720 for (p = optarg;;) {
7721 _cleanup_free_ char *s = NULL;
7722
7723 r = extract_first_word(&p, &s, ",", 0);
7724 if (r < 0)
7725 return log_error_errno(r, "Failed to parse state: %s", optarg);
7726 if (r == 0)
7727 break;
7728
7729 if (streq(s, "help")) {
7730 help_states();
7731 return 0;
7732 }
7733
7734 if (strv_push(&arg_states, s) < 0)
7735 return log_oom();
7736
7737 s = NULL;
7738 }
7739 break;
7740 }
7741
7742 case 'r':
7743 if (geteuid() != 0) {
7744 log_error("--recursive requires root privileges.");
7745 return -EPERM;
7746 }
7747
7748 arg_recursive = true;
7749 break;
7750
7751 case ARG_PRESET_MODE:
7752
7753 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
7754 if (arg_preset_mode < 0) {
7755 log_error("Failed to parse preset mode: %s.", optarg);
7756 return -EINVAL;
7757 }
7758
7759 break;
7760
7761 case ARG_NOW:
7762 arg_now = true;
7763 break;
7764
7765 case ARG_MESSAGE:
7766 if (strv_extend(&arg_wall, optarg) < 0)
7767 return log_oom();
7768 break;
7769
7770 case '?':
7771 return -EINVAL;
7772
7773 default:
7774 assert_not_reached("Unhandled option");
7775 }
7776
7777 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
7778 log_error("Cannot access user instance remotely.");
7779 return -EINVAL;
7780 }
7781
7782 if (arg_wait && arg_no_block) {
7783 log_error("--wait may not be combined with --no-block.");
7784 return -EINVAL;
7785 }
7786
7787 return 1;
7788 }
7789
7790 static int halt_parse_argv(int argc, char *argv[]) {
7791
7792 enum {
7793 ARG_HELP = 0x100,
7794 ARG_HALT,
7795 ARG_REBOOT,
7796 ARG_NO_WALL
7797 };
7798
7799 static const struct option options[] = {
7800 { "help", no_argument, NULL, ARG_HELP },
7801 { "halt", no_argument, NULL, ARG_HALT },
7802 { "poweroff", no_argument, NULL, 'p' },
7803 { "reboot", no_argument, NULL, ARG_REBOOT },
7804 { "force", no_argument, NULL, 'f' },
7805 { "wtmp-only", no_argument, NULL, 'w' },
7806 { "no-wtmp", no_argument, NULL, 'd' },
7807 { "no-sync", no_argument, NULL, 'n' },
7808 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7809 {}
7810 };
7811
7812 int c, r, runlevel;
7813
7814 assert(argc >= 0);
7815 assert(argv);
7816
7817 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
7818 if (runlevel == '0' || runlevel == '6')
7819 arg_force = 2;
7820
7821 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
7822 switch (c) {
7823
7824 case ARG_HELP:
7825 halt_help();
7826 return 0;
7827
7828 case ARG_HALT:
7829 arg_action = ACTION_HALT;
7830 break;
7831
7832 case 'p':
7833 if (arg_action != ACTION_REBOOT)
7834 arg_action = ACTION_POWEROFF;
7835 break;
7836
7837 case ARG_REBOOT:
7838 arg_action = ACTION_REBOOT;
7839 break;
7840
7841 case 'f':
7842 arg_force = 2;
7843 break;
7844
7845 case 'w':
7846 arg_dry = true;
7847 break;
7848
7849 case 'd':
7850 arg_no_wtmp = true;
7851 break;
7852
7853 case 'n':
7854 arg_no_sync = true;
7855 break;
7856
7857 case ARG_NO_WALL:
7858 arg_no_wall = true;
7859 break;
7860
7861 case 'i':
7862 case 'h':
7863 /* Compatibility nops */
7864 break;
7865
7866 case '?':
7867 return -EINVAL;
7868
7869 default:
7870 assert_not_reached("Unhandled option");
7871 }
7872
7873 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
7874 r = update_reboot_parameter_and_warn(argc == optind + 1 ? argv[optind] : NULL);
7875 if (r < 0)
7876 return r;
7877 } else if (optind < argc) {
7878 log_error("Too many arguments.");
7879 return -EINVAL;
7880 }
7881
7882 return 1;
7883 }
7884
7885 static int parse_shutdown_time_spec(const char *t, usec_t *_u) {
7886 assert(t);
7887 assert(_u);
7888
7889 if (streq(t, "now"))
7890 *_u = 0;
7891 else if (!strchr(t, ':')) {
7892 uint64_t u;
7893
7894 if (safe_atou64(t, &u) < 0)
7895 return -EINVAL;
7896
7897 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
7898 } else {
7899 char *e = NULL;
7900 long hour, minute;
7901 struct tm tm = {};
7902 time_t s;
7903 usec_t n;
7904
7905 errno = 0;
7906 hour = strtol(t, &e, 10);
7907 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
7908 return -EINVAL;
7909
7910 minute = strtol(e+1, &e, 10);
7911 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
7912 return -EINVAL;
7913
7914 n = now(CLOCK_REALTIME);
7915 s = (time_t) (n / USEC_PER_SEC);
7916
7917 assert_se(localtime_r(&s, &tm));
7918
7919 tm.tm_hour = (int) hour;
7920 tm.tm_min = (int) minute;
7921 tm.tm_sec = 0;
7922
7923 assert_se(s = mktime(&tm));
7924
7925 *_u = (usec_t) s * USEC_PER_SEC;
7926
7927 while (*_u <= n)
7928 *_u += USEC_PER_DAY;
7929 }
7930
7931 return 0;
7932 }
7933
7934 static int shutdown_parse_argv(int argc, char *argv[]) {
7935
7936 enum {
7937 ARG_HELP = 0x100,
7938 ARG_NO_WALL
7939 };
7940
7941 static const struct option options[] = {
7942 { "help", no_argument, NULL, ARG_HELP },
7943 { "halt", no_argument, NULL, 'H' },
7944 { "poweroff", no_argument, NULL, 'P' },
7945 { "reboot", no_argument, NULL, 'r' },
7946 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
7947 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7948 {}
7949 };
7950
7951 char **wall = NULL;
7952 int c, r;
7953
7954 assert(argc >= 0);
7955 assert(argv);
7956
7957 while ((c = getopt_long(argc, argv, "HPrhkKtafFc", options, NULL)) >= 0)
7958 switch (c) {
7959
7960 case ARG_HELP:
7961 shutdown_help();
7962 return 0;
7963
7964 case 'H':
7965 arg_action = ACTION_HALT;
7966 break;
7967
7968 case 'P':
7969 arg_action = ACTION_POWEROFF;
7970 break;
7971
7972 case 'r':
7973 if (kexec_loaded())
7974 arg_action = ACTION_KEXEC;
7975 else
7976 arg_action = ACTION_REBOOT;
7977 break;
7978
7979 case 'K':
7980 arg_action = ACTION_KEXEC;
7981 break;
7982
7983 case 'h':
7984 if (arg_action != ACTION_HALT)
7985 arg_action = ACTION_POWEROFF;
7986 break;
7987
7988 case 'k':
7989 arg_dry = true;
7990 break;
7991
7992 case ARG_NO_WALL:
7993 arg_no_wall = true;
7994 break;
7995
7996 case 't':
7997 case 'a':
7998 case 'f':
7999 case 'F':
8000 /* Compatibility nops */
8001 break;
8002
8003 case 'c':
8004 arg_action = ACTION_CANCEL_SHUTDOWN;
8005 break;
8006
8007 case '?':
8008 return -EINVAL;
8009
8010 default:
8011 assert_not_reached("Unhandled option");
8012 }
8013
8014 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
8015 r = parse_shutdown_time_spec(argv[optind], &arg_when);
8016 if (r < 0) {
8017 log_error("Failed to parse time specification: %s", argv[optind]);
8018 return r;
8019 }
8020 } else
8021 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
8022
8023 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
8024 /* No time argument for shutdown cancel */
8025 wall = argv + optind;
8026 else if (argc > optind + 1)
8027 /* We skip the time argument */
8028 wall = argv + optind + 1;
8029
8030 if (wall) {
8031 arg_wall = strv_copy(wall);
8032 if (!arg_wall)
8033 return log_oom();
8034 }
8035
8036 optind = argc;
8037
8038 return 1;
8039 }
8040
8041 static int telinit_parse_argv(int argc, char *argv[]) {
8042
8043 enum {
8044 ARG_HELP = 0x100,
8045 ARG_NO_WALL
8046 };
8047
8048 static const struct option options[] = {
8049 { "help", no_argument, NULL, ARG_HELP },
8050 { "no-wall", no_argument, NULL, ARG_NO_WALL },
8051 {}
8052 };
8053
8054 static const struct {
8055 char from;
8056 enum action to;
8057 } table[] = {
8058 { '0', ACTION_POWEROFF },
8059 { '6', ACTION_REBOOT },
8060 { '1', ACTION_RESCUE },
8061 { '2', ACTION_RUNLEVEL2 },
8062 { '3', ACTION_RUNLEVEL3 },
8063 { '4', ACTION_RUNLEVEL4 },
8064 { '5', ACTION_RUNLEVEL5 },
8065 { 's', ACTION_RESCUE },
8066 { 'S', ACTION_RESCUE },
8067 { 'q', ACTION_RELOAD },
8068 { 'Q', ACTION_RELOAD },
8069 { 'u', ACTION_REEXEC },
8070 { 'U', ACTION_REEXEC }
8071 };
8072
8073 unsigned i;
8074 int c;
8075
8076 assert(argc >= 0);
8077 assert(argv);
8078
8079 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
8080 switch (c) {
8081
8082 case ARG_HELP:
8083 telinit_help();
8084 return 0;
8085
8086 case ARG_NO_WALL:
8087 arg_no_wall = true;
8088 break;
8089
8090 case '?':
8091 return -EINVAL;
8092
8093 default:
8094 assert_not_reached("Unhandled option");
8095 }
8096
8097 if (optind >= argc) {
8098 log_error("%s: required argument missing.", program_invocation_short_name);
8099 return -EINVAL;
8100 }
8101
8102 if (optind + 1 < argc) {
8103 log_error("Too many arguments.");
8104 return -EINVAL;
8105 }
8106
8107 if (strlen(argv[optind]) != 1) {
8108 log_error("Expected single character argument.");
8109 return -EINVAL;
8110 }
8111
8112 for (i = 0; i < ELEMENTSOF(table); i++)
8113 if (table[i].from == argv[optind][0])
8114 break;
8115
8116 if (i >= ELEMENTSOF(table)) {
8117 log_error("Unknown command '%s'.", argv[optind]);
8118 return -EINVAL;
8119 }
8120
8121 arg_action = table[i].to;
8122
8123 optind++;
8124
8125 return 1;
8126 }
8127
8128 static int runlevel_parse_argv(int argc, char *argv[]) {
8129
8130 enum {
8131 ARG_HELP = 0x100,
8132 };
8133
8134 static const struct option options[] = {
8135 { "help", no_argument, NULL, ARG_HELP },
8136 {}
8137 };
8138
8139 int c;
8140
8141 assert(argc >= 0);
8142 assert(argv);
8143
8144 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
8145 switch (c) {
8146
8147 case ARG_HELP:
8148 runlevel_help();
8149 return 0;
8150
8151 case '?':
8152 return -EINVAL;
8153
8154 default:
8155 assert_not_reached("Unhandled option");
8156 }
8157
8158 if (optind < argc) {
8159 log_error("Too many arguments.");
8160 return -EINVAL;
8161 }
8162
8163 return 1;
8164 }
8165
8166 static int parse_argv(int argc, char *argv[]) {
8167 assert(argc >= 0);
8168 assert(argv);
8169
8170 if (program_invocation_short_name) {
8171
8172 if (strstr(program_invocation_short_name, "halt")) {
8173 arg_action = ACTION_HALT;
8174 return halt_parse_argv(argc, argv);
8175 } else if (strstr(program_invocation_short_name, "poweroff")) {
8176 arg_action = ACTION_POWEROFF;
8177 return halt_parse_argv(argc, argv);
8178 } else if (strstr(program_invocation_short_name, "reboot")) {
8179 if (kexec_loaded())
8180 arg_action = ACTION_KEXEC;
8181 else
8182 arg_action = ACTION_REBOOT;
8183 return halt_parse_argv(argc, argv);
8184 } else if (strstr(program_invocation_short_name, "shutdown")) {
8185 arg_action = ACTION_POWEROFF;
8186 return shutdown_parse_argv(argc, argv);
8187 } else if (strstr(program_invocation_short_name, "init")) {
8188
8189 if (sd_booted() > 0) {
8190 arg_action = _ACTION_INVALID;
8191 return telinit_parse_argv(argc, argv);
8192 } else {
8193 /* Hmm, so some other init system is
8194 * running, we need to forward this
8195 * request to it. For now we simply
8196 * guess that it is Upstart. */
8197
8198 execv(TELINIT, argv);
8199
8200 log_error("Couldn't find an alternative telinit implementation to spawn.");
8201 return -EIO;
8202 }
8203
8204 } else if (strstr(program_invocation_short_name, "runlevel")) {
8205 arg_action = ACTION_RUNLEVEL;
8206 return runlevel_parse_argv(argc, argv);
8207 }
8208 }
8209
8210 arg_action = ACTION_SYSTEMCTL;
8211 return systemctl_parse_argv(argc, argv);
8212 }
8213
8214 #if HAVE_SYSV_COMPAT
8215 _pure_ static int action_to_runlevel(void) {
8216
8217 static const char table[_ACTION_MAX] = {
8218 [ACTION_HALT] = '0',
8219 [ACTION_POWEROFF] = '0',
8220 [ACTION_REBOOT] = '6',
8221 [ACTION_RUNLEVEL2] = '2',
8222 [ACTION_RUNLEVEL3] = '3',
8223 [ACTION_RUNLEVEL4] = '4',
8224 [ACTION_RUNLEVEL5] = '5',
8225 [ACTION_RESCUE] = '1'
8226 };
8227
8228 assert(arg_action >= 0 && arg_action < _ACTION_MAX);
8229
8230 return table[arg_action];
8231 }
8232 #endif
8233
8234 static int talk_initctl(void) {
8235 #if HAVE_SYSV_COMPAT
8236 struct init_request request = {
8237 .magic = INIT_MAGIC,
8238 .sleeptime = 0,
8239 .cmd = INIT_CMD_RUNLVL
8240 };
8241
8242 _cleanup_close_ int fd = -1;
8243 char rl;
8244 int r;
8245
8246 rl = action_to_runlevel();
8247 if (!rl)
8248 return 0;
8249
8250 request.runlevel = rl;
8251
8252 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
8253 if (fd < 0) {
8254 if (errno == ENOENT)
8255 return 0;
8256
8257 return log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
8258 }
8259
8260 r = loop_write(fd, &request, sizeof(request), false);
8261 if (r < 0)
8262 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
8263
8264 return 1;
8265 #else
8266 return 0;
8267 #endif
8268 }
8269
8270 static int systemctl_main(int argc, char *argv[]) {
8271
8272 static const Verb verbs[] = {
8273 { "list-units", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_NOCHROOT, list_units },
8274 { "list-unit-files", VERB_ANY, VERB_ANY, 0, list_unit_files },
8275 { "list-sockets", VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_sockets },
8276 { "list-timers", VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_timers },
8277 { "list-jobs", VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_jobs },
8278 { "list-machines", VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_machines },
8279 { "clear-jobs", VERB_ANY, 1, VERB_NOCHROOT, trivial_method },
8280 { "cancel", VERB_ANY, VERB_ANY, VERB_NOCHROOT, cancel_job },
8281 { "start", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8282 { "stop", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8283 { "condstop", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatibility with ALTLinux */
8284 { "reload", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8285 { "restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8286 { "try-restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8287 { "reload-or-restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8288 { "reload-or-try-restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatbility with old systemctl <= 228 */
8289 { "try-reload-or-restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8290 { "force-reload", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatibility with SysV */
8291 { "condreload", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatibility with ALTLinux */
8292 { "condrestart", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatibility with RH */
8293 { "isolate", 2, 2, VERB_NOCHROOT, start_unit },
8294 { "kill", 2, VERB_ANY, VERB_NOCHROOT, kill_unit },
8295 { "is-active", 2, VERB_ANY, VERB_NOCHROOT, check_unit_active },
8296 { "check", 2, VERB_ANY, VERB_NOCHROOT, check_unit_active },
8297 { "is-failed", 2, VERB_ANY, VERB_NOCHROOT, check_unit_failed },
8298 { "show", VERB_ANY, VERB_ANY, VERB_NOCHROOT, show },
8299 { "cat", 2, VERB_ANY, VERB_NOCHROOT, cat },
8300 { "status", VERB_ANY, VERB_ANY, VERB_NOCHROOT, show },
8301 { "help", VERB_ANY, VERB_ANY, VERB_NOCHROOT, show },
8302 { "daemon-reload", VERB_ANY, 1, VERB_NOCHROOT, daemon_reload },
8303 { "daemon-reexec", VERB_ANY, 1, VERB_NOCHROOT, daemon_reload },
8304 { "show-environment", VERB_ANY, 1, VERB_NOCHROOT, show_environment },
8305 { "set-environment", 2, VERB_ANY, VERB_NOCHROOT, set_environment },
8306 { "unset-environment", 2, VERB_ANY, VERB_NOCHROOT, set_environment },
8307 { "import-environment", VERB_ANY, VERB_ANY, VERB_NOCHROOT, import_environment },
8308 { "halt", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8309 { "poweroff", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8310 { "reboot", VERB_ANY, 2, VERB_NOCHROOT, start_system_special },
8311 { "kexec", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8312 { "suspend", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8313 { "hibernate", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8314 { "hybrid-sleep", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8315 { "default", VERB_ANY, 1, VERB_NOCHROOT, start_special },
8316 { "rescue", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8317 { "emergency", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8318 { "exit", VERB_ANY, 2, VERB_NOCHROOT, start_special },
8319 { "reset-failed", VERB_ANY, VERB_ANY, VERB_NOCHROOT, reset_failed },
8320 { "enable", 2, VERB_ANY, 0, enable_unit },
8321 { "disable", 2, VERB_ANY, 0, enable_unit },
8322 { "is-enabled", 2, VERB_ANY, 0, unit_is_enabled },
8323 { "reenable", 2, VERB_ANY, 0, enable_unit },
8324 { "preset", 2, VERB_ANY, 0, enable_unit },
8325 { "preset-all", VERB_ANY, 1, 0, preset_all },
8326 { "mask", 2, VERB_ANY, 0, enable_unit },
8327 { "unmask", 2, VERB_ANY, 0, enable_unit },
8328 { "link", 2, VERB_ANY, 0, enable_unit },
8329 { "revert", 2, VERB_ANY, 0, enable_unit },
8330 { "switch-root", 2, VERB_ANY, VERB_NOCHROOT, switch_root },
8331 { "list-dependencies", VERB_ANY, 2, VERB_NOCHROOT, list_dependencies },
8332 { "set-default", 2, 2, 0, set_default },
8333 { "get-default", VERB_ANY, 1, 0, get_default },
8334 { "set-property", 3, VERB_ANY, VERB_NOCHROOT, set_property },
8335 { "is-system-running", VERB_ANY, 1, 0, is_system_running },
8336 { "add-wants", 3, VERB_ANY, 0, add_dependency },
8337 { "add-requires", 3, VERB_ANY, 0, add_dependency },
8338 { "edit", 2, VERB_ANY, VERB_NOCHROOT, edit },
8339 {}
8340 };
8341
8342 return dispatch_verb(argc, argv, verbs, NULL);
8343 }
8344
8345 static int reload_with_fallback(void) {
8346
8347 /* First, try systemd via D-Bus. */
8348 if (daemon_reload(0, NULL, NULL) >= 0)
8349 return 0;
8350
8351 /* Nothing else worked, so let's try signals */
8352 assert(IN_SET(arg_action, ACTION_RELOAD, ACTION_REEXEC));
8353
8354 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
8355 return log_error_errno(errno, "kill() failed: %m");
8356
8357 return 0;
8358 }
8359
8360 static int start_with_fallback(void) {
8361
8362 /* First, try systemd via D-Bus. */
8363 if (start_unit(0, NULL, NULL) >= 0)
8364 return 0;
8365
8366 /* Nothing else worked, so let's try /dev/initctl */
8367 if (talk_initctl() > 0)
8368 return 0;
8369
8370 log_error("Failed to talk to init daemon.");
8371 return -EIO;
8372 }
8373
8374 static int halt_now(enum action a) {
8375 int r;
8376
8377 /* The kernel will automaticall flush ATA disks and suchlike
8378 * on reboot(), but the file systems need to be synce'd
8379 * explicitly in advance. */
8380 if (!arg_no_sync)
8381 (void) sync();
8382
8383 /* Make sure C-A-D is handled by the kernel from this point
8384 * on... */
8385 (void) reboot(RB_ENABLE_CAD);
8386
8387 switch (a) {
8388
8389 case ACTION_HALT:
8390 if (!arg_quiet)
8391 log_info("Halting.");
8392 (void) reboot(RB_HALT_SYSTEM);
8393 return -errno;
8394
8395 case ACTION_POWEROFF:
8396 if (!arg_quiet)
8397 log_info("Powering off.");
8398 (void) reboot(RB_POWER_OFF);
8399 return -errno;
8400
8401 case ACTION_KEXEC:
8402 case ACTION_REBOOT: {
8403 _cleanup_free_ char *param = NULL;
8404
8405 r = read_one_line_file("/run/systemd/reboot-param", &param);
8406 if (r < 0 && r != -ENOENT)
8407 log_warning_errno(r, "Failed to read reboot parameter file: %m");
8408
8409 if (!isempty(param)) {
8410 if (!arg_quiet)
8411 log_info("Rebooting with argument '%s'.", param);
8412 (void) syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param);
8413 log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
8414 }
8415
8416 if (!arg_quiet)
8417 log_info("Rebooting.");
8418 (void) reboot(RB_AUTOBOOT);
8419 return -errno;
8420 }
8421
8422 default:
8423 assert_not_reached("Unknown action.");
8424 }
8425 }
8426
8427 static int logind_schedule_shutdown(void) {
8428
8429 #if ENABLE_LOGIND
8430 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
8431 char date[FORMAT_TIMESTAMP_MAX];
8432 const char *action;
8433 sd_bus *bus;
8434 int r;
8435
8436 r = acquire_bus(BUS_FULL, &bus);
8437 if (r < 0)
8438 return r;
8439
8440 switch (arg_action) {
8441 case ACTION_HALT:
8442 action = "halt";
8443 break;
8444 case ACTION_POWEROFF:
8445 action = "poweroff";
8446 break;
8447 case ACTION_KEXEC:
8448 action = "kexec";
8449 break;
8450 case ACTION_EXIT:
8451 action = "exit";
8452 break;
8453 case ACTION_REBOOT:
8454 default:
8455 action = "reboot";
8456 break;
8457 }
8458
8459 if (arg_dry)
8460 action = strjoina("dry-", action);
8461
8462 (void) logind_set_wall_message();
8463
8464 r = sd_bus_call_method(
8465 bus,
8466 "org.freedesktop.login1",
8467 "/org/freedesktop/login1",
8468 "org.freedesktop.login1.Manager",
8469 "ScheduleShutdown",
8470 &error,
8471 NULL,
8472 "st",
8473 action,
8474 arg_when);
8475 if (r < 0)
8476 return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r));
8477
8478 if (!arg_quiet)
8479 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
8480 return 0;
8481 #else
8482 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
8483 return -ENOSYS;
8484 #endif
8485 }
8486
8487 static int halt_main(void) {
8488 int r;
8489
8490 r = logind_check_inhibitors(arg_action);
8491 if (r < 0)
8492 return r;
8493
8494 if (arg_when > 0)
8495 return logind_schedule_shutdown();
8496
8497 if (geteuid() != 0) {
8498 if (arg_dry || arg_force > 0) {
8499 log_error("Must be root.");
8500 return -EPERM;
8501 }
8502
8503 /* Try logind if we are a normal user and no special
8504 * mode applies. Maybe PolicyKit allows us to shutdown
8505 * the machine. */
8506 if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT)) {
8507 r = logind_reboot(arg_action);
8508 if (r >= 0)
8509 return r;
8510 if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
8511 /* requested operation is not
8512 * supported on the local system or
8513 * already in progress */
8514 return r;
8515 /* on all other errors, try low-level operation */
8516 }
8517 }
8518
8519 if (!arg_dry && !arg_force)
8520 return start_with_fallback();
8521
8522 assert(geteuid() == 0);
8523
8524 if (!arg_no_wtmp) {
8525 if (sd_booted() > 0)
8526 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
8527 else {
8528 r = utmp_put_shutdown();
8529 if (r < 0)
8530 log_warning_errno(r, "Failed to write utmp record: %m");
8531 }
8532 }
8533
8534 if (arg_dry)
8535 return 0;
8536
8537 r = halt_now(arg_action);
8538 return log_error_errno(r, "Failed to reboot: %m");
8539 }
8540
8541 static int runlevel_main(void) {
8542 int r, runlevel, previous;
8543
8544 r = utmp_get_runlevel(&runlevel, &previous);
8545 if (r < 0) {
8546 puts("unknown");
8547 return r;
8548 }
8549
8550 printf("%c %c\n",
8551 previous <= 0 ? 'N' : previous,
8552 runlevel <= 0 ? 'N' : runlevel);
8553
8554 return 0;
8555 }
8556
8557 static int logind_cancel_shutdown(void) {
8558 #if ENABLE_LOGIND
8559 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
8560 sd_bus *bus;
8561 int r;
8562
8563 r = acquire_bus(BUS_FULL, &bus);
8564 if (r < 0)
8565 return r;
8566
8567 (void) logind_set_wall_message();
8568
8569 r = sd_bus_call_method(
8570 bus,
8571 "org.freedesktop.login1",
8572 "/org/freedesktop/login1",
8573 "org.freedesktop.login1.Manager",
8574 "CancelScheduledShutdown",
8575 &error,
8576 NULL, NULL);
8577 if (r < 0)
8578 return log_warning_errno(r, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error, r));
8579
8580 return 0;
8581 #else
8582 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
8583 return -ENOSYS;
8584 #endif
8585 }
8586
8587 int main(int argc, char*argv[]) {
8588 int r;
8589
8590 argv_cmdline = argv[0];
8591
8592 setlocale(LC_ALL, "");
8593 log_parse_environment();
8594 log_open();
8595 sigbus_install();
8596
8597 /* Explicitly not on_tty() to avoid setting cached value.
8598 * This becomes relevant for piping output which might be
8599 * ellipsized. */
8600 original_stdout_is_tty = isatty(STDOUT_FILENO);
8601
8602 r = parse_argv(argc, argv);
8603 if (r <= 0)
8604 goto finish;
8605
8606 if (arg_action != ACTION_SYSTEMCTL && running_in_chroot() > 0) {
8607
8608 if (!arg_quiet)
8609 log_info("Running in chroot, ignoring request.");
8610 r = 0;
8611 goto finish;
8612 }
8613
8614 /* systemctl_main() will print an error message for the bus
8615 * connection, but only if it needs to */
8616
8617 switch (arg_action) {
8618
8619 case ACTION_SYSTEMCTL:
8620 r = systemctl_main(argc, argv);
8621 break;
8622
8623 /* Legacy command aliases set arg_action. They provide some fallbacks,
8624 * e.g. to tell sysvinit to reboot after you have installed systemd
8625 * binaries. */
8626
8627 case ACTION_HALT:
8628 case ACTION_POWEROFF:
8629 case ACTION_REBOOT:
8630 case ACTION_KEXEC:
8631 r = halt_main();
8632 break;
8633
8634 case ACTION_RUNLEVEL2:
8635 case ACTION_RUNLEVEL3:
8636 case ACTION_RUNLEVEL4:
8637 case ACTION_RUNLEVEL5:
8638 case ACTION_RESCUE:
8639 r = start_with_fallback();
8640 break;
8641
8642 case ACTION_RELOAD:
8643 case ACTION_REEXEC:
8644 r = reload_with_fallback();
8645 break;
8646
8647 case ACTION_CANCEL_SHUTDOWN:
8648 r = logind_cancel_shutdown();
8649 break;
8650
8651 case ACTION_RUNLEVEL:
8652 r = runlevel_main();
8653 break;
8654
8655 case ACTION_EXIT:
8656 case ACTION_SUSPEND:
8657 case ACTION_HIBERNATE:
8658 case ACTION_HYBRID_SLEEP:
8659 case ACTION_EMERGENCY:
8660 case ACTION_DEFAULT:
8661 /* systemctl verbs with no equivalent in the legacy commands.
8662 * These cannot appear in arg_action. Fall through. */
8663
8664 case _ACTION_INVALID:
8665 default:
8666 assert_not_reached("Unknown action");
8667 }
8668
8669 finish:
8670 release_busses();
8671
8672 pager_close();
8673 ask_password_agent_close();
8674 polkit_agent_close();
8675
8676 strv_free(arg_types);
8677 strv_free(arg_states);
8678 strv_free(arg_properties);
8679
8680 strv_free(arg_wall);
8681 free(arg_root);
8682
8683 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
8684 return r < 0 ? EXIT_FAILURE : r;
8685 }