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