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