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