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