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