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