1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include "sd-messages.h"
30 #include "path-util.h"
32 #include "sleep-config.h"
33 #include "fileio-label.h"
34 #include "unit-name.h"
37 #include "bus-error.h"
38 #include "bus-common-errors.h"
39 #include "udev-util.h"
40 #include "selinux-util.h"
43 #include "formats-util.h"
44 #include "process-util.h"
45 #include "terminal-util.h"
46 #include "utmp-wtmp.h"
48 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
49 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
58 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
62 r = sd_bus_creds_get_session(creds, &name);
67 session = hashmap_get(m->sessions, name);
69 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
75 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
83 if (uid == UID_INVALID) {
84 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
86 /* Note that we get the owner UID of the session, not the actual client UID here! */
87 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
91 r = sd_bus_creds_get_owner_uid(creds, &uid);
96 user = hashmap_get(m->users, UID_TO_PTR(uid));
98 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
104 int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
115 r = manager_get_session_from_creds(m, message, NULL, error, &session);
119 seat = session->seat;
122 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
124 seat = hashmap_get(m->seats, name);
126 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
133 static int property_get_idle_hint(
136 const char *interface,
137 const char *property,
138 sd_bus_message *reply,
140 sd_bus_error *error) {
142 Manager *m = userdata;
148 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
151 static int property_get_idle_since_hint(
154 const char *interface,
155 const char *property,
156 sd_bus_message *reply,
158 sd_bus_error *error) {
160 Manager *m = userdata;
161 dual_timestamp t = DUAL_TIMESTAMP_NULL;
167 manager_get_idle_hint(m, &t);
169 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
172 static int property_get_inhibited(
175 const char *interface,
176 const char *property,
177 sd_bus_message *reply,
179 sd_bus_error *error) {
181 Manager *m = userdata;
188 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
190 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
193 static int property_get_preparing(
196 const char *interface,
197 const char *property,
198 sd_bus_message *reply,
200 sd_bus_error *error) {
202 Manager *m = userdata;
209 if (streq(property, "PreparingForShutdown"))
210 b = !!(m->action_what & INHIBIT_SHUTDOWN);
212 b = !!(m->action_what & INHIBIT_SLEEP);
214 return sd_bus_message_append(reply, "b", b);
217 static int property_get_scheduled_shutdown(
220 const char *interface,
221 const char *property,
222 sd_bus_message *reply,
224 sd_bus_error *error) {
226 Manager *m = userdata;
233 r = sd_bus_message_open_container(reply, 'r', "st");
237 r = sd_bus_message_append(reply, "st", m->scheduled_shutdown_type, m->scheduled_shutdown_timeout);
241 return sd_bus_message_close_container(reply);
244 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
246 static int property_get_docked(
249 const char *interface,
250 const char *property,
251 sd_bus_message *reply,
253 sd_bus_error *error) {
255 Manager *m = userdata;
261 return sd_bus_message_append(reply, "b", manager_is_docked_or_external_displays(m));
264 static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
265 _cleanup_free_ char *p = NULL;
266 Manager *m = userdata;
274 r = sd_bus_message_read(message, "s", &name);
278 r = manager_get_session_from_creds(m, message, name, error, &session);
282 p = session_bus_path(session);
286 return sd_bus_reply_method_return(message, "o", p);
289 static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
290 _cleanup_free_ char *p = NULL;
291 Session *session = NULL;
292 Manager *m = userdata;
299 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
301 r = sd_bus_message_read(message, "u", &pid);
306 r = manager_get_session_from_creds(m, message, NULL, error, &session);
310 r = manager_get_session_by_pid(m, pid, &session);
315 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
318 p = session_bus_path(session);
322 return sd_bus_reply_method_return(message, "o", p);
325 static int method_get_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
326 _cleanup_free_ char *p = NULL;
327 Manager *m = userdata;
335 r = sd_bus_message_read(message, "u", &uid);
339 r = manager_get_user_from_creds(m, message, uid, error, &user);
343 p = user_bus_path(user);
347 return sd_bus_reply_method_return(message, "o", p);
350 static int method_get_user_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
351 _cleanup_free_ char *p = NULL;
352 Manager *m = userdata;
360 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
362 r = sd_bus_message_read(message, "u", &pid);
367 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
371 r = manager_get_user_by_pid(m, pid, &user);
375 return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID "PID_FMT" does not belong to any known or logged in user", pid);
378 p = user_bus_path(user);
382 return sd_bus_reply_method_return(message, "o", p);
385 static int method_get_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
386 _cleanup_free_ char *p = NULL;
387 Manager *m = userdata;
395 r = sd_bus_message_read(message, "s", &name);
399 r = manager_get_seat_from_creds(m, message, name, error, &seat);
403 p = seat_bus_path(seat);
407 return sd_bus_reply_method_return(message, "o", p);
410 static int method_list_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
411 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
412 Manager *m = userdata;
420 r = sd_bus_message_new_method_return(message, &reply);
424 r = sd_bus_message_open_container(reply, 'a', "(susso)");
428 HASHMAP_FOREACH(session, m->sessions, i) {
429 _cleanup_free_ char *p = NULL;
431 p = session_bus_path(session);
435 r = sd_bus_message_append(reply, "(susso)",
437 (uint32_t) session->user->uid,
439 session->seat ? session->seat->id : "",
445 r = sd_bus_message_close_container(reply);
449 return sd_bus_send(NULL, reply, NULL);
452 static int method_list_users(sd_bus_message *message, void *userdata, sd_bus_error *error) {
453 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
454 Manager *m = userdata;
462 r = sd_bus_message_new_method_return(message, &reply);
466 r = sd_bus_message_open_container(reply, 'a', "(uso)");
470 HASHMAP_FOREACH(user, m->users, i) {
471 _cleanup_free_ char *p = NULL;
473 p = user_bus_path(user);
477 r = sd_bus_message_append(reply, "(uso)",
478 (uint32_t) user->uid,
485 r = sd_bus_message_close_container(reply);
489 return sd_bus_send(NULL, reply, NULL);
492 static int method_list_seats(sd_bus_message *message, void *userdata, sd_bus_error *error) {
493 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
494 Manager *m = userdata;
502 r = sd_bus_message_new_method_return(message, &reply);
506 r = sd_bus_message_open_container(reply, 'a', "(so)");
510 HASHMAP_FOREACH(seat, m->seats, i) {
511 _cleanup_free_ char *p = NULL;
513 p = seat_bus_path(seat);
517 r = sd_bus_message_append(reply, "(so)", seat->id, p);
522 r = sd_bus_message_close_container(reply);
526 return sd_bus_send(NULL, reply, NULL);
529 static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
530 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
531 Manager *m = userdata;
532 Inhibitor *inhibitor;
539 r = sd_bus_message_new_method_return(message, &reply);
543 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
547 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
549 r = sd_bus_message_append(reply, "(ssssuu)",
550 strempty(inhibit_what_to_string(inhibitor->what)),
551 strempty(inhibitor->who),
552 strempty(inhibitor->why),
553 strempty(inhibit_mode_to_string(inhibitor->mode)),
554 (uint32_t) inhibitor->uid,
555 (uint32_t) inhibitor->pid);
560 r = sd_bus_message_close_container(reply);
564 return sd_bus_send(NULL, reply, NULL);
567 static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
568 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
569 uint32_t uid, leader, audit_id = 0;
570 _cleanup_free_ char *id = NULL;
571 Session *session = NULL;
572 Manager *m = userdata;
584 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
589 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
592 t = _SESSION_TYPE_INVALID;
594 t = session_type_from_string(type);
596 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
600 c = _SESSION_CLASS_INVALID;
602 c = session_class_from_string(class);
604 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
607 if (isempty(desktop))
610 if (!string_is_safe(desktop))
611 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
617 seat = hashmap_get(m->seats, cseat);
619 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
622 if (tty_is_vc(tty)) {
627 else if (seat != m->seat0)
628 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat->id);
630 v = vtnr_from_tty(tty);
632 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
636 else if (vtnr != (uint32_t) v)
637 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
639 } else if (tty_is_console(tty)) {
643 else if (seat != m->seat0)
644 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
647 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
651 if (seat_has_vts(seat)) {
652 if (!vtnr || vtnr > 63)
653 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
656 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
660 r = sd_bus_message_enter_container(message, 'a', "(sv)");
664 if (t == _SESSION_TYPE_INVALID) {
665 if (!isempty(display))
667 else if (!isempty(tty))
670 t = SESSION_UNSPECIFIED;
673 if (c == _SESSION_CLASS_INVALID) {
674 if (t == SESSION_UNSPECIFIED)
675 c = SESSION_BACKGROUND;
681 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
683 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
687 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
692 manager_get_session_by_pid(m, leader, &session);
693 if (!session && vtnr > 0 && vtnr < m->seat0->position_count)
694 session = m->seat0->positions[vtnr];
696 _cleanup_free_ char *path = NULL;
697 _cleanup_close_ int fifo_fd = -1;
699 /* Session already exists, client is probably
700 * something like "su" which changes uid but is still
701 * the same session */
703 fifo_fd = session_create_fifo(session);
707 path = session_bus_path(session);
711 log_debug("Sending reply about an existing session: "
712 "id=%s object_path=%s uid=%u runtime_path=%s "
713 "session_fd=%d seat=%s vtnr=%u",
716 (uint32_t) session->user->uid,
717 session->user->runtime_path,
719 session->seat ? session->seat->id : "",
720 (uint32_t) session->vtnr);
722 return sd_bus_reply_method_return(
726 session->user->runtime_path,
728 (uint32_t) session->user->uid,
729 session->seat ? session->seat->id : "",
730 (uint32_t) session->vtnr,
734 audit_session_from_pid(leader, &audit_id);
736 /* Keep our session IDs and the audit session IDs in sync */
738 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
741 /* Wut? There's already a session by this name and we
742 * didn't find it above? Weird, then let's not trust
743 * the audit data and let's better register a new
745 if (hashmap_get(m->sessions, id)) {
746 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
759 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
762 } while (hashmap_get(m->sessions, id));
765 r = manager_add_user_by_uid(m, uid, &user);
769 r = manager_add_session(m, id, &session);
773 session_set_user(session, user);
775 session->leader = leader;
776 session->audit_id = audit_id;
779 session->remote = remote;
780 session->vtnr = vtnr;
783 session->tty = strdup(tty);
790 if (!isempty(display)) {
791 session->display = strdup(display);
792 if (!session->display) {
798 if (!isempty(remote_user)) {
799 session->remote_user = strdup(remote_user);
800 if (!session->remote_user) {
806 if (!isempty(remote_host)) {
807 session->remote_host = strdup(remote_host);
808 if (!session->remote_host) {
814 if (!isempty(service)) {
815 session->service = strdup(service);
816 if (!session->service) {
822 if (!isempty(desktop)) {
823 session->desktop = strdup(desktop);
824 if (!session->desktop) {
831 r = seat_attach_session(seat, session);
836 r = session_start(session);
840 session->create_message = sd_bus_message_ref(message);
842 /* Now, let's wait until the slice unit and stuff got
843 * created. We send the reply back from
844 * session_send_create_reply(). */
850 session_add_to_gc_queue(session);
853 user_add_to_gc_queue(user);
858 static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
859 Manager *m = userdata;
867 r = sd_bus_message_read(message, "s", &name);
871 r = manager_get_session_from_creds(m, message, name, error, &session);
875 r = session_release(session);
879 return sd_bus_reply_method_return(message, NULL);
882 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
883 Manager *m = userdata;
891 r = sd_bus_message_read(message, "s", &name);
895 r = manager_get_session_from_creds(m, message, name, error, &session);
899 return bus_session_method_activate(message, session, error);
902 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
903 const char *session_name, *seat_name;
904 Manager *m = userdata;
912 /* Same as ActivateSession() but refuses to work if
913 * the seat doesn't match */
915 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
919 r = manager_get_session_from_creds(m, message, session_name, error, &session);
923 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
927 if (session->seat != seat)
928 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
930 r = session_activate(session);
934 return sd_bus_reply_method_return(message, NULL);
937 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
938 Manager *m = userdata;
946 r = sd_bus_message_read(message, "s", &name);
950 r = manager_get_session_from_creds(m, message, name, error, &session);
954 return bus_session_method_lock(message, session, error);
957 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
958 Manager *m = userdata;
964 r = bus_verify_polkit_async(
967 "org.freedesktop.login1.lock-sessions",
975 return 1; /* Will call us back */
977 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
981 return sd_bus_reply_method_return(message, NULL);
984 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
986 Manager *m = userdata;
993 r = sd_bus_message_read(message, "s", &name);
997 r = manager_get_session_from_creds(m, message, name, error, &session);
1001 return bus_session_method_kill(message, session, error);
1004 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1005 Manager *m = userdata;
1013 r = sd_bus_message_read(message, "u", &uid);
1017 r = manager_get_user_from_creds(m, message, uid, error, &user);
1021 return bus_user_method_kill(message, user, error);
1024 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1025 Manager *m = userdata;
1033 r = sd_bus_message_read(message, "s", &name);
1037 r = manager_get_session_from_creds(m, message, name, error, &session);
1041 return bus_session_method_terminate(message, session, error);
1044 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1045 Manager *m = userdata;
1053 r = sd_bus_message_read(message, "u", &uid);
1057 r = manager_get_user_from_creds(m, message, uid, error, &user);
1061 return bus_user_method_terminate(message, user, error);
1064 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1065 Manager *m = userdata;
1073 r = sd_bus_message_read(message, "s", &name);
1077 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1081 return bus_seat_method_terminate(message, seat, error);
1084 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1085 _cleanup_free_ char *cc = NULL;
1086 Manager *m = userdata;
1096 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1100 if (uid == UID_INVALID) {
1101 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1103 /* Note that we get the owner UID of the session, not the actual client UID here! */
1104 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1108 r = sd_bus_creds_get_owner_uid(creds, &uid);
1116 return errno ? -errno : -ENOENT;
1118 r = bus_verify_polkit_async(
1121 "org.freedesktop.login1.set-user-linger",
1124 &m->polkit_registry,
1129 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1131 mkdir_p_label("/var/lib/systemd", 0755);
1133 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1137 cc = cescape(pw->pw_name);
1141 path = strjoina("/var/lib/systemd/linger/", cc);
1149 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1156 if (r < 0 && errno != ENOENT)
1159 u = hashmap_get(m->users, UID_TO_PTR(uid));
1161 user_add_to_gc_queue(u);
1164 return sd_bus_reply_method_return(message, NULL);
1167 static int trigger_device(Manager *m, struct udev_device *d) {
1168 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1169 struct udev_list_entry *first, *item;
1174 e = udev_enumerate_new(m->udev);
1179 r = udev_enumerate_add_match_parent(e, d);
1184 r = udev_enumerate_scan_devices(e);
1188 first = udev_enumerate_get_list_entry(e);
1189 udev_list_entry_foreach(item, first) {
1190 _cleanup_free_ char *t = NULL;
1193 p = udev_list_entry_get_name(item);
1195 t = strappend(p, "/uevent");
1199 write_string_file(t, "change", WRITE_STRING_FILE_CREATE);
1205 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1206 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1207 _cleanup_free_ char *rule = NULL, *file = NULL;
1208 const char *id_for_seat;
1215 d = udev_device_new_from_syspath(m->udev, sysfs);
1219 if (!udev_device_has_tag(d, "seat"))
1222 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1226 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1229 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1232 mkdir_p_label("/etc/udev/rules.d", 0755);
1233 mac_selinux_init("/etc");
1234 r = write_string_file_atomic_label(file, rule);
1238 return trigger_device(m, d);
1241 static int flush_devices(Manager *m) {
1242 _cleanup_closedir_ DIR *d;
1246 d = opendir("/etc/udev/rules.d");
1248 if (errno != ENOENT)
1249 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1253 while ((de = readdir(d))) {
1255 if (!dirent_is_file(de))
1258 if (!startswith(de->d_name, "72-seat-"))
1261 if (!endswith(de->d_name, ".rules"))
1264 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1265 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1269 return trigger_device(m, NULL);
1272 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1273 const char *sysfs, *seat;
1274 Manager *m = userdata;
1280 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1284 if (!path_startswith(sysfs, "/sys"))
1285 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1287 if (!seat_name_is_valid(seat))
1288 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1290 r = bus_verify_polkit_async(
1293 "org.freedesktop.login1.attach-device",
1296 &m->polkit_registry,
1301 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1303 r = attach_device(m, seat, sysfs);
1307 return sd_bus_reply_method_return(message, NULL);
1310 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1311 Manager *m = userdata;
1317 r = sd_bus_message_read(message, "b", &interactive);
1321 r = bus_verify_polkit_async(
1324 "org.freedesktop.login1.flush-devices",
1327 &m->polkit_registry,
1332 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1334 r = flush_devices(m);
1338 return sd_bus_reply_method_return(message, NULL);
1341 static int have_multiple_sessions(
1350 /* Check for other users' sessions. Greeter sessions do not
1351 * count, and non-login sessions do not count either. */
1352 HASHMAP_FOREACH(session, m->sessions, i)
1353 if (session->class == SESSION_USER &&
1354 session->user->uid != uid)
1360 static int bus_manager_log_shutdown(
1363 const char *unit_name) {
1370 if (w != INHIBIT_SHUTDOWN)
1373 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1374 p = "MESSAGE=System is powering down.";
1375 q = "SHUTDOWN=power-off";
1376 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1377 p = "MESSAGE=System is halting.";
1378 q = "SHUTDOWN=halt";
1379 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1380 p = "MESSAGE=System is rebooting.";
1381 q = "SHUTDOWN=reboot";
1382 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1383 p = "MESSAGE=System is rebooting with kexec.";
1384 q = "SHUTDOWN=kexec";
1386 p = "MESSAGE=System is shutting down.";
1390 return log_struct(LOG_NOTICE,
1391 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1397 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1398 Manager *m = userdata;
1403 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1407 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1412 if (until <= now(CLOCK_MONOTONIC))
1415 /* We want to ignore the lid switch for a while after each
1416 * suspend, and after boot-up. Hence let's install a timer for
1417 * this. As long as the event source exists we ignore the lid
1420 if (m->lid_switch_ignore_event_source) {
1423 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1430 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1432 r = sd_event_add_time(
1434 &m->lid_switch_ignore_event_source,
1437 lid_switch_ignore_handler, m);
1442 static int execute_shutdown_or_sleep(
1445 const char *unit_name,
1446 sd_bus_error *error) {
1448 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1455 assert(w < _INHIBIT_WHAT_MAX);
1458 bus_manager_log_shutdown(m, w, unit_name);
1460 r = sd_bus_call_method(
1462 "org.freedesktop.systemd1",
1463 "/org/freedesktop/systemd1",
1464 "org.freedesktop.systemd1.Manager",
1468 "ss", unit_name, "replace-irreversibly");
1472 r = sd_bus_message_read(reply, "o", &p);
1480 m->action_unit = unit_name;
1481 free(m->action_job);
1485 /* Make sure the lid switch is ignored for a while */
1486 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1491 int manager_dispatch_delayed(Manager *manager, bool timeout) {
1493 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1494 Inhibitor *offending = NULL;
1499 if (manager->action_what == 0 || manager->action_job)
1502 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1503 _cleanup_free_ char *comm = NULL, *u = NULL;
1508 (void) get_process_comm(offending->pid, &comm);
1509 u = uid_to_name(offending->uid);
1511 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1512 offending->uid, strna(u),
1513 offending->pid, strna(comm));
1516 /* Actually do the operation */
1517 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
1519 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1521 manager->action_unit = NULL;
1522 manager->action_what = 0;
1529 static int manager_inhibit_timeout_handler(
1534 Manager *manager = userdata;
1538 assert(manager->inhibit_timeout_source == s);
1540 r = manager_dispatch_delayed(manager, true);
1541 return (r < 0) ? r : 0;
1544 static int delay_shutdown_or_sleep(
1547 const char *unit_name) {
1554 assert(w < _INHIBIT_WHAT_MAX);
1557 timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1559 if (m->inhibit_timeout_source) {
1560 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1562 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1564 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1566 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1568 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1569 timeout_val, 0, manager_inhibit_timeout_handler, m);
1574 m->action_unit = unit_name;
1580 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1582 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1583 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1584 [INHIBIT_SLEEP] = "PrepareForSleep"
1587 int active = _active;
1591 assert(w < _INHIBIT_WHAT_MAX);
1592 assert(signal_name[w]);
1594 return sd_bus_emit_signal(m->bus,
1595 "/org/freedesktop/login1",
1596 "org.freedesktop.login1.Manager",
1602 int bus_manager_shutdown_or_sleep_now_or_later(
1604 const char *unit_name,
1606 sd_bus_error *error) {
1614 assert(w <= _INHIBIT_WHAT_MAX);
1615 assert(!m->action_job);
1617 /* Tell everybody to prepare for shutdown/sleep */
1618 send_prepare_for(m, w, true);
1621 m->inhibit_delay_max > 0 &&
1622 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1625 /* Shutdown is delayed, keep in mind what we
1626 * want to do, and start a timeout */
1627 r = delay_shutdown_or_sleep(m, w, unit_name);
1629 /* Shutdown is not delayed, execute it
1631 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1636 static int verify_shutdown_creds(
1638 sd_bus_message *message,
1642 const char *action_multiple_sessions,
1643 const char *action_ignore_inhibit,
1644 sd_bus_error *error) {
1646 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1647 bool multiple_sessions, blocked;
1654 assert(w <= _INHIBIT_WHAT_MAX);
1656 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1660 r = sd_bus_creds_get_euid(creds, &uid);
1664 r = have_multiple_sessions(m, uid);
1668 multiple_sessions = r > 0;
1669 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1671 if (multiple_sessions && action_multiple_sessions) {
1672 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1676 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1679 if (blocked && action_ignore_inhibit) {
1680 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1684 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1687 if (!multiple_sessions && !blocked && action) {
1688 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1692 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1698 static int method_do_shutdown_or_sleep(
1700 sd_bus_message *message,
1701 const char *unit_name,
1704 const char *action_multiple_sessions,
1705 const char *action_ignore_inhibit,
1706 const char *sleep_verb,
1707 sd_bus_error *error) {
1715 assert(w <= _INHIBIT_WHAT_MAX);
1717 r = sd_bus_message_read(message, "b", &interactive);
1721 /* Don't allow multiple jobs being executed at the same time */
1723 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1726 r = can_sleep(sleep_verb);
1731 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1734 r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1735 action_ignore_inhibit, error);
1739 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1743 return sd_bus_reply_method_return(message, NULL);
1746 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1747 Manager *m = userdata;
1749 return method_do_shutdown_or_sleep(
1751 SPECIAL_POWEROFF_TARGET,
1753 "org.freedesktop.login1.power-off",
1754 "org.freedesktop.login1.power-off-multiple-sessions",
1755 "org.freedesktop.login1.power-off-ignore-inhibit",
1760 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1761 Manager *m = userdata;
1763 return method_do_shutdown_or_sleep(
1765 SPECIAL_REBOOT_TARGET,
1767 "org.freedesktop.login1.reboot",
1768 "org.freedesktop.login1.reboot-multiple-sessions",
1769 "org.freedesktop.login1.reboot-ignore-inhibit",
1774 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1775 Manager *m = userdata;
1777 return method_do_shutdown_or_sleep(
1779 SPECIAL_SUSPEND_TARGET,
1781 "org.freedesktop.login1.suspend",
1782 "org.freedesktop.login1.suspend-multiple-sessions",
1783 "org.freedesktop.login1.suspend-ignore-inhibit",
1788 static int nologin_timeout_handler(
1793 Manager *m = userdata;
1796 log_info("Creating /run/nologin, blocking further logins...");
1798 r = write_string_file("/run/nologin", "System is going down.", WRITE_STRING_FILE_ATOMIC);
1800 log_error_errno(r, "Failed to create /run/nologin: %m");
1802 m->unlink_nologin = true;
1807 static int update_schedule_file(Manager *m) {
1810 _cleanup_fclose_ FILE *f = NULL;
1811 _cleanup_free_ char *t = NULL, *temp_path = NULL;
1815 r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1817 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1819 t = cescape(m->wall_message);
1823 r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1825 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1827 (void) fchmod(fileno(f), 0644);
1833 m->scheduled_shutdown_timeout,
1834 m->enable_wall_messages,
1835 m->scheduled_shutdown_type);
1837 if (!isempty(m->wall_message))
1838 fprintf(f, "WALL_MESSAGE=%s\n", t);
1840 (void) fflush_and_check(f);
1842 if (ferror(f) || rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1843 log_error_errno(errno, "Failed to write information about scheduled shutdowns: %m");
1846 (void) unlink(temp_path);
1847 (void) unlink("/run/systemd/shutdown/scheduled");
1853 static int manager_scheduled_shutdown_handler(
1858 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1859 Manager *m = userdata;
1865 if (isempty(m->scheduled_shutdown_type))
1868 if (streq(m->scheduled_shutdown_type, "halt"))
1869 target = SPECIAL_HALT_TARGET;
1870 else if (streq(m->scheduled_shutdown_type, "poweroff"))
1871 target = SPECIAL_POWEROFF_TARGET;
1873 target = SPECIAL_REBOOT_TARGET;
1875 r = execute_shutdown_or_sleep(m, 0, target, &error);
1877 return log_error_errno(r, "Unable to execute transition to %s: %m", target);
1882 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1883 Manager *m = userdata;
1884 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1885 const char *action_multiple_sessions = NULL;
1886 const char *action_ignore_inhibit = NULL;
1887 const char *action = NULL;
1895 r = sd_bus_message_read(message, "st", &type, &elapse);
1899 if (streq(type, "reboot")) {
1900 action = "org.freedesktop.login1.reboot";
1901 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1902 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1903 } else if (streq(type, "halt")) {
1904 action = "org.freedesktop.login1.halt";
1905 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1906 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1907 } else if (streq(type, "poweroff")) {
1908 action = "org.freedesktop.login1.poweroff";
1909 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1910 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1912 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1914 r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1915 action, action_multiple_sessions, action_ignore_inhibit, error);
1919 if (m->scheduled_shutdown_timeout_source) {
1920 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1922 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1924 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1926 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1928 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1929 CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1931 return log_error_errno(r, "sd_event_add_time() failed: %m");
1934 r = free_and_strdup(&m->scheduled_shutdown_type, type);
1936 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1940 if (m->nologin_timeout_source) {
1941 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1943 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1945 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1947 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1949 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1950 CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1952 return log_error_errno(r, "sd_event_add_time() failed: %m");
1955 m->scheduled_shutdown_timeout = elapse;
1957 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1961 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1962 (void) sd_bus_creds_get_tty(creds, &tty);
1964 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1966 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1971 r = manager_setup_wall_message_timer(m);
1975 if (!isempty(type)) {
1976 r = update_schedule_file(m);
1980 (void) unlink("/run/systemd/shutdown/scheduled");
1982 return sd_bus_reply_method_return(message, NULL);
1985 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1986 Manager *m = userdata;
1992 cancelled = m->scheduled_shutdown_type != NULL;
1994 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1995 m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
1996 m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
1997 free(m->scheduled_shutdown_type);
1998 m->scheduled_shutdown_type = NULL;
1999 m->scheduled_shutdown_timeout = 0;
2001 if (m->unlink_nologin) {
2002 (void) unlink("/run/nologin");
2003 m->unlink_nologin = false;
2007 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2008 const char *tty = NULL;
2012 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
2014 (void) sd_bus_creds_get_uid(creds, &uid);
2015 (void) sd_bus_creds_get_tty(creds, &tty);
2018 utmp_wall("The system shutdown has been cancelled",
2019 lookup_uid(uid), tty, logind_wall_tty_filter, m);
2022 return sd_bus_reply_method_return(message, "b", cancelled);
2025 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2026 Manager *m = userdata;
2028 return method_do_shutdown_or_sleep(
2030 SPECIAL_HIBERNATE_TARGET,
2032 "org.freedesktop.login1.hibernate",
2033 "org.freedesktop.login1.hibernate-multiple-sessions",
2034 "org.freedesktop.login1.hibernate-ignore-inhibit",
2039 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2040 Manager *m = userdata;
2042 return method_do_shutdown_or_sleep(
2044 SPECIAL_HYBRID_SLEEP_TARGET,
2046 "org.freedesktop.login1.hibernate",
2047 "org.freedesktop.login1.hibernate-multiple-sessions",
2048 "org.freedesktop.login1.hibernate-ignore-inhibit",
2053 static int method_can_shutdown_or_sleep(
2055 sd_bus_message *message,
2058 const char *action_multiple_sessions,
2059 const char *action_ignore_inhibit,
2060 const char *sleep_verb,
2061 sd_bus_error *error) {
2063 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2064 bool multiple_sessions, challenge, blocked;
2065 const char *result = NULL;
2072 assert(w <= _INHIBIT_WHAT_MAX);
2074 assert(action_multiple_sessions);
2075 assert(action_ignore_inhibit);
2078 r = can_sleep(sleep_verb);
2082 return sd_bus_reply_method_return(message, "s", "na");
2085 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2089 r = sd_bus_creds_get_euid(creds, &uid);
2093 r = have_multiple_sessions(m, uid);
2097 multiple_sessions = r > 0;
2098 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2100 if (multiple_sessions) {
2101 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
2108 result = "challenge";
2114 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
2118 if (r > 0 && !result)
2120 else if (challenge && (!result || streq(result, "yes")))
2121 result = "challenge";
2126 if (!multiple_sessions && !blocked) {
2127 /* If neither inhibit nor multiple sessions
2128 * apply then just check the normal policy */
2130 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
2137 result = "challenge";
2142 return sd_bus_reply_method_return(message, "s", result);
2145 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2146 Manager *m = userdata;
2148 return method_can_shutdown_or_sleep(
2151 "org.freedesktop.login1.power-off",
2152 "org.freedesktop.login1.power-off-multiple-sessions",
2153 "org.freedesktop.login1.power-off-ignore-inhibit",
2158 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2159 Manager *m = userdata;
2161 return method_can_shutdown_or_sleep(
2164 "org.freedesktop.login1.reboot",
2165 "org.freedesktop.login1.reboot-multiple-sessions",
2166 "org.freedesktop.login1.reboot-ignore-inhibit",
2171 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2172 Manager *m = userdata;
2174 return method_can_shutdown_or_sleep(
2177 "org.freedesktop.login1.suspend",
2178 "org.freedesktop.login1.suspend-multiple-sessions",
2179 "org.freedesktop.login1.suspend-ignore-inhibit",
2184 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2185 Manager *m = userdata;
2187 return method_can_shutdown_or_sleep(
2190 "org.freedesktop.login1.hibernate",
2191 "org.freedesktop.login1.hibernate-multiple-sessions",
2192 "org.freedesktop.login1.hibernate-ignore-inhibit",
2197 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2198 Manager *m = userdata;
2200 return method_can_shutdown_or_sleep(
2203 "org.freedesktop.login1.hibernate",
2204 "org.freedesktop.login1.hibernate-multiple-sessions",
2205 "org.freedesktop.login1.hibernate-ignore-inhibit",
2210 static int property_get_reboot_to_firmware_setup(
2213 const char *interface,
2214 const char *property,
2215 sd_bus_message *reply,
2217 sd_bus_error *error) {
2224 r = efi_get_reboot_to_firmware();
2225 if (r < 0 && r != -EOPNOTSUPP)
2228 return sd_bus_message_append(reply, "b", r > 0);
2231 static int method_set_reboot_to_firmware_setup(
2232 sd_bus_message *message,
2234 sd_bus_error *error) {
2237 Manager *m = userdata;
2242 r = sd_bus_message_read(message, "b", &b);
2246 r = bus_verify_polkit_async(message,
2248 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2251 &m->polkit_registry,
2256 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2258 r = efi_set_reboot_to_firmware(b);
2262 return sd_bus_reply_method_return(message, NULL);
2265 static int method_can_reboot_to_firmware_setup(
2266 sd_bus_message *message,
2268 sd_bus_error *error) {
2273 Manager *m = userdata;
2278 r = efi_reboot_to_firmware_supported();
2279 if (r == -EOPNOTSUPP)
2280 return sd_bus_reply_method_return(message, "s", "na");
2284 r = bus_test_polkit(message,
2286 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2296 result = "challenge";
2300 return sd_bus_reply_method_return(message, "s", result);
2303 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2304 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2305 const char *who, *why, *what, *mode;
2306 _cleanup_free_ char *id = NULL;
2307 _cleanup_close_ int fifo_fd = -1;
2308 Manager *m = userdata;
2309 Inhibitor *i = NULL;
2319 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2323 w = inhibit_what_from_string(what);
2325 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2327 mm = inhibit_mode_from_string(mode);
2329 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2331 /* Delay is only supported for shutdown/sleep */
2332 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2333 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2335 /* Don't allow taking delay locks while we are already
2336 * executing the operation. We shouldn't create the impression
2337 * that the lock was successful if the machine is about to go
2338 * down/suspend any moment. */
2339 if (m->action_what & w)
2340 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2342 r = bus_verify_polkit_async(
2345 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2346 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2347 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
2348 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
2349 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2350 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2351 "org.freedesktop.login1.inhibit-handle-lid-switch",
2354 &m->polkit_registry,
2359 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2361 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2365 r = sd_bus_creds_get_euid(creds, &uid);
2369 r = sd_bus_creds_get_pid(creds, &pid);
2377 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2380 } while (hashmap_get(m->inhibitors, id));
2382 r = manager_add_inhibitor(m, id, &i);
2390 i->why = strdup(why);
2391 i->who = strdup(who);
2393 if (!i->why || !i->who) {
2398 fifo_fd = inhibitor_create_fifo(i);
2406 return sd_bus_reply_method_return(message, "h", fifo_fd);
2415 const sd_bus_vtable manager_vtable[] = {
2416 SD_BUS_VTABLE_START(0),
2418 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2419 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2421 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2422 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2423 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2424 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2425 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2426 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2427 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2428 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2429 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2430 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2431 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2432 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2433 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2434 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2435 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2436 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2437 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2438 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2439 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2440 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2441 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2442 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2443 SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
2445 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2446 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2447 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2448 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2449 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2450 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2451 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2452 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2453 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2454 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2455 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2456 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2457 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2458 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2459 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2460 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2461 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2462 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2463 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2464 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2465 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2466 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2467 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2468 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2469 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2470 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2471 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2472 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2473 SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2474 SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2475 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2476 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2477 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2478 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2479 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2480 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2481 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2482 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2483 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2484 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2486 SD_BUS_SIGNAL("SessionNew", "so", 0),
2487 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2488 SD_BUS_SIGNAL("UserNew", "uo", 0),
2489 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2490 SD_BUS_SIGNAL("SeatNew", "so", 0),
2491 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2492 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2493 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2498 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2507 if (streq(result, "done"))
2508 r = session_send_create_reply(s, NULL);
2510 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2512 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2513 r = session_send_create_reply(s, &e);
2519 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2520 const char *path, *result, *unit;
2521 Manager *m = userdata;
2530 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2532 bus_log_parse_error(r);
2536 if (m->action_job && streq(m->action_job, path)) {
2537 log_info("Operation finished.");
2539 /* Tell people that they now may take a lock again */
2540 send_prepare_for(m, m->action_what, false);
2542 free(m->action_job);
2543 m->action_job = NULL;
2544 m->action_unit = NULL;
2549 session = hashmap_get(m->session_units, unit);
2552 if (streq_ptr(path, session->scope_job)) {
2553 free(session->scope_job);
2554 session->scope_job = NULL;
2557 session_jobs_reply(session, unit, result);
2559 session_save(session);
2560 user_save(session->user);
2561 session_add_to_gc_queue(session);
2564 user = hashmap_get(m->user_units, unit);
2567 if (streq_ptr(path, user->service_job)) {
2568 free(user->service_job);
2569 user->service_job = NULL;
2572 if (streq_ptr(path, user->slice_job)) {
2573 free(user->slice_job);
2574 user->slice_job = NULL;
2577 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2578 session_jobs_reply(session, unit, result);
2582 user_add_to_gc_queue(user);
2588 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2589 const char *path, *unit;
2590 Manager *m = userdata;
2598 r = sd_bus_message_read(message, "so", &unit, &path);
2600 bus_log_parse_error(r);
2604 session = hashmap_get(m->session_units, unit);
2606 session_add_to_gc_queue(session);
2608 user = hashmap_get(m->user_units, unit);
2610 user_add_to_gc_queue(user);
2615 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2616 _cleanup_free_ char *unit = NULL;
2617 Manager *m = userdata;
2626 path = sd_bus_message_get_path(message);
2630 r = unit_name_from_dbus_path(path, &unit);
2631 if (r == -EINVAL) /* not a unit */
2636 session = hashmap_get(m->session_units, unit);
2638 session_add_to_gc_queue(session);
2640 user = hashmap_get(m->user_units, unit);
2642 user_add_to_gc_queue(user);
2647 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2648 Manager *m = userdata;
2656 r = sd_bus_message_read(message, "b", &b);
2658 bus_log_parse_error(r);
2665 /* systemd finished reloading, let's recheck all our sessions */
2666 log_debug("System manager has been reloaded, rechecking sessions...");
2668 HASHMAP_FOREACH(session, m->sessions, i)
2669 session_add_to_gc_queue(session);
2674 int match_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2675 const char *name, *old, *new;
2676 Manager *m = userdata;
2685 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2687 bus_log_parse_error(r);
2691 if (isempty(old) || !isempty(new))
2694 key = set_remove(m->busnames, (char*) old);
2698 /* Drop all controllers owned by this name */
2702 HASHMAP_FOREACH(session, m->sessions, i)
2703 if (session_is_controller(session, old))
2704 session_drop_controller(session);
2709 int manager_send_changed(Manager *manager, const char *property, ...) {
2714 l = strv_from_stdarg_alloca(property);
2716 return sd_bus_emit_properties_changed_strv(
2718 "/org/freedesktop/login1",
2719 "org.freedesktop.login1.Manager",
2723 int manager_start_scope(
2728 const char *description,
2729 const char *after, const char *after2,
2730 sd_bus_error *error,
2733 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2740 r = sd_bus_message_new_method_call(
2743 "org.freedesktop.systemd1",
2744 "/org/freedesktop/systemd1",
2745 "org.freedesktop.systemd1.Manager",
2746 "StartTransientUnit");
2750 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2754 r = sd_bus_message_open_container(m, 'a', "(sv)");
2758 if (!isempty(slice)) {
2759 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2764 if (!isempty(description)) {
2765 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2770 if (!isempty(after)) {
2771 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2776 if (!isempty(after2)) {
2777 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2782 /* cgroup empty notification is not available in containers
2783 * currently. To make this less problematic, let's shorten the
2784 * stop timeout for sessions, so that we don't wait
2787 /* Make sure that the session shells are terminated with
2788 * SIGHUP since bash and friends tend to ignore SIGTERM */
2789 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2793 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2797 r = sd_bus_message_close_container(m);
2801 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2805 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2813 r = sd_bus_message_read(reply, "o", &j);
2827 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2828 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2834 r = sd_bus_call_method(
2836 "org.freedesktop.systemd1",
2837 "/org/freedesktop/systemd1",
2838 "org.freedesktop.systemd1.Manager",
2842 "ss", unit, "fail");
2850 r = sd_bus_message_read(reply, "o", &j);
2864 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2865 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2871 r = sd_bus_call_method(
2873 "org.freedesktop.systemd1",
2874 "/org/freedesktop/systemd1",
2875 "org.freedesktop.systemd1.Manager",
2879 "ss", unit, "fail");
2881 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2882 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2887 sd_bus_error_free(error);
2898 r = sd_bus_message_read(reply, "o", &j);
2912 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2913 _cleanup_free_ char *path = NULL;
2919 path = unit_dbus_path_from_name(scope);
2923 r = sd_bus_call_method(
2925 "org.freedesktop.systemd1",
2927 "org.freedesktop.systemd1.Scope",
2933 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2934 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2935 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2936 sd_bus_error_free(error);
2946 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2950 return sd_bus_call_method(
2952 "org.freedesktop.systemd1",
2953 "/org/freedesktop/systemd1",
2954 "org.freedesktop.systemd1.Manager",
2958 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2961 int manager_unit_is_active(Manager *manager, const char *unit) {
2962 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2963 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2964 _cleanup_free_ char *path = NULL;
2971 path = unit_dbus_path_from_name(unit);
2975 r = sd_bus_get_property(
2977 "org.freedesktop.systemd1",
2979 "org.freedesktop.systemd1.Unit",
2985 /* systemd might have droppped off momentarily, let's
2986 * not make this an error */
2987 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2988 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2991 /* If the unit is already unloaded then it's not
2993 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2994 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
3000 r = sd_bus_message_read(reply, "s", &state);
3004 return !streq(state, "inactive") && !streq(state, "failed");
3007 int manager_job_is_active(Manager *manager, const char *path) {
3008 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3009 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3015 r = sd_bus_get_property(
3017 "org.freedesktop.systemd1",
3019 "org.freedesktop.systemd1.Job",
3025 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3026 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3029 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3035 /* We don't actually care about the state really. The fact
3036 * that we could read the job state is enough for us */