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