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