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