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