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