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