]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/systemctl/systemctl.c
systemctl: show Timers{Monotonic,Calendar}=
[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_free_ char *buf = NULL, *path = NULL;
2654 UnitActiveState state;
2655 int r;
2656
2657 assert(name);
2658 assert(active_state);
2659
2660 path = unit_dbus_path_from_name(name);
2661 if (!path)
2662 return log_oom();
2663
2664 r = sd_bus_get_property_string(
2665 bus,
2666 "org.freedesktop.systemd1",
2667 path,
2668 "org.freedesktop.systemd1.Unit",
2669 "ActiveState",
2670 &error,
2671 &buf);
2672 if (r < 0)
2673 return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r));
2674
2675 state = unit_active_state_from_string(buf);
2676 if (state == _UNIT_ACTIVE_STATE_INVALID) {
2677 log_error("Invalid unit state '%s' for: %s", buf, name);
2678 return -EINVAL;
2679 }
2680
2681 *active_state = state;
2682 return 0;
2683 }
2684
2685 static int check_triggering_units(
2686 sd_bus *bus,
2687 const char *name) {
2688
2689 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2690 _cleanup_free_ char *path = NULL, *n = NULL, *load_state = NULL;
2691 _cleanup_strv_free_ char **triggered_by = NULL;
2692 bool print_warning_label = true;
2693 UnitActiveState active_state;
2694 char **i;
2695 int r;
2696
2697 r = unit_name_mangle(name, UNIT_NAME_NOGLOB, &n);
2698 if (r < 0)
2699 return log_error_errno(r, "Failed to mangle unit name: %m");
2700
2701 path = unit_dbus_path_from_name(n);
2702 if (!path)
2703 return log_oom();
2704
2705 r = sd_bus_get_property_string(
2706 bus,
2707 "org.freedesktop.systemd1",
2708 path,
2709 "org.freedesktop.systemd1.Unit",
2710 "LoadState",
2711 &error,
2712 &load_state);
2713 if (r < 0)
2714 return log_error_errno(r, "Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2715
2716 if (streq(load_state, "masked"))
2717 return 0;
2718
2719 r = sd_bus_get_property_strv(
2720 bus,
2721 "org.freedesktop.systemd1",
2722 path,
2723 "org.freedesktop.systemd1.Unit",
2724 "TriggeredBy",
2725 &error,
2726 &triggered_by);
2727 if (r < 0)
2728 return log_error_errno(r, "Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2729
2730 STRV_FOREACH(i, triggered_by) {
2731 r = get_state_one_unit(bus, *i, &active_state);
2732 if (r < 0)
2733 return r;
2734
2735 if (!IN_SET(active_state, UNIT_ACTIVE, UNIT_RELOADING))
2736 continue;
2737
2738 if (print_warning_label) {
2739 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2740 print_warning_label = false;
2741 }
2742
2743 log_warning(" %s", *i);
2744 }
2745
2746 return 0;
2747 }
2748
2749 static const struct {
2750 const char *verb;
2751 const char *method;
2752 } unit_actions[] = {
2753 { "start", "StartUnit" },
2754 { "stop", "StopUnit" },
2755 { "condstop", "StopUnit" },
2756 { "reload", "ReloadUnit" },
2757 { "restart", "RestartUnit" },
2758 { "try-restart", "TryRestartUnit" },
2759 { "condrestart", "TryRestartUnit" },
2760 { "reload-or-restart", "ReloadOrRestartUnit" },
2761 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2762 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2763 { "condreload", "ReloadOrTryRestartUnit" },
2764 { "force-reload", "ReloadOrTryRestartUnit" }
2765 };
2766
2767 static const char *verb_to_method(const char *verb) {
2768 uint i;
2769
2770 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2771 if (streq_ptr(unit_actions[i].verb, verb))
2772 return unit_actions[i].method;
2773
2774 return "StartUnit";
2775 }
2776
2777 static const char *method_to_verb(const char *method) {
2778 uint i;
2779
2780 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2781 if (streq_ptr(unit_actions[i].method, method))
2782 return unit_actions[i].verb;
2783
2784 return "n/a";
2785 }
2786
2787 typedef struct {
2788 sd_bus_slot *match;
2789 sd_event *event;
2790 Set *unit_paths;
2791 bool any_failed;
2792 } WaitContext;
2793
2794 static void wait_context_free(WaitContext *c) {
2795 c->match = sd_bus_slot_unref(c->match);
2796 c->event = sd_event_unref(c->event);
2797 c->unit_paths = set_free_free(c->unit_paths);
2798 }
2799
2800 static int on_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
2801 WaitContext *c = userdata;
2802 const char *path;
2803 int r;
2804
2805 path = sd_bus_message_get_path(m);
2806 if (!set_contains(c->unit_paths, path))
2807 return 0;
2808
2809 /* Check if ActiveState changed to inactive/failed */
2810 /* (s interface, a{sv} changed_properties, as invalidated_properties) */
2811 r = sd_bus_message_skip(m, "s");
2812 if (r < 0)
2813 return bus_log_parse_error(r);
2814
2815 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
2816 if (r < 0)
2817 return bus_log_parse_error(r);
2818
2819 while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
2820 const char *s;
2821
2822 r = sd_bus_message_read(m, "s", &s);
2823 if (r < 0)
2824 return bus_log_parse_error(r);
2825
2826 if (streq(s, "ActiveState")) {
2827 bool is_failed;
2828
2829 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "s");
2830 if (r < 0)
2831 return bus_log_parse_error(r);
2832
2833 r = sd_bus_message_read(m, "s", &s);
2834 if (r < 0)
2835 return bus_log_parse_error(r);
2836
2837 is_failed = streq(s, "failed");
2838 if (streq(s, "inactive") || is_failed) {
2839 log_debug("%s became %s, dropping from --wait tracking", path, s);
2840 free(set_remove(c->unit_paths, path));
2841 c->any_failed = c->any_failed || is_failed;
2842 } else
2843 log_debug("ActiveState on %s changed to %s", path, s);
2844
2845 break; /* no need to dissect the rest of the message */
2846 } else {
2847 /* other property */
2848 r = sd_bus_message_skip(m, "v");
2849 if (r < 0)
2850 return bus_log_parse_error(r);
2851 }
2852 r = sd_bus_message_exit_container(m);
2853 if (r < 0)
2854 return bus_log_parse_error(r);
2855 }
2856 if (r < 0)
2857 return bus_log_parse_error(r);
2858
2859 if (set_isempty(c->unit_paths))
2860 sd_event_exit(c->event, EXIT_SUCCESS);
2861
2862 return 0;
2863 }
2864
2865 static int start_unit_one(
2866 sd_bus *bus,
2867 const char *method,
2868 const char *name,
2869 const char *mode,
2870 sd_bus_error *error,
2871 BusWaitForJobs *w,
2872 WaitContext *wait_context) {
2873
2874 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2875 const char *path;
2876 int r;
2877
2878 assert(method);
2879 assert(name);
2880 assert(mode);
2881 assert(error);
2882
2883 if (wait_context) {
2884 _cleanup_free_ char *unit_path = NULL;
2885
2886 log_debug("Watching for property changes of %s", name);
2887 r = sd_bus_call_method(
2888 bus,
2889 "org.freedesktop.systemd1",
2890 "/org/freedesktop/systemd1",
2891 "org.freedesktop.systemd1.Manager",
2892 "RefUnit",
2893 error,
2894 NULL,
2895 "s", name);
2896 if (r < 0)
2897 return log_error_errno(r, "Failed to RefUnit %s: %s", name, bus_error_message(error, r));
2898
2899 unit_path = unit_dbus_path_from_name(name);
2900 if (!unit_path)
2901 return log_oom();
2902
2903 r = set_put_strdup(wait_context->unit_paths, unit_path);
2904 if (r < 0)
2905 return log_error_errno(r, "Failed to add unit path %s to set: %m", unit_path);
2906
2907 r = sd_bus_match_signal_async(bus,
2908 &wait_context->match,
2909 NULL,
2910 unit_path,
2911 "org.freedesktop.DBus.Properties",
2912 "PropertiesChanged",
2913 on_properties_changed, NULL, wait_context);
2914 if (r < 0)
2915 return log_error_errno(r, "Failed to request match for PropertiesChanged signal: %m");
2916 }
2917
2918 log_debug("%s manager for %s on %s, %s",
2919 arg_dry_run ? "Would call" : "Calling",
2920 method, name, mode);
2921 if (arg_dry_run)
2922 return 0;
2923
2924 r = sd_bus_call_method(
2925 bus,
2926 "org.freedesktop.systemd1",
2927 "/org/freedesktop/systemd1",
2928 "org.freedesktop.systemd1.Manager",
2929 method,
2930 error,
2931 &reply,
2932 "ss", name, mode);
2933 if (r < 0) {
2934 const char *verb;
2935
2936 /* There's always a fallback possible for legacy actions. */
2937 if (arg_action != ACTION_SYSTEMCTL)
2938 return r;
2939
2940 verb = method_to_verb(method);
2941
2942 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2943
2944 if (!sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) &&
2945 !sd_bus_error_has_name(error, BUS_ERROR_UNIT_MASKED))
2946 log_error("See %s logs and 'systemctl%s status%s %s' for details.",
2947 arg_scope == UNIT_FILE_SYSTEM ? "system" : "user",
2948 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user",
2949 name[0] == '-' ? " --" : "",
2950 name);
2951
2952 return r;
2953 }
2954
2955 r = sd_bus_message_read(reply, "o", &path);
2956 if (r < 0)
2957 return bus_log_parse_error(r);
2958
2959 if (need_daemon_reload(bus, name) > 0)
2960 warn_unit_file_changed(name);
2961
2962 if (w) {
2963 log_debug("Adding %s to the set", path);
2964 r = bus_wait_for_jobs_add(w, path);
2965 if (r < 0)
2966 return log_oom();
2967 }
2968
2969 return 0;
2970 }
2971
2972 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2973 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2974 char **name;
2975 int r, i;
2976
2977 assert(bus);
2978 assert(ret);
2979
2980 STRV_FOREACH(name, names) {
2981 char *t;
2982
2983 if (suffix)
2984 r = unit_name_mangle_with_suffix(*name, UNIT_NAME_GLOB, suffix, &t);
2985 else
2986 r = unit_name_mangle(*name, UNIT_NAME_GLOB, &t);
2987 if (r < 0)
2988 return log_error_errno(r, "Failed to mangle name: %m");
2989
2990 if (string_is_glob(t))
2991 r = strv_consume(&globs, t);
2992 else
2993 r = strv_consume(&mangled, t);
2994 if (r < 0)
2995 return log_oom();
2996 }
2997
2998 /* Query the manager only if any of the names are a glob, since
2999 * this is fairly expensive */
3000 if (!strv_isempty(globs)) {
3001 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
3002 _cleanup_free_ UnitInfo *unit_infos = NULL;
3003 size_t allocated, n;
3004
3005 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
3006 if (r < 0)
3007 return r;
3008
3009 n = strv_length(mangled);
3010 allocated = n + 1;
3011
3012 for (i = 0; i < r; i++) {
3013 if (!GREEDY_REALLOC(mangled, allocated, n+2))
3014 return log_oom();
3015
3016 mangled[n] = strdup(unit_infos[i].id);
3017 if (!mangled[n])
3018 return log_oom();
3019
3020 mangled[++n] = NULL;
3021 }
3022 }
3023
3024 *ret = mangled;
3025 mangled = NULL; /* do not free */
3026
3027 return 0;
3028 }
3029
3030 static const struct {
3031 const char *target;
3032 const char *verb;
3033 const char *mode;
3034 } action_table[_ACTION_MAX] = {
3035 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
3036 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
3037 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
3038 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
3039 [ACTION_RUNLEVEL2] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
3040 [ACTION_RUNLEVEL3] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
3041 [ACTION_RUNLEVEL4] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
3042 [ACTION_RUNLEVEL5] = { SPECIAL_GRAPHICAL_TARGET, NULL, "isolate" },
3043 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
3044 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
3045 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
3046 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
3047 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
3048 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
3049 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
3050 };
3051
3052 static enum action verb_to_action(const char *verb) {
3053 enum action i;
3054
3055 for (i = 0; i < _ACTION_MAX; i++)
3056 if (streq_ptr(action_table[i].verb, verb))
3057 return i;
3058
3059 return _ACTION_INVALID;
3060 }
3061
3062 static int start_unit(int argc, char *argv[], void *userdata) {
3063 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
3064 const char *method, *mode, *one_name, *suffix = NULL;
3065 _cleanup_strv_free_ char **names = NULL;
3066 sd_bus *bus;
3067 _cleanup_(wait_context_free) WaitContext wait_context = {};
3068 char **name;
3069 int r = 0;
3070
3071 if (arg_wait && !STR_IN_SET(argv[0], "start", "restart")) {
3072 log_error("--wait may only be used with the 'start' or 'restart' commands.");
3073 return -EINVAL;
3074 }
3075
3076 /* we cannot do sender tracking on the private bus, so we need the full
3077 * one for RefUnit to implement --wait */
3078 r = acquire_bus(arg_wait ? BUS_FULL : BUS_MANAGER, &bus);
3079 if (r < 0)
3080 return r;
3081
3082 ask_password_agent_open_if_enabled();
3083 polkit_agent_open_maybe();
3084
3085 if (arg_action == ACTION_SYSTEMCTL) {
3086 enum action action;
3087
3088 action = verb_to_action(argv[0]);
3089
3090 if (action != _ACTION_INVALID) {
3091 method = "StartUnit";
3092 mode = action_table[action].mode;
3093 one_name = action_table[action].target;
3094 } else {
3095 if (streq(argv[0], "isolate")) {
3096 method = "StartUnit";
3097 mode = "isolate";
3098
3099 suffix = ".target";
3100 } else {
3101 method = verb_to_method(argv[0]);
3102 mode = arg_job_mode;
3103 }
3104 one_name = NULL;
3105 }
3106 } else {
3107 assert(arg_action >= 0 && arg_action < _ACTION_MAX);
3108 assert(action_table[arg_action].target);
3109 assert(action_table[arg_action].mode);
3110
3111 method = "StartUnit";
3112 mode = action_table[arg_action].mode;
3113 one_name = action_table[arg_action].target;
3114 }
3115
3116 if (one_name)
3117 names = strv_new(one_name, NULL);
3118 else {
3119 r = expand_names(bus, strv_skip(argv, 1), suffix, &names);
3120 if (r < 0)
3121 return log_error_errno(r, "Failed to expand names: %m");
3122 }
3123
3124 if (!arg_no_block) {
3125 r = bus_wait_for_jobs_new(bus, &w);
3126 if (r < 0)
3127 return log_error_errno(r, "Could not watch jobs: %m");
3128 }
3129
3130 if (arg_wait) {
3131 wait_context.unit_paths = set_new(&string_hash_ops);
3132 if (!wait_context.unit_paths)
3133 return log_oom();
3134
3135 r = sd_bus_call_method_async(
3136 bus,
3137 NULL,
3138 "org.freedesktop.systemd1",
3139 "/org/freedesktop/systemd1",
3140 "org.freedesktop.systemd1.Manager",
3141 "Subscribe",
3142 NULL, NULL,
3143 NULL);
3144 if (r < 0)
3145 return log_error_errno(r, "Failed to enable subscription: %m");
3146 r = sd_event_default(&wait_context.event);
3147 if (r < 0)
3148 return log_error_errno(r, "Failed to allocate event loop: %m");
3149 r = sd_bus_attach_event(bus, wait_context.event, 0);
3150 if (r < 0)
3151 return log_error_errno(r, "Failed to attach bus to event loop: %m");
3152 }
3153
3154 STRV_FOREACH(name, names) {
3155 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3156 int q;
3157
3158 q = start_unit_one(bus, method, *name, mode, &error, w, arg_wait ? &wait_context : NULL);
3159 if (r >= 0 && q < 0)
3160 r = translate_bus_error_to_exit_status(q, &error);
3161 }
3162
3163 if (!arg_no_block) {
3164 int q, arg_count = 0;
3165 const char* extra_args[4] = {};
3166
3167 if (arg_scope != UNIT_FILE_SYSTEM)
3168 extra_args[arg_count++] = "--user";
3169
3170 assert(IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_REMOTE, BUS_TRANSPORT_MACHINE));
3171 if (arg_transport == BUS_TRANSPORT_REMOTE) {
3172 extra_args[arg_count++] = "-H";
3173 extra_args[arg_count++] = arg_host;
3174 } else if (arg_transport == BUS_TRANSPORT_MACHINE) {
3175 extra_args[arg_count++] = "-M";
3176 extra_args[arg_count++] = arg_host;
3177 }
3178
3179 q = bus_wait_for_jobs(w, arg_quiet, extra_args);
3180 if (q < 0)
3181 return q;
3182
3183 /* When stopping units, warn if they can still be triggered by
3184 * another active unit (socket, path, timer) */
3185 if (!arg_quiet && streq(method, "StopUnit"))
3186 STRV_FOREACH(name, names)
3187 check_triggering_units(bus, *name);
3188 }
3189
3190 if (r >= 0 && arg_wait) {
3191 int q;
3192 q = sd_event_loop(wait_context.event);
3193 if (q < 0)
3194 return log_error_errno(q, "Failed to run event loop: %m");
3195 if (wait_context.any_failed)
3196 r = EXIT_FAILURE;
3197 }
3198
3199 return r;
3200 }
3201
3202 #if ENABLE_LOGIND
3203 static int logind_set_wall_message(void) {
3204 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3205 sd_bus *bus;
3206 _cleanup_free_ char *m = NULL;
3207 int r;
3208
3209 r = acquire_bus(BUS_FULL, &bus);
3210 if (r < 0)
3211 return r;
3212
3213 m = strv_join(arg_wall, " ");
3214 if (!m)
3215 return log_oom();
3216
3217 r = sd_bus_call_method(
3218 bus,
3219 "org.freedesktop.login1",
3220 "/org/freedesktop/login1",
3221 "org.freedesktop.login1.Manager",
3222 "SetWallMessage",
3223 &error,
3224 NULL,
3225 "sb",
3226 m,
3227 !arg_no_wall);
3228
3229 if (r < 0)
3230 return log_warning_errno(r, "Failed to set wall message, ignoring: %s", bus_error_message(&error, r));
3231 return 0;
3232 }
3233 #endif
3234
3235 /* Ask systemd-logind, which might grant access to unprivileged users
3236 * through PolicyKit */
3237 static int logind_reboot(enum action a) {
3238 #if ENABLE_LOGIND
3239 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3240 const char *method, *description;
3241 sd_bus *bus;
3242 int r;
3243
3244 r = acquire_bus(BUS_FULL, &bus);
3245 if (r < 0)
3246 return r;
3247
3248 switch (a) {
3249
3250 case ACTION_POWEROFF:
3251 method = "PowerOff";
3252 description = "power off system";
3253 break;
3254
3255 case ACTION_REBOOT:
3256 method = "Reboot";
3257 description = "reboot system";
3258 break;
3259
3260 case ACTION_HALT:
3261 method = "Halt";
3262 description = "halt system";
3263 break;
3264
3265 case ACTION_SUSPEND:
3266 method = "Suspend";
3267 description = "suspend system";
3268 break;
3269
3270 case ACTION_HIBERNATE:
3271 method = "Hibernate";
3272 description = "hibernate system";
3273 break;
3274
3275 case ACTION_HYBRID_SLEEP:
3276 method = "HybridSleep";
3277 description = "put system into hybrid sleep";
3278 break;
3279
3280 default:
3281 return -EINVAL;
3282 }
3283
3284 polkit_agent_open_maybe();
3285 (void) logind_set_wall_message();
3286
3287 r = sd_bus_call_method(
3288 bus,
3289 "org.freedesktop.login1",
3290 "/org/freedesktop/login1",
3291 "org.freedesktop.login1.Manager",
3292 method,
3293 &error,
3294 NULL,
3295 "b", arg_ask_password);
3296 if (r < 0)
3297 return log_error_errno(r, "Failed to %s via logind: %s", description, bus_error_message(&error, r));
3298
3299 return 0;
3300 #else
3301 return -ENOSYS;
3302 #endif
3303 }
3304
3305 static int logind_check_inhibitors(enum action a) {
3306 #if ENABLE_LOGIND
3307 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
3308 _cleanup_strv_free_ char **sessions = NULL;
3309 const char *what, *who, *why, *mode;
3310 uint32_t uid, pid;
3311 sd_bus *bus;
3312 unsigned c = 0;
3313 char **s;
3314 int r;
3315
3316 if (arg_ignore_inhibitors || arg_force > 0)
3317 return 0;
3318
3319 if (arg_when > 0)
3320 return 0;
3321
3322 if (geteuid() == 0)
3323 return 0;
3324
3325 if (!on_tty())
3326 return 0;
3327
3328 if (arg_transport != BUS_TRANSPORT_LOCAL)
3329 return 0;
3330
3331 r = acquire_bus(BUS_FULL, &bus);
3332 if (r < 0)
3333 return r;
3334
3335 r = sd_bus_call_method(
3336 bus,
3337 "org.freedesktop.login1",
3338 "/org/freedesktop/login1",
3339 "org.freedesktop.login1.Manager",
3340 "ListInhibitors",
3341 NULL,
3342 &reply,
3343 NULL);
3344 if (r < 0)
3345 /* If logind is not around, then there are no inhibitors... */
3346 return 0;
3347
3348 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
3349 if (r < 0)
3350 return bus_log_parse_error(r);
3351
3352 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
3353 _cleanup_free_ char *comm = NULL, *user = NULL;
3354 _cleanup_strv_free_ char **sv = NULL;
3355
3356 if (!streq(mode, "block"))
3357 continue;
3358
3359 sv = strv_split(what, ":");
3360 if (!sv)
3361 return log_oom();
3362
3363 if (!pid_is_valid((pid_t) pid)) {
3364 log_error("Invalid PID "PID_FMT".", (pid_t) pid);
3365 return -ERANGE;
3366 }
3367
3368 if (!strv_contains(sv,
3369 IN_SET(a,
3370 ACTION_HALT,
3371 ACTION_POWEROFF,
3372 ACTION_REBOOT,
3373 ACTION_KEXEC) ? "shutdown" : "sleep"))
3374 continue;
3375
3376 get_process_comm(pid, &comm);
3377 user = uid_to_name(uid);
3378
3379 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
3380 who, (pid_t) pid, strna(comm), strna(user), why);
3381
3382 c++;
3383 }
3384 if (r < 0)
3385 return bus_log_parse_error(r);
3386
3387 r = sd_bus_message_exit_container(reply);
3388 if (r < 0)
3389 return bus_log_parse_error(r);
3390
3391 /* Check for current sessions */
3392 sd_get_sessions(&sessions);
3393 STRV_FOREACH(s, sessions) {
3394 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
3395
3396 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
3397 continue;
3398
3399 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
3400 continue;
3401
3402 if (sd_session_get_type(*s, &type) < 0 || !STR_IN_SET(type, "x11", "wayland", "tty", "mir"))
3403 continue;
3404
3405 sd_session_get_tty(*s, &tty);
3406 sd_session_get_seat(*s, &seat);
3407 sd_session_get_service(*s, &service);
3408 user = uid_to_name(uid);
3409
3410 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
3411 c++;
3412 }
3413
3414 if (c <= 0)
3415 return 0;
3416
3417 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3418 action_table[a].verb);
3419
3420 return -EPERM;
3421 #else
3422 return 0;
3423 #endif
3424 }
3425
3426 static int logind_prepare_firmware_setup(void) {
3427 #if ENABLE_LOGIND
3428 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3429 sd_bus *bus;
3430 int r;
3431
3432 r = acquire_bus(BUS_FULL, &bus);
3433 if (r < 0)
3434 return r;
3435
3436 r = sd_bus_call_method(
3437 bus,
3438 "org.freedesktop.login1",
3439 "/org/freedesktop/login1",
3440 "org.freedesktop.login1.Manager",
3441 "SetRebootToFirmwareSetup",
3442 &error,
3443 NULL,
3444 "b", true);
3445 if (r < 0)
3446 return log_error_errno(r, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error, r));
3447
3448 return 0;
3449 #else
3450 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3451 return -ENOSYS;
3452 #endif
3453 }
3454
3455 static int prepare_firmware_setup(void) {
3456 int r;
3457
3458 if (!arg_firmware_setup)
3459 return 0;
3460
3461 if (arg_transport == BUS_TRANSPORT_LOCAL) {
3462
3463 r = efi_set_reboot_to_firmware(true);
3464 if (r < 0)
3465 log_debug_errno(r, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3466 else
3467 return r;
3468 }
3469
3470 return logind_prepare_firmware_setup();
3471 }
3472
3473 static int load_kexec_kernel(void) {
3474 _cleanup_(boot_config_free) BootConfig config = {};
3475 _cleanup_free_ char *where = NULL, *kernel = NULL, *initrd = NULL, *options = NULL;
3476 const BootEntry *e;
3477 pid_t pid;
3478 int r;
3479
3480 if (kexec_loaded()) {
3481 log_debug("Kexec kernel already loaded.");
3482 return 0;
3483 }
3484
3485 r = find_esp_and_warn(arg_esp_path, false, &where, NULL, NULL, NULL, NULL);
3486 if (r == -ENOKEY) /* find_esp_and_warn() doesn't warn about this case */
3487 return log_error_errno(r, "Cannot find the ESP partition mount point.");
3488 if (r < 0) /* But it logs about all these cases, hence don't log here again */
3489 return r;
3490
3491 r = boot_entries_load_config(where, &config);
3492 if (r < 0)
3493 return log_error_errno(r, "Failed to load bootspec config from \"%s/loader\": %m", where);
3494
3495 if (config.default_entry < 0) {
3496 log_error("No entry suitable as default, refusing to guess.");
3497 return -ENOENT;
3498 }
3499 e = &config.entries[config.default_entry];
3500
3501 if (strv_length(e->initrd) > 1) {
3502 log_error("Boot entry specifies multiple initrds, which is not supported currently.");
3503 return -EINVAL;
3504 }
3505
3506 kernel = path_join(NULL, where, e->kernel);
3507 if (!strv_isempty(e->initrd))
3508 initrd = path_join(NULL, where, *e->initrd);
3509 options = strv_join(e->options, " ");
3510 if (!options)
3511 return log_oom();
3512
3513 log_debug("%s kexec kernel %s initrd %s options \"%s\".",
3514 arg_dry_run ? "Would load" : "loading",
3515 kernel, initrd, options);
3516 if (arg_dry_run)
3517 return 0;
3518
3519 r = safe_fork("(kexec)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
3520 if (r < 0)
3521 return r;
3522 if (r == 0) {
3523
3524 const char* const args[] = {
3525 KEXEC,
3526 "--load", kernel,
3527 "--append", options,
3528 initrd ? "--initrd" : NULL, initrd,
3529 NULL };
3530
3531 /* Child */
3532 execv(args[0], (char * const *) args);
3533 _exit(EXIT_FAILURE);
3534 }
3535
3536 return wait_for_terminate_and_check("kexec", pid, WAIT_LOG);
3537 }
3538
3539 static int set_exit_code(uint8_t code) {
3540 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3541 sd_bus *bus;
3542 int r;
3543
3544 r = acquire_bus(BUS_MANAGER, &bus);
3545 if (r < 0)
3546 return r;
3547
3548 r = sd_bus_call_method(
3549 bus,
3550 "org.freedesktop.systemd1",
3551 "/org/freedesktop/systemd1",
3552 "org.freedesktop.systemd1.Manager",
3553 "SetExitCode",
3554 &error,
3555 NULL,
3556 "y", code);
3557 if (r < 0)
3558 return log_error_errno(r, "Failed to set exit code: %s", bus_error_message(&error, r));
3559
3560 return 0;
3561 }
3562
3563 static int start_special(int argc, char *argv[], void *userdata) {
3564 enum action a;
3565 int r;
3566 bool termination_action; /* an action that terminates the manager,
3567 * can be performed also by signal. */
3568
3569 assert(argv);
3570
3571 a = verb_to_action(argv[0]);
3572
3573 r = logind_check_inhibitors(a);
3574 if (r < 0)
3575 return r;
3576
3577 if (arg_force >= 2) {
3578 r = must_be_root();
3579 if (r < 0)
3580 return r;
3581 }
3582
3583 r = prepare_firmware_setup();
3584 if (r < 0)
3585 return r;
3586
3587 if (a == ACTION_REBOOT && argc > 1) {
3588 r = update_reboot_parameter_and_warn(argv[1]);
3589 if (r < 0)
3590 return r;
3591
3592 } else if (a == ACTION_KEXEC) {
3593 r = load_kexec_kernel();
3594 if (r < 0)
3595 return r;
3596
3597 } else if (a == ACTION_EXIT && argc > 1) {
3598 uint8_t code;
3599
3600 /* If the exit code is not given on the command line,
3601 * don't reset it to zero: just keep it as it might
3602 * have been set previously. */
3603
3604 r = safe_atou8(argv[1], &code);
3605 if (r < 0)
3606 return log_error_errno(r, "Invalid exit code.");
3607
3608 r = set_exit_code(code);
3609 if (r < 0)
3610 return r;
3611 }
3612
3613 termination_action = IN_SET(a,
3614 ACTION_HALT,
3615 ACTION_POWEROFF,
3616 ACTION_REBOOT);
3617 if (termination_action && arg_force >= 2)
3618 return halt_now(a);
3619
3620 if (arg_force >= 1 &&
3621 (termination_action || IN_SET(a, ACTION_KEXEC, ACTION_EXIT)))
3622 r = trivial_method(argc, argv, userdata);
3623 else {
3624 /* First try logind, to allow authentication with polkit */
3625 if (IN_SET(a,
3626 ACTION_POWEROFF,
3627 ACTION_REBOOT,
3628 ACTION_HALT,
3629 ACTION_SUSPEND,
3630 ACTION_HIBERNATE,
3631 ACTION_HYBRID_SLEEP)) {
3632
3633 r = logind_reboot(a);
3634 if (r >= 0)
3635 return r;
3636 if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
3637 /* requested operation is not supported or already in progress */
3638 return r;
3639
3640 /* On all other errors, try low-level operation. In order to minimize the difference between
3641 * operation with and without logind, we explicitly enable non-blocking mode for this, as
3642 * logind's shutdown operations are always non-blocking. */
3643
3644 arg_no_block = true;
3645
3646 } else if (IN_SET(a, ACTION_EXIT, ACTION_KEXEC))
3647 /* Since exit/kexec are so close in behaviour to power-off/reboot, let's also make them
3648 * asynchronous, in order to not confuse the user needlessly with unexpected behaviour. */
3649 arg_no_block = true;
3650
3651 r = start_unit(argc, argv, userdata);
3652 }
3653
3654 if (termination_action && arg_force < 2 &&
3655 IN_SET(r, -ENOENT, -ETIMEDOUT))
3656 log_notice("It is possible to perform action directly, see discussion of --force --force in man:systemctl(1).");
3657
3658 return r;
3659 }
3660
3661 static int start_system_special(int argc, char *argv[], void *userdata) {
3662 /* Like start_special above, but raises an error when running in user mode */
3663
3664 if (arg_scope != UNIT_FILE_SYSTEM) {
3665 log_error("Bad action for %s mode.",
3666 arg_scope == UNIT_FILE_GLOBAL ? "--global" : "--user");
3667 return -EINVAL;
3668 }
3669
3670 return start_special(argc, argv, userdata);
3671 }
3672
3673 static int check_unit_generic(int code, const UnitActiveState good_states[], int nb_states, char **args) {
3674 _cleanup_strv_free_ char **names = NULL;
3675 UnitActiveState active_state;
3676 sd_bus *bus;
3677 char **name;
3678 int r, i;
3679 bool found = false;
3680
3681 r = acquire_bus(BUS_MANAGER, &bus);
3682 if (r < 0)
3683 return r;
3684
3685 r = expand_names(bus, args, NULL, &names);
3686 if (r < 0)
3687 return log_error_errno(r, "Failed to expand names: %m");
3688
3689 STRV_FOREACH(name, names) {
3690 r = get_state_one_unit(bus, *name, &active_state);
3691 if (r < 0)
3692 return r;
3693
3694 if (!arg_quiet)
3695 puts(unit_active_state_to_string(active_state));
3696
3697 for (i = 0; i < nb_states; ++i)
3698 if (good_states[i] == active_state)
3699 found = true;
3700 }
3701
3702 /* use the given return code for the case that we won't find
3703 * any unit which matches the list */
3704 return found ? 0 : code;
3705 }
3706
3707 static int check_unit_active(int argc, char *argv[], void *userdata) {
3708 const UnitActiveState states[] = { UNIT_ACTIVE, UNIT_RELOADING };
3709 /* According to LSB: 3, "program is not running" */
3710 return check_unit_generic(EXIT_PROGRAM_NOT_RUNNING, states, ELEMENTSOF(states), strv_skip(argv, 1));
3711 }
3712
3713 static int check_unit_failed(int argc, char *argv[], void *userdata) {
3714 const UnitActiveState states[] = { UNIT_FAILED };
3715 return check_unit_generic(EXIT_PROGRAM_DEAD_AND_PID_EXISTS, states, ELEMENTSOF(states), strv_skip(argv, 1));
3716 }
3717
3718 static int kill_unit(int argc, char *argv[], void *userdata) {
3719 _cleanup_strv_free_ char **names = NULL;
3720 char *kill_who = NULL, **name;
3721 sd_bus *bus;
3722 int r, q;
3723
3724 r = acquire_bus(BUS_MANAGER, &bus);
3725 if (r < 0)
3726 return r;
3727
3728 polkit_agent_open_maybe();
3729
3730 if (!arg_kill_who)
3731 arg_kill_who = "all";
3732
3733 /* --fail was specified */
3734 if (streq(arg_job_mode, "fail"))
3735 kill_who = strjoina(arg_kill_who, "-fail");
3736
3737 r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
3738 if (r < 0)
3739 return log_error_errno(r, "Failed to expand names: %m");
3740
3741 STRV_FOREACH(name, names) {
3742 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3743
3744 q = sd_bus_call_method(
3745 bus,
3746 "org.freedesktop.systemd1",
3747 "/org/freedesktop/systemd1",
3748 "org.freedesktop.systemd1.Manager",
3749 "KillUnit",
3750 &error,
3751 NULL,
3752 "ssi", *name, kill_who ? kill_who : arg_kill_who, arg_signal);
3753 if (q < 0) {
3754 log_error_errno(q, "Failed to kill unit %s: %s", *name, bus_error_message(&error, q));
3755 if (r == 0)
3756 r = q;
3757 }
3758 }
3759
3760 return r;
3761 }
3762
3763 typedef struct ExecStatusInfo {
3764 char *name;
3765
3766 char *path;
3767 char **argv;
3768
3769 bool ignore;
3770
3771 usec_t start_timestamp;
3772 usec_t exit_timestamp;
3773 pid_t pid;
3774 int code;
3775 int status;
3776
3777 LIST_FIELDS(struct ExecStatusInfo, exec);
3778 } ExecStatusInfo;
3779
3780 static void exec_status_info_free(ExecStatusInfo *i) {
3781 assert(i);
3782
3783 free(i->name);
3784 free(i->path);
3785 strv_free(i->argv);
3786 free(i);
3787 }
3788
3789 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3790 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3791 const char *path;
3792 uint32_t pid;
3793 int32_t code, status;
3794 int ignore, r;
3795
3796 assert(m);
3797 assert(i);
3798
3799 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3800 if (r < 0)
3801 return bus_log_parse_error(r);
3802 else if (r == 0)
3803 return 0;
3804
3805 r = sd_bus_message_read(m, "s", &path);
3806 if (r < 0)
3807 return bus_log_parse_error(r);
3808
3809 i->path = strdup(path);
3810 if (!i->path)
3811 return log_oom();
3812
3813 r = sd_bus_message_read_strv(m, &i->argv);
3814 if (r < 0)
3815 return bus_log_parse_error(r);
3816
3817 r = sd_bus_message_read(m,
3818 "bttttuii",
3819 &ignore,
3820 &start_timestamp, &start_timestamp_monotonic,
3821 &exit_timestamp, &exit_timestamp_monotonic,
3822 &pid,
3823 &code, &status);
3824 if (r < 0)
3825 return bus_log_parse_error(r);
3826
3827 i->ignore = ignore;
3828 i->start_timestamp = (usec_t) start_timestamp;
3829 i->exit_timestamp = (usec_t) exit_timestamp;
3830 i->pid = (pid_t) pid;
3831 i->code = code;
3832 i->status = status;
3833
3834 r = sd_bus_message_exit_container(m);
3835 if (r < 0)
3836 return bus_log_parse_error(r);
3837
3838 return 1;
3839 }
3840
3841 typedef struct UnitCondition {
3842 char *name;
3843 char *param;
3844 bool trigger;
3845 bool negate;
3846 int tristate;
3847
3848 LIST_FIELDS(struct UnitCondition, conditions);
3849 } UnitCondition;
3850
3851 static void unit_condition_free(UnitCondition *c) {
3852 if (!c)
3853 return;
3854
3855 free(c->name);
3856 free(c->param);
3857 free(c);
3858 }
3859
3860 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitCondition*, unit_condition_free);
3861
3862 typedef struct UnitStatusInfo {
3863 const char *id;
3864 const char *load_state;
3865 const char *active_state;
3866 const char *sub_state;
3867 const char *unit_file_state;
3868 const char *unit_file_preset;
3869
3870 const char *description;
3871 const char *following;
3872
3873 char **documentation;
3874
3875 const char *fragment_path;
3876 const char *source_path;
3877 const char *control_group;
3878
3879 char **dropin_paths;
3880
3881 const char *load_error;
3882 const char *result;
3883
3884 usec_t inactive_exit_timestamp;
3885 usec_t inactive_exit_timestamp_monotonic;
3886 usec_t active_enter_timestamp;
3887 usec_t active_exit_timestamp;
3888 usec_t inactive_enter_timestamp;
3889
3890 bool need_daemon_reload;
3891 bool transient;
3892
3893 /* Service */
3894 pid_t main_pid;
3895 pid_t control_pid;
3896 const char *status_text;
3897 const char *pid_file;
3898 bool running:1;
3899 int status_errno;
3900
3901 usec_t start_timestamp;
3902 usec_t exit_timestamp;
3903
3904 int exit_code, exit_status;
3905
3906 usec_t condition_timestamp;
3907 bool condition_result;
3908 LIST_HEAD(UnitCondition, conditions);
3909
3910 usec_t assert_timestamp;
3911 bool assert_result;
3912 bool failed_assert_trigger;
3913 bool failed_assert_negate;
3914 const char *failed_assert;
3915 const char *failed_assert_parameter;
3916 usec_t next_elapse_real;
3917 usec_t next_elapse_monotonic;
3918
3919 /* Socket */
3920 unsigned n_accepted;
3921 unsigned n_connections;
3922 bool accept;
3923
3924 /* Pairs of type, path */
3925 char **listen;
3926
3927 /* Device */
3928 const char *sysfs_path;
3929
3930 /* Mount, Automount */
3931 const char *where;
3932
3933 /* Swap */
3934 const char *what;
3935
3936 /* CGroup */
3937 uint64_t memory_current;
3938 uint64_t memory_low;
3939 uint64_t memory_high;
3940 uint64_t memory_max;
3941 uint64_t memory_swap_max;
3942 uint64_t memory_limit;
3943 uint64_t cpu_usage_nsec;
3944 uint64_t tasks_current;
3945 uint64_t tasks_max;
3946
3947 uint64_t ip_ingress_bytes;
3948 uint64_t ip_egress_bytes;
3949
3950 LIST_HEAD(ExecStatusInfo, exec);
3951 } UnitStatusInfo;
3952
3953 static void unit_status_info_free(UnitStatusInfo *info) {
3954 ExecStatusInfo *p;
3955 UnitCondition *c;
3956
3957 strv_free(info->documentation);
3958 strv_free(info->dropin_paths);
3959 strv_free(info->listen);
3960
3961 while ((c = info->conditions)) {
3962 LIST_REMOVE(conditions, info->conditions, c);
3963 unit_condition_free(c);
3964 }
3965
3966 while ((p = info->exec)) {
3967 LIST_REMOVE(exec, info->exec, p);
3968 exec_status_info_free(p);
3969 }
3970 }
3971
3972 static void print_status_info(
3973 sd_bus *bus,
3974 UnitStatusInfo *i,
3975 bool *ellipsized) {
3976
3977 ExecStatusInfo *p;
3978 const char *active_on, *active_off, *on, *off, *ss;
3979 usec_t timestamp;
3980 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3981 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3982 const char *path;
3983 char **t, **t2;
3984 int r;
3985
3986 assert(i);
3987
3988 /* This shows pretty information about a unit. See
3989 * print_property() for a low-level property printer */
3990
3991 if (streq_ptr(i->active_state, "failed")) {
3992 active_on = ansi_highlight_red();
3993 active_off = ansi_normal();
3994 } else if (STRPTR_IN_SET(i->active_state, "active", "reloading")) {
3995 active_on = ansi_highlight_green();
3996 active_off = ansi_normal();
3997 } else
3998 active_on = active_off = "";
3999
4000 printf("%s%s%s %s", active_on, special_glyph(BLACK_CIRCLE), active_off, strna(i->id));
4001
4002 if (i->description && !streq_ptr(i->id, i->description))
4003 printf(" - %s", i->description);
4004
4005 printf("\n");
4006
4007 if (i->following)
4008 printf(" Follow: unit currently follows state of %s\n", i->following);
4009
4010 if (streq_ptr(i->load_state, "error")) {
4011 on = ansi_highlight_red();
4012 off = ansi_normal();
4013 } else
4014 on = off = "";
4015
4016 path = i->source_path ? i->source_path : i->fragment_path;
4017
4018 if (i->load_error != 0)
4019 printf(" Loaded: %s%s%s (Reason: %s)\n",
4020 on, strna(i->load_state), off, i->load_error);
4021 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset) &&
4022 !STR_IN_SET(i->unit_file_state, "generated", "transient"))
4023 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
4024 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
4025 else if (path && !isempty(i->unit_file_state))
4026 printf(" Loaded: %s%s%s (%s; %s)\n",
4027 on, strna(i->load_state), off, path, i->unit_file_state);
4028 else if (path)
4029 printf(" Loaded: %s%s%s (%s)\n",
4030 on, strna(i->load_state), off, path);
4031 else
4032 printf(" Loaded: %s%s%s\n",
4033 on, strna(i->load_state), off);
4034
4035 if (i->transient)
4036 printf("Transient: yes\n");
4037
4038 if (!strv_isempty(i->dropin_paths)) {
4039 _cleanup_free_ char *dir = NULL;
4040 bool last = false;
4041 char ** dropin;
4042
4043 STRV_FOREACH(dropin, i->dropin_paths) {
4044 if (! dir || last) {
4045 printf(dir ? " " : " Drop-In: ");
4046
4047 dir = mfree(dir);
4048
4049 dir = dirname_malloc(*dropin);
4050 if (!dir) {
4051 log_oom();
4052 return;
4053 }
4054
4055 printf("%s\n %s", dir,
4056 special_glyph(TREE_RIGHT));
4057 }
4058
4059 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
4060
4061 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
4062 }
4063 }
4064
4065 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
4066 if (ss)
4067 printf(" Active: %s%s (%s)%s",
4068 active_on, strna(i->active_state), ss, active_off);
4069 else
4070 printf(" Active: %s%s%s",
4071 active_on, strna(i->active_state), active_off);
4072
4073 if (!isempty(i->result) && !streq(i->result, "success"))
4074 printf(" (Result: %s)", i->result);
4075
4076 timestamp = STRPTR_IN_SET(i->active_state, "active", "reloading") ? i->active_enter_timestamp :
4077 STRPTR_IN_SET(i->active_state, "inactive", "failed") ? i->inactive_enter_timestamp :
4078 STRPTR_IN_SET(i->active_state, "activating") ? i->inactive_exit_timestamp :
4079 i->active_exit_timestamp;
4080
4081 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
4082 s2 = format_timestamp(since2, sizeof(since2), timestamp);
4083
4084 if (s1)
4085 printf(" since %s; %s\n", s2, s1);
4086 else if (s2)
4087 printf(" since %s\n", s2);
4088 else
4089 printf("\n");
4090
4091 if (endswith(i->id, ".timer")) {
4092 char tstamp1[FORMAT_TIMESTAMP_RELATIVE_MAX],
4093 tstamp2[FORMAT_TIMESTAMP_MAX];
4094 char *next_rel_time, *next_time;
4095 dual_timestamp nw, next = {i->next_elapse_real,
4096 i->next_elapse_monotonic};
4097 usec_t next_elapse;
4098
4099 printf(" Trigger: ");
4100
4101 dual_timestamp_get(&nw);
4102 next_elapse = calc_next_elapse(&nw, &next);
4103 next_rel_time = format_timestamp_relative(tstamp1,
4104 sizeof(tstamp1),
4105 next_elapse);
4106 next_time = format_timestamp(tstamp2,
4107 sizeof(tstamp2),
4108 next_elapse);
4109
4110 if (next_time && next_rel_time)
4111 printf("%s; %s\n", next_time, next_rel_time);
4112 else
4113 printf("n/a\n");
4114 }
4115
4116 if (!i->condition_result && i->condition_timestamp > 0) {
4117 UnitCondition *c;
4118 int n = 0;
4119
4120 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
4121 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
4122
4123 printf("Condition: start %scondition failed%s at %s%s%s\n",
4124 ansi_highlight_yellow(), ansi_normal(),
4125 s2, s1 ? "; " : "", strempty(s1));
4126
4127 LIST_FOREACH(conditions, c, i->conditions)
4128 if (c->tristate < 0)
4129 n++;
4130
4131 LIST_FOREACH(conditions, c, i->conditions)
4132 if (c->tristate < 0)
4133 printf(" %s %s=%s%s%s was not met\n",
4134 --n ? special_glyph(TREE_BRANCH) : special_glyph(TREE_RIGHT),
4135 c->name,
4136 c->trigger ? "|" : "",
4137 c->negate ? "!" : "",
4138 c->param);
4139 }
4140
4141 if (!i->assert_result && i->assert_timestamp > 0) {
4142 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
4143 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
4144
4145 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
4146 ansi_highlight_red(), ansi_normal(),
4147 s2, s1 ? "; " : "", strempty(s1));
4148 if (i->failed_assert_trigger)
4149 printf(" none of the trigger assertions were met\n");
4150 else if (i->failed_assert)
4151 printf(" %s=%s%s was not met\n",
4152 i->failed_assert,
4153 i->failed_assert_negate ? "!" : "",
4154 i->failed_assert_parameter);
4155 }
4156
4157 if (i->sysfs_path)
4158 printf(" Device: %s\n", i->sysfs_path);
4159 if (i->where)
4160 printf(" Where: %s\n", i->where);
4161 if (i->what)
4162 printf(" What: %s\n", i->what);
4163
4164 STRV_FOREACH(t, i->documentation)
4165 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
4166
4167 STRV_FOREACH_PAIR(t, t2, i->listen)
4168 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
4169
4170 if (i->accept)
4171 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
4172
4173 LIST_FOREACH(exec, p, i->exec) {
4174 _cleanup_free_ char *argv = NULL;
4175 bool good;
4176
4177 /* Only show exited processes here */
4178 if (p->code == 0)
4179 continue;
4180
4181 argv = strv_join(p->argv, " ");
4182 printf(" Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
4183
4184 good = is_clean_exit(p->code, p->status, EXIT_CLEAN_DAEMON, NULL);
4185 if (!good) {
4186 on = ansi_highlight_red();
4187 off = ansi_normal();
4188 } else
4189 on = off = "";
4190
4191 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
4192
4193 if (p->code == CLD_EXITED) {
4194 const char *c;
4195
4196 printf("status=%i", p->status);
4197
4198 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
4199 if (c)
4200 printf("/%s", c);
4201
4202 } else
4203 printf("signal=%s", signal_to_string(p->status));
4204
4205 printf(")%s\n", off);
4206
4207 if (i->main_pid == p->pid &&
4208 i->start_timestamp == p->start_timestamp &&
4209 i->exit_timestamp == p->start_timestamp)
4210 /* Let's not show this twice */
4211 i->main_pid = 0;
4212
4213 if (p->pid == i->control_pid)
4214 i->control_pid = 0;
4215 }
4216
4217 if (i->main_pid > 0 || i->control_pid > 0) {
4218 if (i->main_pid > 0) {
4219 printf(" Main PID: "PID_FMT, i->main_pid);
4220
4221 if (i->running) {
4222
4223 if (arg_transport == BUS_TRANSPORT_LOCAL) {
4224 _cleanup_free_ char *comm = NULL;
4225
4226 (void) get_process_comm(i->main_pid, &comm);
4227 if (comm)
4228 printf(" (%s)", comm);
4229 }
4230
4231 } else if (i->exit_code > 0) {
4232 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
4233
4234 if (i->exit_code == CLD_EXITED) {
4235 const char *c;
4236
4237 printf("status=%i", i->exit_status);
4238
4239 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
4240 if (c)
4241 printf("/%s", c);
4242
4243 } else
4244 printf("signal=%s", signal_to_string(i->exit_status));
4245 printf(")");
4246 }
4247 }
4248
4249 if (i->control_pid > 0) {
4250 _cleanup_free_ char *c = NULL;
4251
4252 if (i->main_pid > 0)
4253 fputs("; Control PID: ", stdout);
4254 else
4255 fputs("Cntrl PID: ", stdout); /* if first in column, abbreviated so it fits alignment */
4256
4257 printf(PID_FMT, i->control_pid);
4258
4259 if (arg_transport == BUS_TRANSPORT_LOCAL) {
4260 (void) get_process_comm(i->control_pid, &c);
4261 if (c)
4262 printf(" (%s)", c);
4263 }
4264 }
4265
4266 printf("\n");
4267 }
4268
4269 if (i->status_text)
4270 printf(" Status: \"%s\"\n", i->status_text);
4271 if (i->status_errno > 0)
4272 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
4273
4274 if (i->ip_ingress_bytes != (uint64_t) -1 && i->ip_egress_bytes != (uint64_t) -1) {
4275 char buf_in[FORMAT_BYTES_MAX], buf_out[FORMAT_BYTES_MAX];
4276
4277 printf(" IP: %s in, %s out\n",
4278 format_bytes(buf_in, sizeof(buf_in), i->ip_ingress_bytes),
4279 format_bytes(buf_out, sizeof(buf_out), i->ip_egress_bytes));
4280 }
4281
4282 if (i->tasks_current != (uint64_t) -1) {
4283 printf(" Tasks: %" PRIu64, i->tasks_current);
4284
4285 if (i->tasks_max != (uint64_t) -1)
4286 printf(" (limit: %" PRIu64 ")\n", i->tasks_max);
4287 else
4288 printf("\n");
4289 }
4290
4291 if (i->memory_current != (uint64_t) -1) {
4292 char buf[FORMAT_BYTES_MAX];
4293
4294 printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
4295
4296 if (i->memory_low > 0 || i->memory_high != CGROUP_LIMIT_MAX ||
4297 i->memory_max != CGROUP_LIMIT_MAX || i->memory_swap_max != CGROUP_LIMIT_MAX ||
4298 i->memory_limit != CGROUP_LIMIT_MAX) {
4299 const char *prefix = "";
4300
4301 printf(" (");
4302 if (i->memory_low > 0) {
4303 printf("%slow: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_low));
4304 prefix = " ";
4305 }
4306 if (i->memory_high != CGROUP_LIMIT_MAX) {
4307 printf("%shigh: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_high));
4308 prefix = " ";
4309 }
4310 if (i->memory_max != CGROUP_LIMIT_MAX) {
4311 printf("%smax: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_max));
4312 prefix = " ";
4313 }
4314 if (i->memory_swap_max != CGROUP_LIMIT_MAX) {
4315 printf("%sswap max: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_swap_max));
4316 prefix = " ";
4317 }
4318 if (i->memory_limit != CGROUP_LIMIT_MAX) {
4319 printf("%slimit: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_limit));
4320 prefix = " ";
4321 }
4322 printf(")");
4323 }
4324 printf("\n");
4325 }
4326
4327 if (i->cpu_usage_nsec != (uint64_t) -1) {
4328 char buf[FORMAT_TIMESPAN_MAX];
4329 printf(" CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
4330 }
4331
4332 if (i->control_group) {
4333 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4334 static const char prefix[] = " ";
4335 unsigned c;
4336
4337 printf(" CGroup: %s\n", i->control_group);
4338
4339 c = columns();
4340 if (c > sizeof(prefix) - 1)
4341 c -= sizeof(prefix) - 1;
4342 else
4343 c = 0;
4344
4345 r = unit_show_processes(bus, i->id, i->control_group, prefix, c, get_output_flags(), &error);
4346 if (r == -EBADR) {
4347 unsigned k = 0;
4348 pid_t extra[2];
4349
4350 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
4351
4352 if (i->main_pid > 0)
4353 extra[k++] = i->main_pid;
4354
4355 if (i->control_pid > 0)
4356 extra[k++] = i->control_pid;
4357
4358 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, extra, k, get_output_flags());
4359 } else if (r < 0)
4360 log_warning_errno(r, "Failed to dump process list, ignoring: %s", bus_error_message(&error, r));
4361 }
4362
4363 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL)
4364 show_journal_by_unit(
4365 stdout,
4366 i->id,
4367 arg_output,
4368 0,
4369 i->inactive_exit_timestamp_monotonic,
4370 arg_lines,
4371 getuid(),
4372 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
4373 SD_JOURNAL_LOCAL_ONLY,
4374 arg_scope == UNIT_FILE_SYSTEM,
4375 ellipsized);
4376
4377 if (i->need_daemon_reload)
4378 warn_unit_file_changed(i->id);
4379 }
4380
4381 static void show_unit_help(UnitStatusInfo *i) {
4382 char **p;
4383
4384 assert(i);
4385
4386 if (!i->documentation) {
4387 log_info("Documentation for %s not known.", i->id);
4388 return;
4389 }
4390
4391 STRV_FOREACH(p, i->documentation)
4392 if (startswith(*p, "man:"))
4393 show_man_page(*p + 4, false);
4394 else
4395 log_info("Can't show: %s", *p);
4396 }
4397
4398 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
4399 int r;
4400
4401 assert(name);
4402 assert(m);
4403 assert(i);
4404
4405 switch (contents[0]) {
4406
4407 case SD_BUS_TYPE_STRING: {
4408 const char *s;
4409
4410 r = sd_bus_message_read(m, "s", &s);
4411 if (r < 0)
4412 return bus_log_parse_error(r);
4413
4414 if (!isempty(s)) {
4415 if (streq(name, "Id"))
4416 i->id = s;
4417 else if (streq(name, "LoadState"))
4418 i->load_state = s;
4419 else if (streq(name, "ActiveState"))
4420 i->active_state = s;
4421 else if (streq(name, "SubState"))
4422 i->sub_state = s;
4423 else if (streq(name, "Description"))
4424 i->description = s;
4425 else if (streq(name, "FragmentPath"))
4426 i->fragment_path = s;
4427 else if (streq(name, "SourcePath"))
4428 i->source_path = s;
4429 #ifndef NOLEGACY
4430 else if (streq(name, "DefaultControlGroup")) {
4431 const char *e;
4432 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
4433 if (e)
4434 i->control_group = e;
4435 }
4436 #endif
4437 else if (streq(name, "ControlGroup"))
4438 i->control_group = s;
4439 else if (streq(name, "StatusText"))
4440 i->status_text = s;
4441 else if (streq(name, "PIDFile"))
4442 i->pid_file = s;
4443 else if (streq(name, "SysFSPath"))
4444 i->sysfs_path = s;
4445 else if (streq(name, "Where"))
4446 i->where = s;
4447 else if (streq(name, "What"))
4448 i->what = s;
4449 else if (streq(name, "Following"))
4450 i->following = s;
4451 else if (streq(name, "UnitFileState"))
4452 i->unit_file_state = s;
4453 else if (streq(name, "UnitFilePreset"))
4454 i->unit_file_preset = s;
4455 else if (streq(name, "Result"))
4456 i->result = s;
4457 }
4458
4459 break;
4460 }
4461
4462 case SD_BUS_TYPE_BOOLEAN: {
4463 int b;
4464
4465 r = sd_bus_message_read(m, "b", &b);
4466 if (r < 0)
4467 return bus_log_parse_error(r);
4468
4469 if (streq(name, "Accept"))
4470 i->accept = b;
4471 else if (streq(name, "NeedDaemonReload"))
4472 i->need_daemon_reload = b;
4473 else if (streq(name, "ConditionResult"))
4474 i->condition_result = b;
4475 else if (streq(name, "AssertResult"))
4476 i->assert_result = b;
4477 else if (streq(name, "Transient"))
4478 i->transient = b;
4479
4480 break;
4481 }
4482
4483 case SD_BUS_TYPE_UINT32: {
4484 uint32_t u;
4485
4486 r = sd_bus_message_read(m, "u", &u);
4487 if (r < 0)
4488 return bus_log_parse_error(r);
4489
4490 if (streq(name, "MainPID")) {
4491 if (u > 0) {
4492 i->main_pid = (pid_t) u;
4493 i->running = true;
4494 }
4495 } else if (streq(name, "ControlPID"))
4496 i->control_pid = (pid_t) u;
4497 else if (streq(name, "ExecMainPID")) {
4498 if (u > 0)
4499 i->main_pid = (pid_t) u;
4500 } else if (streq(name, "NAccepted"))
4501 i->n_accepted = u;
4502 else if (streq(name, "NConnections"))
4503 i->n_connections = u;
4504
4505 break;
4506 }
4507
4508 case SD_BUS_TYPE_INT32: {
4509 int32_t j;
4510
4511 r = sd_bus_message_read(m, "i", &j);
4512 if (r < 0)
4513 return bus_log_parse_error(r);
4514
4515 if (streq(name, "ExecMainCode"))
4516 i->exit_code = (int) j;
4517 else if (streq(name, "ExecMainStatus"))
4518 i->exit_status = (int) j;
4519 else if (streq(name, "StatusErrno"))
4520 i->status_errno = (int) j;
4521
4522 break;
4523 }
4524
4525 case SD_BUS_TYPE_UINT64: {
4526 uint64_t u;
4527
4528 r = sd_bus_message_read(m, "t", &u);
4529 if (r < 0)
4530 return bus_log_parse_error(r);
4531
4532 if (streq(name, "ExecMainStartTimestamp"))
4533 i->start_timestamp = (usec_t) u;
4534 else if (streq(name, "ExecMainExitTimestamp"))
4535 i->exit_timestamp = (usec_t) u;
4536 else if (streq(name, "ActiveEnterTimestamp"))
4537 i->active_enter_timestamp = (usec_t) u;
4538 else if (streq(name, "InactiveEnterTimestamp"))
4539 i->inactive_enter_timestamp = (usec_t) u;
4540 else if (streq(name, "InactiveExitTimestamp"))
4541 i->inactive_exit_timestamp = (usec_t) u;
4542 else if (streq(name, "InactiveExitTimestampMonotonic"))
4543 i->inactive_exit_timestamp_monotonic = (usec_t) u;
4544 else if (streq(name, "ActiveExitTimestamp"))
4545 i->active_exit_timestamp = (usec_t) u;
4546 else if (streq(name, "ConditionTimestamp"))
4547 i->condition_timestamp = (usec_t) u;
4548 else if (streq(name, "AssertTimestamp"))
4549 i->assert_timestamp = (usec_t) u;
4550 else if (streq(name, "MemoryCurrent"))
4551 i->memory_current = u;
4552 else if (streq(name, "MemoryLow"))
4553 i->memory_low = u;
4554 else if (streq(name, "MemoryHigh"))
4555 i->memory_high = u;
4556 else if (streq(name, "MemoryMax"))
4557 i->memory_max = u;
4558 else if (streq(name, "MemorySwapMax"))
4559 i->memory_swap_max = u;
4560 else if (streq(name, "MemoryLimit"))
4561 i->memory_limit = u;
4562 else if (streq(name, "TasksCurrent"))
4563 i->tasks_current = u;
4564 else if (streq(name, "TasksMax"))
4565 i->tasks_max = u;
4566 else if (streq(name, "CPUUsageNSec"))
4567 i->cpu_usage_nsec = u;
4568 else if (streq(name, "NextElapseUSecMonotonic"))
4569 i->next_elapse_monotonic = u;
4570 else if (streq(name, "NextElapseUSecRealtime"))
4571 i->next_elapse_real = u;
4572 else if (streq(name, "IPIngressBytes"))
4573 i->ip_ingress_bytes = u;
4574 else if (streq(name, "IPEgressBytes"))
4575 i->ip_egress_bytes = u;
4576
4577 break;
4578 }
4579
4580 case SD_BUS_TYPE_ARRAY:
4581
4582 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4583 _cleanup_free_ ExecStatusInfo *info = NULL;
4584
4585 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4586 if (r < 0)
4587 return bus_log_parse_error(r);
4588
4589 info = new0(ExecStatusInfo, 1);
4590 if (!info)
4591 return log_oom();
4592
4593 while ((r = exec_status_info_deserialize(m, info)) > 0) {
4594
4595 info->name = strdup(name);
4596 if (!info->name)
4597 return log_oom();
4598
4599 LIST_PREPEND(exec, i->exec, info);
4600
4601 info = new0(ExecStatusInfo, 1);
4602 if (!info)
4603 return log_oom();
4604 }
4605
4606 if (r < 0)
4607 return bus_log_parse_error(r);
4608
4609 r = sd_bus_message_exit_container(m);
4610 if (r < 0)
4611 return bus_log_parse_error(r);
4612
4613 return 0;
4614
4615 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4616 const char *type, *path;
4617
4618 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4619 if (r < 0)
4620 return bus_log_parse_error(r);
4621
4622 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
4623
4624 r = strv_extend(&i->listen, type);
4625 if (r < 0)
4626 return r;
4627
4628 r = strv_extend(&i->listen, path);
4629 if (r < 0)
4630 return r;
4631 }
4632 if (r < 0)
4633 return bus_log_parse_error(r);
4634
4635 r = sd_bus_message_exit_container(m);
4636 if (r < 0)
4637 return bus_log_parse_error(r);
4638
4639 return 0;
4640
4641 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
4642
4643 r = sd_bus_message_read_strv(m, &i->dropin_paths);
4644 if (r < 0)
4645 return bus_log_parse_error(r);
4646
4647 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
4648
4649 r = sd_bus_message_read_strv(m, &i->documentation);
4650 if (r < 0)
4651 return bus_log_parse_error(r);
4652
4653 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
4654 const char *cond, *param;
4655 int trigger, negate;
4656 int32_t state;
4657
4658 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
4659 if (r < 0)
4660 return bus_log_parse_error(r);
4661
4662 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
4663 _cleanup_(unit_condition_freep) UnitCondition *c = NULL;
4664
4665 log_debug("%s trigger=%d negate=%d %s →%d", cond, trigger, negate, param, state);
4666
4667 c = new0(UnitCondition, 1);
4668 if (!c)
4669 return log_oom();
4670
4671 c->name = strdup(cond);
4672 c->param = strdup(param);
4673 if (!c->name || !c->param)
4674 return log_oom();
4675
4676 c->trigger = trigger;
4677 c->negate = negate;
4678 c->tristate = state;
4679
4680 LIST_PREPEND(conditions, i->conditions, c);
4681 c = NULL;
4682 }
4683 if (r < 0)
4684 return bus_log_parse_error(r);
4685
4686 r = sd_bus_message_exit_container(m);
4687 if (r < 0)
4688 return bus_log_parse_error(r);
4689
4690 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
4691 const char *cond, *param;
4692 int trigger, negate;
4693 int32_t state;
4694
4695 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
4696 if (r < 0)
4697 return bus_log_parse_error(r);
4698
4699 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
4700 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
4701 if (state < 0 && (!trigger || !i->failed_assert)) {
4702 i->failed_assert = cond;
4703 i->failed_assert_trigger = trigger;
4704 i->failed_assert_negate = negate;
4705 i->failed_assert_parameter = param;
4706 }
4707 }
4708 if (r < 0)
4709 return bus_log_parse_error(r);
4710
4711 r = sd_bus_message_exit_container(m);
4712 if (r < 0)
4713 return bus_log_parse_error(r);
4714
4715 } else
4716 goto skip;
4717
4718 break;
4719
4720 case SD_BUS_TYPE_STRUCT_BEGIN:
4721
4722 if (streq(name, "LoadError")) {
4723 const char *n, *message;
4724
4725 r = sd_bus_message_read(m, "(ss)", &n, &message);
4726 if (r < 0)
4727 return bus_log_parse_error(r);
4728
4729 if (!isempty(message))
4730 i->load_error = message;
4731 } else
4732 goto skip;
4733
4734 break;
4735
4736 default:
4737 goto skip;
4738 }
4739
4740 return 0;
4741
4742 skip:
4743 r = sd_bus_message_skip(m, contents);
4744 if (r < 0)
4745 return bus_log_parse_error(r);
4746
4747 return 0;
4748 }
4749
4750 #define print_prop(name, fmt, ...) \
4751 do { \
4752 if (arg_value) \
4753 printf(fmt "\n", __VA_ARGS__); \
4754 else \
4755 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4756 } while (0)
4757
4758 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
4759 int r;
4760
4761 assert(name);
4762 assert(m);
4763
4764 /* This is a low-level property printer, see
4765 * print_status_info() for the nicer output */
4766
4767 if (arg_properties && !strv_find(arg_properties, name)) {
4768 /* skip what we didn't read */
4769 r = sd_bus_message_skip(m, contents);
4770 return r;
4771 }
4772
4773 switch (contents[0]) {
4774
4775 case SD_BUS_TYPE_STRUCT_BEGIN:
4776
4777 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
4778 uint32_t u;
4779
4780 r = sd_bus_message_read(m, "(uo)", &u, NULL);
4781 if (r < 0)
4782 return bus_log_parse_error(r);
4783
4784 if (u > 0)
4785 print_prop(name, "%"PRIu32, u);
4786 else if (arg_all)
4787 print_prop(name, "%s", "");
4788
4789 return 0;
4790
4791 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
4792 const char *s;
4793
4794 r = sd_bus_message_read(m, "(so)", &s, NULL);
4795 if (r < 0)
4796 return bus_log_parse_error(r);
4797
4798 if (arg_all || !isempty(s))
4799 print_prop(name, "%s", s);
4800
4801 return 0;
4802
4803 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
4804 const char *a = NULL, *b = NULL;
4805
4806 r = sd_bus_message_read(m, "(ss)", &a, &b);
4807 if (r < 0)
4808 return bus_log_parse_error(r);
4809
4810 if (arg_all || !isempty(a) || !isempty(b))
4811 print_prop(name, "%s \"%s\"", strempty(a), strempty(b));
4812
4813 return 0;
4814 } else if (streq_ptr(name, "SystemCallFilter")) {
4815 _cleanup_strv_free_ char **l = NULL;
4816 int whitelist;
4817
4818 r = sd_bus_message_enter_container(m, 'r', "bas");
4819 if (r < 0)
4820 return bus_log_parse_error(r);
4821
4822 r = sd_bus_message_read(m, "b", &whitelist);
4823 if (r < 0)
4824 return bus_log_parse_error(r);
4825
4826 r = sd_bus_message_read_strv(m, &l);
4827 if (r < 0)
4828 return bus_log_parse_error(r);
4829
4830 r = sd_bus_message_exit_container(m);
4831 if (r < 0)
4832 return bus_log_parse_error(r);
4833
4834 if (arg_all || whitelist || !strv_isempty(l)) {
4835 bool first = true;
4836 char **i;
4837
4838 if (!arg_value) {
4839 fputs(name, stdout);
4840 fputc('=', stdout);
4841 }
4842
4843 if (!whitelist)
4844 fputc('~', stdout);
4845
4846 STRV_FOREACH(i, l) {
4847 if (first)
4848 first = false;
4849 else
4850 fputc(' ', stdout);
4851
4852 fputs(*i, stdout);
4853 }
4854 fputc('\n', stdout);
4855 }
4856
4857 return 0;
4858 }
4859
4860 break;
4861
4862 case SD_BUS_TYPE_ARRAY:
4863
4864 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4865 const char *path;
4866 int ignore;
4867
4868 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4869 if (r < 0)
4870 return bus_log_parse_error(r);
4871
4872 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4873 print_prop("EnvironmentFile", "%s (ignore_errors=%s)", path, yes_no(ignore));
4874
4875 if (r < 0)
4876 return bus_log_parse_error(r);
4877
4878 r = sd_bus_message_exit_container(m);
4879 if (r < 0)
4880 return bus_log_parse_error(r);
4881
4882 return 0;
4883
4884 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4885 const char *type, *path;
4886
4887 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4888 if (r < 0)
4889 return bus_log_parse_error(r);
4890
4891 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4892 print_prop(type, "%s", path);
4893 if (r < 0)
4894 return bus_log_parse_error(r);
4895
4896 r = sd_bus_message_exit_container(m);
4897 if (r < 0)
4898 return bus_log_parse_error(r);
4899
4900 return 0;
4901
4902 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4903 const char *type, *path;
4904
4905 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4906 if (r < 0)
4907 return bus_log_parse_error(r);
4908
4909 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4910 if (arg_value)
4911 puts(path);
4912 else
4913 printf("Listen%s=%s\n", type, path);
4914 if (r < 0)
4915 return bus_log_parse_error(r);
4916
4917 r = sd_bus_message_exit_container(m);
4918 if (r < 0)
4919 return bus_log_parse_error(r);
4920
4921 return 0;
4922
4923 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "TimersMonotonic")) {
4924 const char *base;
4925 uint64_t value, next_elapse;
4926
4927 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4928 if (r < 0)
4929 return bus_log_parse_error(r);
4930
4931 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4932 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4933
4934 print_prop(name, "{ %s=%s ; next_elapse=%s }", base,
4935 format_timespan(timespan1, sizeof(timespan1), value, 0),
4936 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4937 }
4938 if (r < 0)
4939 return bus_log_parse_error(r);
4940
4941 r = sd_bus_message_exit_container(m);
4942 if (r < 0)
4943 return bus_log_parse_error(r);
4944
4945 return 0;
4946
4947 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "TimersCalendar")) {
4948 const char *base, *spec;
4949 uint64_t next_elapse;
4950
4951 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sst)");
4952 if (r < 0)
4953 return bus_log_parse_error(r);
4954
4955 while ((r = sd_bus_message_read(m, "(sst)", &base, &spec, &next_elapse)) > 0) {
4956 char timestamp[FORMAT_TIMESTAMP_MAX];
4957
4958 print_prop(name, "{ %s=%s ; next_elapse=%s }", base, spec,
4959 format_timestamp(timestamp, sizeof(timestamp), next_elapse));
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 const char *name;
6069 unsigned c = 1;
6070 pid_t pid;
6071 int j;
6072
6073 name = args[f++];
6074
6075 if (!endswith(name, ".service"))
6076 continue;
6077
6078 if (path_is_absolute(name))
6079 continue;
6080
6081 j = unit_file_exists(arg_scope, &paths, name);
6082 if (j < 0 && !IN_SET(j, -ELOOP, -ERFKILL, -EADDRNOTAVAIL))
6083 return log_error_errno(j, "Failed to lookup unit file state: %m");
6084 found_native = j != 0;
6085
6086 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
6087 * prefer the native unit */
6088 if (found_native && streq(verb, "is-enabled"))
6089 continue;
6090
6091 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
6092 if (!p)
6093 return log_oom();
6094
6095 p[strlen(p) - STRLEN(".service")] = 0;
6096 found_sysv = access(p, F_OK) >= 0;
6097 if (!found_sysv)
6098 continue;
6099
6100 if (!arg_quiet) {
6101 if (found_native)
6102 log_info("Synchronizing state of %s with SysV service script with %s.", name, argv[0]);
6103 else
6104 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name);
6105 }
6106
6107 if (!isempty(arg_root))
6108 argv[c++] = q = strappend("--root=", arg_root);
6109
6110 argv[c++] = verb;
6111 argv[c++] = basename(p);
6112 argv[c] = NULL;
6113
6114 l = strv_join((char**)argv, " ");
6115 if (!l)
6116 return log_oom();
6117
6118 if (!arg_quiet)
6119 log_info("Executing: %s", l);
6120
6121 j = safe_fork("(sysv-install)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
6122 if (j < 0)
6123 return j;
6124 if (j == 0) {
6125 /* Child */
6126 execv(argv[0], (char**) argv);
6127 log_error_errno(errno, "Failed to execute %s: %m", argv[0]);
6128 _exit(EXIT_FAILURE);
6129 }
6130
6131 j = wait_for_terminate_and_check("sysv-install", pid, WAIT_LOG_ABNORMAL);
6132 if (j < 0)
6133 return j;
6134 if (streq(verb, "is-enabled")) {
6135 if (j == EXIT_SUCCESS) {
6136 if (!arg_quiet)
6137 puts("enabled");
6138 r = 1;
6139 } else {
6140 if (!arg_quiet)
6141 puts("disabled");
6142 }
6143
6144 } else if (j != EXIT_SUCCESS)
6145 return -EBADE; /* We don't warn here, under the assumption the script already showed an explanation */
6146
6147 if (found_native)
6148 continue;
6149
6150 /* Remove this entry, so that we don't try enabling it as native unit */
6151 assert(f > 0);
6152 f--;
6153 assert(args[f] == name);
6154 strv_remove(args, name);
6155 }
6156
6157 #endif
6158 return r;
6159 }
6160
6161 static int mangle_names(char **original_names, char ***mangled_names) {
6162 char **i, **l, **name;
6163 int r;
6164
6165 l = i = new(char*, strv_length(original_names) + 1);
6166 if (!l)
6167 return log_oom();
6168
6169 STRV_FOREACH(name, original_names) {
6170
6171 /* When enabling units qualified path names are OK,
6172 * too, hence allow them explicitly. */
6173
6174 if (is_path(*name)) {
6175 *i = strdup(*name);
6176 if (!*i) {
6177 strv_free(l);
6178 return log_oom();
6179 }
6180 } else {
6181 r = unit_name_mangle(*name, UNIT_NAME_NOGLOB, i);
6182 if (r < 0) {
6183 *i = NULL;
6184 strv_free(l);
6185 return log_error_errno(r, "Failed to mangle unit name: %m");
6186 }
6187 }
6188
6189 i++;
6190 }
6191
6192 *i = NULL;
6193 *mangled_names = l;
6194
6195 return 0;
6196 }
6197
6198 static int normalize_filenames(char **names) {
6199 char **u;
6200 int r;
6201
6202 STRV_FOREACH(u, names)
6203 if (!path_is_absolute(*u)) {
6204 char* normalized_path;
6205
6206 if (!isempty(arg_root)) {
6207 log_error("Non-absolute paths are not allowed when --root is used: %s", *u);
6208 return -EINVAL;
6209 }
6210
6211 if (!strchr(*u,'/')) {
6212 log_error("Link argument does contain at least one directory separator: %s", *u);
6213 return -EINVAL;
6214 }
6215
6216 r = path_make_absolute_cwd(*u, &normalized_path);
6217 if (r < 0)
6218 return r;
6219
6220 free_and_replace(*u, normalized_path);
6221 }
6222
6223 return 0;
6224 }
6225
6226 static int normalize_names(char **names, bool warn_if_path) {
6227 char **u;
6228 bool was_path = false;
6229
6230 STRV_FOREACH(u, names) {
6231 int r;
6232
6233 if (!is_path(*u))
6234 continue;
6235
6236 r = free_and_strdup(u, basename(*u));
6237 if (r < 0)
6238 return log_error_errno(r, "Failed to normalize unit file path: %m");
6239
6240 was_path = true;
6241 }
6242
6243 if (warn_if_path && was_path)
6244 log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
6245
6246 return 0;
6247 }
6248
6249 static int unit_exists(LookupPaths *lp, const char *unit) {
6250 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6251 _cleanup_free_ char *path = NULL;
6252 static const struct bus_properties_map property_map[] = {
6253 { "LoadState", "s", map_string_no_copy, offsetof(UnitStatusInfo, load_state) },
6254 { "ActiveState", "s", map_string_no_copy, offsetof(UnitStatusInfo, active_state)},
6255 {},
6256 };
6257 UnitStatusInfo info = {};
6258 sd_bus *bus;
6259 int r;
6260
6261 if (unit_name_is_valid(unit, UNIT_NAME_TEMPLATE))
6262 return unit_find_template_path(unit, lp, NULL, NULL);
6263
6264 path = unit_dbus_path_from_name(unit);
6265 if (!path)
6266 return log_oom();
6267
6268 r = acquire_bus(BUS_MANAGER, &bus);
6269 if (r < 0)
6270 return r;
6271
6272 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", path, property_map, &error, &info);
6273 if (r < 0)
6274 return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
6275
6276 return !streq_ptr(info.load_state, "not-found") || !streq_ptr(info.active_state, "inactive");
6277 }
6278
6279 static int enable_unit(int argc, char *argv[], void *userdata) {
6280 _cleanup_strv_free_ char **names = NULL;
6281 const char *verb = argv[0];
6282 UnitFileChange *changes = NULL;
6283 unsigned n_changes = 0;
6284 int carries_install_info = -1;
6285 bool ignore_carries_install_info = arg_quiet;
6286 int r;
6287
6288 if (!argv[1])
6289 return 0;
6290
6291 r = mangle_names(strv_skip(argv, 1), &names);
6292 if (r < 0)
6293 return r;
6294
6295 r = enable_sysv_units(verb, names);
6296 if (r < 0)
6297 return r;
6298
6299 /* If the operation was fully executed by the SysV compat, let's finish early */
6300 if (strv_isempty(names)) {
6301 if (arg_no_reload || install_client_side())
6302 return 0;
6303 return daemon_reload(argc, argv, userdata);
6304 }
6305
6306 if (streq(verb, "disable")) {
6307 r = normalize_names(names, true);
6308 if (r < 0)
6309 return r;
6310 }
6311
6312 if (streq(verb, "link")) {
6313 r = normalize_filenames(names);
6314 if (r < 0)
6315 return r;
6316 }
6317
6318 if (install_client_side()) {
6319 UnitFileFlags flags;
6320
6321 flags = args_to_flags();
6322 if (streq(verb, "enable")) {
6323 r = unit_file_enable(arg_scope, flags, arg_root, names, &changes, &n_changes);
6324 carries_install_info = r;
6325 } else if (streq(verb, "disable"))
6326 r = unit_file_disable(arg_scope, flags, arg_root, names, &changes, &n_changes);
6327 else if (streq(verb, "reenable")) {
6328 r = unit_file_reenable(arg_scope, flags, arg_root, names, &changes, &n_changes);
6329 carries_install_info = r;
6330 } else if (streq(verb, "link"))
6331 r = unit_file_link(arg_scope, flags, arg_root, names, &changes, &n_changes);
6332 else if (streq(verb, "preset")) {
6333 r = unit_file_preset(arg_scope, flags, arg_root, names, arg_preset_mode, &changes, &n_changes);
6334 } else if (streq(verb, "mask"))
6335 r = unit_file_mask(arg_scope, flags, arg_root, names, &changes, &n_changes);
6336 else if (streq(verb, "unmask"))
6337 r = unit_file_unmask(arg_scope, flags, arg_root, names, &changes, &n_changes);
6338 else if (streq(verb, "revert"))
6339 r = unit_file_revert(arg_scope, arg_root, names, &changes, &n_changes);
6340 else
6341 assert_not_reached("Unknown verb");
6342
6343 unit_file_dump_changes(r, verb, changes, n_changes, arg_quiet);
6344 if (r < 0)
6345 goto finish;
6346 r = 0;
6347 } else {
6348 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
6349 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6350 bool expect_carries_install_info = false;
6351 bool send_runtime = true, send_force = true, send_preset_mode = false;
6352 const char *method;
6353 sd_bus *bus;
6354
6355 if (STR_IN_SET(verb, "mask", "unmask")) {
6356 char **name;
6357 _cleanup_lookup_paths_free_ LookupPaths lp = {};
6358
6359 r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
6360 if (r < 0)
6361 return r;
6362
6363 STRV_FOREACH(name, names) {
6364 r = unit_exists(&lp, *name);
6365 if (r < 0)
6366 return r;
6367 if (r == 0)
6368 log_notice("Unit %s does not exist, proceeding anyway.", *names);
6369 }
6370 }
6371
6372 r = acquire_bus(BUS_MANAGER, &bus);
6373 if (r < 0)
6374 return r;
6375
6376 polkit_agent_open_maybe();
6377
6378 if (streq(verb, "enable")) {
6379 method = "EnableUnitFiles";
6380 expect_carries_install_info = true;
6381 } else if (streq(verb, "disable")) {
6382 method = "DisableUnitFiles";
6383 send_force = false;
6384 } else if (streq(verb, "reenable")) {
6385 method = "ReenableUnitFiles";
6386 expect_carries_install_info = true;
6387 } else if (streq(verb, "link"))
6388 method = "LinkUnitFiles";
6389 else if (streq(verb, "preset")) {
6390
6391 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
6392 method = "PresetUnitFilesWithMode";
6393 send_preset_mode = true;
6394 } else
6395 method = "PresetUnitFiles";
6396
6397 expect_carries_install_info = true;
6398 ignore_carries_install_info = true;
6399 } else if (streq(verb, "mask"))
6400 method = "MaskUnitFiles";
6401 else if (streq(verb, "unmask")) {
6402 method = "UnmaskUnitFiles";
6403 send_force = false;
6404 } else if (streq(verb, "revert")) {
6405 method = "RevertUnitFiles";
6406 send_runtime = send_force = false;
6407 } else
6408 assert_not_reached("Unknown verb");
6409
6410 r = sd_bus_message_new_method_call(
6411 bus,
6412 &m,
6413 "org.freedesktop.systemd1",
6414 "/org/freedesktop/systemd1",
6415 "org.freedesktop.systemd1.Manager",
6416 method);
6417 if (r < 0)
6418 return bus_log_create_error(r);
6419
6420 r = sd_bus_message_append_strv(m, names);
6421 if (r < 0)
6422 return bus_log_create_error(r);
6423
6424 if (send_preset_mode) {
6425 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
6426 if (r < 0)
6427 return bus_log_create_error(r);
6428 }
6429
6430 if (send_runtime) {
6431 r = sd_bus_message_append(m, "b", arg_runtime);
6432 if (r < 0)
6433 return bus_log_create_error(r);
6434 }
6435
6436 if (send_force) {
6437 r = sd_bus_message_append(m, "b", arg_force);
6438 if (r < 0)
6439 return bus_log_create_error(r);
6440 }
6441
6442 r = sd_bus_call(bus, m, 0, &error, &reply);
6443 if (r < 0)
6444 return log_error_errno(r, "Failed to %s unit: %s", verb, bus_error_message(&error, r));
6445
6446 if (expect_carries_install_info) {
6447 r = sd_bus_message_read(reply, "b", &carries_install_info);
6448 if (r < 0)
6449 return bus_log_parse_error(r);
6450 }
6451
6452 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
6453 if (r < 0)
6454 goto finish;
6455
6456 /* Try to reload if enabled */
6457 if (!arg_no_reload)
6458 r = daemon_reload(argc, argv, userdata);
6459 else
6460 r = 0;
6461 }
6462
6463 if (carries_install_info == 0 && !ignore_carries_install_info)
6464 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
6465 "settings in the [Install] section, and DefaultInstance for template units).\n"
6466 "This means they are not meant to be enabled using systemctl.\n"
6467 "Possible reasons for having this kind of units are:\n"
6468 "1) A unit may be statically enabled by being symlinked from another unit's\n"
6469 " .wants/ or .requires/ directory.\n"
6470 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
6471 " a requirement dependency on it.\n"
6472 "3) A unit may be started when needed via activation (socket, path, timer,\n"
6473 " D-Bus, udev, scripted systemctl call, ...).\n"
6474 "4) In case of template units, the unit is meant to be enabled with some\n"
6475 " instance name specified.");
6476
6477 if (arg_now && STR_IN_SET(argv[0], "enable", "disable", "mask")) {
6478 sd_bus *bus;
6479 unsigned len, i;
6480
6481 r = acquire_bus(BUS_MANAGER, &bus);
6482 if (r < 0)
6483 goto finish;
6484
6485 len = strv_length(names);
6486 {
6487 char *new_args[len + 2];
6488
6489 new_args[0] = (char*) (streq(argv[0], "enable") ? "start" : "stop");
6490 for (i = 0; i < len; i++)
6491 new_args[i + 1] = basename(names[i]);
6492 new_args[i + 1] = NULL;
6493
6494 r = start_unit(len + 1, new_args, userdata);
6495 }
6496 }
6497
6498 finish:
6499 unit_file_changes_free(changes, n_changes);
6500
6501 return r;
6502 }
6503
6504 static int add_dependency(int argc, char *argv[], void *userdata) {
6505 _cleanup_strv_free_ char **names = NULL;
6506 _cleanup_free_ char *target = NULL;
6507 const char *verb = argv[0];
6508 UnitFileChange *changes = NULL;
6509 unsigned n_changes = 0;
6510 UnitDependency dep;
6511 int r = 0;
6512
6513 if (!argv[1])
6514 return 0;
6515
6516 r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".target", &target);
6517 if (r < 0)
6518 return log_error_errno(r, "Failed to mangle unit name: %m");
6519
6520 r = mangle_names(strv_skip(argv, 2), &names);
6521 if (r < 0)
6522 return r;
6523
6524 if (streq(verb, "add-wants"))
6525 dep = UNIT_WANTS;
6526 else if (streq(verb, "add-requires"))
6527 dep = UNIT_REQUIRES;
6528 else
6529 assert_not_reached("Unknown verb");
6530
6531 if (install_client_side()) {
6532 r = unit_file_add_dependency(arg_scope, args_to_flags(), arg_root, names, target, dep, &changes, &n_changes);
6533 unit_file_dump_changes(r, "add dependency on", changes, n_changes, arg_quiet);
6534
6535 if (r > 0)
6536 r = 0;
6537 } else {
6538 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
6539 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6540 sd_bus *bus;
6541
6542 r = acquire_bus(BUS_MANAGER, &bus);
6543 if (r < 0)
6544 return r;
6545
6546 polkit_agent_open_maybe();
6547
6548 r = sd_bus_message_new_method_call(
6549 bus,
6550 &m,
6551 "org.freedesktop.systemd1",
6552 "/org/freedesktop/systemd1",
6553 "org.freedesktop.systemd1.Manager",
6554 "AddDependencyUnitFiles");
6555 if (r < 0)
6556 return bus_log_create_error(r);
6557
6558 r = sd_bus_message_append_strv(m, names);
6559 if (r < 0)
6560 return bus_log_create_error(r);
6561
6562 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
6563 if (r < 0)
6564 return bus_log_create_error(r);
6565
6566 r = sd_bus_call(bus, m, 0, &error, &reply);
6567 if (r < 0)
6568 return log_error_errno(r, "Failed to add dependency: %s", bus_error_message(&error, r));
6569
6570 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
6571 if (r < 0)
6572 goto finish;
6573
6574 if (arg_no_reload) {
6575 r = 0;
6576 goto finish;
6577 }
6578
6579 r = daemon_reload(argc, argv, userdata);
6580 }
6581
6582 finish:
6583 unit_file_changes_free(changes, n_changes);
6584
6585 return r;
6586 }
6587
6588 static int preset_all(int argc, char *argv[], void *userdata) {
6589 UnitFileChange *changes = NULL;
6590 unsigned n_changes = 0;
6591 int r;
6592
6593 if (install_client_side()) {
6594 r = unit_file_preset_all(arg_scope, args_to_flags(), arg_root, arg_preset_mode, &changes, &n_changes);
6595 unit_file_dump_changes(r, "preset", changes, n_changes, arg_quiet);
6596
6597 if (r > 0)
6598 r = 0;
6599 } else {
6600 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6601 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
6602 sd_bus *bus;
6603
6604 r = acquire_bus(BUS_MANAGER, &bus);
6605 if (r < 0)
6606 return r;
6607
6608 polkit_agent_open_maybe();
6609
6610 r = sd_bus_call_method(
6611 bus,
6612 "org.freedesktop.systemd1",
6613 "/org/freedesktop/systemd1",
6614 "org.freedesktop.systemd1.Manager",
6615 "PresetAllUnitFiles",
6616 &error,
6617 &reply,
6618 "sbb",
6619 unit_file_preset_mode_to_string(arg_preset_mode),
6620 arg_runtime,
6621 arg_force);
6622 if (r < 0)
6623 return log_error_errno(r, "Failed to preset all units: %s", bus_error_message(&error, r));
6624
6625 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
6626 if (r < 0)
6627 goto finish;
6628
6629 if (arg_no_reload) {
6630 r = 0;
6631 goto finish;
6632 }
6633
6634 r = daemon_reload(argc, argv, userdata);
6635 }
6636
6637 finish:
6638 unit_file_changes_free(changes, n_changes);
6639
6640 return r;
6641 }
6642
6643 static int show_installation_targets_client_side(const char *name) {
6644 UnitFileChange *changes = NULL;
6645 unsigned n_changes = 0, i;
6646 UnitFileFlags flags;
6647 char **p;
6648 int r;
6649
6650 p = STRV_MAKE(name);
6651 flags = UNIT_FILE_DRY_RUN |
6652 (arg_runtime ? UNIT_FILE_RUNTIME : 0);
6653
6654 r = unit_file_disable(UNIT_FILE_SYSTEM, flags, NULL, p, &changes, &n_changes);
6655 if (r < 0)
6656 return log_error_errno(r, "Failed to get file links for %s: %m", name);
6657
6658 for (i = 0; i < n_changes; i++)
6659 if (changes[i].type == UNIT_FILE_UNLINK)
6660 printf(" %s\n", changes[i].path);
6661
6662 return 0;
6663 }
6664
6665 static int show_installation_targets(sd_bus *bus, const char *name) {
6666 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
6667 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6668 const char *link;
6669 int r;
6670
6671 r = sd_bus_call_method(
6672 bus,
6673 "org.freedesktop.systemd1",
6674 "/org/freedesktop/systemd1",
6675 "org.freedesktop.systemd1.Manager",
6676 "GetUnitFileLinks",
6677 &error,
6678 &reply,
6679 "sb", name, arg_runtime);
6680 if (r < 0)
6681 return log_error_errno(r, "Failed to get unit file links for %s: %s", name, bus_error_message(&error, r));
6682
6683 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
6684 if (r < 0)
6685 return bus_log_parse_error(r);
6686
6687 while ((r = sd_bus_message_read(reply, "s", &link)) > 0)
6688 printf(" %s\n", link);
6689
6690 if (r < 0)
6691 return bus_log_parse_error(r);
6692
6693 r = sd_bus_message_exit_container(reply);
6694 if (r < 0)
6695 return bus_log_parse_error(r);
6696
6697 return 0;
6698 }
6699
6700 static int unit_is_enabled(int argc, char *argv[], void *userdata) {
6701
6702 _cleanup_strv_free_ char **names = NULL;
6703 bool enabled;
6704 char **name;
6705 int r;
6706
6707 r = mangle_names(strv_skip(argv, 1), &names);
6708 if (r < 0)
6709 return r;
6710
6711 r = enable_sysv_units(argv[0], names);
6712 if (r < 0)
6713 return r;
6714
6715 enabled = r > 0;
6716
6717 if (install_client_side()) {
6718 STRV_FOREACH(name, names) {
6719 UnitFileState state;
6720
6721 r = unit_file_get_state(arg_scope, arg_root, *name, &state);
6722 if (r < 0)
6723 return log_error_errno(r, "Failed to get unit file state for %s: %m", *name);
6724
6725 if (IN_SET(state,
6726 UNIT_FILE_ENABLED,
6727 UNIT_FILE_ENABLED_RUNTIME,
6728 UNIT_FILE_STATIC,
6729 UNIT_FILE_INDIRECT,
6730 UNIT_FILE_GENERATED))
6731 enabled = true;
6732
6733 if (!arg_quiet) {
6734 puts(unit_file_state_to_string(state));
6735 if (arg_full) {
6736 r = show_installation_targets_client_side(*name);
6737 if (r < 0)
6738 return r;
6739 }
6740 }
6741 }
6742
6743 r = 0;
6744 } else {
6745 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6746 sd_bus *bus;
6747
6748 r = acquire_bus(BUS_MANAGER, &bus);
6749 if (r < 0)
6750 return r;
6751
6752 STRV_FOREACH(name, names) {
6753 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
6754 const char *s;
6755
6756 r = sd_bus_call_method(
6757 bus,
6758 "org.freedesktop.systemd1",
6759 "/org/freedesktop/systemd1",
6760 "org.freedesktop.systemd1.Manager",
6761 "GetUnitFileState",
6762 &error,
6763 &reply,
6764 "s", *name);
6765 if (r < 0)
6766 return log_error_errno(r, "Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
6767
6768 r = sd_bus_message_read(reply, "s", &s);
6769 if (r < 0)
6770 return bus_log_parse_error(r);
6771
6772 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect", "generated"))
6773 enabled = true;
6774
6775 if (!arg_quiet) {
6776 puts(s);
6777 if (arg_full) {
6778 r = show_installation_targets(bus, *name);
6779 if (r < 0)
6780 return r;
6781 }
6782 }
6783 }
6784 }
6785
6786 return enabled ? EXIT_SUCCESS : EXIT_FAILURE;
6787 }
6788
6789 static int is_system_running(int argc, char *argv[], void *userdata) {
6790 _cleanup_free_ char *state = NULL;
6791 sd_bus *bus;
6792 int r;
6793
6794 if (running_in_chroot() > 0 || (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted())) {
6795 if (!arg_quiet)
6796 puts("offline");
6797 return EXIT_FAILURE;
6798 }
6799
6800 r = acquire_bus(BUS_MANAGER, &bus);
6801 if (r < 0)
6802 return r;
6803
6804 r = sd_bus_get_property_string(
6805 bus,
6806 "org.freedesktop.systemd1",
6807 "/org/freedesktop/systemd1",
6808 "org.freedesktop.systemd1.Manager",
6809 "SystemState",
6810 NULL,
6811 &state);
6812 if (r < 0) {
6813 if (!arg_quiet)
6814 puts("unknown");
6815 return 0;
6816 }
6817
6818 if (!arg_quiet)
6819 puts(state);
6820
6821 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
6822 }
6823
6824 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
6825 _cleanup_free_ char *t = NULL;
6826 int r;
6827
6828 assert(new_path);
6829 assert(original_path);
6830 assert(ret_tmp_fn);
6831
6832 r = tempfn_random(new_path, NULL, &t);
6833 if (r < 0)
6834 return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
6835
6836 r = mkdir_parents(new_path, 0755);
6837 if (r < 0)
6838 return log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
6839
6840 r = copy_file(original_path, t, 0, 0644, 0, COPY_REFLINK);
6841 if (r == -ENOENT) {
6842
6843 r = touch(t);
6844 if (r < 0)
6845 return log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
6846
6847 } else if (r < 0)
6848 return log_error_errno(r, "Failed to create temporary file for \"%s\": %m", new_path);
6849
6850 *ret_tmp_fn = t;
6851 t = NULL;
6852
6853 return 0;
6854 }
6855
6856 static int get_file_to_edit(
6857 const LookupPaths *paths,
6858 const char *name,
6859 char **ret_path) {
6860
6861 _cleanup_free_ char *path = NULL, *run = NULL;
6862
6863 assert(name);
6864 assert(ret_path);
6865
6866 path = strjoin(paths->persistent_config, "/", name);
6867 if (!path)
6868 return log_oom();
6869
6870 if (arg_runtime) {
6871 run = strjoin(paths->runtime_config, "/", name);
6872 if (!run)
6873 return log_oom();
6874 }
6875
6876 if (arg_runtime) {
6877 if (access(path, F_OK) >= 0) {
6878 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path);
6879 return -EEXIST;
6880 }
6881
6882 *ret_path = run;
6883 run = NULL;
6884 } else {
6885 *ret_path = path;
6886 path = NULL;
6887 }
6888
6889 return 0;
6890 }
6891
6892 static int unit_file_create_new(
6893 const LookupPaths *paths,
6894 const char *unit_name,
6895 const char *suffix,
6896 char **ret_new_path,
6897 char **ret_tmp_path) {
6898
6899 char *tmp_new_path, *tmp_tmp_path, *ending;
6900 int r;
6901
6902 assert(unit_name);
6903 assert(ret_new_path);
6904 assert(ret_tmp_path);
6905
6906 ending = strjoina(unit_name, suffix);
6907 r = get_file_to_edit(paths, ending, &tmp_new_path);
6908 if (r < 0)
6909 return r;
6910
6911 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
6912 if (r < 0) {
6913 free(tmp_new_path);
6914 return r;
6915 }
6916
6917 *ret_new_path = tmp_new_path;
6918 *ret_tmp_path = tmp_tmp_path;
6919
6920 return 0;
6921 }
6922
6923 static int unit_file_create_copy(
6924 const LookupPaths *paths,
6925 const char *unit_name,
6926 const char *fragment_path,
6927 char **ret_new_path,
6928 char **ret_tmp_path) {
6929
6930 char *tmp_new_path, *tmp_tmp_path;
6931 int r;
6932
6933 assert(fragment_path);
6934 assert(unit_name);
6935 assert(ret_new_path);
6936 assert(ret_tmp_path);
6937
6938 r = get_file_to_edit(paths, unit_name, &tmp_new_path);
6939 if (r < 0)
6940 return r;
6941
6942 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
6943 char response;
6944
6945 r = ask_char(&response, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path, fragment_path);
6946 if (r < 0) {
6947 free(tmp_new_path);
6948 return r;
6949 }
6950 if (response != 'y') {
6951 log_warning("%s ignored", unit_name);
6952 free(tmp_new_path);
6953 return -EKEYREJECTED;
6954 }
6955 }
6956
6957 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
6958 if (r < 0) {
6959 free(tmp_new_path);
6960 return r;
6961 }
6962
6963 *ret_new_path = tmp_new_path;
6964 *ret_tmp_path = tmp_tmp_path;
6965
6966 return 0;
6967 }
6968
6969 static int run_editor(char **paths) {
6970 int r;
6971
6972 assert(paths);
6973
6974 r = safe_fork("(editor)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
6975 if (r < 0)
6976 return r;
6977 if (r == 0) {
6978 const char **args;
6979 char *editor, **editor_args = NULL;
6980 char **tmp_path, **original_path, *p;
6981 unsigned n_editor_args = 0, i = 1;
6982 size_t argc;
6983
6984 argc = strv_length(paths)/2 + 1;
6985
6986 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6987 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6988 * we try to execute well known editors
6989 */
6990 editor = getenv("SYSTEMD_EDITOR");
6991 if (!editor)
6992 editor = getenv("EDITOR");
6993 if (!editor)
6994 editor = getenv("VISUAL");
6995
6996 if (!isempty(editor)) {
6997 editor_args = strv_split(editor, WHITESPACE);
6998 if (!editor_args) {
6999 (void) log_oom();
7000 _exit(EXIT_FAILURE);
7001 }
7002 n_editor_args = strv_length(editor_args);
7003 argc += n_editor_args - 1;
7004 }
7005 args = newa(const char*, argc + 1);
7006
7007 if (n_editor_args > 0) {
7008 args[0] = editor_args[0];
7009 for (; i < n_editor_args; i++)
7010 args[i] = editor_args[i];
7011 }
7012
7013 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
7014 args[i] = *tmp_path;
7015 i++;
7016 }
7017 args[i] = NULL;
7018
7019 if (n_editor_args > 0)
7020 execvp(args[0], (char* const*) args);
7021
7022 FOREACH_STRING(p, "editor", "nano", "vim", "vi") {
7023 args[0] = p;
7024 execvp(p, (char* const*) args);
7025 /* We do not fail if the editor doesn't exist
7026 * because we want to try each one of them before
7027 * failing.
7028 */
7029 if (errno != ENOENT) {
7030 log_error_errno(errno, "Failed to execute %s: %m", editor);
7031 _exit(EXIT_FAILURE);
7032 }
7033 }
7034
7035 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
7036 _exit(EXIT_FAILURE);
7037 }
7038
7039 return 0;
7040 }
7041
7042 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
7043 _cleanup_lookup_paths_free_ LookupPaths lp = {};
7044 char **name;
7045 int r;
7046
7047 assert(names);
7048 assert(paths);
7049
7050 r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
7051 if (r < 0)
7052 return r;
7053
7054 STRV_FOREACH(name, names) {
7055 _cleanup_free_ char *path = NULL, *new_path = NULL, *tmp_path = NULL, *tmp_name = NULL;
7056 const char *unit_name;
7057
7058 r = unit_find_paths(bus, *name, &lp, &path, NULL);
7059 if (r < 0)
7060 return r;
7061
7062 if (r == 0) {
7063 assert(!path);
7064
7065 if (!arg_force) {
7066 log_error("Run 'systemctl edit%s --force %s' to create a new unit.",
7067 arg_scope == UNIT_FILE_GLOBAL ? " --global" :
7068 arg_scope == UNIT_FILE_USER ? " --user" : "",
7069 *name);
7070 return -ENOENT;
7071 }
7072
7073 /* Create a new unit from scratch */
7074 unit_name = *name;
7075 r = unit_file_create_new(&lp, unit_name,
7076 arg_full ? NULL : ".d/override.conf",
7077 &new_path, &tmp_path);
7078 } else {
7079 assert(path);
7080
7081 unit_name = basename(path);
7082 /* We follow unit aliases, but we need to propagate the instance */
7083 if (unit_name_is_valid(*name, UNIT_NAME_INSTANCE) &&
7084 unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) {
7085 _cleanup_free_ char *instance = NULL;
7086
7087 r = unit_name_to_instance(*name, &instance);
7088 if (r < 0)
7089 return r;
7090
7091 r = unit_name_replace_instance(unit_name, instance, &tmp_name);
7092 if (r < 0)
7093 return r;
7094
7095 unit_name = tmp_name;
7096 }
7097
7098 if (arg_full)
7099 r = unit_file_create_copy(&lp, unit_name, path, &new_path, &tmp_path);
7100 else
7101 r = unit_file_create_new(&lp, unit_name, ".d/override.conf", &new_path, &tmp_path);
7102 }
7103 if (r < 0)
7104 return r;
7105
7106 r = strv_push_pair(paths, new_path, tmp_path);
7107 if (r < 0)
7108 return log_oom();
7109 new_path = tmp_path = NULL;
7110 }
7111
7112 return 0;
7113 }
7114
7115 static int edit(int argc, char *argv[], void *userdata) {
7116 _cleanup_strv_free_ char **names = NULL;
7117 _cleanup_strv_free_ char **paths = NULL;
7118 char **original, **tmp;
7119 sd_bus *bus;
7120 int r;
7121
7122 if (!on_tty()) {
7123 log_error("Cannot edit units if not on a tty.");
7124 return -EINVAL;
7125 }
7126
7127 if (arg_transport != BUS_TRANSPORT_LOCAL) {
7128 log_error("Cannot edit units remotely.");
7129 return -EINVAL;
7130 }
7131
7132 r = acquire_bus(BUS_MANAGER, &bus);
7133 if (r < 0)
7134 return r;
7135
7136 r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
7137 if (r < 0)
7138 return log_error_errno(r, "Failed to expand names: %m");
7139
7140 r = find_paths_to_edit(bus, names, &paths);
7141 if (r < 0)
7142 return r;
7143
7144 if (strv_isempty(paths))
7145 return -ENOENT;
7146
7147 r = run_editor(paths);
7148 if (r < 0)
7149 goto end;
7150
7151 STRV_FOREACH_PAIR(original, tmp, paths) {
7152 /* If the temporary file is empty we ignore it. It's
7153 * useful if the user wants to cancel its modification
7154 */
7155 if (null_or_empty_path(*tmp)) {
7156 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original);
7157 continue;
7158 }
7159
7160 r = rename(*tmp, *original);
7161 if (r < 0) {
7162 r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
7163 goto end;
7164 }
7165 }
7166
7167 r = 0;
7168
7169 if (!arg_no_reload && !install_client_side())
7170 r = daemon_reload(argc, argv, userdata);
7171
7172 end:
7173 STRV_FOREACH_PAIR(original, tmp, paths) {
7174 (void) unlink(*tmp);
7175
7176 /* Removing empty dropin dirs */
7177 if (!arg_full) {
7178 _cleanup_free_ char *dir;
7179
7180 dir = dirname_malloc(*original);
7181 if (!dir)
7182 return log_oom();
7183
7184 /* no need to check if the dir is empty, rmdir
7185 * does nothing if it is not the case.
7186 */
7187 (void) rmdir(dir);
7188 }
7189 }
7190
7191 return r;
7192 }
7193
7194 static void systemctl_help(void) {
7195
7196 pager_open(arg_no_pager, false);
7197
7198 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
7199 "Query or send control commands to the systemd manager.\n\n"
7200 " -h --help Show this help\n"
7201 " --version Show package version\n"
7202 " --system Connect to system manager\n"
7203 " --user Connect to user service manager\n"
7204 " -H --host=[USER@]HOST\n"
7205 " Operate on remote host\n"
7206 " -M --machine=CONTAINER\n"
7207 " Operate on local container\n"
7208 " -t --type=TYPE List units of a particular type\n"
7209 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
7210 " -p --property=NAME Show only properties by this name\n"
7211 " -a --all Show all properties/all units currently in memory,\n"
7212 " including dead/empty ones. To list all units installed on\n"
7213 " the system, use the 'list-unit-files' command instead.\n"
7214 " --failed Same as --state=failed\n"
7215 " -l --full Don't ellipsize unit names on output\n"
7216 " -r --recursive Show unit list of host and local containers\n"
7217 " --reverse Show reverse dependencies with 'list-dependencies'\n"
7218 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
7219 " queueing a new job\n"
7220 " --show-types When showing sockets, explicitly show their type\n"
7221 " --value When showing properties, only print the value\n"
7222 " -i --ignore-inhibitors\n"
7223 " When shutting down or sleeping, ignore inhibitors\n"
7224 " --kill-who=WHO Who to send signal to\n"
7225 " -s --signal=SIGNAL Which signal to send\n"
7226 " --now Start or stop unit in addition to enabling or disabling it\n"
7227 " --dry-run Only print what would be done\n"
7228 " -q --quiet Suppress output\n"
7229 " --wait For (re)start, wait until service stopped again\n"
7230 " --no-block Do not wait until operation finished\n"
7231 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7232 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
7233 " --no-legend Do not print a legend (column headers and hints)\n"
7234 " --no-pager Do not pipe output into a pager\n"
7235 " --no-ask-password\n"
7236 " Do not ask for system passwords\n"
7237 " --global Enable/disable/mask unit files globally\n"
7238 " --runtime Enable/disable/mask unit files temporarily until next\n"
7239 " reboot\n"
7240 " -f --force When enabling unit files, override existing symlinks\n"
7241 " When shutting down, execute action immediately\n"
7242 " --preset-mode= Apply only enable, only disable, or all presets\n"
7243 " --root=PATH Enable/disable/mask unit files in the specified root\n"
7244 " directory\n"
7245 " -n --lines=INTEGER Number of journal entries to show\n"
7246 " -o --output=STRING Change journal output mode (short, short-precise,\n"
7247 " short-iso, short-iso-precise, short-full,\n"
7248 " short-monotonic, short-unix,\n"
7249 " verbose, export, json, json-pretty, json-sse, cat)\n"
7250 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
7251 " --plain Print unit dependencies as a list instead of a tree\n\n"
7252 "Unit Commands:\n"
7253 " list-units [PATTERN...] List units currently in memory\n"
7254 " list-sockets [PATTERN...] List socket units currently in memory, ordered\n"
7255 " by address\n"
7256 " list-timers [PATTERN...] List timer units currently in memory, ordered\n"
7257 " by next elapse\n"
7258 " start NAME... Start (activate) one or more units\n"
7259 " stop NAME... Stop (deactivate) one or more units\n"
7260 " reload NAME... Reload one or more units\n"
7261 " restart NAME... Start or restart one or more units\n"
7262 " try-restart NAME... Restart one or more units if active\n"
7263 " reload-or-restart NAME... Reload one or more units if possible,\n"
7264 " otherwise start or restart\n"
7265 " try-reload-or-restart NAME... If active, reload one or more units,\n"
7266 " if supported, otherwise restart\n"
7267 " isolate NAME Start one unit and stop all others\n"
7268 " kill NAME... Send signal to processes of a unit\n"
7269 " is-active PATTERN... Check whether units are active\n"
7270 " is-failed PATTERN... Check whether units are failed\n"
7271 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
7272 " show [PATTERN...|JOB...] Show properties of one or more\n"
7273 " units/jobs or the manager\n"
7274 " cat PATTERN... Show files and drop-ins of one or more units\n"
7275 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
7276 " help PATTERN...|PID... Show manual for one or more units\n"
7277 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
7278 " units\n"
7279 " list-dependencies [NAME] Recursively show units which are required\n"
7280 " or wanted by this unit or by which this\n"
7281 " unit is required or wanted\n\n"
7282 "Unit File Commands:\n"
7283 " list-unit-files [PATTERN...] List installed unit files\n"
7284 " enable [NAME...|PATH...] Enable one or more unit files\n"
7285 " disable NAME... Disable one or more unit files\n"
7286 " reenable NAME... Reenable one or more unit files\n"
7287 " preset NAME... Enable/disable one or more unit files\n"
7288 " based on preset configuration\n"
7289 " preset-all Enable/disable all unit files based on\n"
7290 " preset configuration\n"
7291 " is-enabled NAME... Check whether unit files are enabled\n"
7292 " mask NAME... Mask one or more units\n"
7293 " unmask NAME... Unmask one or more units\n"
7294 " link PATH... Link one or more units files into\n"
7295 " the search path\n"
7296 " revert NAME... Revert one or more unit files to vendor\n"
7297 " version\n"
7298 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
7299 " on specified one or more units\n"
7300 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
7301 " on specified one or more units\n"
7302 " edit NAME... Edit one or more unit files\n"
7303 " get-default Get the name of the default target\n"
7304 " set-default NAME Set the default target\n\n"
7305 "Machine Commands:\n"
7306 " list-machines [PATTERN...] List local containers and host\n\n"
7307 "Job Commands:\n"
7308 " list-jobs [PATTERN...] List jobs\n"
7309 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
7310 "Environment Commands:\n"
7311 " show-environment Dump environment\n"
7312 " set-environment NAME=VALUE... Set one or more environment variables\n"
7313 " unset-environment NAME... Unset one or more environment variables\n"
7314 " import-environment [NAME...] Import all or some environment variables\n\n"
7315 "Manager Lifecycle Commands:\n"
7316 " daemon-reload Reload systemd manager configuration\n"
7317 " daemon-reexec Reexecute systemd manager\n\n"
7318 "System Commands:\n"
7319 " is-system-running Check whether system is fully running\n"
7320 " default Enter system default mode\n"
7321 " rescue Enter system rescue mode\n"
7322 " emergency Enter system emergency mode\n"
7323 " halt Shut down and halt the system\n"
7324 " poweroff Shut down and power-off the system\n"
7325 " reboot [ARG] Shut down and reboot the system\n"
7326 " kexec Shut down and reboot the system with kexec\n"
7327 " exit [EXIT_CODE] Request user instance or container exit\n"
7328 " switch-root ROOT [INIT] Change to a different root file system\n"
7329 " suspend Suspend the system\n"
7330 " hibernate Hibernate the system\n"
7331 " hybrid-sleep Hibernate and suspend the system\n",
7332 program_invocation_short_name);
7333 }
7334
7335 static void halt_help(void) {
7336 printf("%s [OPTIONS...]%s\n\n"
7337 "%s the system.\n\n"
7338 " --help Show this help\n"
7339 " --halt Halt the machine\n"
7340 " -p --poweroff Switch off the machine\n"
7341 " --reboot Reboot the machine\n"
7342 " -f --force Force immediate halt/power-off/reboot\n"
7343 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
7344 " -d --no-wtmp Don't write wtmp record\n"
7345 " --no-wall Don't send wall message before halt/power-off/reboot\n",
7346 program_invocation_short_name,
7347 arg_action == ACTION_REBOOT ? " [ARG]" : "",
7348 arg_action == ACTION_REBOOT ? "Reboot" :
7349 arg_action == ACTION_POWEROFF ? "Power off" :
7350 "Halt");
7351 }
7352
7353 static void shutdown_help(void) {
7354 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
7355 "Shut down the system.\n\n"
7356 " --help Show this help\n"
7357 " -H --halt Halt the machine\n"
7358 " -P --poweroff Power-off the machine\n"
7359 " -r --reboot Reboot the machine\n"
7360 " -h Equivalent to --poweroff, overridden by --halt\n"
7361 " -k Don't halt/power-off/reboot, just send warnings\n"
7362 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7363 " -c Cancel a pending shutdown\n",
7364 program_invocation_short_name);
7365 }
7366
7367 static void telinit_help(void) {
7368 printf("%s [OPTIONS...] {COMMAND}\n\n"
7369 "Send control commands to the init daemon.\n\n"
7370 " --help Show this help\n"
7371 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
7372 "Commands:\n"
7373 " 0 Power-off the machine\n"
7374 " 6 Reboot the machine\n"
7375 " 2, 3, 4, 5 Start runlevelX.target unit\n"
7376 " 1, s, S Enter rescue mode\n"
7377 " q, Q Reload init daemon configuration\n"
7378 " u, U Reexecute init daemon\n",
7379 program_invocation_short_name);
7380 }
7381
7382 static void runlevel_help(void) {
7383 printf("%s [OPTIONS...]\n\n"
7384 "Prints the previous and current runlevel of the init system.\n\n"
7385 " --help Show this help\n",
7386 program_invocation_short_name);
7387 }
7388
7389 static void help_types(void) {
7390 int i;
7391
7392 if (!arg_no_legend)
7393 puts("Available unit types:");
7394 for (i = 0; i < _UNIT_TYPE_MAX; i++)
7395 puts(unit_type_to_string(i));
7396 }
7397
7398 static void help_states(void) {
7399 int i;
7400
7401 if (!arg_no_legend)
7402 puts("Available unit load states:");
7403 for (i = 0; i < _UNIT_LOAD_STATE_MAX; i++)
7404 puts(unit_load_state_to_string(i));
7405
7406 if (!arg_no_legend)
7407 puts("\nAvailable unit active states:");
7408 for (i = 0; i < _UNIT_ACTIVE_STATE_MAX; i++)
7409 puts(unit_active_state_to_string(i));
7410
7411 if (!arg_no_legend)
7412 puts("\nAvailable automount unit substates:");
7413 for (i = 0; i < _AUTOMOUNT_STATE_MAX; i++)
7414 puts(automount_state_to_string(i));
7415
7416 if (!arg_no_legend)
7417 puts("\nAvailable device unit substates:");
7418 for (i = 0; i < _DEVICE_STATE_MAX; i++)
7419 puts(device_state_to_string(i));
7420
7421 if (!arg_no_legend)
7422 puts("\nAvailable mount unit substates:");
7423 for (i = 0; i < _MOUNT_STATE_MAX; i++)
7424 puts(mount_state_to_string(i));
7425
7426 if (!arg_no_legend)
7427 puts("\nAvailable path unit substates:");
7428 for (i = 0; i < _PATH_STATE_MAX; i++)
7429 puts(path_state_to_string(i));
7430
7431 if (!arg_no_legend)
7432 puts("\nAvailable scope unit substates:");
7433 for (i = 0; i < _SCOPE_STATE_MAX; i++)
7434 puts(scope_state_to_string(i));
7435
7436 if (!arg_no_legend)
7437 puts("\nAvailable service unit substates:");
7438 for (i = 0; i < _SERVICE_STATE_MAX; i++)
7439 puts(service_state_to_string(i));
7440
7441 if (!arg_no_legend)
7442 puts("\nAvailable slice unit substates:");
7443 for (i = 0; i < _SLICE_STATE_MAX; i++)
7444 puts(slice_state_to_string(i));
7445
7446 if (!arg_no_legend)
7447 puts("\nAvailable socket unit substates:");
7448 for (i = 0; i < _SOCKET_STATE_MAX; i++)
7449 puts(socket_state_to_string(i));
7450
7451 if (!arg_no_legend)
7452 puts("\nAvailable swap unit substates:");
7453 for (i = 0; i < _SWAP_STATE_MAX; i++)
7454 puts(swap_state_to_string(i));
7455
7456 if (!arg_no_legend)
7457 puts("\nAvailable target unit substates:");
7458 for (i = 0; i < _TARGET_STATE_MAX; i++)
7459 puts(target_state_to_string(i));
7460
7461 if (!arg_no_legend)
7462 puts("\nAvailable timer unit substates:");
7463 for (i = 0; i < _TIMER_STATE_MAX; i++)
7464 puts(timer_state_to_string(i));
7465 }
7466
7467 static int systemctl_parse_argv(int argc, char *argv[]) {
7468
7469 enum {
7470 ARG_FAIL = 0x100,
7471 ARG_REVERSE,
7472 ARG_AFTER,
7473 ARG_BEFORE,
7474 ARG_DRY_RUN,
7475 ARG_SHOW_TYPES,
7476 ARG_IRREVERSIBLE,
7477 ARG_IGNORE_DEPENDENCIES,
7478 ARG_VALUE,
7479 ARG_VERSION,
7480 ARG_USER,
7481 ARG_SYSTEM,
7482 ARG_GLOBAL,
7483 ARG_NO_BLOCK,
7484 ARG_NO_LEGEND,
7485 ARG_NO_PAGER,
7486 ARG_NO_WALL,
7487 ARG_ROOT,
7488 ARG_NO_RELOAD,
7489 ARG_KILL_WHO,
7490 ARG_NO_ASK_PASSWORD,
7491 ARG_FAILED,
7492 ARG_RUNTIME,
7493 ARG_FORCE,
7494 ARG_PLAIN,
7495 ARG_STATE,
7496 ARG_JOB_MODE,
7497 ARG_PRESET_MODE,
7498 ARG_FIRMWARE_SETUP,
7499 ARG_NOW,
7500 ARG_MESSAGE,
7501 ARG_WAIT,
7502 };
7503
7504 static const struct option options[] = {
7505 { "help", no_argument, NULL, 'h' },
7506 { "version", no_argument, NULL, ARG_VERSION },
7507 { "type", required_argument, NULL, 't' },
7508 { "property", required_argument, NULL, 'p' },
7509 { "all", no_argument, NULL, 'a' },
7510 { "reverse", no_argument, NULL, ARG_REVERSE },
7511 { "after", no_argument, NULL, ARG_AFTER },
7512 { "before", no_argument, NULL, ARG_BEFORE },
7513 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
7514 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
7515 { "full", no_argument, NULL, 'l' },
7516 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
7517 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
7518 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
7519 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
7520 { "ignore-inhibitors", no_argument, NULL, 'i' },
7521 { "value", no_argument, NULL, ARG_VALUE },
7522 { "user", no_argument, NULL, ARG_USER },
7523 { "system", no_argument, NULL, ARG_SYSTEM },
7524 { "global", no_argument, NULL, ARG_GLOBAL },
7525 { "wait", no_argument, NULL, ARG_WAIT },
7526 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
7527 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
7528 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
7529 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7530 { "dry-run", no_argument, NULL, ARG_DRY_RUN },
7531 { "quiet", no_argument, NULL, 'q' },
7532 { "root", required_argument, NULL, ARG_ROOT },
7533 { "force", no_argument, NULL, ARG_FORCE },
7534 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
7535 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
7536 { "signal", required_argument, NULL, 's' },
7537 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
7538 { "host", required_argument, NULL, 'H' },
7539 { "machine", required_argument, NULL, 'M' },
7540 { "runtime", no_argument, NULL, ARG_RUNTIME },
7541 { "lines", required_argument, NULL, 'n' },
7542 { "output", required_argument, NULL, 'o' },
7543 { "plain", no_argument, NULL, ARG_PLAIN },
7544 { "state", required_argument, NULL, ARG_STATE },
7545 { "recursive", no_argument, NULL, 'r' },
7546 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
7547 { "firmware-setup", no_argument, NULL, ARG_FIRMWARE_SETUP },
7548 { "now", no_argument, NULL, ARG_NOW },
7549 { "message", required_argument, NULL, ARG_MESSAGE },
7550 {}
7551 };
7552
7553 const char *p;
7554 int c, r;
7555
7556 assert(argc >= 0);
7557 assert(argv);
7558
7559 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
7560 arg_ask_password = true;
7561
7562 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
7563
7564 switch (c) {
7565
7566 case 'h':
7567 systemctl_help();
7568 return 0;
7569
7570 case ARG_VERSION:
7571 return version();
7572
7573 case 't': {
7574 if (isempty(optarg)) {
7575 log_error("--type= requires arguments.");
7576 return -EINVAL;
7577 }
7578
7579 for (p = optarg;;) {
7580 _cleanup_free_ char *type = NULL;
7581
7582 r = extract_first_word(&p, &type, ",", 0);
7583 if (r < 0)
7584 return log_error_errno(r, "Failed to parse type: %s", optarg);
7585 if (r == 0)
7586 break;
7587
7588 if (streq(type, "help")) {
7589 help_types();
7590 return 0;
7591 }
7592
7593 if (unit_type_from_string(type) >= 0) {
7594 if (strv_push(&arg_types, type) < 0)
7595 return log_oom();
7596 type = NULL;
7597 continue;
7598 }
7599
7600 /* It's much nicer to use --state= for
7601 * load states, but let's support this
7602 * in --types= too for compatibility
7603 * with old versions */
7604 if (unit_load_state_from_string(type) >= 0) {
7605 if (strv_push(&arg_states, type) < 0)
7606 return log_oom();
7607 type = NULL;
7608 continue;
7609 }
7610
7611 log_error("Unknown unit type or load state '%s'.", type);
7612 log_info("Use -t help to see a list of allowed values.");
7613 return -EINVAL;
7614 }
7615
7616 break;
7617 }
7618
7619 case 'p': {
7620 /* Make sure that if the empty property list
7621 was specified, we won't show any properties. */
7622 if (isempty(optarg) && !arg_properties) {
7623 arg_properties = new0(char*, 1);
7624 if (!arg_properties)
7625 return log_oom();
7626 } else
7627 for (p = optarg;;) {
7628 _cleanup_free_ char *prop = NULL;
7629
7630 r = extract_first_word(&p, &prop, ",", 0);
7631 if (r < 0)
7632 return log_error_errno(r, "Failed to parse property: %s", optarg);
7633 if (r == 0)
7634 break;
7635
7636 if (strv_push(&arg_properties, prop) < 0)
7637 return log_oom();
7638
7639 prop = NULL;
7640 }
7641
7642 /* If the user asked for a particular
7643 * property, show it to him, even if it is
7644 * empty. */
7645 arg_all = true;
7646
7647 break;
7648 }
7649
7650 case 'a':
7651 arg_all = true;
7652 break;
7653
7654 case ARG_REVERSE:
7655 arg_dependency = DEPENDENCY_REVERSE;
7656 break;
7657
7658 case ARG_AFTER:
7659 arg_dependency = DEPENDENCY_AFTER;
7660 arg_jobs_after = true;
7661 break;
7662
7663 case ARG_BEFORE:
7664 arg_dependency = DEPENDENCY_BEFORE;
7665 arg_jobs_before = true;
7666 break;
7667
7668 case ARG_SHOW_TYPES:
7669 arg_show_types = true;
7670 break;
7671
7672 case ARG_VALUE:
7673 arg_value = true;
7674 break;
7675
7676 case ARG_JOB_MODE:
7677 arg_job_mode = optarg;
7678 break;
7679
7680 case ARG_FAIL:
7681 arg_job_mode = "fail";
7682 break;
7683
7684 case ARG_IRREVERSIBLE:
7685 arg_job_mode = "replace-irreversibly";
7686 break;
7687
7688 case ARG_IGNORE_DEPENDENCIES:
7689 arg_job_mode = "ignore-dependencies";
7690 break;
7691
7692 case ARG_USER:
7693 arg_scope = UNIT_FILE_USER;
7694 break;
7695
7696 case ARG_SYSTEM:
7697 arg_scope = UNIT_FILE_SYSTEM;
7698 break;
7699
7700 case ARG_GLOBAL:
7701 arg_scope = UNIT_FILE_GLOBAL;
7702 break;
7703
7704 case ARG_WAIT:
7705 arg_wait = true;
7706 break;
7707
7708 case ARG_NO_BLOCK:
7709 arg_no_block = true;
7710 break;
7711
7712 case ARG_NO_LEGEND:
7713 arg_no_legend = true;
7714 break;
7715
7716 case ARG_NO_PAGER:
7717 arg_no_pager = true;
7718 break;
7719
7720 case ARG_NO_WALL:
7721 arg_no_wall = true;
7722 break;
7723
7724 case ARG_ROOT:
7725 r = parse_path_argument_and_warn(optarg, false, &arg_root);
7726 if (r < 0)
7727 return r;
7728 break;
7729
7730 case 'l':
7731 arg_full = true;
7732 break;
7733
7734 case ARG_FAILED:
7735 if (strv_extend(&arg_states, "failed") < 0)
7736 return log_oom();
7737
7738 break;
7739
7740 case ARG_DRY_RUN:
7741 arg_dry_run = true;
7742 break;
7743
7744 case 'q':
7745 arg_quiet = true;
7746 break;
7747
7748 case ARG_FORCE:
7749 arg_force++;
7750 break;
7751
7752 case 'f':
7753 arg_force++;
7754 break;
7755
7756 case ARG_NO_RELOAD:
7757 arg_no_reload = true;
7758 break;
7759
7760 case ARG_KILL_WHO:
7761 arg_kill_who = optarg;
7762 break;
7763
7764 case 's':
7765 arg_signal = signal_from_string_try_harder(optarg);
7766 if (arg_signal < 0) {
7767 log_error("Failed to parse signal string %s.", optarg);
7768 return -EINVAL;
7769 }
7770 break;
7771
7772 case ARG_NO_ASK_PASSWORD:
7773 arg_ask_password = false;
7774 break;
7775
7776 case 'H':
7777 arg_transport = BUS_TRANSPORT_REMOTE;
7778 arg_host = optarg;
7779 break;
7780
7781 case 'M':
7782 arg_transport = BUS_TRANSPORT_MACHINE;
7783 arg_host = optarg;
7784 break;
7785
7786 case ARG_RUNTIME:
7787 arg_runtime = true;
7788 break;
7789
7790 case 'n':
7791 if (safe_atou(optarg, &arg_lines) < 0) {
7792 log_error("Failed to parse lines '%s'", optarg);
7793 return -EINVAL;
7794 }
7795 break;
7796
7797 case 'o':
7798 arg_output = output_mode_from_string(optarg);
7799 if (arg_output < 0) {
7800 log_error("Unknown output '%s'.", optarg);
7801 return -EINVAL;
7802 }
7803 break;
7804
7805 case 'i':
7806 arg_ignore_inhibitors = true;
7807 break;
7808
7809 case ARG_PLAIN:
7810 arg_plain = true;
7811 break;
7812
7813 case ARG_FIRMWARE_SETUP:
7814 arg_firmware_setup = true;
7815 break;
7816
7817 case ARG_STATE: {
7818 if (isempty(optarg)) {
7819 log_error("--state= requires arguments.");
7820 return -EINVAL;
7821 }
7822
7823 for (p = optarg;;) {
7824 _cleanup_free_ char *s = NULL;
7825
7826 r = extract_first_word(&p, &s, ",", 0);
7827 if (r < 0)
7828 return log_error_errno(r, "Failed to parse state: %s", optarg);
7829 if (r == 0)
7830 break;
7831
7832 if (streq(s, "help")) {
7833 help_states();
7834 return 0;
7835 }
7836
7837 if (strv_push(&arg_states, s) < 0)
7838 return log_oom();
7839
7840 s = NULL;
7841 }
7842 break;
7843 }
7844
7845 case 'r':
7846 if (geteuid() != 0) {
7847 log_error("--recursive requires root privileges.");
7848 return -EPERM;
7849 }
7850
7851 arg_recursive = true;
7852 break;
7853
7854 case ARG_PRESET_MODE:
7855
7856 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
7857 if (arg_preset_mode < 0) {
7858 log_error("Failed to parse preset mode: %s.", optarg);
7859 return -EINVAL;
7860 }
7861
7862 break;
7863
7864 case ARG_NOW:
7865 arg_now = true;
7866 break;
7867
7868 case ARG_MESSAGE:
7869 if (strv_extend(&arg_wall, optarg) < 0)
7870 return log_oom();
7871 break;
7872
7873 case '?':
7874 return -EINVAL;
7875
7876 default:
7877 assert_not_reached("Unhandled option");
7878 }
7879
7880 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
7881 log_error("Cannot access user instance remotely.");
7882 return -EINVAL;
7883 }
7884
7885 if (arg_wait && arg_no_block) {
7886 log_error("--wait may not be combined with --no-block.");
7887 return -EINVAL;
7888 }
7889
7890 return 1;
7891 }
7892
7893 static int halt_parse_argv(int argc, char *argv[]) {
7894
7895 enum {
7896 ARG_HELP = 0x100,
7897 ARG_HALT,
7898 ARG_REBOOT,
7899 ARG_NO_WALL
7900 };
7901
7902 static const struct option options[] = {
7903 { "help", no_argument, NULL, ARG_HELP },
7904 { "halt", no_argument, NULL, ARG_HALT },
7905 { "poweroff", no_argument, NULL, 'p' },
7906 { "reboot", no_argument, NULL, ARG_REBOOT },
7907 { "force", no_argument, NULL, 'f' },
7908 { "wtmp-only", no_argument, NULL, 'w' },
7909 { "no-wtmp", no_argument, NULL, 'd' },
7910 { "no-sync", no_argument, NULL, 'n' },
7911 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7912 {}
7913 };
7914
7915 int c, r, runlevel;
7916
7917 assert(argc >= 0);
7918 assert(argv);
7919
7920 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
7921 if (IN_SET(runlevel, '0', '6'))
7922 arg_force = 2;
7923
7924 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
7925 switch (c) {
7926
7927 case ARG_HELP:
7928 halt_help();
7929 return 0;
7930
7931 case ARG_HALT:
7932 arg_action = ACTION_HALT;
7933 break;
7934
7935 case 'p':
7936 if (arg_action != ACTION_REBOOT)
7937 arg_action = ACTION_POWEROFF;
7938 break;
7939
7940 case ARG_REBOOT:
7941 arg_action = ACTION_REBOOT;
7942 break;
7943
7944 case 'f':
7945 arg_force = 2;
7946 break;
7947
7948 case 'w':
7949 arg_dry_run = true;
7950 break;
7951
7952 case 'd':
7953 arg_no_wtmp = true;
7954 break;
7955
7956 case 'n':
7957 arg_no_sync = true;
7958 break;
7959
7960 case ARG_NO_WALL:
7961 arg_no_wall = true;
7962 break;
7963
7964 case 'i':
7965 case 'h':
7966 /* Compatibility nops */
7967 break;
7968
7969 case '?':
7970 return -EINVAL;
7971
7972 default:
7973 assert_not_reached("Unhandled option");
7974 }
7975
7976 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
7977 r = update_reboot_parameter_and_warn(argc == optind + 1 ? argv[optind] : NULL);
7978 if (r < 0)
7979 return r;
7980 } else if (optind < argc) {
7981 log_error("Too many arguments.");
7982 return -EINVAL;
7983 }
7984
7985 return 1;
7986 }
7987
7988 static int parse_shutdown_time_spec(const char *t, usec_t *_u) {
7989 assert(t);
7990 assert(_u);
7991
7992 if (streq(t, "now"))
7993 *_u = 0;
7994 else if (!strchr(t, ':')) {
7995 uint64_t u;
7996
7997 if (safe_atou64(t, &u) < 0)
7998 return -EINVAL;
7999
8000 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
8001 } else {
8002 char *e = NULL;
8003 long hour, minute;
8004 struct tm tm = {};
8005 time_t s;
8006 usec_t n;
8007
8008 errno = 0;
8009 hour = strtol(t, &e, 10);
8010 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
8011 return -EINVAL;
8012
8013 minute = strtol(e+1, &e, 10);
8014 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
8015 return -EINVAL;
8016
8017 n = now(CLOCK_REALTIME);
8018 s = (time_t) (n / USEC_PER_SEC);
8019
8020 assert_se(localtime_r(&s, &tm));
8021
8022 tm.tm_hour = (int) hour;
8023 tm.tm_min = (int) minute;
8024 tm.tm_sec = 0;
8025
8026 assert_se(s = mktime(&tm));
8027
8028 *_u = (usec_t) s * USEC_PER_SEC;
8029
8030 while (*_u <= n)
8031 *_u += USEC_PER_DAY;
8032 }
8033
8034 return 0;
8035 }
8036
8037 static int shutdown_parse_argv(int argc, char *argv[]) {
8038
8039 enum {
8040 ARG_HELP = 0x100,
8041 ARG_NO_WALL
8042 };
8043
8044 static const struct option options[] = {
8045 { "help", no_argument, NULL, ARG_HELP },
8046 { "halt", no_argument, NULL, 'H' },
8047 { "poweroff", no_argument, NULL, 'P' },
8048 { "reboot", no_argument, NULL, 'r' },
8049 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
8050 { "no-wall", no_argument, NULL, ARG_NO_WALL },
8051 {}
8052 };
8053
8054 char **wall = NULL;
8055 int c, r;
8056
8057 assert(argc >= 0);
8058 assert(argv);
8059
8060 while ((c = getopt_long(argc, argv, "HPrhkKat:fFc", options, NULL)) >= 0)
8061 switch (c) {
8062
8063 case ARG_HELP:
8064 shutdown_help();
8065 return 0;
8066
8067 case 'H':
8068 arg_action = ACTION_HALT;
8069 break;
8070
8071 case 'P':
8072 arg_action = ACTION_POWEROFF;
8073 break;
8074
8075 case 'r':
8076 if (kexec_loaded())
8077 arg_action = ACTION_KEXEC;
8078 else
8079 arg_action = ACTION_REBOOT;
8080 break;
8081
8082 case 'K':
8083 arg_action = ACTION_KEXEC;
8084 break;
8085
8086 case 'h':
8087 if (arg_action != ACTION_HALT)
8088 arg_action = ACTION_POWEROFF;
8089 break;
8090
8091 case 'k':
8092 arg_dry_run = true;
8093 break;
8094
8095 case ARG_NO_WALL:
8096 arg_no_wall = true;
8097 break;
8098
8099 case 'a':
8100 case 't': /* Note that we also ignore any passed argument to -t, not just the -t itself */
8101 case 'f':
8102 case 'F':
8103 /* Compatibility nops */
8104 break;
8105
8106 case 'c':
8107 arg_action = ACTION_CANCEL_SHUTDOWN;
8108 break;
8109
8110 case '?':
8111 return -EINVAL;
8112
8113 default:
8114 assert_not_reached("Unhandled option");
8115 }
8116
8117 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
8118 r = parse_shutdown_time_spec(argv[optind], &arg_when);
8119 if (r < 0) {
8120 log_error("Failed to parse time specification: %s", argv[optind]);
8121 return r;
8122 }
8123 } else
8124 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
8125
8126 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
8127 /* No time argument for shutdown cancel */
8128 wall = argv + optind;
8129 else if (argc > optind + 1)
8130 /* We skip the time argument */
8131 wall = argv + optind + 1;
8132
8133 if (wall) {
8134 arg_wall = strv_copy(wall);
8135 if (!arg_wall)
8136 return log_oom();
8137 }
8138
8139 optind = argc;
8140
8141 return 1;
8142 }
8143
8144 static int telinit_parse_argv(int argc, char *argv[]) {
8145
8146 enum {
8147 ARG_HELP = 0x100,
8148 ARG_NO_WALL
8149 };
8150
8151 static const struct option options[] = {
8152 { "help", no_argument, NULL, ARG_HELP },
8153 { "no-wall", no_argument, NULL, ARG_NO_WALL },
8154 {}
8155 };
8156
8157 static const struct {
8158 char from;
8159 enum action to;
8160 } table[] = {
8161 { '0', ACTION_POWEROFF },
8162 { '6', ACTION_REBOOT },
8163 { '1', ACTION_RESCUE },
8164 { '2', ACTION_RUNLEVEL2 },
8165 { '3', ACTION_RUNLEVEL3 },
8166 { '4', ACTION_RUNLEVEL4 },
8167 { '5', ACTION_RUNLEVEL5 },
8168 { 's', ACTION_RESCUE },
8169 { 'S', ACTION_RESCUE },
8170 { 'q', ACTION_RELOAD },
8171 { 'Q', ACTION_RELOAD },
8172 { 'u', ACTION_REEXEC },
8173 { 'U', ACTION_REEXEC }
8174 };
8175
8176 unsigned i;
8177 int c;
8178
8179 assert(argc >= 0);
8180 assert(argv);
8181
8182 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
8183 switch (c) {
8184
8185 case ARG_HELP:
8186 telinit_help();
8187 return 0;
8188
8189 case ARG_NO_WALL:
8190 arg_no_wall = true;
8191 break;
8192
8193 case '?':
8194 return -EINVAL;
8195
8196 default:
8197 assert_not_reached("Unhandled option");
8198 }
8199
8200 if (optind >= argc) {
8201 log_error("%s: required argument missing.", program_invocation_short_name);
8202 return -EINVAL;
8203 }
8204
8205 if (optind + 1 < argc) {
8206 log_error("Too many arguments.");
8207 return -EINVAL;
8208 }
8209
8210 if (strlen(argv[optind]) != 1) {
8211 log_error("Expected single character argument.");
8212 return -EINVAL;
8213 }
8214
8215 for (i = 0; i < ELEMENTSOF(table); i++)
8216 if (table[i].from == argv[optind][0])
8217 break;
8218
8219 if (i >= ELEMENTSOF(table)) {
8220 log_error("Unknown command '%s'.", argv[optind]);
8221 return -EINVAL;
8222 }
8223
8224 arg_action = table[i].to;
8225
8226 optind++;
8227
8228 return 1;
8229 }
8230
8231 static int runlevel_parse_argv(int argc, char *argv[]) {
8232
8233 enum {
8234 ARG_HELP = 0x100,
8235 };
8236
8237 static const struct option options[] = {
8238 { "help", no_argument, NULL, ARG_HELP },
8239 {}
8240 };
8241
8242 int c;
8243
8244 assert(argc >= 0);
8245 assert(argv);
8246
8247 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
8248 switch (c) {
8249
8250 case ARG_HELP:
8251 runlevel_help();
8252 return 0;
8253
8254 case '?':
8255 return -EINVAL;
8256
8257 default:
8258 assert_not_reached("Unhandled option");
8259 }
8260
8261 if (optind < argc) {
8262 log_error("Too many arguments.");
8263 return -EINVAL;
8264 }
8265
8266 return 1;
8267 }
8268
8269 static int parse_argv(int argc, char *argv[]) {
8270 assert(argc >= 0);
8271 assert(argv);
8272
8273 if (program_invocation_short_name) {
8274
8275 if (strstr(program_invocation_short_name, "halt")) {
8276 arg_action = ACTION_HALT;
8277 return halt_parse_argv(argc, argv);
8278 } else if (strstr(program_invocation_short_name, "poweroff")) {
8279 arg_action = ACTION_POWEROFF;
8280 return halt_parse_argv(argc, argv);
8281 } else if (strstr(program_invocation_short_name, "reboot")) {
8282 if (kexec_loaded())
8283 arg_action = ACTION_KEXEC;
8284 else
8285 arg_action = ACTION_REBOOT;
8286 return halt_parse_argv(argc, argv);
8287 } else if (strstr(program_invocation_short_name, "shutdown")) {
8288 arg_action = ACTION_POWEROFF;
8289 return shutdown_parse_argv(argc, argv);
8290 } else if (strstr(program_invocation_short_name, "init")) {
8291
8292 if (sd_booted() > 0) {
8293 arg_action = _ACTION_INVALID;
8294 return telinit_parse_argv(argc, argv);
8295 } else {
8296 /* Hmm, so some other init system is
8297 * running, we need to forward this
8298 * request to it. For now we simply
8299 * guess that it is Upstart. */
8300
8301 execv(TELINIT, argv);
8302
8303 log_error("Couldn't find an alternative telinit implementation to spawn.");
8304 return -EIO;
8305 }
8306
8307 } else if (strstr(program_invocation_short_name, "runlevel")) {
8308 arg_action = ACTION_RUNLEVEL;
8309 return runlevel_parse_argv(argc, argv);
8310 }
8311 }
8312
8313 arg_action = ACTION_SYSTEMCTL;
8314 return systemctl_parse_argv(argc, argv);
8315 }
8316
8317 #if HAVE_SYSV_COMPAT
8318 _pure_ static int action_to_runlevel(void) {
8319
8320 static const char table[_ACTION_MAX] = {
8321 [ACTION_HALT] = '0',
8322 [ACTION_POWEROFF] = '0',
8323 [ACTION_REBOOT] = '6',
8324 [ACTION_RUNLEVEL2] = '2',
8325 [ACTION_RUNLEVEL3] = '3',
8326 [ACTION_RUNLEVEL4] = '4',
8327 [ACTION_RUNLEVEL5] = '5',
8328 [ACTION_RESCUE] = '1'
8329 };
8330
8331 assert(arg_action >= 0 && arg_action < _ACTION_MAX);
8332
8333 return table[arg_action];
8334 }
8335 #endif
8336
8337 static int talk_initctl(void) {
8338 #if HAVE_SYSV_COMPAT
8339 struct init_request request = {
8340 .magic = INIT_MAGIC,
8341 .sleeptime = 0,
8342 .cmd = INIT_CMD_RUNLVL
8343 };
8344
8345 _cleanup_close_ int fd = -1;
8346 char rl;
8347 int r;
8348
8349 rl = action_to_runlevel();
8350 if (!rl)
8351 return 0;
8352
8353 request.runlevel = rl;
8354
8355 fd = open(INIT_FIFO, O_WRONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
8356 if (fd < 0) {
8357 if (errno == ENOENT)
8358 return 0;
8359
8360 return log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
8361 }
8362
8363 r = loop_write(fd, &request, sizeof(request), false);
8364 if (r < 0)
8365 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
8366
8367 return 1;
8368 #else
8369 return 0;
8370 #endif
8371 }
8372
8373 static int systemctl_main(int argc, char *argv[]) {
8374
8375 static const Verb verbs[] = {
8376 { "list-units", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, list_units },
8377 { "list-unit-files", VERB_ANY, VERB_ANY, 0, list_unit_files },
8378 { "list-sockets", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_sockets },
8379 { "list-timers", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_timers },
8380 { "list-jobs", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_jobs },
8381 { "list-machines", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY|VERB_MUST_BE_ROOT, list_machines },
8382 { "clear-jobs", VERB_ANY, 1, VERB_ONLINE_ONLY, trivial_method },
8383 { "cancel", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, cancel_job },
8384 { "start", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit },
8385 { "stop", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit },
8386 { "condstop", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, /* For compatibility with ALTLinux */
8387 { "reload", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit },
8388 { "restart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit },
8389 { "try-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit },
8390 { "reload-or-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit },
8391 { "reload-or-try-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, /* For compatbility with old systemctl <= 228 */
8392 { "try-reload-or-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit },
8393 { "force-reload", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, /* For compatibility with SysV */
8394 { "condreload", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, /* For compatibility with ALTLinux */
8395 { "condrestart", 2, VERB_ANY, VERB_ONLINE_ONLY, start_unit }, /* For compatibility with RH */
8396 { "isolate", 2, 2, VERB_ONLINE_ONLY, start_unit },
8397 { "kill", 2, VERB_ANY, VERB_ONLINE_ONLY, kill_unit },
8398 { "is-active", 2, VERB_ANY, VERB_ONLINE_ONLY, check_unit_active },
8399 { "check", 2, VERB_ANY, VERB_ONLINE_ONLY, check_unit_active }, /* deprecated alias of is-active */
8400 { "is-failed", 2, VERB_ANY, VERB_ONLINE_ONLY, check_unit_failed },
8401 { "show", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show },
8402 { "cat", 2, VERB_ANY, VERB_ONLINE_ONLY, cat },
8403 { "status", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show },
8404 { "help", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show },
8405 { "daemon-reload", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload },
8406 { "daemon-reexec", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload },
8407 { "show-environment", VERB_ANY, 1, VERB_ONLINE_ONLY, show_environment },
8408 { "set-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment },
8409 { "unset-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment },
8410 { "import-environment", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, import_environment },
8411 { "halt", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special },
8412 { "poweroff", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special },
8413 { "reboot", VERB_ANY, 2, VERB_ONLINE_ONLY, start_system_special },
8414 { "kexec", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special },
8415 { "suspend", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special },
8416 { "hibernate", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special },
8417 { "hybrid-sleep", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special },
8418 { "default", VERB_ANY, 1, VERB_ONLINE_ONLY, start_special },
8419 { "rescue", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special },
8420 { "emergency", VERB_ANY, 1, VERB_ONLINE_ONLY, start_system_special },
8421 { "exit", VERB_ANY, 2, VERB_ONLINE_ONLY, start_special },
8422 { "reset-failed", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, reset_failed },
8423 { "enable", 2, VERB_ANY, 0, enable_unit },
8424 { "disable", 2, VERB_ANY, 0, enable_unit },
8425 { "is-enabled", 2, VERB_ANY, 0, unit_is_enabled },
8426 { "reenable", 2, VERB_ANY, 0, enable_unit },
8427 { "preset", 2, VERB_ANY, 0, enable_unit },
8428 { "preset-all", VERB_ANY, 1, 0, preset_all },
8429 { "mask", 2, VERB_ANY, 0, enable_unit },
8430 { "unmask", 2, VERB_ANY, 0, enable_unit },
8431 { "link", 2, VERB_ANY, 0, enable_unit },
8432 { "revert", 2, VERB_ANY, 0, enable_unit },
8433 { "switch-root", 2, VERB_ANY, VERB_ONLINE_ONLY, switch_root },
8434 { "list-dependencies", VERB_ANY, 2, VERB_ONLINE_ONLY, list_dependencies },
8435 { "set-default", 2, 2, 0, set_default },
8436 { "get-default", VERB_ANY, 1, 0, get_default },
8437 { "set-property", 3, VERB_ANY, VERB_ONLINE_ONLY, set_property },
8438 { "is-system-running", VERB_ANY, 1, 0, is_system_running },
8439 { "add-wants", 3, VERB_ANY, 0, add_dependency },
8440 { "add-requires", 3, VERB_ANY, 0, add_dependency },
8441 { "edit", 2, VERB_ANY, VERB_ONLINE_ONLY, edit },
8442 {}
8443 };
8444
8445 return dispatch_verb(argc, argv, verbs, NULL);
8446 }
8447
8448 static int reload_with_fallback(void) {
8449
8450 /* First, try systemd via D-Bus. */
8451 if (daemon_reload(0, NULL, NULL) >= 0)
8452 return 0;
8453
8454 /* Nothing else worked, so let's try signals */
8455 assert(IN_SET(arg_action, ACTION_RELOAD, ACTION_REEXEC));
8456
8457 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
8458 return log_error_errno(errno, "kill() failed: %m");
8459
8460 return 0;
8461 }
8462
8463 static int start_with_fallback(void) {
8464
8465 /* First, try systemd via D-Bus. */
8466 if (start_unit(0, NULL, NULL) >= 0)
8467 return 0;
8468
8469 /* Nothing else worked, so let's try /dev/initctl */
8470 if (talk_initctl() > 0)
8471 return 0;
8472
8473 log_error("Failed to talk to init daemon.");
8474 return -EIO;
8475 }
8476
8477 static int halt_now(enum action a) {
8478 int r;
8479
8480 /* The kernel will automaticall flush ATA disks and suchlike
8481 * on reboot(), but the file systems need to be synce'd
8482 * explicitly in advance. */
8483 if (!arg_no_sync && !arg_dry_run)
8484 (void) sync();
8485
8486 /* Make sure C-A-D is handled by the kernel from this point on... */
8487 if (!arg_dry_run)
8488 (void) reboot(RB_ENABLE_CAD);
8489
8490 switch (a) {
8491
8492 case ACTION_HALT:
8493 if (!arg_quiet)
8494 log_info("Halting.");
8495 if (arg_dry_run)
8496 return 0;
8497 (void) reboot(RB_HALT_SYSTEM);
8498 return -errno;
8499
8500 case ACTION_POWEROFF:
8501 if (!arg_quiet)
8502 log_info("Powering off.");
8503 if (arg_dry_run)
8504 return 0;
8505 (void) reboot(RB_POWER_OFF);
8506 return -errno;
8507
8508 case ACTION_KEXEC:
8509 case ACTION_REBOOT: {
8510 _cleanup_free_ char *param = NULL;
8511
8512 r = read_one_line_file("/run/systemd/reboot-param", &param);
8513 if (r < 0 && r != -ENOENT)
8514 log_warning_errno(r, "Failed to read reboot parameter file: %m");
8515
8516 if (!isempty(param)) {
8517 if (!arg_quiet)
8518 log_info("Rebooting with argument '%s'.", param);
8519 if (!arg_dry_run) {
8520 (void) syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
8521 LINUX_REBOOT_CMD_RESTART2, param);
8522 log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
8523 }
8524 }
8525
8526 if (!arg_quiet)
8527 log_info("Rebooting.");
8528 if (arg_dry_run)
8529 return 0;
8530 (void) reboot(RB_AUTOBOOT);
8531 return -errno;
8532 }
8533
8534 default:
8535 assert_not_reached("Unknown action.");
8536 }
8537 }
8538
8539 static int logind_schedule_shutdown(void) {
8540
8541 #if ENABLE_LOGIND
8542 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
8543 char date[FORMAT_TIMESTAMP_MAX];
8544 const char *action;
8545 sd_bus *bus;
8546 int r;
8547
8548 r = acquire_bus(BUS_FULL, &bus);
8549 if (r < 0)
8550 return r;
8551
8552 switch (arg_action) {
8553 case ACTION_HALT:
8554 action = "halt";
8555 break;
8556 case ACTION_POWEROFF:
8557 action = "poweroff";
8558 break;
8559 case ACTION_KEXEC:
8560 action = "kexec";
8561 break;
8562 case ACTION_EXIT:
8563 action = "exit";
8564 break;
8565 case ACTION_REBOOT:
8566 default:
8567 action = "reboot";
8568 break;
8569 }
8570
8571 if (arg_dry_run)
8572 action = strjoina("dry-", action);
8573
8574 (void) logind_set_wall_message();
8575
8576 r = sd_bus_call_method(
8577 bus,
8578 "org.freedesktop.login1",
8579 "/org/freedesktop/login1",
8580 "org.freedesktop.login1.Manager",
8581 "ScheduleShutdown",
8582 &error,
8583 NULL,
8584 "st",
8585 action,
8586 arg_when);
8587 if (r < 0)
8588 return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r));
8589
8590 if (!arg_quiet)
8591 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
8592 return 0;
8593 #else
8594 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
8595 return -ENOSYS;
8596 #endif
8597 }
8598
8599 static int halt_main(void) {
8600 int r;
8601
8602 r = logind_check_inhibitors(arg_action);
8603 if (r < 0)
8604 return r;
8605
8606 if (arg_when > 0)
8607 return logind_schedule_shutdown();
8608
8609 if (geteuid() != 0) {
8610 if (arg_dry_run || arg_force > 0) {
8611 (void) must_be_root();
8612 return -EPERM;
8613 }
8614
8615 /* Try logind if we are a normal user and no special
8616 * mode applies. Maybe PolicyKit allows us to shutdown
8617 * the machine. */
8618 if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT, ACTION_HALT)) {
8619 r = logind_reboot(arg_action);
8620 if (r >= 0)
8621 return r;
8622 if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
8623 /* requested operation is not
8624 * supported on the local system or
8625 * already in progress */
8626 return r;
8627 /* on all other errors, try low-level operation */
8628 }
8629 }
8630
8631 if (!arg_dry_run && !arg_force)
8632 return start_with_fallback();
8633
8634 assert(geteuid() == 0);
8635
8636 if (!arg_no_wtmp) {
8637 if (sd_booted() > 0)
8638 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
8639 else {
8640 r = utmp_put_shutdown();
8641 if (r < 0)
8642 log_warning_errno(r, "Failed to write utmp record: %m");
8643 }
8644 }
8645
8646 if (arg_dry_run)
8647 return 0;
8648
8649 r = halt_now(arg_action);
8650 return log_error_errno(r, "Failed to reboot: %m");
8651 }
8652
8653 static int runlevel_main(void) {
8654 int r, runlevel, previous;
8655
8656 r = utmp_get_runlevel(&runlevel, &previous);
8657 if (r < 0) {
8658 puts("unknown");
8659 return r;
8660 }
8661
8662 printf("%c %c\n",
8663 previous <= 0 ? 'N' : previous,
8664 runlevel <= 0 ? 'N' : runlevel);
8665
8666 return 0;
8667 }
8668
8669 static int logind_cancel_shutdown(void) {
8670 #if ENABLE_LOGIND
8671 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
8672 sd_bus *bus;
8673 int r;
8674
8675 r = acquire_bus(BUS_FULL, &bus);
8676 if (r < 0)
8677 return r;
8678
8679 (void) logind_set_wall_message();
8680
8681 r = sd_bus_call_method(
8682 bus,
8683 "org.freedesktop.login1",
8684 "/org/freedesktop/login1",
8685 "org.freedesktop.login1.Manager",
8686 "CancelScheduledShutdown",
8687 &error,
8688 NULL, NULL);
8689 if (r < 0)
8690 return log_warning_errno(r, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error, r));
8691
8692 return 0;
8693 #else
8694 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
8695 return -ENOSYS;
8696 #endif
8697 }
8698
8699 int main(int argc, char*argv[]) {
8700 int r;
8701
8702 argv_cmdline = argv[0];
8703
8704 setlocale(LC_ALL, "");
8705 log_parse_environment();
8706 log_open();
8707 sigbus_install();
8708
8709 /* Explicitly not on_tty() to avoid setting cached value.
8710 * This becomes relevant for piping output which might be
8711 * ellipsized. */
8712 original_stdout_is_tty = isatty(STDOUT_FILENO);
8713
8714 r = parse_argv(argc, argv);
8715 if (r <= 0)
8716 goto finish;
8717
8718 if (arg_action != ACTION_SYSTEMCTL && running_in_chroot() > 0) {
8719
8720 if (!arg_quiet)
8721 log_info("Running in chroot, ignoring request.");
8722 r = 0;
8723 goto finish;
8724 }
8725
8726 /* systemctl_main() will print an error message for the bus
8727 * connection, but only if it needs to */
8728
8729 switch (arg_action) {
8730
8731 case ACTION_SYSTEMCTL:
8732 r = systemctl_main(argc, argv);
8733 break;
8734
8735 /* Legacy command aliases set arg_action. They provide some fallbacks,
8736 * e.g. to tell sysvinit to reboot after you have installed systemd
8737 * binaries. */
8738
8739 case ACTION_HALT:
8740 case ACTION_POWEROFF:
8741 case ACTION_REBOOT:
8742 case ACTION_KEXEC:
8743 r = halt_main();
8744 break;
8745
8746 case ACTION_RUNLEVEL2:
8747 case ACTION_RUNLEVEL3:
8748 case ACTION_RUNLEVEL4:
8749 case ACTION_RUNLEVEL5:
8750 case ACTION_RESCUE:
8751 r = start_with_fallback();
8752 break;
8753
8754 case ACTION_RELOAD:
8755 case ACTION_REEXEC:
8756 r = reload_with_fallback();
8757 break;
8758
8759 case ACTION_CANCEL_SHUTDOWN:
8760 r = logind_cancel_shutdown();
8761 break;
8762
8763 case ACTION_RUNLEVEL:
8764 r = runlevel_main();
8765 break;
8766
8767 case ACTION_EXIT:
8768 case ACTION_SUSPEND:
8769 case ACTION_HIBERNATE:
8770 case ACTION_HYBRID_SLEEP:
8771 case ACTION_EMERGENCY:
8772 case ACTION_DEFAULT:
8773 /* systemctl verbs with no equivalent in the legacy commands.
8774 * These cannot appear in arg_action. Fall through. */
8775
8776 case _ACTION_INVALID:
8777 default:
8778 assert_not_reached("Unknown action");
8779 }
8780
8781 finish:
8782 release_busses();
8783
8784 pager_close();
8785 ask_password_agent_close();
8786 polkit_agent_close();
8787
8788 strv_free(arg_types);
8789 strv_free(arg_states);
8790 strv_free(arg_properties);
8791
8792 strv_free(arg_wall);
8793 free(arg_root);
8794 free(arg_esp_path);
8795
8796 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
8797 return r < 0 ? EXIT_FAILURE : r;
8798 }