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