]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/systemctl/systemctl.c
core: add two new unit file settings: StandardInputData= + StandardInputText=
[thirdparty/systemd.git] / src / systemctl / systemctl.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5 Copyright 2013 Marc-Antoine Perennou
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <getopt.h>
24 #include <linux/reboot.h>
25 #include <locale.h>
26 #include <stdbool.h>
27 #include <stddef.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <sys/reboot.h>
31 #include <sys/socket.h>
32 #include <unistd.h>
33
34 #include "sd-bus.h"
35 #include "sd-daemon.h"
36 #include "sd-login.h"
37
38 #include "alloc-util.h"
39 #include "bus-common-errors.h"
40 #include "bus-error.h"
41 #include "bus-message.h"
42 #include "bus-unit-util.h"
43 #include "bus-util.h"
44 #include "cgroup-show.h"
45 #include "cgroup-util.h"
46 #include "copy.h"
47 #include "dropin.h"
48 #include "efivars.h"
49 #include "env-util.h"
50 #include "escape.h"
51 #include "exit-status.h"
52 #include "fd-util.h"
53 #include "fileio.h"
54 #include "format-util.h"
55 #include "fs-util.h"
56 #include "glob-util.h"
57 #include "hostname-util.h"
58 #include "hexdecoct.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 } else if (contents[1] == SD_BUS_TYPE_BYTE && streq(name, "StandardInputData")) {
4983 _cleanup_free_ char *h = NULL;
4984 const void *p;
4985 size_t sz;
4986 ssize_t n;
4987
4988 r = sd_bus_message_read_array(m, 'y', &p, &sz);
4989 if (r < 0)
4990 return bus_log_parse_error(r);
4991
4992 n = base64mem(p, sz, &h);
4993 if (n < 0)
4994 return log_oom();
4995
4996 print_prop(name, "%s", h);
4997
4998 return 0;
4999 }
5000
5001 break;
5002 }
5003
5004 r = bus_print_property(name, m, arg_value, arg_all);
5005 if (r < 0)
5006 return bus_log_parse_error(r);
5007
5008 if (r == 0) {
5009 r = sd_bus_message_skip(m, contents);
5010 if (r < 0)
5011 return bus_log_parse_error(r);
5012
5013 if (arg_all)
5014 printf("%s=[unprintable]\n", name);
5015 }
5016
5017 return 0;
5018 }
5019
5020 static int show_one(
5021 const char *verb,
5022 sd_bus *bus,
5023 const char *path,
5024 const char *unit,
5025 bool show_properties,
5026 bool *new_line,
5027 bool *ellipsized) {
5028
5029 static const struct bus_properties_map property_map[] = {
5030 { "LoadState", "s", map_string_no_copy, offsetof(UnitStatusInfo, load_state) },
5031 { "ActiveState", "s", map_string_no_copy, offsetof(UnitStatusInfo, active_state) },
5032 {}
5033 };
5034
5035 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
5036 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5037 _cleanup_set_free_ Set *found_properties = NULL;
5038 _cleanup_(unit_status_info_free) UnitStatusInfo info = {
5039 .memory_current = (uint64_t) -1,
5040 .memory_high = CGROUP_LIMIT_MAX,
5041 .memory_max = CGROUP_LIMIT_MAX,
5042 .memory_swap_max = CGROUP_LIMIT_MAX,
5043 .memory_limit = (uint64_t) -1,
5044 .cpu_usage_nsec = (uint64_t) -1,
5045 .tasks_current = (uint64_t) -1,
5046 .tasks_max = (uint64_t) -1,
5047 .ip_ingress_bytes = (uint64_t) -1,
5048 .ip_egress_bytes = (uint64_t) -1,
5049 };
5050 int r;
5051
5052 assert(path);
5053 assert(new_line);
5054
5055 log_debug("Showing one %s", path);
5056
5057 r = sd_bus_call_method(
5058 bus,
5059 "org.freedesktop.systemd1",
5060 path,
5061 "org.freedesktop.DBus.Properties",
5062 "GetAll",
5063 &error,
5064 &reply,
5065 "s", "");
5066 if (r < 0)
5067 return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
5068
5069 if (unit) {
5070 r = bus_message_map_all_properties(reply, property_map, &error, &info);
5071 if (r < 0)
5072 return log_error_errno(r, "Failed to map properties: %s", bus_error_message(&error, r));
5073
5074 if (streq_ptr(info.load_state, "not-found") && streq_ptr(info.active_state, "inactive")) {
5075 log_full(streq(verb, "status") ? LOG_ERR : LOG_DEBUG,
5076 "Unit %s could not be found.", unit);
5077
5078 if (streq(verb, "status"))
5079 return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN;
5080
5081 if (!streq(verb, "show"))
5082 return -ENOENT;
5083 }
5084
5085 r = sd_bus_message_rewind(reply, true);
5086 if (r < 0)
5087 return log_error_errno(r, "Failed to rewind: %s", bus_error_message(&error, r));
5088 }
5089
5090 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
5091 if (r < 0)
5092 return bus_log_parse_error(r);
5093
5094 if (*new_line)
5095 printf("\n");
5096
5097 *new_line = true;
5098
5099 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
5100 const char *name, *contents;
5101
5102 r = sd_bus_message_read(reply, "s", &name);
5103 if (r < 0)
5104 return bus_log_parse_error(r);
5105
5106 r = sd_bus_message_peek_type(reply, NULL, &contents);
5107 if (r < 0)
5108 return bus_log_parse_error(r);
5109
5110 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
5111 if (r < 0)
5112 return bus_log_parse_error(r);
5113
5114 if (show_properties) {
5115 r = set_ensure_allocated(&found_properties, &string_hash_ops);
5116 if (r < 0)
5117 return log_oom();
5118
5119 r = set_put(found_properties, name);
5120 if (r < 0 && r != EEXIST)
5121 return log_oom();
5122
5123 r = print_property(name, reply, contents);
5124 } else
5125 r = status_property(name, reply, &info, contents);
5126 if (r < 0)
5127 return r;
5128
5129 r = sd_bus_message_exit_container(reply);
5130 if (r < 0)
5131 return bus_log_parse_error(r);
5132
5133 r = sd_bus_message_exit_container(reply);
5134 if (r < 0)
5135 return bus_log_parse_error(r);
5136 }
5137 if (r < 0)
5138 return bus_log_parse_error(r);
5139
5140 r = sd_bus_message_exit_container(reply);
5141 if (r < 0)
5142 return bus_log_parse_error(r);
5143
5144 r = 0;
5145 if (show_properties) {
5146 char **pp;
5147
5148 STRV_FOREACH(pp, arg_properties)
5149 if (!set_contains(found_properties, *pp))
5150 log_debug("Property %s does not exist.", *pp);
5151
5152 } else if (streq(verb, "help"))
5153 show_unit_help(&info);
5154 else if (streq(verb, "status")) {
5155 print_status_info(bus, &info, ellipsized);
5156
5157 if (info.active_state && !STR_IN_SET(info.active_state, "active", "reloading"))
5158 r = EXIT_PROGRAM_NOT_RUNNING;
5159 else
5160 r = EXIT_PROGRAM_RUNNING_OR_SERVICE_OK;
5161 }
5162
5163 return r;
5164 }
5165
5166 static int get_unit_dbus_path_by_pid(
5167 sd_bus *bus,
5168 uint32_t pid,
5169 char **unit) {
5170
5171 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5172 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
5173 char *u;
5174 int r;
5175
5176 r = sd_bus_call_method(
5177 bus,
5178 "org.freedesktop.systemd1",
5179 "/org/freedesktop/systemd1",
5180 "org.freedesktop.systemd1.Manager",
5181 "GetUnitByPID",
5182 &error,
5183 &reply,
5184 "u", pid);
5185 if (r < 0)
5186 return log_error_errno(r, "Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
5187
5188 r = sd_bus_message_read(reply, "o", &u);
5189 if (r < 0)
5190 return bus_log_parse_error(r);
5191
5192 u = strdup(u);
5193 if (!u)
5194 return log_oom();
5195
5196 *unit = u;
5197 return 0;
5198 }
5199
5200 static int show_all(
5201 const char* verb,
5202 sd_bus *bus,
5203 bool show_properties,
5204 bool *new_line,
5205 bool *ellipsized) {
5206
5207 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
5208 _cleanup_free_ UnitInfo *unit_infos = NULL;
5209 const UnitInfo *u;
5210 unsigned c;
5211 int r, ret = 0;
5212
5213 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
5214 if (r < 0)
5215 return r;
5216
5217 pager_open(arg_no_pager, false);
5218
5219 c = (unsigned) r;
5220
5221 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
5222
5223 for (u = unit_infos; u < unit_infos + c; u++) {
5224 _cleanup_free_ char *p = NULL;
5225
5226 p = unit_dbus_path_from_name(u->id);
5227 if (!p)
5228 return log_oom();
5229
5230 r = show_one(verb, bus, p, u->id, show_properties, new_line, ellipsized);
5231 if (r < 0)
5232 return r;
5233 else if (r > 0 && ret == 0)
5234 ret = r;
5235 }
5236
5237 return ret;
5238 }
5239
5240 static int show_system_status(sd_bus *bus) {
5241 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
5242 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5243 _cleanup_(machine_info_clear) struct machine_info mi = {};
5244 _cleanup_free_ char *hn = NULL;
5245 const char *on, *off;
5246 int r;
5247
5248 hn = gethostname_malloc();
5249 if (!hn)
5250 return log_oom();
5251
5252 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &error, &mi);
5253 if (r < 0)
5254 return log_error_errno(r, "Failed to read server status: %s", bus_error_message(&error, r));
5255
5256 if (streq_ptr(mi.state, "degraded")) {
5257 on = ansi_highlight_red();
5258 off = ansi_normal();
5259 } else if (streq_ptr(mi.state, "running")) {
5260 on = ansi_highlight_green();
5261 off = ansi_normal();
5262 } else {
5263 on = ansi_highlight_yellow();
5264 off = ansi_normal();
5265 }
5266
5267 printf("%s%s%s %s\n", on, special_glyph(BLACK_CIRCLE), off, arg_host ? arg_host : hn);
5268
5269 printf(" State: %s%s%s\n",
5270 on, strna(mi.state), off);
5271
5272 printf(" Jobs: %" PRIu32 " queued\n", mi.n_jobs);
5273 printf(" Failed: %" PRIu32 " units\n", mi.n_failed_units);
5274
5275 printf(" Since: %s; %s\n",
5276 format_timestamp(since2, sizeof(since2), mi.timestamp),
5277 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
5278
5279 printf(" CGroup: %s\n", mi.control_group ?: "/");
5280 if (IN_SET(arg_transport,
5281 BUS_TRANSPORT_LOCAL,
5282 BUS_TRANSPORT_MACHINE)) {
5283 static const char prefix[] = " ";
5284 unsigned c;
5285
5286 c = columns();
5287 if (c > sizeof(prefix) - 1)
5288 c -= sizeof(prefix) - 1;
5289 else
5290 c = 0;
5291
5292 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, get_output_flags());
5293 }
5294
5295 return 0;
5296 }
5297
5298 static int show(int argc, char *argv[], void *userdata) {
5299 bool show_properties, show_status, show_help, new_line = false;
5300 bool ellipsized = false;
5301 int r, ret = 0;
5302 sd_bus *bus;
5303
5304 assert(argv);
5305
5306 show_properties = streq(argv[0], "show");
5307 show_status = streq(argv[0], "status");
5308 show_help = streq(argv[0], "help");
5309
5310 if (show_help && argc <= 1) {
5311 log_error("This command expects one or more unit names. Did you mean --help?");
5312 return -EINVAL;
5313 }
5314
5315 r = acquire_bus(BUS_MANAGER, &bus);
5316 if (r < 0)
5317 return r;
5318
5319 pager_open(arg_no_pager, false);
5320
5321 if (show_status)
5322 /* Increase max number of open files to 16K if we can, we
5323 * might needs this when browsing journal files, which might
5324 * be split up into many files. */
5325 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
5326
5327 /* If no argument is specified inspect the manager itself */
5328 if (show_properties && argc <= 1)
5329 return show_one(argv[0], bus, "/org/freedesktop/systemd1", NULL, show_properties, &new_line, &ellipsized);
5330
5331 if (show_status && argc <= 1) {
5332
5333 show_system_status(bus);
5334 new_line = true;
5335
5336 if (arg_all)
5337 ret = show_all(argv[0], bus, false, &new_line, &ellipsized);
5338 } else {
5339 _cleanup_free_ char **patterns = NULL;
5340 char **name;
5341
5342 STRV_FOREACH(name, strv_skip(argv, 1)) {
5343 _cleanup_free_ char *path = NULL, *unit = NULL;
5344 uint32_t id;
5345
5346 if (safe_atou32(*name, &id) < 0) {
5347 if (strv_push(&patterns, *name) < 0)
5348 return log_oom();
5349
5350 continue;
5351 } else if (show_properties) {
5352 /* Interpret as job id */
5353 if (asprintf(&path, "/org/freedesktop/systemd1/job/%u", id) < 0)
5354 return log_oom();
5355
5356 } else {
5357 /* Interpret as PID */
5358 r = get_unit_dbus_path_by_pid(bus, id, &path);
5359 if (r < 0) {
5360 ret = r;
5361 continue;
5362 }
5363
5364 r = unit_name_from_dbus_path(path, &unit);
5365 if (r < 0)
5366 return log_oom();
5367 }
5368
5369 r = show_one(argv[0], bus, path, unit, show_properties, &new_line, &ellipsized);
5370 if (r < 0)
5371 return r;
5372 else if (r > 0 && ret == 0)
5373 ret = r;
5374 }
5375
5376 if (!strv_isempty(patterns)) {
5377 _cleanup_strv_free_ char **names = NULL;
5378
5379 r = expand_names(bus, patterns, NULL, &names);
5380 if (r < 0)
5381 return log_error_errno(r, "Failed to expand names: %m");
5382
5383 STRV_FOREACH(name, names) {
5384 _cleanup_free_ char *path;
5385
5386 path = unit_dbus_path_from_name(*name);
5387 if (!path)
5388 return log_oom();
5389
5390 r = show_one(argv[0], bus, path, *name, show_properties, &new_line, &ellipsized);
5391 if (r < 0)
5392 return r;
5393 if (r > 0 && ret == 0)
5394 ret = r;
5395 }
5396 }
5397 }
5398
5399 if (ellipsized && !arg_quiet)
5400 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
5401
5402 return ret;
5403 }
5404
5405 static int cat_file(const char *filename, bool newline) {
5406 _cleanup_close_ int fd;
5407
5408 fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
5409 if (fd < 0)
5410 return -errno;
5411
5412 printf("%s%s# %s%s\n",
5413 newline ? "\n" : "",
5414 ansi_highlight_blue(),
5415 filename,
5416 ansi_normal());
5417 fflush(stdout);
5418
5419 return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, 0);
5420 }
5421
5422 static int cat(int argc, char *argv[], void *userdata) {
5423 _cleanup_lookup_paths_free_ LookupPaths lp = {};
5424 _cleanup_strv_free_ char **names = NULL;
5425 char **name;
5426 sd_bus *bus;
5427 bool first = true;
5428 int r;
5429
5430 if (arg_transport != BUS_TRANSPORT_LOCAL) {
5431 log_error("Cannot remotely cat units.");
5432 return -EINVAL;
5433 }
5434
5435 r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
5436 if (r < 0)
5437 return log_error_errno(r, "Failed to determine unit paths: %m");
5438
5439 r = acquire_bus(BUS_MANAGER, &bus);
5440 if (r < 0)
5441 return r;
5442
5443 r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
5444 if (r < 0)
5445 return log_error_errno(r, "Failed to expand names: %m");
5446
5447 pager_open(arg_no_pager, false);
5448
5449 STRV_FOREACH(name, names) {
5450 _cleanup_free_ char *fragment_path = NULL;
5451 _cleanup_strv_free_ char **dropin_paths = NULL;
5452 char **path;
5453
5454 r = unit_find_paths(bus, *name, &lp, &fragment_path, &dropin_paths);
5455 if (r < 0)
5456 return r;
5457 else if (r == 0)
5458 return -ENOENT;
5459
5460 if (first)
5461 first = false;
5462 else
5463 puts("");
5464
5465 if (need_daemon_reload(bus, *name) > 0) /* ignore errors (<0), this is informational output */
5466 fprintf(stderr,
5467 "%s# Warning: %s changed on disk, the version systemd has loaded is outdated.\n"
5468 "%s# This output shows the current version of the unit's original fragment and drop-in files.\n"
5469 "%s# If fragments or drop-ins were added or removed, they are not properly reflected in this output.\n"
5470 "%s# Run 'systemctl%s daemon-reload' to reload units.%s\n",
5471 ansi_highlight_red(),
5472 *name,
5473 ansi_highlight_red(),
5474 ansi_highlight_red(),
5475 ansi_highlight_red(),
5476 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user",
5477 ansi_normal());
5478
5479 if (fragment_path) {
5480 r = cat_file(fragment_path, false);
5481 if (r < 0)
5482 return log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
5483 }
5484
5485 STRV_FOREACH(path, dropin_paths) {
5486 r = cat_file(*path, path == dropin_paths);
5487 if (r < 0)
5488 return log_warning_errno(r, "Failed to cat %s: %m", *path);
5489 }
5490 }
5491
5492 return 0;
5493 }
5494
5495 static int set_property(int argc, char *argv[], void *userdata) {
5496 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
5497 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5498 _cleanup_free_ char *n = NULL;
5499 sd_bus *bus;
5500 int r;
5501
5502 r = acquire_bus(BUS_MANAGER, &bus);
5503 if (r < 0)
5504 return r;
5505
5506 polkit_agent_open_maybe();
5507
5508 r = sd_bus_message_new_method_call(
5509 bus,
5510 &m,
5511 "org.freedesktop.systemd1",
5512 "/org/freedesktop/systemd1",
5513 "org.freedesktop.systemd1.Manager",
5514 "SetUnitProperties");
5515 if (r < 0)
5516 return bus_log_create_error(r);
5517
5518 r = unit_name_mangle(argv[1], UNIT_NAME_NOGLOB, &n);
5519 if (r < 0)
5520 return log_error_errno(r, "Failed to mangle unit name: %m");
5521
5522 r = sd_bus_message_append(m, "sb", n, arg_runtime);
5523 if (r < 0)
5524 return bus_log_create_error(r);
5525
5526 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
5527 if (r < 0)
5528 return bus_log_create_error(r);
5529
5530 r = bus_append_unit_property_assignment_many(m, strv_skip(argv, 2));
5531 if (r < 0)
5532 return r;
5533
5534 r = sd_bus_message_close_container(m);
5535 if (r < 0)
5536 return bus_log_create_error(r);
5537
5538 r = sd_bus_call(bus, m, 0, &error, NULL);
5539 if (r < 0)
5540 return log_error_errno(r, "Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
5541
5542 return 0;
5543 }
5544
5545 static int daemon_reload(int argc, char *argv[], void *userdata) {
5546 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5547 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
5548 const char *method;
5549 sd_bus *bus;
5550 int r;
5551
5552 r = acquire_bus(BUS_MANAGER, &bus);
5553 if (r < 0)
5554 return r;
5555
5556 polkit_agent_open_maybe();
5557
5558 switch (arg_action) {
5559
5560 case ACTION_RELOAD:
5561 method = "Reload";
5562 break;
5563
5564 case ACTION_REEXEC:
5565 method = "Reexecute";
5566 break;
5567
5568 case ACTION_SYSTEMCTL:
5569 method = streq(argv[0], "daemon-reexec") ? "Reexecute" :
5570 /* "daemon-reload" */ "Reload";
5571 break;
5572
5573 default:
5574 assert_not_reached("Unexpected action");
5575 }
5576
5577 r = sd_bus_message_new_method_call(
5578 bus,
5579 &m,
5580 "org.freedesktop.systemd1",
5581 "/org/freedesktop/systemd1",
5582 "org.freedesktop.systemd1.Manager",
5583 method);
5584 if (r < 0)
5585 return bus_log_create_error(r);
5586
5587 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
5588 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
5589 * their timeout, and for everything else there's the same time budget in place. */
5590
5591 r = sd_bus_call(bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL);
5592
5593 /* On reexecution, we expect a disconnect, not a reply */
5594 if (IN_SET(r, -ETIMEDOUT, -ECONNRESET) && streq(method, "Reexecute"))
5595 r = 0;
5596
5597 if (r < 0 && arg_action == ACTION_SYSTEMCTL)
5598 return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
5599
5600 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5601 * old ways of doing things, hence don't log any error in that case here. */
5602
5603 return r < 0 ? r : 0;
5604 }
5605
5606 static int trivial_method(int argc, char *argv[], void *userdata) {
5607 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5608 const char *method;
5609 sd_bus *bus;
5610 int r;
5611
5612 r = acquire_bus(BUS_MANAGER, &bus);
5613 if (r < 0)
5614 return r;
5615
5616 polkit_agent_open_maybe();
5617
5618 method =
5619 streq(argv[0], "clear-jobs") ||
5620 streq(argv[0], "cancel") ? "ClearJobs" :
5621 streq(argv[0], "reset-failed") ? "ResetFailed" :
5622 streq(argv[0], "halt") ? "Halt" :
5623 streq(argv[0], "reboot") ? "Reboot" :
5624 streq(argv[0], "kexec") ? "KExec" :
5625 streq(argv[0], "exit") ? "Exit" :
5626 /* poweroff */ "PowerOff";
5627
5628 r = sd_bus_call_method(
5629 bus,
5630 "org.freedesktop.systemd1",
5631 "/org/freedesktop/systemd1",
5632 "org.freedesktop.systemd1.Manager",
5633 method,
5634 &error,
5635 NULL,
5636 NULL);
5637 if (r < 0 && arg_action == ACTION_SYSTEMCTL)
5638 return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
5639
5640 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5641 * old ways of doing things, hence don't log any error in that case here. */
5642
5643 return r < 0 ? r : 0;
5644 }
5645
5646 static int reset_failed(int argc, char *argv[], void *userdata) {
5647 _cleanup_strv_free_ char **names = NULL;
5648 sd_bus *bus;
5649 char **name;
5650 int r, q;
5651
5652 if (argc <= 1)
5653 return trivial_method(argc, argv, userdata);
5654
5655 r = acquire_bus(BUS_MANAGER, &bus);
5656 if (r < 0)
5657 return r;
5658
5659 polkit_agent_open_maybe();
5660
5661 r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
5662 if (r < 0)
5663 return log_error_errno(r, "Failed to expand names: %m");
5664
5665 STRV_FOREACH(name, names) {
5666 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5667
5668 q = sd_bus_call_method(
5669 bus,
5670 "org.freedesktop.systemd1",
5671 "/org/freedesktop/systemd1",
5672 "org.freedesktop.systemd1.Manager",
5673 "ResetFailedUnit",
5674 &error,
5675 NULL,
5676 "s", *name);
5677 if (q < 0) {
5678 log_error_errno(q, "Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
5679 if (r == 0)
5680 r = q;
5681 }
5682 }
5683
5684 return r;
5685 }
5686
5687 static int print_variable(const char *s) {
5688 const char *sep;
5689 _cleanup_free_ char *esc = NULL;
5690
5691 sep = strchr(s, '=');
5692 if (!sep) {
5693 log_error("Invalid environment block");
5694 return -EUCLEAN;
5695 }
5696
5697 esc = shell_maybe_quote(sep + 1, ESCAPE_POSIX);
5698 if (!esc)
5699 return log_oom();
5700
5701 printf("%.*s=%s\n", (int)(sep-s), s, esc);
5702 return 0;
5703 }
5704
5705 static int show_environment(int argc, char *argv[], void *userdata) {
5706 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5707 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
5708 const char *text;
5709 sd_bus *bus;
5710 int r;
5711
5712 r = acquire_bus(BUS_MANAGER, &bus);
5713 if (r < 0)
5714 return r;
5715
5716 pager_open(arg_no_pager, false);
5717
5718 r = sd_bus_get_property(
5719 bus,
5720 "org.freedesktop.systemd1",
5721 "/org/freedesktop/systemd1",
5722 "org.freedesktop.systemd1.Manager",
5723 "Environment",
5724 &error,
5725 &reply,
5726 "as");
5727 if (r < 0)
5728 return log_error_errno(r, "Failed to get environment: %s", bus_error_message(&error, r));
5729
5730 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
5731 if (r < 0)
5732 return bus_log_parse_error(r);
5733
5734 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0) {
5735 r = print_variable(text);
5736 if (r < 0)
5737 return r;
5738 }
5739 if (r < 0)
5740 return bus_log_parse_error(r);
5741
5742 r = sd_bus_message_exit_container(reply);
5743 if (r < 0)
5744 return bus_log_parse_error(r);
5745
5746 return 0;
5747 }
5748
5749 static int switch_root(int argc, char *argv[], void *userdata) {
5750 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5751 _cleanup_free_ char *cmdline_init = NULL;
5752 const char *root, *init;
5753 sd_bus *bus;
5754 int r;
5755
5756 if (arg_transport != BUS_TRANSPORT_LOCAL) {
5757 log_error("Cannot switch root remotely.");
5758 return -EINVAL;
5759 }
5760
5761 if (argc < 2 || argc > 3) {
5762 log_error("Wrong number of arguments.");
5763 return -EINVAL;
5764 }
5765
5766 root = argv[1];
5767
5768 if (argc >= 3)
5769 init = argv[2];
5770 else {
5771 r = parse_env_file("/proc/cmdline", WHITESPACE,
5772 "init", &cmdline_init,
5773 NULL);
5774 if (r < 0)
5775 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
5776
5777 init = cmdline_init;
5778 }
5779
5780 init = empty_to_null(init);
5781 if (init) {
5782 const char *root_systemd_path = NULL, *root_init_path = NULL;
5783
5784 root_systemd_path = strjoina(root, "/" SYSTEMD_BINARY_PATH);
5785 root_init_path = strjoina(root, "/", init);
5786
5787 /* If the passed init is actually the same as the
5788 * systemd binary, then let's suppress it. */
5789 if (files_same(root_init_path, root_systemd_path, 0) > 0)
5790 init = NULL;
5791 }
5792
5793 /* Instruct PID1 to exclude us from its killing spree applied during
5794 * the transition. Otherwise we would exit with a failure status even
5795 * though the switch to the new root has succeed. */
5796 argv_cmdline[0] = '@';
5797
5798 r = acquire_bus(BUS_MANAGER, &bus);
5799 if (r < 0)
5800 return r;
5801
5802 /* If we are slow to exit after the root switch, the new systemd instance
5803 * will send us a signal to terminate. Just ignore it and exit normally.
5804 * This way the unit does not end up as failed.
5805 */
5806 r = ignore_signals(SIGTERM, -1);
5807 if (r < 0)
5808 log_warning_errno(r, "Failed to change disposition of SIGTERM to ignore: %m");
5809
5810 log_debug("Switching root - root: %s; init: %s", root, strna(init));
5811
5812 r = sd_bus_call_method(
5813 bus,
5814 "org.freedesktop.systemd1",
5815 "/org/freedesktop/systemd1",
5816 "org.freedesktop.systemd1.Manager",
5817 "SwitchRoot",
5818 &error,
5819 NULL,
5820 "ss", root, init);
5821 if (r < 0) {
5822 (void) default_signals(SIGTERM, -1);
5823
5824 return log_error_errno(r, "Failed to switch root: %s", bus_error_message(&error, r));
5825 }
5826
5827 return 0;
5828 }
5829
5830 static int set_environment(int argc, char *argv[], void *userdata) {
5831 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5832 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
5833 const char *method;
5834 sd_bus *bus;
5835 int r;
5836
5837 assert(argc > 1);
5838 assert(argv);
5839
5840 r = acquire_bus(BUS_MANAGER, &bus);
5841 if (r < 0)
5842 return r;
5843
5844 polkit_agent_open_maybe();
5845
5846 method = streq(argv[0], "set-environment")
5847 ? "SetEnvironment"
5848 : "UnsetEnvironment";
5849
5850 r = sd_bus_message_new_method_call(
5851 bus,
5852 &m,
5853 "org.freedesktop.systemd1",
5854 "/org/freedesktop/systemd1",
5855 "org.freedesktop.systemd1.Manager",
5856 method);
5857 if (r < 0)
5858 return bus_log_create_error(r);
5859
5860 r = sd_bus_message_append_strv(m, strv_skip(argv, 1));
5861 if (r < 0)
5862 return bus_log_create_error(r);
5863
5864 r = sd_bus_call(bus, m, 0, &error, NULL);
5865 if (r < 0)
5866 return log_error_errno(r, "Failed to set environment: %s", bus_error_message(&error, r));
5867
5868 return 0;
5869 }
5870
5871 static int import_environment(int argc, char *argv[], void *userdata) {
5872 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
5873 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
5874 sd_bus *bus;
5875 int r;
5876
5877 r = acquire_bus(BUS_MANAGER, &bus);
5878 if (r < 0)
5879 return r;
5880
5881 polkit_agent_open_maybe();
5882
5883 r = sd_bus_message_new_method_call(
5884 bus,
5885 &m,
5886 "org.freedesktop.systemd1",
5887 "/org/freedesktop/systemd1",
5888 "org.freedesktop.systemd1.Manager",
5889 "SetEnvironment");
5890 if (r < 0)
5891 return bus_log_create_error(r);
5892
5893 if (argc < 2)
5894 r = sd_bus_message_append_strv(m, environ);
5895 else {
5896 char **a, **b;
5897
5898 r = sd_bus_message_open_container(m, 'a', "s");
5899 if (r < 0)
5900 return bus_log_create_error(r);
5901
5902 STRV_FOREACH(a, strv_skip(argv, 1)) {
5903
5904 if (!env_name_is_valid(*a)) {
5905 log_error("Not a valid environment variable name: %s", *a);
5906 return -EINVAL;
5907 }
5908
5909 STRV_FOREACH(b, environ) {
5910 const char *eq;
5911
5912 eq = startswith(*b, *a);
5913 if (eq && *eq == '=') {
5914
5915 r = sd_bus_message_append(m, "s", *b);
5916 if (r < 0)
5917 return bus_log_create_error(r);
5918
5919 break;
5920 }
5921 }
5922 }
5923
5924 r = sd_bus_message_close_container(m);
5925 }
5926 if (r < 0)
5927 return bus_log_create_error(r);
5928
5929 r = sd_bus_call(bus, m, 0, &error, NULL);
5930 if (r < 0)
5931 return log_error_errno(r, "Failed to import environment: %s", bus_error_message(&error, r));
5932
5933 return 0;
5934 }
5935
5936 static int enable_sysv_units(const char *verb, char **args) {
5937 int r = 0;
5938
5939 #if HAVE_SYSV_COMPAT
5940 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5941 unsigned f = 0;
5942
5943 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5944
5945 if (arg_scope != UNIT_FILE_SYSTEM)
5946 return 0;
5947
5948 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5949 return 0;
5950
5951 if (!STR_IN_SET(verb,
5952 "enable",
5953 "disable",
5954 "is-enabled"))
5955 return 0;
5956
5957 r = lookup_paths_init(&paths, arg_scope, LOOKUP_PATHS_EXCLUDE_GENERATED, arg_root);
5958 if (r < 0)
5959 return r;
5960
5961 r = 0;
5962 while (args[f]) {
5963
5964 const char *argv[] = {
5965 ROOTLIBEXECDIR "/systemd-sysv-install",
5966 NULL,
5967 NULL,
5968 NULL,
5969 NULL,
5970 };
5971
5972 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5973 bool found_native = false, found_sysv;
5974 siginfo_t status;
5975 const char *name;
5976 unsigned c = 1;
5977 pid_t pid;
5978 int j;
5979
5980 name = args[f++];
5981
5982 if (!endswith(name, ".service"))
5983 continue;
5984
5985 if (path_is_absolute(name))
5986 continue;
5987
5988 j = unit_file_exists(arg_scope, &paths, name);
5989 if (j < 0 && !IN_SET(j, -ELOOP, -ERFKILL, -EADDRNOTAVAIL))
5990 return log_error_errno(j, "Failed to lookup unit file state: %m");
5991 found_native = j != 0;
5992
5993 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5994 * prefer the native unit */
5995 if (found_native && streq(verb, "is-enabled"))
5996 continue;
5997
5998 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5999 if (!p)
6000 return log_oom();
6001
6002 p[strlen(p) - strlen(".service")] = 0;
6003 found_sysv = access(p, F_OK) >= 0;
6004 if (!found_sysv)
6005 continue;
6006
6007 if (!arg_quiet) {
6008 if (found_native)
6009 log_info("Synchronizing state of %s with SysV service script with %s.", name, argv[0]);
6010 else
6011 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name);
6012 }
6013
6014 if (!isempty(arg_root))
6015 argv[c++] = q = strappend("--root=", arg_root);
6016
6017 argv[c++] = verb;
6018 argv[c++] = basename(p);
6019 argv[c] = NULL;
6020
6021 l = strv_join((char**)argv, " ");
6022 if (!l)
6023 return log_oom();
6024
6025 if (!arg_quiet)
6026 log_info("Executing: %s", l);
6027
6028 pid = fork();
6029 if (pid < 0)
6030 return log_error_errno(errno, "Failed to fork: %m");
6031 else if (pid == 0) {
6032 /* Child */
6033
6034 (void) reset_all_signal_handlers();
6035 (void) reset_signal_mask();
6036
6037 execv(argv[0], (char**) argv);
6038 log_error_errno(errno, "Failed to execute %s: %m", argv[0]);
6039 _exit(EXIT_FAILURE);
6040 }
6041
6042 j = wait_for_terminate(pid, &status);
6043 if (j < 0)
6044 return log_error_errno(j, "Failed to wait for child: %m");
6045
6046 if (status.si_code == CLD_EXITED) {
6047 if (streq(verb, "is-enabled")) {
6048 if (status.si_status == 0) {
6049 if (!arg_quiet)
6050 puts("enabled");
6051 r = 1;
6052 } else {
6053 if (!arg_quiet)
6054 puts("disabled");
6055 }
6056
6057 } else if (status.si_status != 0)
6058 return -EBADE; /* We don't warn here, under the assumption the script already showed an explanation */
6059 } else {
6060 log_error("Unexpected waitid() result.");
6061 return -EPROTO;
6062 }
6063
6064 if (found_native)
6065 continue;
6066
6067 /* Remove this entry, so that we don't try enabling it as native unit */
6068 assert(f > 0);
6069 f--;
6070 assert(args[f] == name);
6071 strv_remove(args, name);
6072 }
6073
6074 #endif
6075 return r;
6076 }
6077
6078 static int mangle_names(char **original_names, char ***mangled_names) {
6079 char **i, **l, **name;
6080 int r;
6081
6082 l = i = new(char*, strv_length(original_names) + 1);
6083 if (!l)
6084 return log_oom();
6085
6086 STRV_FOREACH(name, original_names) {
6087
6088 /* When enabling units qualified path names are OK,
6089 * too, hence allow them explicitly. */
6090
6091 if (is_path(*name)) {
6092 *i = strdup(*name);
6093 if (!*i) {
6094 strv_free(l);
6095 return log_oom();
6096 }
6097 } else {
6098 r = unit_name_mangle(*name, UNIT_NAME_NOGLOB, i);
6099 if (r < 0) {
6100 *i = NULL;
6101 strv_free(l);
6102 return log_error_errno(r, "Failed to mangle unit name: %m");
6103 }
6104 }
6105
6106 i++;
6107 }
6108
6109 *i = NULL;
6110 *mangled_names = l;
6111
6112 return 0;
6113 }
6114
6115 static int normalize_filenames(char **names) {
6116 char **u;
6117 int r;
6118
6119 STRV_FOREACH(u, names)
6120 if (!path_is_absolute(*u)) {
6121 char* normalized_path;
6122
6123 if (!isempty(arg_root)) {
6124 log_error("Non-absolute paths are not allowed when --root is used: %s", *u);
6125 return -EINVAL;
6126 }
6127
6128 if (!strchr(*u,'/')) {
6129 log_error("Link argument does contain at least one directory separator: %s", *u);
6130 return -EINVAL;
6131 }
6132
6133 r = path_make_absolute_cwd(*u, &normalized_path);
6134 if (r < 0)
6135 return r;
6136
6137 free_and_replace(*u, normalized_path);
6138 }
6139
6140 return 0;
6141 }
6142
6143 static int normalize_names(char **names, bool warn_if_path) {
6144 char **u;
6145 bool was_path = false;
6146
6147 STRV_FOREACH(u, names) {
6148 int r;
6149
6150 if (!is_path(*u))
6151 continue;
6152
6153 r = free_and_strdup(u, basename(*u));
6154 if (r < 0)
6155 return log_error_errno(r, "Failed to normalize unit file path: %m");
6156
6157 was_path = true;
6158 }
6159
6160 if (warn_if_path && was_path)
6161 log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
6162
6163 return 0;
6164 }
6165
6166 static int unit_exists(LookupPaths *lp, const char *unit) {
6167 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
6168 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6169 _cleanup_free_ char *path = NULL;
6170 static const struct bus_properties_map property_map[] = {
6171 { "LoadState", "s", map_string_no_copy, offsetof(UnitStatusInfo, load_state) },
6172 { "ActiveState", "s", map_string_no_copy, offsetof(UnitStatusInfo, active_state)},
6173 {},
6174 };
6175 UnitStatusInfo info = {};
6176 sd_bus *bus;
6177 int r;
6178
6179 if (unit_name_is_valid(unit, UNIT_NAME_TEMPLATE))
6180 return unit_find_template_path(unit, lp, NULL, NULL);
6181
6182 path = unit_dbus_path_from_name(unit);
6183 if (!path)
6184 return log_oom();
6185
6186 r = acquire_bus(BUS_MANAGER, &bus);
6187 if (r < 0)
6188 return r;
6189
6190 r = sd_bus_call_method(
6191 bus,
6192 "org.freedesktop.systemd1",
6193 path,
6194 "org.freedesktop.DBus.Properties",
6195 "GetAll",
6196 &error,
6197 &reply,
6198 "s", "");
6199 if (r < 0)
6200 return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
6201
6202 r = bus_message_map_all_properties(reply, property_map, &error, &info);
6203 if (r < 0)
6204 return log_error_errno(r, "Failed to map properties: %s", bus_error_message(&error, r));
6205
6206 return !streq_ptr(info.load_state, "not-found") || !streq_ptr(info.active_state, "inactive");
6207 }
6208
6209 static int enable_unit(int argc, char *argv[], void *userdata) {
6210 _cleanup_strv_free_ char **names = NULL;
6211 const char *verb = argv[0];
6212 UnitFileChange *changes = NULL;
6213 unsigned n_changes = 0;
6214 int carries_install_info = -1;
6215 bool ignore_carries_install_info = arg_quiet;
6216 int r;
6217
6218 if (!argv[1])
6219 return 0;
6220
6221 r = mangle_names(strv_skip(argv, 1), &names);
6222 if (r < 0)
6223 return r;
6224
6225 r = enable_sysv_units(verb, names);
6226 if (r < 0)
6227 return r;
6228
6229 /* If the operation was fully executed by the SysV compat, let's finish early */
6230 if (strv_isempty(names)) {
6231 if (arg_no_reload || install_client_side())
6232 return 0;
6233 return daemon_reload(argc, argv, userdata);
6234 }
6235
6236 if (streq(verb, "disable")) {
6237 r = normalize_names(names, true);
6238 if (r < 0)
6239 return r;
6240 }
6241
6242 if (streq(verb, "link")) {
6243 r = normalize_filenames(names);
6244 if (r < 0)
6245 return r;
6246 }
6247
6248 if (install_client_side()) {
6249 UnitFileFlags flags;
6250
6251 flags = args_to_flags();
6252 if (streq(verb, "enable")) {
6253 r = unit_file_enable(arg_scope, flags, arg_root, names, &changes, &n_changes);
6254 carries_install_info = r;
6255 } else if (streq(verb, "disable"))
6256 r = unit_file_disable(arg_scope, flags, arg_root, names, &changes, &n_changes);
6257 else if (streq(verb, "reenable")) {
6258 r = unit_file_reenable(arg_scope, flags, arg_root, names, &changes, &n_changes);
6259 carries_install_info = r;
6260 } else if (streq(verb, "link"))
6261 r = unit_file_link(arg_scope, flags, arg_root, names, &changes, &n_changes);
6262 else if (streq(verb, "preset")) {
6263 r = unit_file_preset(arg_scope, flags, arg_root, names, arg_preset_mode, &changes, &n_changes);
6264 } else if (streq(verb, "mask"))
6265 r = unit_file_mask(arg_scope, flags, arg_root, names, &changes, &n_changes);
6266 else if (streq(verb, "unmask"))
6267 r = unit_file_unmask(arg_scope, flags, arg_root, names, &changes, &n_changes);
6268 else if (streq(verb, "revert"))
6269 r = unit_file_revert(arg_scope, arg_root, names, &changes, &n_changes);
6270 else
6271 assert_not_reached("Unknown verb");
6272
6273 unit_file_dump_changes(r, verb, changes, n_changes, arg_quiet);
6274 if (r < 0)
6275 goto finish;
6276 r = 0;
6277 } else {
6278 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
6279 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6280 bool expect_carries_install_info = false;
6281 bool send_runtime = true, send_force = true, send_preset_mode = false;
6282 const char *method;
6283 sd_bus *bus;
6284
6285 if (STR_IN_SET(verb, "mask", "unmask")) {
6286 char **name;
6287 _cleanup_lookup_paths_free_ LookupPaths lp = {};
6288
6289 r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
6290 if (r < 0)
6291 return r;
6292
6293 STRV_FOREACH(name, names) {
6294 r = unit_exists(&lp, *name);
6295 if (r < 0)
6296 return r;
6297 if (r == 0)
6298 log_notice("Unit %s does not exist, proceeding anyway.", *names);
6299 }
6300 }
6301
6302 r = acquire_bus(BUS_MANAGER, &bus);
6303 if (r < 0)
6304 return r;
6305
6306 polkit_agent_open_maybe();
6307
6308 if (streq(verb, "enable")) {
6309 method = "EnableUnitFiles";
6310 expect_carries_install_info = true;
6311 } else if (streq(verb, "disable")) {
6312 method = "DisableUnitFiles";
6313 send_force = false;
6314 } else if (streq(verb, "reenable")) {
6315 method = "ReenableUnitFiles";
6316 expect_carries_install_info = true;
6317 } else if (streq(verb, "link"))
6318 method = "LinkUnitFiles";
6319 else if (streq(verb, "preset")) {
6320
6321 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
6322 method = "PresetUnitFilesWithMode";
6323 send_preset_mode = true;
6324 } else
6325 method = "PresetUnitFiles";
6326
6327 expect_carries_install_info = true;
6328 ignore_carries_install_info = true;
6329 } else if (streq(verb, "mask"))
6330 method = "MaskUnitFiles";
6331 else if (streq(verb, "unmask")) {
6332 method = "UnmaskUnitFiles";
6333 send_force = false;
6334 } else if (streq(verb, "revert")) {
6335 method = "RevertUnitFiles";
6336 send_runtime = send_force = false;
6337 } else
6338 assert_not_reached("Unknown verb");
6339
6340 r = sd_bus_message_new_method_call(
6341 bus,
6342 &m,
6343 "org.freedesktop.systemd1",
6344 "/org/freedesktop/systemd1",
6345 "org.freedesktop.systemd1.Manager",
6346 method);
6347 if (r < 0)
6348 return bus_log_create_error(r);
6349
6350 r = sd_bus_message_append_strv(m, names);
6351 if (r < 0)
6352 return bus_log_create_error(r);
6353
6354 if (send_preset_mode) {
6355 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
6356 if (r < 0)
6357 return bus_log_create_error(r);
6358 }
6359
6360 if (send_runtime) {
6361 r = sd_bus_message_append(m, "b", arg_runtime);
6362 if (r < 0)
6363 return bus_log_create_error(r);
6364 }
6365
6366 if (send_force) {
6367 r = sd_bus_message_append(m, "b", arg_force);
6368 if (r < 0)
6369 return bus_log_create_error(r);
6370 }
6371
6372 r = sd_bus_call(bus, m, 0, &error, &reply);
6373 if (r < 0)
6374 return log_error_errno(r, "Failed to %s unit: %s", verb, bus_error_message(&error, r));
6375
6376 if (expect_carries_install_info) {
6377 r = sd_bus_message_read(reply, "b", &carries_install_info);
6378 if (r < 0)
6379 return bus_log_parse_error(r);
6380 }
6381
6382 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
6383 if (r < 0)
6384 goto finish;
6385
6386 /* Try to reload if enabled */
6387 if (!arg_no_reload)
6388 r = daemon_reload(argc, argv, userdata);
6389 else
6390 r = 0;
6391 }
6392
6393 if (carries_install_info == 0 && !ignore_carries_install_info)
6394 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
6395 "settings in the [Install] section, and DefaultInstance for template units).\n"
6396 "This means they are not meant to be enabled using systemctl.\n"
6397 "Possible reasons for having this kind of units are:\n"
6398 "1) A unit may be statically enabled by being symlinked from another unit's\n"
6399 " .wants/ or .requires/ directory.\n"
6400 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
6401 " a requirement dependency on it.\n"
6402 "3) A unit may be started when needed via activation (socket, path, timer,\n"
6403 " D-Bus, udev, scripted systemctl call, ...).\n"
6404 "4) In case of template units, the unit is meant to be enabled with some\n"
6405 " instance name specified.");
6406
6407 if (arg_now && STR_IN_SET(argv[0], "enable", "disable", "mask")) {
6408 sd_bus *bus;
6409 unsigned len, i;
6410
6411 r = acquire_bus(BUS_MANAGER, &bus);
6412 if (r < 0)
6413 goto finish;
6414
6415 len = strv_length(names);
6416 {
6417 char *new_args[len + 2];
6418
6419 new_args[0] = (char*) (streq(argv[0], "enable") ? "start" : "stop");
6420 for (i = 0; i < len; i++)
6421 new_args[i + 1] = basename(names[i]);
6422 new_args[i + 1] = NULL;
6423
6424 r = start_unit(len + 1, new_args, userdata);
6425 }
6426 }
6427
6428 finish:
6429 unit_file_changes_free(changes, n_changes);
6430
6431 return r;
6432 }
6433
6434 static int add_dependency(int argc, char *argv[], void *userdata) {
6435 _cleanup_strv_free_ char **names = NULL;
6436 _cleanup_free_ char *target = NULL;
6437 const char *verb = argv[0];
6438 UnitFileChange *changes = NULL;
6439 unsigned n_changes = 0;
6440 UnitDependency dep;
6441 int r = 0;
6442
6443 if (!argv[1])
6444 return 0;
6445
6446 r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".target", &target);
6447 if (r < 0)
6448 return log_error_errno(r, "Failed to mangle unit name: %m");
6449
6450 r = mangle_names(strv_skip(argv, 2), &names);
6451 if (r < 0)
6452 return r;
6453
6454 if (streq(verb, "add-wants"))
6455 dep = UNIT_WANTS;
6456 else if (streq(verb, "add-requires"))
6457 dep = UNIT_REQUIRES;
6458 else
6459 assert_not_reached("Unknown verb");
6460
6461 if (install_client_side()) {
6462 r = unit_file_add_dependency(arg_scope, args_to_flags(), arg_root, names, target, dep, &changes, &n_changes);
6463 unit_file_dump_changes(r, "add dependency on", changes, n_changes, arg_quiet);
6464
6465 if (r > 0)
6466 r = 0;
6467 } else {
6468 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
6469 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6470 sd_bus *bus;
6471
6472 r = acquire_bus(BUS_MANAGER, &bus);
6473 if (r < 0)
6474 return r;
6475
6476 polkit_agent_open_maybe();
6477
6478 r = sd_bus_message_new_method_call(
6479 bus,
6480 &m,
6481 "org.freedesktop.systemd1",
6482 "/org/freedesktop/systemd1",
6483 "org.freedesktop.systemd1.Manager",
6484 "AddDependencyUnitFiles");
6485 if (r < 0)
6486 return bus_log_create_error(r);
6487
6488 r = sd_bus_message_append_strv(m, names);
6489 if (r < 0)
6490 return bus_log_create_error(r);
6491
6492 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
6493 if (r < 0)
6494 return bus_log_create_error(r);
6495
6496 r = sd_bus_call(bus, m, 0, &error, &reply);
6497 if (r < 0)
6498 return log_error_errno(r, "Failed to add dependency: %s", bus_error_message(&error, r));
6499
6500 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
6501 if (r < 0)
6502 goto finish;
6503
6504 if (arg_no_reload) {
6505 r = 0;
6506 goto finish;
6507 }
6508
6509 r = daemon_reload(argc, argv, userdata);
6510 }
6511
6512 finish:
6513 unit_file_changes_free(changes, n_changes);
6514
6515 return r;
6516 }
6517
6518 static int preset_all(int argc, char *argv[], void *userdata) {
6519 UnitFileChange *changes = NULL;
6520 unsigned n_changes = 0;
6521 int r;
6522
6523 if (install_client_side()) {
6524 r = unit_file_preset_all(arg_scope, args_to_flags(), arg_root, arg_preset_mode, &changes, &n_changes);
6525 unit_file_dump_changes(r, "preset", changes, n_changes, arg_quiet);
6526
6527 if (r > 0)
6528 r = 0;
6529 } else {
6530 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6531 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
6532 sd_bus *bus;
6533
6534 r = acquire_bus(BUS_MANAGER, &bus);
6535 if (r < 0)
6536 return r;
6537
6538 polkit_agent_open_maybe();
6539
6540 r = sd_bus_call_method(
6541 bus,
6542 "org.freedesktop.systemd1",
6543 "/org/freedesktop/systemd1",
6544 "org.freedesktop.systemd1.Manager",
6545 "PresetAllUnitFiles",
6546 &error,
6547 &reply,
6548 "sbb",
6549 unit_file_preset_mode_to_string(arg_preset_mode),
6550 arg_runtime,
6551 arg_force);
6552 if (r < 0)
6553 return log_error_errno(r, "Failed to preset all units: %s", bus_error_message(&error, r));
6554
6555 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
6556 if (r < 0)
6557 goto finish;
6558
6559 if (arg_no_reload) {
6560 r = 0;
6561 goto finish;
6562 }
6563
6564 r = daemon_reload(argc, argv, userdata);
6565 }
6566
6567 finish:
6568 unit_file_changes_free(changes, n_changes);
6569
6570 return r;
6571 }
6572
6573 static int show_installation_targets_client_side(const char *name) {
6574 UnitFileChange *changes = NULL;
6575 unsigned n_changes = 0, i;
6576 UnitFileFlags flags;
6577 char **p;
6578 int r;
6579
6580 p = STRV_MAKE(name);
6581 flags = UNIT_FILE_DRY_RUN |
6582 (arg_runtime ? UNIT_FILE_RUNTIME : 0);
6583
6584 r = unit_file_disable(UNIT_FILE_SYSTEM, flags, NULL, p, &changes, &n_changes);
6585 if (r < 0)
6586 return log_error_errno(r, "Failed to get file links for %s: %m", name);
6587
6588 for (i = 0; i < n_changes; i++)
6589 if (changes[i].type == UNIT_FILE_UNLINK)
6590 printf(" %s\n", changes[i].path);
6591
6592 return 0;
6593 }
6594
6595 static int show_installation_targets(sd_bus *bus, const char *name) {
6596 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
6597 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6598 const char *link;
6599 int r;
6600
6601 r = sd_bus_call_method(
6602 bus,
6603 "org.freedesktop.systemd1",
6604 "/org/freedesktop/systemd1",
6605 "org.freedesktop.systemd1.Manager",
6606 "GetUnitFileLinks",
6607 &error,
6608 &reply,
6609 "sb", name, arg_runtime);
6610 if (r < 0)
6611 return log_error_errno(r, "Failed to get unit file links for %s: %s", name, bus_error_message(&error, r));
6612
6613 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
6614 if (r < 0)
6615 return bus_log_parse_error(r);
6616
6617 while ((r = sd_bus_message_read(reply, "s", &link)) > 0)
6618 printf(" %s\n", link);
6619
6620 if (r < 0)
6621 return bus_log_parse_error(r);
6622
6623 r = sd_bus_message_exit_container(reply);
6624 if (r < 0)
6625 return bus_log_parse_error(r);
6626
6627 return 0;
6628 }
6629
6630 static int unit_is_enabled(int argc, char *argv[], void *userdata) {
6631
6632 _cleanup_strv_free_ char **names = NULL;
6633 bool enabled;
6634 char **name;
6635 int r;
6636
6637 r = mangle_names(strv_skip(argv, 1), &names);
6638 if (r < 0)
6639 return r;
6640
6641 r = enable_sysv_units(argv[0], names);
6642 if (r < 0)
6643 return r;
6644
6645 enabled = r > 0;
6646
6647 if (install_client_side()) {
6648 STRV_FOREACH(name, names) {
6649 UnitFileState state;
6650
6651 r = unit_file_get_state(arg_scope, arg_root, *name, &state);
6652 if (r < 0)
6653 return log_error_errno(r, "Failed to get unit file state for %s: %m", *name);
6654
6655 if (IN_SET(state,
6656 UNIT_FILE_ENABLED,
6657 UNIT_FILE_ENABLED_RUNTIME,
6658 UNIT_FILE_STATIC,
6659 UNIT_FILE_INDIRECT,
6660 UNIT_FILE_GENERATED))
6661 enabled = true;
6662
6663 if (!arg_quiet) {
6664 puts(unit_file_state_to_string(state));
6665 if (arg_full) {
6666 r = show_installation_targets_client_side(*name);
6667 if (r < 0)
6668 return r;
6669 }
6670 }
6671 }
6672
6673 r = 0;
6674 } else {
6675 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
6676 sd_bus *bus;
6677
6678 r = acquire_bus(BUS_MANAGER, &bus);
6679 if (r < 0)
6680 return r;
6681
6682 STRV_FOREACH(name, names) {
6683 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
6684 const char *s;
6685
6686 r = sd_bus_call_method(
6687 bus,
6688 "org.freedesktop.systemd1",
6689 "/org/freedesktop/systemd1",
6690 "org.freedesktop.systemd1.Manager",
6691 "GetUnitFileState",
6692 &error,
6693 &reply,
6694 "s", *name);
6695 if (r < 0)
6696 return log_error_errno(r, "Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
6697
6698 r = sd_bus_message_read(reply, "s", &s);
6699 if (r < 0)
6700 return bus_log_parse_error(r);
6701
6702 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect", "generated"))
6703 enabled = true;
6704
6705 if (!arg_quiet) {
6706 puts(s);
6707 if (arg_full) {
6708 r = show_installation_targets(bus, *name);
6709 if (r < 0)
6710 return r;
6711 }
6712 }
6713 }
6714 }
6715
6716 return enabled ? EXIT_SUCCESS : EXIT_FAILURE;
6717 }
6718
6719 static int is_system_running(int argc, char *argv[], void *userdata) {
6720 _cleanup_free_ char *state = NULL;
6721 sd_bus *bus;
6722 int r;
6723
6724 if (running_in_chroot() > 0 || (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted())) {
6725 if (!arg_quiet)
6726 puts("offline");
6727 return EXIT_FAILURE;
6728 }
6729
6730 r = acquire_bus(BUS_MANAGER, &bus);
6731 if (r < 0)
6732 return r;
6733
6734 r = sd_bus_get_property_string(
6735 bus,
6736 "org.freedesktop.systemd1",
6737 "/org/freedesktop/systemd1",
6738 "org.freedesktop.systemd1.Manager",
6739 "SystemState",
6740 NULL,
6741 &state);
6742 if (r < 0) {
6743 if (!arg_quiet)
6744 puts("unknown");
6745 return 0;
6746 }
6747
6748 if (!arg_quiet)
6749 puts(state);
6750
6751 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
6752 }
6753
6754 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
6755 _cleanup_free_ char *t = NULL;
6756 int r;
6757
6758 assert(new_path);
6759 assert(original_path);
6760 assert(ret_tmp_fn);
6761
6762 r = tempfn_random(new_path, NULL, &t);
6763 if (r < 0)
6764 return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
6765
6766 r = mkdir_parents(new_path, 0755);
6767 if (r < 0)
6768 return log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
6769
6770 r = copy_file(original_path, t, 0, 0644, 0, COPY_REFLINK);
6771 if (r == -ENOENT) {
6772
6773 r = touch(t);
6774 if (r < 0)
6775 return log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
6776
6777 } else if (r < 0)
6778 return log_error_errno(r, "Failed to create temporary file for \"%s\": %m", new_path);
6779
6780 *ret_tmp_fn = t;
6781 t = NULL;
6782
6783 return 0;
6784 }
6785
6786 static int get_file_to_edit(
6787 const LookupPaths *paths,
6788 const char *name,
6789 char **ret_path) {
6790
6791 _cleanup_free_ char *path = NULL, *run = NULL;
6792
6793 assert(name);
6794 assert(ret_path);
6795
6796 path = strjoin(paths->persistent_config, "/", name);
6797 if (!path)
6798 return log_oom();
6799
6800 if (arg_runtime) {
6801 run = strjoin(paths->runtime_config, "/", name);
6802 if (!run)
6803 return log_oom();
6804 }
6805
6806 if (arg_runtime) {
6807 if (access(path, F_OK) >= 0) {
6808 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path);
6809 return -EEXIST;
6810 }
6811
6812 *ret_path = run;
6813 run = NULL;
6814 } else {
6815 *ret_path = path;
6816 path = NULL;
6817 }
6818
6819 return 0;
6820 }
6821
6822 static int unit_file_create_new(
6823 const LookupPaths *paths,
6824 const char *unit_name,
6825 const char *suffix,
6826 char **ret_new_path,
6827 char **ret_tmp_path) {
6828
6829 char *tmp_new_path, *tmp_tmp_path, *ending;
6830 int r;
6831
6832 assert(unit_name);
6833 assert(ret_new_path);
6834 assert(ret_tmp_path);
6835
6836 ending = strjoina(unit_name, suffix);
6837 r = get_file_to_edit(paths, ending, &tmp_new_path);
6838 if (r < 0)
6839 return r;
6840
6841 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
6842 if (r < 0) {
6843 free(tmp_new_path);
6844 return r;
6845 }
6846
6847 *ret_new_path = tmp_new_path;
6848 *ret_tmp_path = tmp_tmp_path;
6849
6850 return 0;
6851 }
6852
6853 static int unit_file_create_copy(
6854 const LookupPaths *paths,
6855 const char *unit_name,
6856 const char *fragment_path,
6857 char **ret_new_path,
6858 char **ret_tmp_path) {
6859
6860 char *tmp_new_path, *tmp_tmp_path;
6861 int r;
6862
6863 assert(fragment_path);
6864 assert(unit_name);
6865 assert(ret_new_path);
6866 assert(ret_tmp_path);
6867
6868 r = get_file_to_edit(paths, unit_name, &tmp_new_path);
6869 if (r < 0)
6870 return r;
6871
6872 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
6873 char response;
6874
6875 r = ask_char(&response, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path, fragment_path);
6876 if (r < 0) {
6877 free(tmp_new_path);
6878 return r;
6879 }
6880 if (response != 'y') {
6881 log_warning("%s ignored", unit_name);
6882 free(tmp_new_path);
6883 return -EKEYREJECTED;
6884 }
6885 }
6886
6887 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
6888 if (r < 0) {
6889 free(tmp_new_path);
6890 return r;
6891 }
6892
6893 *ret_new_path = tmp_new_path;
6894 *ret_tmp_path = tmp_tmp_path;
6895
6896 return 0;
6897 }
6898
6899 static int run_editor(char **paths) {
6900 pid_t pid;
6901 int r;
6902
6903 assert(paths);
6904
6905 pid = fork();
6906 if (pid < 0)
6907 return log_error_errno(errno, "Failed to fork: %m");
6908
6909 if (pid == 0) {
6910 const char **args;
6911 char *editor, **editor_args = NULL;
6912 char **tmp_path, **original_path, *p;
6913 unsigned n_editor_args = 0, i = 1;
6914 size_t argc;
6915
6916 (void) reset_all_signal_handlers();
6917 (void) reset_signal_mask();
6918
6919 argc = strv_length(paths)/2 + 1;
6920
6921 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6922 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6923 * we try to execute well known editors
6924 */
6925 editor = getenv("SYSTEMD_EDITOR");
6926 if (!editor)
6927 editor = getenv("EDITOR");
6928 if (!editor)
6929 editor = getenv("VISUAL");
6930
6931 if (!isempty(editor)) {
6932 editor_args = strv_split(editor, WHITESPACE);
6933 if (!editor_args) {
6934 (void) log_oom();
6935 _exit(EXIT_FAILURE);
6936 }
6937 n_editor_args = strv_length(editor_args);
6938 argc += n_editor_args - 1;
6939 }
6940 args = newa(const char*, argc + 1);
6941
6942 if (n_editor_args > 0) {
6943 args[0] = editor_args[0];
6944 for (; i < n_editor_args; i++)
6945 args[i] = editor_args[i];
6946 }
6947
6948 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
6949 args[i] = *tmp_path;
6950 i++;
6951 }
6952 args[i] = NULL;
6953
6954 if (n_editor_args > 0)
6955 execvp(args[0], (char* const*) args);
6956
6957 FOREACH_STRING(p, "editor", "nano", "vim", "vi") {
6958 args[0] = p;
6959 execvp(p, (char* const*) args);
6960 /* We do not fail if the editor doesn't exist
6961 * because we want to try each one of them before
6962 * failing.
6963 */
6964 if (errno != ENOENT) {
6965 log_error_errno(errno, "Failed to execute %s: %m", editor);
6966 _exit(EXIT_FAILURE);
6967 }
6968 }
6969
6970 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6971 _exit(EXIT_FAILURE);
6972 }
6973
6974 r = wait_for_terminate_and_warn("editor", pid, true);
6975 if (r < 0)
6976 return log_error_errno(r, "Failed to wait for child: %m");
6977
6978 return 0;
6979 }
6980
6981 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
6982 _cleanup_lookup_paths_free_ LookupPaths lp = {};
6983 char **name;
6984 int r;
6985
6986 assert(names);
6987 assert(paths);
6988
6989 r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
6990 if (r < 0)
6991 return r;
6992
6993 STRV_FOREACH(name, names) {
6994 _cleanup_free_ char *path = NULL, *new_path = NULL, *tmp_path = NULL, *tmp_name = NULL;
6995 const char *unit_name;
6996
6997 r = unit_find_paths(bus, *name, &lp, &path, NULL);
6998 if (r < 0)
6999 return r;
7000
7001 if (r == 0) {
7002 assert(!path);
7003
7004 if (!arg_force) {
7005 log_error("Run 'systemctl edit%s --force %s' to create a new unit.",
7006 arg_scope == UNIT_FILE_GLOBAL ? " --global" :
7007 arg_scope == UNIT_FILE_USER ? " --user" : "",
7008 *name);
7009 return -ENOENT;
7010 }
7011
7012 /* Create a new unit from scratch */
7013 unit_name = *name;
7014 r = unit_file_create_new(&lp, unit_name,
7015 arg_full ? NULL : ".d/override.conf",
7016 &new_path, &tmp_path);
7017 } else {
7018 assert(path);
7019
7020 unit_name = basename(path);
7021 /* We follow unit aliases, but we need to propagate the instance */
7022 if (unit_name_is_valid(*name, UNIT_NAME_INSTANCE) &&
7023 unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) {
7024 _cleanup_free_ char *instance = NULL;
7025
7026 r = unit_name_to_instance(*name, &instance);
7027 if (r < 0)
7028 return r;
7029
7030 r = unit_name_replace_instance(unit_name, instance, &tmp_name);
7031 if (r < 0)
7032 return r;
7033
7034 unit_name = tmp_name;
7035 }
7036
7037 if (arg_full)
7038 r = unit_file_create_copy(&lp, unit_name, path, &new_path, &tmp_path);
7039 else
7040 r = unit_file_create_new(&lp, unit_name, ".d/override.conf", &new_path, &tmp_path);
7041 }
7042 if (r < 0)
7043 return r;
7044
7045 r = strv_push_pair(paths, new_path, tmp_path);
7046 if (r < 0)
7047 return log_oom();
7048 new_path = tmp_path = NULL;
7049 }
7050
7051 return 0;
7052 }
7053
7054 static int edit(int argc, char *argv[], void *userdata) {
7055 _cleanup_strv_free_ char **names = NULL;
7056 _cleanup_strv_free_ char **paths = NULL;
7057 char **original, **tmp;
7058 sd_bus *bus;
7059 int r;
7060
7061 if (!on_tty()) {
7062 log_error("Cannot edit units if not on a tty.");
7063 return -EINVAL;
7064 }
7065
7066 if (arg_transport != BUS_TRANSPORT_LOCAL) {
7067 log_error("Cannot edit units remotely.");
7068 return -EINVAL;
7069 }
7070
7071 r = acquire_bus(BUS_MANAGER, &bus);
7072 if (r < 0)
7073 return r;
7074
7075 r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
7076 if (r < 0)
7077 return log_error_errno(r, "Failed to expand names: %m");
7078
7079 r = find_paths_to_edit(bus, names, &paths);
7080 if (r < 0)
7081 return r;
7082
7083 if (strv_isempty(paths))
7084 return -ENOENT;
7085
7086 r = run_editor(paths);
7087 if (r < 0)
7088 goto end;
7089
7090 STRV_FOREACH_PAIR(original, tmp, paths) {
7091 /* If the temporary file is empty we ignore it. It's
7092 * useful if the user wants to cancel its modification
7093 */
7094 if (null_or_empty_path(*tmp)) {
7095 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original);
7096 continue;
7097 }
7098
7099 r = rename(*tmp, *original);
7100 if (r < 0) {
7101 r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
7102 goto end;
7103 }
7104 }
7105
7106 r = 0;
7107
7108 if (!arg_no_reload && !install_client_side())
7109 r = daemon_reload(argc, argv, userdata);
7110
7111 end:
7112 STRV_FOREACH_PAIR(original, tmp, paths) {
7113 (void) unlink(*tmp);
7114
7115 /* Removing empty dropin dirs */
7116 if (!arg_full) {
7117 _cleanup_free_ char *dir;
7118
7119 dir = dirname_malloc(*original);
7120 if (!dir)
7121 return log_oom();
7122
7123 /* no need to check if the dir is empty, rmdir
7124 * does nothing if it is not the case.
7125 */
7126 (void) rmdir(dir);
7127 }
7128 }
7129
7130 return r;
7131 }
7132
7133 static void systemctl_help(void) {
7134
7135 pager_open(arg_no_pager, false);
7136
7137 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
7138 "Query or send control commands to the systemd manager.\n\n"
7139 " -h --help Show this help\n"
7140 " --version Show package version\n"
7141 " --system Connect to system manager\n"
7142 " --user Connect to user service manager\n"
7143 " -H --host=[USER@]HOST\n"
7144 " Operate on remote host\n"
7145 " -M --machine=CONTAINER\n"
7146 " Operate on local container\n"
7147 " -t --type=TYPE List units of a particular type\n"
7148 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
7149 " -p --property=NAME Show only properties by this name\n"
7150 " -a --all Show all properties/all units currently in memory,\n"
7151 " including dead/empty ones. To list all units installed on\n"
7152 " the system, use the 'list-unit-files' command instead.\n"
7153 " --failed Same as --state=failed\n"
7154 " -l --full Don't ellipsize unit names on output\n"
7155 " -r --recursive Show unit list of host and local containers\n"
7156 " --reverse Show reverse dependencies with 'list-dependencies'\n"
7157 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
7158 " queueing a new job\n"
7159 " --show-types When showing sockets, explicitly show their type\n"
7160 " --value When showing properties, only print the value\n"
7161 " -i --ignore-inhibitors\n"
7162 " When shutting down or sleeping, ignore inhibitors\n"
7163 " --kill-who=WHO Who to send signal to\n"
7164 " -s --signal=SIGNAL Which signal to send\n"
7165 " --now Start or stop unit in addition to enabling or disabling it\n"
7166 " -q --quiet Suppress output\n"
7167 " --wait For (re)start, wait until service stopped again\n"
7168 " --no-block Do not wait until operation finished\n"
7169 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7170 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
7171 " --no-legend Do not print a legend (column headers and hints)\n"
7172 " --no-pager Do not pipe output into a pager\n"
7173 " --no-ask-password\n"
7174 " Do not ask for system passwords\n"
7175 " --global Enable/disable/mask unit files globally\n"
7176 " --runtime Enable/disable/mask unit files temporarily until next\n"
7177 " reboot\n"
7178 " -f --force When enabling unit files, override existing symlinks\n"
7179 " When shutting down, execute action immediately\n"
7180 " --preset-mode= Apply only enable, only disable, or all presets\n"
7181 " --root=PATH Enable/disable/mask unit files in the specified root\n"
7182 " directory\n"
7183 " -n --lines=INTEGER Number of journal entries to show\n"
7184 " -o --output=STRING Change journal output mode (short, short-precise,\n"
7185 " short-iso, short-iso-precise, short-full,\n"
7186 " short-monotonic, short-unix,\n"
7187 " verbose, export, json, json-pretty, json-sse, cat)\n"
7188 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
7189 " --plain Print unit dependencies as a list instead of a tree\n\n"
7190 "Unit Commands:\n"
7191 " list-units [PATTERN...] List units currently in memory\n"
7192 " list-sockets [PATTERN...] List socket units currently in memory, ordered\n"
7193 " by address\n"
7194 " list-timers [PATTERN...] List timer units currently in memory, ordered\n"
7195 " by next elapse\n"
7196 " start NAME... Start (activate) one or more units\n"
7197 " stop NAME... Stop (deactivate) one or more units\n"
7198 " reload NAME... Reload one or more units\n"
7199 " restart NAME... Start or restart one or more units\n"
7200 " try-restart NAME... Restart one or more units if active\n"
7201 " reload-or-restart NAME... Reload one or more units if possible,\n"
7202 " otherwise start or restart\n"
7203 " try-reload-or-restart NAME... If active, reload one or more units,\n"
7204 " if supported, otherwise restart\n"
7205 " isolate NAME Start one unit and stop all others\n"
7206 " kill NAME... Send signal to processes of a unit\n"
7207 " is-active PATTERN... Check whether units are active\n"
7208 " is-failed PATTERN... Check whether units are failed\n"
7209 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
7210 " show [PATTERN...|JOB...] Show properties of one or more\n"
7211 " units/jobs or the manager\n"
7212 " cat PATTERN... Show files and drop-ins of one or more units\n"
7213 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
7214 " help PATTERN...|PID... Show manual for one or more units\n"
7215 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
7216 " units\n"
7217 " list-dependencies [NAME] Recursively show units which are required\n"
7218 " or wanted by this unit or by which this\n"
7219 " unit is required or wanted\n\n"
7220 "Unit File Commands:\n"
7221 " list-unit-files [PATTERN...] List installed unit files\n"
7222 " enable [NAME...|PATH...] Enable one or more unit files\n"
7223 " disable NAME... Disable one or more unit files\n"
7224 " reenable NAME... Reenable one or more unit files\n"
7225 " preset NAME... Enable/disable one or more unit files\n"
7226 " based on preset configuration\n"
7227 " preset-all Enable/disable all unit files based on\n"
7228 " preset configuration\n"
7229 " is-enabled NAME... Check whether unit files are enabled\n"
7230 " mask NAME... Mask one or more units\n"
7231 " unmask NAME... Unmask one or more units\n"
7232 " link PATH... Link one or more units files into\n"
7233 " the search path\n"
7234 " revert NAME... Revert one or more unit files to vendor\n"
7235 " version\n"
7236 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
7237 " on specified one or more units\n"
7238 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
7239 " on specified one or more units\n"
7240 " edit NAME... Edit one or more unit files\n"
7241 " get-default Get the name of the default target\n"
7242 " set-default NAME Set the default target\n\n"
7243 "Machine Commands:\n"
7244 " list-machines [PATTERN...] List local containers and host\n\n"
7245 "Job Commands:\n"
7246 " list-jobs [PATTERN...] List jobs\n"
7247 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
7248 "Environment Commands:\n"
7249 " show-environment Dump environment\n"
7250 " set-environment NAME=VALUE... Set one or more environment variables\n"
7251 " unset-environment NAME... Unset one or more environment variables\n"
7252 " import-environment [NAME...] Import all or some environment variables\n\n"
7253 "Manager Lifecycle Commands:\n"
7254 " daemon-reload Reload systemd manager configuration\n"
7255 " daemon-reexec Reexecute systemd manager\n\n"
7256 "System Commands:\n"
7257 " is-system-running Check whether system is fully running\n"
7258 " default Enter system default mode\n"
7259 " rescue Enter system rescue mode\n"
7260 " emergency Enter system emergency mode\n"
7261 " halt Shut down and halt the system\n"
7262 " poweroff Shut down and power-off the system\n"
7263 " reboot [ARG] Shut down and reboot the system\n"
7264 " kexec Shut down and reboot the system with kexec\n"
7265 " exit [EXIT_CODE] Request user instance or container exit\n"
7266 " switch-root ROOT [INIT] Change to a different root file system\n"
7267 " suspend Suspend the system\n"
7268 " hibernate Hibernate the system\n"
7269 " hybrid-sleep Hibernate and suspend the system\n",
7270 program_invocation_short_name);
7271 }
7272
7273 static void halt_help(void) {
7274 printf("%s [OPTIONS...]%s\n\n"
7275 "%s the system.\n\n"
7276 " --help Show this help\n"
7277 " --halt Halt the machine\n"
7278 " -p --poweroff Switch off the machine\n"
7279 " --reboot Reboot the machine\n"
7280 " -f --force Force immediate halt/power-off/reboot\n"
7281 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
7282 " -d --no-wtmp Don't write wtmp record\n"
7283 " --no-wall Don't send wall message before halt/power-off/reboot\n",
7284 program_invocation_short_name,
7285 arg_action == ACTION_REBOOT ? " [ARG]" : "",
7286 arg_action == ACTION_REBOOT ? "Reboot" :
7287 arg_action == ACTION_POWEROFF ? "Power off" :
7288 "Halt");
7289 }
7290
7291 static void shutdown_help(void) {
7292 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
7293 "Shut down the system.\n\n"
7294 " --help Show this help\n"
7295 " -H --halt Halt the machine\n"
7296 " -P --poweroff Power-off the machine\n"
7297 " -r --reboot Reboot the machine\n"
7298 " -h Equivalent to --poweroff, overridden by --halt\n"
7299 " -k Don't halt/power-off/reboot, just send warnings\n"
7300 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7301 " -c Cancel a pending shutdown\n",
7302 program_invocation_short_name);
7303 }
7304
7305 static void telinit_help(void) {
7306 printf("%s [OPTIONS...] {COMMAND}\n\n"
7307 "Send control commands to the init daemon.\n\n"
7308 " --help Show this help\n"
7309 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
7310 "Commands:\n"
7311 " 0 Power-off the machine\n"
7312 " 6 Reboot the machine\n"
7313 " 2, 3, 4, 5 Start runlevelX.target unit\n"
7314 " 1, s, S Enter rescue mode\n"
7315 " q, Q Reload init daemon configuration\n"
7316 " u, U Reexecute init daemon\n",
7317 program_invocation_short_name);
7318 }
7319
7320 static void runlevel_help(void) {
7321 printf("%s [OPTIONS...]\n\n"
7322 "Prints the previous and current runlevel of the init system.\n\n"
7323 " --help Show this help\n",
7324 program_invocation_short_name);
7325 }
7326
7327 static void help_types(void) {
7328 int i;
7329
7330 if (!arg_no_legend)
7331 puts("Available unit types:");
7332 for (i = 0; i < _UNIT_TYPE_MAX; i++)
7333 puts(unit_type_to_string(i));
7334 }
7335
7336 static void help_states(void) {
7337 int i;
7338
7339 if (!arg_no_legend)
7340 puts("Available unit load states:");
7341 for (i = 0; i < _UNIT_LOAD_STATE_MAX; i++)
7342 puts(unit_load_state_to_string(i));
7343
7344 if (!arg_no_legend)
7345 puts("\nAvailable unit active states:");
7346 for (i = 0; i < _UNIT_ACTIVE_STATE_MAX; i++)
7347 puts(unit_active_state_to_string(i));
7348
7349 if (!arg_no_legend)
7350 puts("\nAvailable automount unit substates:");
7351 for (i = 0; i < _AUTOMOUNT_STATE_MAX; i++)
7352 puts(automount_state_to_string(i));
7353
7354 if (!arg_no_legend)
7355 puts("\nAvailable device unit substates:");
7356 for (i = 0; i < _DEVICE_STATE_MAX; i++)
7357 puts(device_state_to_string(i));
7358
7359 if (!arg_no_legend)
7360 puts("\nAvailable mount unit substates:");
7361 for (i = 0; i < _MOUNT_STATE_MAX; i++)
7362 puts(mount_state_to_string(i));
7363
7364 if (!arg_no_legend)
7365 puts("\nAvailable path unit substates:");
7366 for (i = 0; i < _PATH_STATE_MAX; i++)
7367 puts(path_state_to_string(i));
7368
7369 if (!arg_no_legend)
7370 puts("\nAvailable scope unit substates:");
7371 for (i = 0; i < _SCOPE_STATE_MAX; i++)
7372 puts(scope_state_to_string(i));
7373
7374 if (!arg_no_legend)
7375 puts("\nAvailable service unit substates:");
7376 for (i = 0; i < _SERVICE_STATE_MAX; i++)
7377 puts(service_state_to_string(i));
7378
7379 if (!arg_no_legend)
7380 puts("\nAvailable slice unit substates:");
7381 for (i = 0; i < _SLICE_STATE_MAX; i++)
7382 puts(slice_state_to_string(i));
7383
7384 if (!arg_no_legend)
7385 puts("\nAvailable socket unit substates:");
7386 for (i = 0; i < _SOCKET_STATE_MAX; i++)
7387 puts(socket_state_to_string(i));
7388
7389 if (!arg_no_legend)
7390 puts("\nAvailable swap unit substates:");
7391 for (i = 0; i < _SWAP_STATE_MAX; i++)
7392 puts(swap_state_to_string(i));
7393
7394 if (!arg_no_legend)
7395 puts("\nAvailable target unit substates:");
7396 for (i = 0; i < _TARGET_STATE_MAX; i++)
7397 puts(target_state_to_string(i));
7398
7399 if (!arg_no_legend)
7400 puts("\nAvailable timer unit substates:");
7401 for (i = 0; i < _TIMER_STATE_MAX; i++)
7402 puts(timer_state_to_string(i));
7403 }
7404
7405 static int systemctl_parse_argv(int argc, char *argv[]) {
7406
7407 enum {
7408 ARG_FAIL = 0x100,
7409 ARG_REVERSE,
7410 ARG_AFTER,
7411 ARG_BEFORE,
7412 ARG_SHOW_TYPES,
7413 ARG_IRREVERSIBLE,
7414 ARG_IGNORE_DEPENDENCIES,
7415 ARG_VALUE,
7416 ARG_VERSION,
7417 ARG_USER,
7418 ARG_SYSTEM,
7419 ARG_GLOBAL,
7420 ARG_NO_BLOCK,
7421 ARG_NO_LEGEND,
7422 ARG_NO_PAGER,
7423 ARG_NO_WALL,
7424 ARG_ROOT,
7425 ARG_NO_RELOAD,
7426 ARG_KILL_WHO,
7427 ARG_NO_ASK_PASSWORD,
7428 ARG_FAILED,
7429 ARG_RUNTIME,
7430 ARG_FORCE,
7431 ARG_PLAIN,
7432 ARG_STATE,
7433 ARG_JOB_MODE,
7434 ARG_PRESET_MODE,
7435 ARG_FIRMWARE_SETUP,
7436 ARG_NOW,
7437 ARG_MESSAGE,
7438 ARG_WAIT,
7439 };
7440
7441 static const struct option options[] = {
7442 { "help", no_argument, NULL, 'h' },
7443 { "version", no_argument, NULL, ARG_VERSION },
7444 { "type", required_argument, NULL, 't' },
7445 { "property", required_argument, NULL, 'p' },
7446 { "all", no_argument, NULL, 'a' },
7447 { "reverse", no_argument, NULL, ARG_REVERSE },
7448 { "after", no_argument, NULL, ARG_AFTER },
7449 { "before", no_argument, NULL, ARG_BEFORE },
7450 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
7451 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
7452 { "full", no_argument, NULL, 'l' },
7453 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
7454 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
7455 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
7456 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
7457 { "ignore-inhibitors", no_argument, NULL, 'i' },
7458 { "value", no_argument, NULL, ARG_VALUE },
7459 { "user", no_argument, NULL, ARG_USER },
7460 { "system", no_argument, NULL, ARG_SYSTEM },
7461 { "global", no_argument, NULL, ARG_GLOBAL },
7462 { "wait", no_argument, NULL, ARG_WAIT },
7463 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
7464 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
7465 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
7466 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7467 { "quiet", no_argument, NULL, 'q' },
7468 { "root", required_argument, NULL, ARG_ROOT },
7469 { "force", no_argument, NULL, ARG_FORCE },
7470 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
7471 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
7472 { "signal", required_argument, NULL, 's' },
7473 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
7474 { "host", required_argument, NULL, 'H' },
7475 { "machine", required_argument, NULL, 'M' },
7476 { "runtime", no_argument, NULL, ARG_RUNTIME },
7477 { "lines", required_argument, NULL, 'n' },
7478 { "output", required_argument, NULL, 'o' },
7479 { "plain", no_argument, NULL, ARG_PLAIN },
7480 { "state", required_argument, NULL, ARG_STATE },
7481 { "recursive", no_argument, NULL, 'r' },
7482 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
7483 { "firmware-setup", no_argument, NULL, ARG_FIRMWARE_SETUP },
7484 { "now", no_argument, NULL, ARG_NOW },
7485 { "message", required_argument, NULL, ARG_MESSAGE },
7486 {}
7487 };
7488
7489 const char *p;
7490 int c, r;
7491
7492 assert(argc >= 0);
7493 assert(argv);
7494
7495 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
7496 arg_ask_password = true;
7497
7498 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
7499
7500 switch (c) {
7501
7502 case 'h':
7503 systemctl_help();
7504 return 0;
7505
7506 case ARG_VERSION:
7507 return version();
7508
7509 case 't': {
7510 if (isempty(optarg)) {
7511 log_error("--type= requires arguments.");
7512 return -EINVAL;
7513 }
7514
7515 for (p = optarg;;) {
7516 _cleanup_free_ char *type = NULL;
7517
7518 r = extract_first_word(&p, &type, ",", 0);
7519 if (r < 0)
7520 return log_error_errno(r, "Failed to parse type: %s", optarg);
7521 if (r == 0)
7522 break;
7523
7524 if (streq(type, "help")) {
7525 help_types();
7526 return 0;
7527 }
7528
7529 if (unit_type_from_string(type) >= 0) {
7530 if (strv_push(&arg_types, type) < 0)
7531 return log_oom();
7532 type = NULL;
7533 continue;
7534 }
7535
7536 /* It's much nicer to use --state= for
7537 * load states, but let's support this
7538 * in --types= too for compatibility
7539 * with old versions */
7540 if (unit_load_state_from_string(type) >= 0) {
7541 if (strv_push(&arg_states, type) < 0)
7542 return log_oom();
7543 type = NULL;
7544 continue;
7545 }
7546
7547 log_error("Unknown unit type or load state '%s'.", type);
7548 log_info("Use -t help to see a list of allowed values.");
7549 return -EINVAL;
7550 }
7551
7552 break;
7553 }
7554
7555 case 'p': {
7556 /* Make sure that if the empty property list
7557 was specified, we won't show any properties. */
7558 if (isempty(optarg) && !arg_properties) {
7559 arg_properties = new0(char*, 1);
7560 if (!arg_properties)
7561 return log_oom();
7562 } else
7563 for (p = optarg;;) {
7564 _cleanup_free_ char *prop = NULL;
7565
7566 r = extract_first_word(&p, &prop, ",", 0);
7567 if (r < 0)
7568 return log_error_errno(r, "Failed to parse property: %s", optarg);
7569 if (r == 0)
7570 break;
7571
7572 if (strv_push(&arg_properties, prop) < 0)
7573 return log_oom();
7574
7575 prop = NULL;
7576 }
7577
7578 /* If the user asked for a particular
7579 * property, show it to him, even if it is
7580 * empty. */
7581 arg_all = true;
7582
7583 break;
7584 }
7585
7586 case 'a':
7587 arg_all = true;
7588 break;
7589
7590 case ARG_REVERSE:
7591 arg_dependency = DEPENDENCY_REVERSE;
7592 break;
7593
7594 case ARG_AFTER:
7595 arg_dependency = DEPENDENCY_AFTER;
7596 arg_jobs_after = true;
7597 break;
7598
7599 case ARG_BEFORE:
7600 arg_dependency = DEPENDENCY_BEFORE;
7601 arg_jobs_before = true;
7602 break;
7603
7604 case ARG_SHOW_TYPES:
7605 arg_show_types = true;
7606 break;
7607
7608 case ARG_VALUE:
7609 arg_value = true;
7610 break;
7611
7612 case ARG_JOB_MODE:
7613 arg_job_mode = optarg;
7614 break;
7615
7616 case ARG_FAIL:
7617 arg_job_mode = "fail";
7618 break;
7619
7620 case ARG_IRREVERSIBLE:
7621 arg_job_mode = "replace-irreversibly";
7622 break;
7623
7624 case ARG_IGNORE_DEPENDENCIES:
7625 arg_job_mode = "ignore-dependencies";
7626 break;
7627
7628 case ARG_USER:
7629 arg_scope = UNIT_FILE_USER;
7630 break;
7631
7632 case ARG_SYSTEM:
7633 arg_scope = UNIT_FILE_SYSTEM;
7634 break;
7635
7636 case ARG_GLOBAL:
7637 arg_scope = UNIT_FILE_GLOBAL;
7638 break;
7639
7640 case ARG_WAIT:
7641 arg_wait = true;
7642 break;
7643
7644 case ARG_NO_BLOCK:
7645 arg_no_block = true;
7646 break;
7647
7648 case ARG_NO_LEGEND:
7649 arg_no_legend = true;
7650 break;
7651
7652 case ARG_NO_PAGER:
7653 arg_no_pager = true;
7654 break;
7655
7656 case ARG_NO_WALL:
7657 arg_no_wall = true;
7658 break;
7659
7660 case ARG_ROOT:
7661 r = parse_path_argument_and_warn(optarg, false, &arg_root);
7662 if (r < 0)
7663 return r;
7664 break;
7665
7666 case 'l':
7667 arg_full = true;
7668 break;
7669
7670 case ARG_FAILED:
7671 if (strv_extend(&arg_states, "failed") < 0)
7672 return log_oom();
7673
7674 break;
7675
7676 case 'q':
7677 arg_quiet = true;
7678 break;
7679
7680 case ARG_FORCE:
7681 arg_force++;
7682 break;
7683
7684 case 'f':
7685 arg_force++;
7686 break;
7687
7688 case ARG_NO_RELOAD:
7689 arg_no_reload = true;
7690 break;
7691
7692 case ARG_KILL_WHO:
7693 arg_kill_who = optarg;
7694 break;
7695
7696 case 's':
7697 arg_signal = signal_from_string_try_harder(optarg);
7698 if (arg_signal < 0) {
7699 log_error("Failed to parse signal string %s.", optarg);
7700 return -EINVAL;
7701 }
7702 break;
7703
7704 case ARG_NO_ASK_PASSWORD:
7705 arg_ask_password = false;
7706 break;
7707
7708 case 'H':
7709 arg_transport = BUS_TRANSPORT_REMOTE;
7710 arg_host = optarg;
7711 break;
7712
7713 case 'M':
7714 arg_transport = BUS_TRANSPORT_MACHINE;
7715 arg_host = optarg;
7716 break;
7717
7718 case ARG_RUNTIME:
7719 arg_runtime = true;
7720 break;
7721
7722 case 'n':
7723 if (safe_atou(optarg, &arg_lines) < 0) {
7724 log_error("Failed to parse lines '%s'", optarg);
7725 return -EINVAL;
7726 }
7727 break;
7728
7729 case 'o':
7730 arg_output = output_mode_from_string(optarg);
7731 if (arg_output < 0) {
7732 log_error("Unknown output '%s'.", optarg);
7733 return -EINVAL;
7734 }
7735 break;
7736
7737 case 'i':
7738 arg_ignore_inhibitors = true;
7739 break;
7740
7741 case ARG_PLAIN:
7742 arg_plain = true;
7743 break;
7744
7745 case ARG_FIRMWARE_SETUP:
7746 arg_firmware_setup = true;
7747 break;
7748
7749 case ARG_STATE: {
7750 if (isempty(optarg)) {
7751 log_error("--state= requires arguments.");
7752 return -EINVAL;
7753 }
7754
7755 for (p = optarg;;) {
7756 _cleanup_free_ char *s = NULL;
7757
7758 r = extract_first_word(&p, &s, ",", 0);
7759 if (r < 0)
7760 return log_error_errno(r, "Failed to parse state: %s", optarg);
7761 if (r == 0)
7762 break;
7763
7764 if (streq(s, "help")) {
7765 help_states();
7766 return 0;
7767 }
7768
7769 if (strv_push(&arg_states, s) < 0)
7770 return log_oom();
7771
7772 s = NULL;
7773 }
7774 break;
7775 }
7776
7777 case 'r':
7778 if (geteuid() != 0) {
7779 log_error("--recursive requires root privileges.");
7780 return -EPERM;
7781 }
7782
7783 arg_recursive = true;
7784 break;
7785
7786 case ARG_PRESET_MODE:
7787
7788 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
7789 if (arg_preset_mode < 0) {
7790 log_error("Failed to parse preset mode: %s.", optarg);
7791 return -EINVAL;
7792 }
7793
7794 break;
7795
7796 case ARG_NOW:
7797 arg_now = true;
7798 break;
7799
7800 case ARG_MESSAGE:
7801 if (strv_extend(&arg_wall, optarg) < 0)
7802 return log_oom();
7803 break;
7804
7805 case '?':
7806 return -EINVAL;
7807
7808 default:
7809 assert_not_reached("Unhandled option");
7810 }
7811
7812 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
7813 log_error("Cannot access user instance remotely.");
7814 return -EINVAL;
7815 }
7816
7817 if (arg_wait && arg_no_block) {
7818 log_error("--wait may not be combined with --no-block.");
7819 return -EINVAL;
7820 }
7821
7822 return 1;
7823 }
7824
7825 static int halt_parse_argv(int argc, char *argv[]) {
7826
7827 enum {
7828 ARG_HELP = 0x100,
7829 ARG_HALT,
7830 ARG_REBOOT,
7831 ARG_NO_WALL
7832 };
7833
7834 static const struct option options[] = {
7835 { "help", no_argument, NULL, ARG_HELP },
7836 { "halt", no_argument, NULL, ARG_HALT },
7837 { "poweroff", no_argument, NULL, 'p' },
7838 { "reboot", no_argument, NULL, ARG_REBOOT },
7839 { "force", no_argument, NULL, 'f' },
7840 { "wtmp-only", no_argument, NULL, 'w' },
7841 { "no-wtmp", no_argument, NULL, 'd' },
7842 { "no-sync", no_argument, NULL, 'n' },
7843 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7844 {}
7845 };
7846
7847 int c, r, runlevel;
7848
7849 assert(argc >= 0);
7850 assert(argv);
7851
7852 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
7853 if (IN_SET(runlevel, '0', '6'))
7854 arg_force = 2;
7855
7856 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
7857 switch (c) {
7858
7859 case ARG_HELP:
7860 halt_help();
7861 return 0;
7862
7863 case ARG_HALT:
7864 arg_action = ACTION_HALT;
7865 break;
7866
7867 case 'p':
7868 if (arg_action != ACTION_REBOOT)
7869 arg_action = ACTION_POWEROFF;
7870 break;
7871
7872 case ARG_REBOOT:
7873 arg_action = ACTION_REBOOT;
7874 break;
7875
7876 case 'f':
7877 arg_force = 2;
7878 break;
7879
7880 case 'w':
7881 arg_dry = true;
7882 break;
7883
7884 case 'd':
7885 arg_no_wtmp = true;
7886 break;
7887
7888 case 'n':
7889 arg_no_sync = true;
7890 break;
7891
7892 case ARG_NO_WALL:
7893 arg_no_wall = true;
7894 break;
7895
7896 case 'i':
7897 case 'h':
7898 /* Compatibility nops */
7899 break;
7900
7901 case '?':
7902 return -EINVAL;
7903
7904 default:
7905 assert_not_reached("Unhandled option");
7906 }
7907
7908 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
7909 r = update_reboot_parameter_and_warn(argc == optind + 1 ? argv[optind] : NULL);
7910 if (r < 0)
7911 return r;
7912 } else if (optind < argc) {
7913 log_error("Too many arguments.");
7914 return -EINVAL;
7915 }
7916
7917 return 1;
7918 }
7919
7920 static int parse_shutdown_time_spec(const char *t, usec_t *_u) {
7921 assert(t);
7922 assert(_u);
7923
7924 if (streq(t, "now"))
7925 *_u = 0;
7926 else if (!strchr(t, ':')) {
7927 uint64_t u;
7928
7929 if (safe_atou64(t, &u) < 0)
7930 return -EINVAL;
7931
7932 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
7933 } else {
7934 char *e = NULL;
7935 long hour, minute;
7936 struct tm tm = {};
7937 time_t s;
7938 usec_t n;
7939
7940 errno = 0;
7941 hour = strtol(t, &e, 10);
7942 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
7943 return -EINVAL;
7944
7945 minute = strtol(e+1, &e, 10);
7946 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
7947 return -EINVAL;
7948
7949 n = now(CLOCK_REALTIME);
7950 s = (time_t) (n / USEC_PER_SEC);
7951
7952 assert_se(localtime_r(&s, &tm));
7953
7954 tm.tm_hour = (int) hour;
7955 tm.tm_min = (int) minute;
7956 tm.tm_sec = 0;
7957
7958 assert_se(s = mktime(&tm));
7959
7960 *_u = (usec_t) s * USEC_PER_SEC;
7961
7962 while (*_u <= n)
7963 *_u += USEC_PER_DAY;
7964 }
7965
7966 return 0;
7967 }
7968
7969 static int shutdown_parse_argv(int argc, char *argv[]) {
7970
7971 enum {
7972 ARG_HELP = 0x100,
7973 ARG_NO_WALL
7974 };
7975
7976 static const struct option options[] = {
7977 { "help", no_argument, NULL, ARG_HELP },
7978 { "halt", no_argument, NULL, 'H' },
7979 { "poweroff", no_argument, NULL, 'P' },
7980 { "reboot", no_argument, NULL, 'r' },
7981 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
7982 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7983 {}
7984 };
7985
7986 char **wall = NULL;
7987 int c, r;
7988
7989 assert(argc >= 0);
7990 assert(argv);
7991
7992 while ((c = getopt_long(argc, argv, "HPrhkKtafFc", options, NULL)) >= 0)
7993 switch (c) {
7994
7995 case ARG_HELP:
7996 shutdown_help();
7997 return 0;
7998
7999 case 'H':
8000 arg_action = ACTION_HALT;
8001 break;
8002
8003 case 'P':
8004 arg_action = ACTION_POWEROFF;
8005 break;
8006
8007 case 'r':
8008 if (kexec_loaded())
8009 arg_action = ACTION_KEXEC;
8010 else
8011 arg_action = ACTION_REBOOT;
8012 break;
8013
8014 case 'K':
8015 arg_action = ACTION_KEXEC;
8016 break;
8017
8018 case 'h':
8019 if (arg_action != ACTION_HALT)
8020 arg_action = ACTION_POWEROFF;
8021 break;
8022
8023 case 'k':
8024 arg_dry = true;
8025 break;
8026
8027 case ARG_NO_WALL:
8028 arg_no_wall = true;
8029 break;
8030
8031 case 't':
8032 case 'a':
8033 case 'f':
8034 case 'F':
8035 /* Compatibility nops */
8036 break;
8037
8038 case 'c':
8039 arg_action = ACTION_CANCEL_SHUTDOWN;
8040 break;
8041
8042 case '?':
8043 return -EINVAL;
8044
8045 default:
8046 assert_not_reached("Unhandled option");
8047 }
8048
8049 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
8050 r = parse_shutdown_time_spec(argv[optind], &arg_when);
8051 if (r < 0) {
8052 log_error("Failed to parse time specification: %s", argv[optind]);
8053 return r;
8054 }
8055 } else
8056 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
8057
8058 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
8059 /* No time argument for shutdown cancel */
8060 wall = argv + optind;
8061 else if (argc > optind + 1)
8062 /* We skip the time argument */
8063 wall = argv + optind + 1;
8064
8065 if (wall) {
8066 arg_wall = strv_copy(wall);
8067 if (!arg_wall)
8068 return log_oom();
8069 }
8070
8071 optind = argc;
8072
8073 return 1;
8074 }
8075
8076 static int telinit_parse_argv(int argc, char *argv[]) {
8077
8078 enum {
8079 ARG_HELP = 0x100,
8080 ARG_NO_WALL
8081 };
8082
8083 static const struct option options[] = {
8084 { "help", no_argument, NULL, ARG_HELP },
8085 { "no-wall", no_argument, NULL, ARG_NO_WALL },
8086 {}
8087 };
8088
8089 static const struct {
8090 char from;
8091 enum action to;
8092 } table[] = {
8093 { '0', ACTION_POWEROFF },
8094 { '6', ACTION_REBOOT },
8095 { '1', ACTION_RESCUE },
8096 { '2', ACTION_RUNLEVEL2 },
8097 { '3', ACTION_RUNLEVEL3 },
8098 { '4', ACTION_RUNLEVEL4 },
8099 { '5', ACTION_RUNLEVEL5 },
8100 { 's', ACTION_RESCUE },
8101 { 'S', ACTION_RESCUE },
8102 { 'q', ACTION_RELOAD },
8103 { 'Q', ACTION_RELOAD },
8104 { 'u', ACTION_REEXEC },
8105 { 'U', ACTION_REEXEC }
8106 };
8107
8108 unsigned i;
8109 int c;
8110
8111 assert(argc >= 0);
8112 assert(argv);
8113
8114 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
8115 switch (c) {
8116
8117 case ARG_HELP:
8118 telinit_help();
8119 return 0;
8120
8121 case ARG_NO_WALL:
8122 arg_no_wall = true;
8123 break;
8124
8125 case '?':
8126 return -EINVAL;
8127
8128 default:
8129 assert_not_reached("Unhandled option");
8130 }
8131
8132 if (optind >= argc) {
8133 log_error("%s: required argument missing.", program_invocation_short_name);
8134 return -EINVAL;
8135 }
8136
8137 if (optind + 1 < argc) {
8138 log_error("Too many arguments.");
8139 return -EINVAL;
8140 }
8141
8142 if (strlen(argv[optind]) != 1) {
8143 log_error("Expected single character argument.");
8144 return -EINVAL;
8145 }
8146
8147 for (i = 0; i < ELEMENTSOF(table); i++)
8148 if (table[i].from == argv[optind][0])
8149 break;
8150
8151 if (i >= ELEMENTSOF(table)) {
8152 log_error("Unknown command '%s'.", argv[optind]);
8153 return -EINVAL;
8154 }
8155
8156 arg_action = table[i].to;
8157
8158 optind++;
8159
8160 return 1;
8161 }
8162
8163 static int runlevel_parse_argv(int argc, char *argv[]) {
8164
8165 enum {
8166 ARG_HELP = 0x100,
8167 };
8168
8169 static const struct option options[] = {
8170 { "help", no_argument, NULL, ARG_HELP },
8171 {}
8172 };
8173
8174 int c;
8175
8176 assert(argc >= 0);
8177 assert(argv);
8178
8179 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
8180 switch (c) {
8181
8182 case ARG_HELP:
8183 runlevel_help();
8184 return 0;
8185
8186 case '?':
8187 return -EINVAL;
8188
8189 default:
8190 assert_not_reached("Unhandled option");
8191 }
8192
8193 if (optind < argc) {
8194 log_error("Too many arguments.");
8195 return -EINVAL;
8196 }
8197
8198 return 1;
8199 }
8200
8201 static int parse_argv(int argc, char *argv[]) {
8202 assert(argc >= 0);
8203 assert(argv);
8204
8205 if (program_invocation_short_name) {
8206
8207 if (strstr(program_invocation_short_name, "halt")) {
8208 arg_action = ACTION_HALT;
8209 return halt_parse_argv(argc, argv);
8210 } else if (strstr(program_invocation_short_name, "poweroff")) {
8211 arg_action = ACTION_POWEROFF;
8212 return halt_parse_argv(argc, argv);
8213 } else if (strstr(program_invocation_short_name, "reboot")) {
8214 if (kexec_loaded())
8215 arg_action = ACTION_KEXEC;
8216 else
8217 arg_action = ACTION_REBOOT;
8218 return halt_parse_argv(argc, argv);
8219 } else if (strstr(program_invocation_short_name, "shutdown")) {
8220 arg_action = ACTION_POWEROFF;
8221 return shutdown_parse_argv(argc, argv);
8222 } else if (strstr(program_invocation_short_name, "init")) {
8223
8224 if (sd_booted() > 0) {
8225 arg_action = _ACTION_INVALID;
8226 return telinit_parse_argv(argc, argv);
8227 } else {
8228 /* Hmm, so some other init system is
8229 * running, we need to forward this
8230 * request to it. For now we simply
8231 * guess that it is Upstart. */
8232
8233 execv(TELINIT, argv);
8234
8235 log_error("Couldn't find an alternative telinit implementation to spawn.");
8236 return -EIO;
8237 }
8238
8239 } else if (strstr(program_invocation_short_name, "runlevel")) {
8240 arg_action = ACTION_RUNLEVEL;
8241 return runlevel_parse_argv(argc, argv);
8242 }
8243 }
8244
8245 arg_action = ACTION_SYSTEMCTL;
8246 return systemctl_parse_argv(argc, argv);
8247 }
8248
8249 #if HAVE_SYSV_COMPAT
8250 _pure_ static int action_to_runlevel(void) {
8251
8252 static const char table[_ACTION_MAX] = {
8253 [ACTION_HALT] = '0',
8254 [ACTION_POWEROFF] = '0',
8255 [ACTION_REBOOT] = '6',
8256 [ACTION_RUNLEVEL2] = '2',
8257 [ACTION_RUNLEVEL3] = '3',
8258 [ACTION_RUNLEVEL4] = '4',
8259 [ACTION_RUNLEVEL5] = '5',
8260 [ACTION_RESCUE] = '1'
8261 };
8262
8263 assert(arg_action >= 0 && arg_action < _ACTION_MAX);
8264
8265 return table[arg_action];
8266 }
8267 #endif
8268
8269 static int talk_initctl(void) {
8270 #if HAVE_SYSV_COMPAT
8271 struct init_request request = {
8272 .magic = INIT_MAGIC,
8273 .sleeptime = 0,
8274 .cmd = INIT_CMD_RUNLVL
8275 };
8276
8277 _cleanup_close_ int fd = -1;
8278 char rl;
8279 int r;
8280
8281 rl = action_to_runlevel();
8282 if (!rl)
8283 return 0;
8284
8285 request.runlevel = rl;
8286
8287 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
8288 if (fd < 0) {
8289 if (errno == ENOENT)
8290 return 0;
8291
8292 return log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
8293 }
8294
8295 r = loop_write(fd, &request, sizeof(request), false);
8296 if (r < 0)
8297 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
8298
8299 return 1;
8300 #else
8301 return 0;
8302 #endif
8303 }
8304
8305 static int systemctl_main(int argc, char *argv[]) {
8306
8307 static const Verb verbs[] = {
8308 { "list-units", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_NOCHROOT, list_units },
8309 { "list-unit-files", VERB_ANY, VERB_ANY, 0, list_unit_files },
8310 { "list-sockets", VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_sockets },
8311 { "list-timers", VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_timers },
8312 { "list-jobs", VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_jobs },
8313 { "list-machines", VERB_ANY, VERB_ANY, VERB_NOCHROOT, list_machines },
8314 { "clear-jobs", VERB_ANY, 1, VERB_NOCHROOT, trivial_method },
8315 { "cancel", VERB_ANY, VERB_ANY, VERB_NOCHROOT, cancel_job },
8316 { "start", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8317 { "stop", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8318 { "condstop", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatibility with ALTLinux */
8319 { "reload", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8320 { "restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8321 { "try-restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8322 { "reload-or-restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8323 { "reload-or-try-restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatbility with old systemctl <= 228 */
8324 { "try-reload-or-restart", 2, VERB_ANY, VERB_NOCHROOT, start_unit },
8325 { "force-reload", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatibility with SysV */
8326 { "condreload", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatibility with ALTLinux */
8327 { "condrestart", 2, VERB_ANY, VERB_NOCHROOT, start_unit }, /* For compatibility with RH */
8328 { "isolate", 2, 2, VERB_NOCHROOT, start_unit },
8329 { "kill", 2, VERB_ANY, VERB_NOCHROOT, kill_unit },
8330 { "is-active", 2, VERB_ANY, VERB_NOCHROOT, check_unit_active },
8331 { "check", 2, VERB_ANY, VERB_NOCHROOT, check_unit_active },
8332 { "is-failed", 2, VERB_ANY, VERB_NOCHROOT, check_unit_failed },
8333 { "show", VERB_ANY, VERB_ANY, VERB_NOCHROOT, show },
8334 { "cat", 2, VERB_ANY, VERB_NOCHROOT, cat },
8335 { "status", VERB_ANY, VERB_ANY, VERB_NOCHROOT, show },
8336 { "help", VERB_ANY, VERB_ANY, VERB_NOCHROOT, show },
8337 { "daemon-reload", VERB_ANY, 1, VERB_NOCHROOT, daemon_reload },
8338 { "daemon-reexec", VERB_ANY, 1, VERB_NOCHROOT, daemon_reload },
8339 { "show-environment", VERB_ANY, 1, VERB_NOCHROOT, show_environment },
8340 { "set-environment", 2, VERB_ANY, VERB_NOCHROOT, set_environment },
8341 { "unset-environment", 2, VERB_ANY, VERB_NOCHROOT, set_environment },
8342 { "import-environment", VERB_ANY, VERB_ANY, VERB_NOCHROOT, import_environment },
8343 { "halt", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8344 { "poweroff", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8345 { "reboot", VERB_ANY, 2, VERB_NOCHROOT, start_system_special },
8346 { "kexec", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8347 { "suspend", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8348 { "hibernate", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8349 { "hybrid-sleep", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8350 { "default", VERB_ANY, 1, VERB_NOCHROOT, start_special },
8351 { "rescue", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8352 { "emergency", VERB_ANY, 1, VERB_NOCHROOT, start_system_special },
8353 { "exit", VERB_ANY, 2, VERB_NOCHROOT, start_special },
8354 { "reset-failed", VERB_ANY, VERB_ANY, VERB_NOCHROOT, reset_failed },
8355 { "enable", 2, VERB_ANY, 0, enable_unit },
8356 { "disable", 2, VERB_ANY, 0, enable_unit },
8357 { "is-enabled", 2, VERB_ANY, 0, unit_is_enabled },
8358 { "reenable", 2, VERB_ANY, 0, enable_unit },
8359 { "preset", 2, VERB_ANY, 0, enable_unit },
8360 { "preset-all", VERB_ANY, 1, 0, preset_all },
8361 { "mask", 2, VERB_ANY, 0, enable_unit },
8362 { "unmask", 2, VERB_ANY, 0, enable_unit },
8363 { "link", 2, VERB_ANY, 0, enable_unit },
8364 { "revert", 2, VERB_ANY, 0, enable_unit },
8365 { "switch-root", 2, VERB_ANY, VERB_NOCHROOT, switch_root },
8366 { "list-dependencies", VERB_ANY, 2, VERB_NOCHROOT, list_dependencies },
8367 { "set-default", 2, 2, 0, set_default },
8368 { "get-default", VERB_ANY, 1, 0, get_default },
8369 { "set-property", 3, VERB_ANY, VERB_NOCHROOT, set_property },
8370 { "is-system-running", VERB_ANY, 1, 0, is_system_running },
8371 { "add-wants", 3, VERB_ANY, 0, add_dependency },
8372 { "add-requires", 3, VERB_ANY, 0, add_dependency },
8373 { "edit", 2, VERB_ANY, VERB_NOCHROOT, edit },
8374 {}
8375 };
8376
8377 return dispatch_verb(argc, argv, verbs, NULL);
8378 }
8379
8380 static int reload_with_fallback(void) {
8381
8382 /* First, try systemd via D-Bus. */
8383 if (daemon_reload(0, NULL, NULL) >= 0)
8384 return 0;
8385
8386 /* Nothing else worked, so let's try signals */
8387 assert(IN_SET(arg_action, ACTION_RELOAD, ACTION_REEXEC));
8388
8389 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
8390 return log_error_errno(errno, "kill() failed: %m");
8391
8392 return 0;
8393 }
8394
8395 static int start_with_fallback(void) {
8396
8397 /* First, try systemd via D-Bus. */
8398 if (start_unit(0, NULL, NULL) >= 0)
8399 return 0;
8400
8401 /* Nothing else worked, so let's try /dev/initctl */
8402 if (talk_initctl() > 0)
8403 return 0;
8404
8405 log_error("Failed to talk to init daemon.");
8406 return -EIO;
8407 }
8408
8409 static int halt_now(enum action a) {
8410 int r;
8411
8412 /* The kernel will automaticall flush ATA disks and suchlike
8413 * on reboot(), but the file systems need to be synce'd
8414 * explicitly in advance. */
8415 if (!arg_no_sync)
8416 (void) sync();
8417
8418 /* Make sure C-A-D is handled by the kernel from this point
8419 * on... */
8420 (void) reboot(RB_ENABLE_CAD);
8421
8422 switch (a) {
8423
8424 case ACTION_HALT:
8425 if (!arg_quiet)
8426 log_info("Halting.");
8427 (void) reboot(RB_HALT_SYSTEM);
8428 return -errno;
8429
8430 case ACTION_POWEROFF:
8431 if (!arg_quiet)
8432 log_info("Powering off.");
8433 (void) reboot(RB_POWER_OFF);
8434 return -errno;
8435
8436 case ACTION_KEXEC:
8437 case ACTION_REBOOT: {
8438 _cleanup_free_ char *param = NULL;
8439
8440 r = read_one_line_file("/run/systemd/reboot-param", &param);
8441 if (r < 0 && r != -ENOENT)
8442 log_warning_errno(r, "Failed to read reboot parameter file: %m");
8443
8444 if (!isempty(param)) {
8445 if (!arg_quiet)
8446 log_info("Rebooting with argument '%s'.", param);
8447 (void) syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param);
8448 log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
8449 }
8450
8451 if (!arg_quiet)
8452 log_info("Rebooting.");
8453 (void) reboot(RB_AUTOBOOT);
8454 return -errno;
8455 }
8456
8457 default:
8458 assert_not_reached("Unknown action.");
8459 }
8460 }
8461
8462 static int logind_schedule_shutdown(void) {
8463
8464 #if ENABLE_LOGIND
8465 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
8466 char date[FORMAT_TIMESTAMP_MAX];
8467 const char *action;
8468 sd_bus *bus;
8469 int r;
8470
8471 r = acquire_bus(BUS_FULL, &bus);
8472 if (r < 0)
8473 return r;
8474
8475 switch (arg_action) {
8476 case ACTION_HALT:
8477 action = "halt";
8478 break;
8479 case ACTION_POWEROFF:
8480 action = "poweroff";
8481 break;
8482 case ACTION_KEXEC:
8483 action = "kexec";
8484 break;
8485 case ACTION_EXIT:
8486 action = "exit";
8487 break;
8488 case ACTION_REBOOT:
8489 default:
8490 action = "reboot";
8491 break;
8492 }
8493
8494 if (arg_dry)
8495 action = strjoina("dry-", action);
8496
8497 (void) logind_set_wall_message();
8498
8499 r = sd_bus_call_method(
8500 bus,
8501 "org.freedesktop.login1",
8502 "/org/freedesktop/login1",
8503 "org.freedesktop.login1.Manager",
8504 "ScheduleShutdown",
8505 &error,
8506 NULL,
8507 "st",
8508 action,
8509 arg_when);
8510 if (r < 0)
8511 return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r));
8512
8513 if (!arg_quiet)
8514 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
8515 return 0;
8516 #else
8517 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
8518 return -ENOSYS;
8519 #endif
8520 }
8521
8522 static int halt_main(void) {
8523 int r;
8524
8525 r = logind_check_inhibitors(arg_action);
8526 if (r < 0)
8527 return r;
8528
8529 if (arg_when > 0)
8530 return logind_schedule_shutdown();
8531
8532 if (geteuid() != 0) {
8533 if (arg_dry || arg_force > 0) {
8534 log_error("Must be root.");
8535 return -EPERM;
8536 }
8537
8538 /* Try logind if we are a normal user and no special
8539 * mode applies. Maybe PolicyKit allows us to shutdown
8540 * the machine. */
8541 if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT, ACTION_HALT)) {
8542 r = logind_reboot(arg_action);
8543 if (r >= 0)
8544 return r;
8545 if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
8546 /* requested operation is not
8547 * supported on the local system or
8548 * already in progress */
8549 return r;
8550 /* on all other errors, try low-level operation */
8551 }
8552 }
8553
8554 if (!arg_dry && !arg_force)
8555 return start_with_fallback();
8556
8557 assert(geteuid() == 0);
8558
8559 if (!arg_no_wtmp) {
8560 if (sd_booted() > 0)
8561 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
8562 else {
8563 r = utmp_put_shutdown();
8564 if (r < 0)
8565 log_warning_errno(r, "Failed to write utmp record: %m");
8566 }
8567 }
8568
8569 if (arg_dry)
8570 return 0;
8571
8572 r = halt_now(arg_action);
8573 return log_error_errno(r, "Failed to reboot: %m");
8574 }
8575
8576 static int runlevel_main(void) {
8577 int r, runlevel, previous;
8578
8579 r = utmp_get_runlevel(&runlevel, &previous);
8580 if (r < 0) {
8581 puts("unknown");
8582 return r;
8583 }
8584
8585 printf("%c %c\n",
8586 previous <= 0 ? 'N' : previous,
8587 runlevel <= 0 ? 'N' : runlevel);
8588
8589 return 0;
8590 }
8591
8592 static int logind_cancel_shutdown(void) {
8593 #if ENABLE_LOGIND
8594 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
8595 sd_bus *bus;
8596 int r;
8597
8598 r = acquire_bus(BUS_FULL, &bus);
8599 if (r < 0)
8600 return r;
8601
8602 (void) logind_set_wall_message();
8603
8604 r = sd_bus_call_method(
8605 bus,
8606 "org.freedesktop.login1",
8607 "/org/freedesktop/login1",
8608 "org.freedesktop.login1.Manager",
8609 "CancelScheduledShutdown",
8610 &error,
8611 NULL, NULL);
8612 if (r < 0)
8613 return log_warning_errno(r, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error, r));
8614
8615 return 0;
8616 #else
8617 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
8618 return -ENOSYS;
8619 #endif
8620 }
8621
8622 int main(int argc, char*argv[]) {
8623 int r;
8624
8625 argv_cmdline = argv[0];
8626
8627 setlocale(LC_ALL, "");
8628 log_parse_environment();
8629 log_open();
8630 sigbus_install();
8631
8632 /* Explicitly not on_tty() to avoid setting cached value.
8633 * This becomes relevant for piping output which might be
8634 * ellipsized. */
8635 original_stdout_is_tty = isatty(STDOUT_FILENO);
8636
8637 r = parse_argv(argc, argv);
8638 if (r <= 0)
8639 goto finish;
8640
8641 if (arg_action != ACTION_SYSTEMCTL && running_in_chroot() > 0) {
8642
8643 if (!arg_quiet)
8644 log_info("Running in chroot, ignoring request.");
8645 r = 0;
8646 goto finish;
8647 }
8648
8649 /* systemctl_main() will print an error message for the bus
8650 * connection, but only if it needs to */
8651
8652 switch (arg_action) {
8653
8654 case ACTION_SYSTEMCTL:
8655 r = systemctl_main(argc, argv);
8656 break;
8657
8658 /* Legacy command aliases set arg_action. They provide some fallbacks,
8659 * e.g. to tell sysvinit to reboot after you have installed systemd
8660 * binaries. */
8661
8662 case ACTION_HALT:
8663 case ACTION_POWEROFF:
8664 case ACTION_REBOOT:
8665 case ACTION_KEXEC:
8666 r = halt_main();
8667 break;
8668
8669 case ACTION_RUNLEVEL2:
8670 case ACTION_RUNLEVEL3:
8671 case ACTION_RUNLEVEL4:
8672 case ACTION_RUNLEVEL5:
8673 case ACTION_RESCUE:
8674 r = start_with_fallback();
8675 break;
8676
8677 case ACTION_RELOAD:
8678 case ACTION_REEXEC:
8679 r = reload_with_fallback();
8680 break;
8681
8682 case ACTION_CANCEL_SHUTDOWN:
8683 r = logind_cancel_shutdown();
8684 break;
8685
8686 case ACTION_RUNLEVEL:
8687 r = runlevel_main();
8688 break;
8689
8690 case ACTION_EXIT:
8691 case ACTION_SUSPEND:
8692 case ACTION_HIBERNATE:
8693 case ACTION_HYBRID_SLEEP:
8694 case ACTION_EMERGENCY:
8695 case ACTION_DEFAULT:
8696 /* systemctl verbs with no equivalent in the legacy commands.
8697 * These cannot appear in arg_action. Fall through. */
8698
8699 case _ACTION_INVALID:
8700 default:
8701 assert_not_reached("Unknown action");
8702 }
8703
8704 finish:
8705 release_busses();
8706
8707 pager_close();
8708 ask_password_agent_close();
8709 polkit_agent_close();
8710
8711 strv_free(arg_types);
8712 strv_free(arg_states);
8713 strv_free(arg_properties);
8714
8715 strv_free(arg_wall);
8716 free(arg_root);
8717
8718 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
8719 return r < 0 ? EXIT_FAILURE : r;
8720 }