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 r = manager_get_session_by_pid(m, leader, NULL);
694 return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session");
697 * Old gdm and lightdm start the user-session on the same VT as
698 * the greeter session. But they destroy the greeter session
699 * after the user-session and want the user-session to take
700 * over the VT. We need to support this for
701 * backwards-compatibility, so make sure we allow new sessions
702 * on a VT that a greeter is running on. Furthermore, to allow
703 * re-logins, we have to allow a greeter to take over a used VT for
704 * the exact same reasons.
706 if (c != SESSION_GREETER &&
708 vtnr < m->seat0->position_count &&
709 m->seat0->positions[vtnr] &&
710 m->seat0->positions[vtnr]->class != SESSION_GREETER)
711 return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session");
713 audit_session_from_pid(leader, &audit_id);
715 /* Keep our session IDs and the audit session IDs in sync */
717 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
720 /* Wut? There's already a session by this name and we
721 * didn't find it above? Weird, then let's not trust
722 * the audit data and let's better register a new
724 if (hashmap_get(m->sessions, id)) {
725 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
738 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
741 } while (hashmap_get(m->sessions, id));
744 r = manager_add_user_by_uid(m, uid, &user);
748 r = manager_add_session(m, id, &session);
752 session_set_user(session, user);
754 session->leader = leader;
755 session->audit_id = audit_id;
758 session->remote = remote;
759 session->vtnr = vtnr;
762 session->tty = strdup(tty);
769 if (!isempty(display)) {
770 session->display = strdup(display);
771 if (!session->display) {
777 if (!isempty(remote_user)) {
778 session->remote_user = strdup(remote_user);
779 if (!session->remote_user) {
785 if (!isempty(remote_host)) {
786 session->remote_host = strdup(remote_host);
787 if (!session->remote_host) {
793 if (!isempty(service)) {
794 session->service = strdup(service);
795 if (!session->service) {
801 if (!isempty(desktop)) {
802 session->desktop = strdup(desktop);
803 if (!session->desktop) {
810 r = seat_attach_session(seat, session);
815 r = session_start(session);
819 session->create_message = sd_bus_message_ref(message);
821 /* Now, let's wait until the slice unit and stuff got
822 * created. We send the reply back from
823 * session_send_create_reply(). */
825 /* Elogind note: replying directly, since we're not actually
826 starting slices and thus we aren't waiting on systemd. */
828 r = session_send_create_reply(session, NULL);
832 session_save(session);
838 session_add_to_gc_queue(session);
841 user_add_to_gc_queue(user);
846 static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
847 Manager *m = userdata;
855 r = sd_bus_message_read(message, "s", &name);
859 r = manager_get_session_from_creds(m, message, name, error, &session);
863 r = session_release(session);
867 return sd_bus_reply_method_return(message, NULL);
870 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
871 Manager *m = userdata;
879 r = sd_bus_message_read(message, "s", &name);
883 r = manager_get_session_from_creds(m, message, name, error, &session);
887 return bus_session_method_activate(message, session, error);
890 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
891 const char *session_name, *seat_name;
892 Manager *m = userdata;
900 /* Same as ActivateSession() but refuses to work if
901 * the seat doesn't match */
903 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
907 r = manager_get_session_from_creds(m, message, session_name, error, &session);
911 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
915 if (session->seat != seat)
916 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
918 r = session_activate(session);
922 return sd_bus_reply_method_return(message, NULL);
925 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
926 Manager *m = userdata;
934 r = sd_bus_message_read(message, "s", &name);
938 r = manager_get_session_from_creds(m, message, name, error, &session);
942 return bus_session_method_lock(message, session, error);
945 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
946 Manager *m = userdata;
952 r = bus_verify_polkit_async(
955 "org.freedesktop.login1.lock-sessions",
963 return 1; /* Will call us back */
965 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
969 return sd_bus_reply_method_return(message, NULL);
972 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
974 Manager *m = userdata;
981 r = sd_bus_message_read(message, "s", &name);
985 r = manager_get_session_from_creds(m, message, name, error, &session);
989 return bus_session_method_kill(message, session, error);
992 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
993 Manager *m = userdata;
1001 r = sd_bus_message_read(message, "u", &uid);
1005 r = manager_get_user_from_creds(m, message, uid, error, &user);
1009 return bus_user_method_kill(message, user, error);
1012 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1013 Manager *m = userdata;
1021 r = sd_bus_message_read(message, "s", &name);
1025 r = manager_get_session_from_creds(m, message, name, error, &session);
1029 return bus_session_method_terminate(message, session, error);
1032 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1033 Manager *m = userdata;
1041 r = sd_bus_message_read(message, "u", &uid);
1045 r = manager_get_user_from_creds(m, message, uid, error, &user);
1049 return bus_user_method_terminate(message, user, error);
1052 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1053 Manager *m = userdata;
1061 r = sd_bus_message_read(message, "s", &name);
1065 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1069 return bus_seat_method_terminate(message, seat, error);
1072 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1073 _cleanup_free_ char *cc = NULL;
1074 Manager *m = userdata;
1084 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1088 if (uid == UID_INVALID) {
1089 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1091 /* Note that we get the owner UID of the session, not the actual client UID here! */
1092 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1096 r = sd_bus_creds_get_owner_uid(creds, &uid);
1104 return errno ? -errno : -ENOENT;
1106 r = bus_verify_polkit_async(
1109 "org.freedesktop.login1.set-user-linger",
1112 &m->polkit_registry,
1117 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1119 mkdir_p_label("/var/lib/systemd", 0755);
1121 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1125 cc = cescape(pw->pw_name);
1129 path = strjoina("/var/lib/systemd/linger/", cc);
1137 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1144 if (r < 0 && errno != ENOENT)
1147 u = hashmap_get(m->users, UID_TO_PTR(uid));
1149 user_add_to_gc_queue(u);
1152 return sd_bus_reply_method_return(message, NULL);
1155 static int trigger_device(Manager *m, struct udev_device *d) {
1156 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1157 struct udev_list_entry *first, *item;
1162 e = udev_enumerate_new(m->udev);
1167 r = udev_enumerate_add_match_parent(e, d);
1172 r = udev_enumerate_scan_devices(e);
1176 first = udev_enumerate_get_list_entry(e);
1177 udev_list_entry_foreach(item, first) {
1178 _cleanup_free_ char *t = NULL;
1181 p = udev_list_entry_get_name(item);
1183 t = strappend(p, "/uevent");
1187 write_string_file(t, "change", WRITE_STRING_FILE_CREATE);
1193 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1194 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1195 _cleanup_free_ char *rule = NULL, *file = NULL;
1196 const char *id_for_seat;
1203 d = udev_device_new_from_syspath(m->udev, sysfs);
1207 if (!udev_device_has_tag(d, "seat"))
1210 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1214 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1217 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1220 mkdir_p_label("/etc/udev/rules.d", 0755);
1221 mac_selinux_init("/etc");
1222 r = write_string_file_atomic_label(file, rule);
1226 return trigger_device(m, d);
1229 static int flush_devices(Manager *m) {
1230 _cleanup_closedir_ DIR *d;
1234 d = opendir("/etc/udev/rules.d");
1236 if (errno != ENOENT)
1237 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1241 while ((de = readdir(d))) {
1243 if (!dirent_is_file(de))
1246 if (!startswith(de->d_name, "72-seat-"))
1249 if (!endswith(de->d_name, ".rules"))
1252 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1253 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1257 return trigger_device(m, NULL);
1260 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1261 const char *sysfs, *seat;
1262 Manager *m = userdata;
1268 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1272 if (!path_startswith(sysfs, "/sys"))
1273 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1275 if (!seat_name_is_valid(seat))
1276 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1278 r = bus_verify_polkit_async(
1281 "org.freedesktop.login1.attach-device",
1284 &m->polkit_registry,
1289 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1291 r = attach_device(m, seat, sysfs);
1295 return sd_bus_reply_method_return(message, NULL);
1298 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1299 Manager *m = userdata;
1305 r = sd_bus_message_read(message, "b", &interactive);
1309 r = bus_verify_polkit_async(
1312 "org.freedesktop.login1.flush-devices",
1315 &m->polkit_registry,
1320 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1322 r = flush_devices(m);
1326 return sd_bus_reply_method_return(message, NULL);
1329 static int have_multiple_sessions(
1338 /* Check for other users' sessions. Greeter sessions do not
1339 * count, and non-login sessions do not count either. */
1340 HASHMAP_FOREACH(session, m->sessions, i)
1341 if (session->class == SESSION_USER &&
1342 session->user->uid != uid)
1348 static int bus_manager_log_shutdown(
1351 const char *unit_name) {
1358 if (w != INHIBIT_SHUTDOWN)
1361 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1362 p = "MESSAGE=System is powering down.";
1363 q = "SHUTDOWN=power-off";
1364 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1365 p = "MESSAGE=System is halting.";
1366 q = "SHUTDOWN=halt";
1367 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1368 p = "MESSAGE=System is rebooting.";
1369 q = "SHUTDOWN=reboot";
1370 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1371 p = "MESSAGE=System is rebooting with kexec.";
1372 q = "SHUTDOWN=kexec";
1374 p = "MESSAGE=System is shutting down.";
1378 return log_struct(LOG_NOTICE,
1379 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1385 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1386 Manager *m = userdata;
1391 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1395 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1400 if (until <= now(CLOCK_MONOTONIC))
1403 /* We want to ignore the lid switch for a while after each
1404 * suspend, and after boot-up. Hence let's install a timer for
1405 * this. As long as the event source exists we ignore the lid
1408 if (m->lid_switch_ignore_event_source) {
1411 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1418 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1420 r = sd_event_add_time(
1422 &m->lid_switch_ignore_event_source,
1425 lid_switch_ignore_handler, m);
1430 static int execute_shutdown_or_sleep(
1433 const char *unit_name,
1434 sd_bus_error *error) {
1436 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1443 assert(w < _INHIBIT_WHAT_MAX);
1446 bus_manager_log_shutdown(m, w, unit_name);
1448 r = sd_bus_call_method(
1450 "org.freedesktop.systemd1",
1451 "/org/freedesktop/systemd1",
1452 "org.freedesktop.systemd1.Manager",
1456 "ss", unit_name, "replace-irreversibly");
1460 r = sd_bus_message_read(reply, "o", &p);
1468 m->action_unit = unit_name;
1469 free(m->action_job);
1473 /* Make sure the lid switch is ignored for a while */
1474 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1479 int manager_dispatch_delayed(Manager *manager, bool timeout) {
1481 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1482 Inhibitor *offending = NULL;
1487 if (manager->action_what == 0 || manager->action_job)
1490 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1491 _cleanup_free_ char *comm = NULL, *u = NULL;
1496 (void) get_process_comm(offending->pid, &comm);
1497 u = uid_to_name(offending->uid);
1499 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1500 offending->uid, strna(u),
1501 offending->pid, strna(comm));
1504 /* Actually do the operation */
1505 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
1507 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1509 manager->action_unit = NULL;
1510 manager->action_what = 0;
1517 static int manager_inhibit_timeout_handler(
1522 Manager *manager = userdata;
1526 assert(manager->inhibit_timeout_source == s);
1528 r = manager_dispatch_delayed(manager, true);
1529 return (r < 0) ? r : 0;
1532 static int delay_shutdown_or_sleep(
1535 const char *unit_name) {
1542 assert(w < _INHIBIT_WHAT_MAX);
1545 timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1547 if (m->inhibit_timeout_source) {
1548 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1550 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1552 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1554 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1556 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1557 timeout_val, 0, manager_inhibit_timeout_handler, m);
1562 m->action_unit = unit_name;
1568 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1570 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1571 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1572 [INHIBIT_SLEEP] = "PrepareForSleep"
1575 int active = _active;
1579 assert(w < _INHIBIT_WHAT_MAX);
1580 assert(signal_name[w]);
1582 return sd_bus_emit_signal(m->bus,
1583 "/org/freedesktop/login1",
1584 "org.freedesktop.login1.Manager",
1590 int bus_manager_shutdown_or_sleep_now_or_later(
1592 const char *unit_name,
1594 sd_bus_error *error) {
1602 assert(w <= _INHIBIT_WHAT_MAX);
1603 assert(!m->action_job);
1605 /* Tell everybody to prepare for shutdown/sleep */
1606 send_prepare_for(m, w, true);
1609 m->inhibit_delay_max > 0 &&
1610 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1613 /* Shutdown is delayed, keep in mind what we
1614 * want to do, and start a timeout */
1615 r = delay_shutdown_or_sleep(m, w, unit_name);
1617 /* Shutdown is not delayed, execute it
1619 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1624 static int verify_shutdown_creds(
1626 sd_bus_message *message,
1630 const char *action_multiple_sessions,
1631 const char *action_ignore_inhibit,
1632 sd_bus_error *error) {
1634 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1635 bool multiple_sessions, blocked;
1642 assert(w <= _INHIBIT_WHAT_MAX);
1644 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1648 r = sd_bus_creds_get_euid(creds, &uid);
1652 r = have_multiple_sessions(m, uid);
1656 multiple_sessions = r > 0;
1657 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1659 if (multiple_sessions && action_multiple_sessions) {
1660 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1664 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1667 if (blocked && action_ignore_inhibit) {
1668 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1672 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1675 if (!multiple_sessions && !blocked && action) {
1676 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1680 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1686 static int method_do_shutdown_or_sleep(
1688 sd_bus_message *message,
1689 const char *unit_name,
1692 const char *action_multiple_sessions,
1693 const char *action_ignore_inhibit,
1694 const char *sleep_verb,
1695 sd_bus_error *error) {
1703 assert(w <= _INHIBIT_WHAT_MAX);
1705 r = sd_bus_message_read(message, "b", &interactive);
1709 /* Don't allow multiple jobs being executed at the same time */
1711 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1714 r = can_sleep(sleep_verb);
1719 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1722 r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1723 action_ignore_inhibit, error);
1727 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1731 return sd_bus_reply_method_return(message, NULL);
1734 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1735 Manager *m = userdata;
1737 return method_do_shutdown_or_sleep(
1739 SPECIAL_POWEROFF_TARGET,
1741 "org.freedesktop.login1.power-off",
1742 "org.freedesktop.login1.power-off-multiple-sessions",
1743 "org.freedesktop.login1.power-off-ignore-inhibit",
1748 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1749 Manager *m = userdata;
1751 return method_do_shutdown_or_sleep(
1753 SPECIAL_REBOOT_TARGET,
1755 "org.freedesktop.login1.reboot",
1756 "org.freedesktop.login1.reboot-multiple-sessions",
1757 "org.freedesktop.login1.reboot-ignore-inhibit",
1762 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1763 Manager *m = userdata;
1765 return method_do_shutdown_or_sleep(
1767 SPECIAL_SUSPEND_TARGET,
1769 "org.freedesktop.login1.suspend",
1770 "org.freedesktop.login1.suspend-multiple-sessions",
1771 "org.freedesktop.login1.suspend-ignore-inhibit",
1776 static int nologin_timeout_handler(
1781 Manager *m = userdata;
1784 log_info("Creating /run/nologin, blocking further logins...");
1786 r = write_string_file("/run/nologin", "System is going down.", WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
1788 log_error_errno(r, "Failed to create /run/nologin: %m");
1790 m->unlink_nologin = true;
1795 static int update_schedule_file(Manager *m) {
1798 _cleanup_fclose_ FILE *f = NULL;
1799 _cleanup_free_ char *t = NULL, *temp_path = NULL;
1803 r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1805 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1807 t = cescape(m->wall_message);
1811 r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1813 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1815 (void) fchmod(fileno(f), 0644);
1821 m->scheduled_shutdown_timeout,
1822 m->enable_wall_messages,
1823 m->scheduled_shutdown_type);
1825 if (!isempty(m->wall_message))
1826 fprintf(f, "WALL_MESSAGE=%s\n", t);
1828 (void) fflush_and_check(f);
1830 if (ferror(f) || rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1831 log_error_errno(errno, "Failed to write information about scheduled shutdowns: %m");
1834 (void) unlink(temp_path);
1835 (void) unlink("/run/systemd/shutdown/scheduled");
1841 static int manager_scheduled_shutdown_handler(
1846 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1847 Manager *m = userdata;
1853 if (isempty(m->scheduled_shutdown_type))
1856 if (streq(m->scheduled_shutdown_type, "halt"))
1857 target = SPECIAL_HALT_TARGET;
1858 else if (streq(m->scheduled_shutdown_type, "poweroff"))
1859 target = SPECIAL_POWEROFF_TARGET;
1861 target = SPECIAL_REBOOT_TARGET;
1863 r = execute_shutdown_or_sleep(m, 0, target, &error);
1865 return log_error_errno(r, "Unable to execute transition to %s: %m", target);
1870 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1871 Manager *m = userdata;
1872 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1873 const char *action_multiple_sessions = NULL;
1874 const char *action_ignore_inhibit = NULL;
1875 const char *action = NULL;
1883 r = sd_bus_message_read(message, "st", &type, &elapse);
1887 if (streq(type, "reboot")) {
1888 action = "org.freedesktop.login1.reboot";
1889 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1890 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1891 } else if (streq(type, "halt")) {
1892 action = "org.freedesktop.login1.halt";
1893 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1894 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1895 } else if (streq(type, "poweroff")) {
1896 action = "org.freedesktop.login1.poweroff";
1897 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1898 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1900 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1902 r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1903 action, action_multiple_sessions, action_ignore_inhibit, error);
1907 if (m->scheduled_shutdown_timeout_source) {
1908 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1910 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1912 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1914 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1916 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1917 CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1919 return log_error_errno(r, "sd_event_add_time() failed: %m");
1922 r = free_and_strdup(&m->scheduled_shutdown_type, type);
1924 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1928 if (m->nologin_timeout_source) {
1929 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1931 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1933 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1935 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1937 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1938 CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1940 return log_error_errno(r, "sd_event_add_time() failed: %m");
1943 m->scheduled_shutdown_timeout = elapse;
1945 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1949 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1950 (void) sd_bus_creds_get_tty(creds, &tty);
1952 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1954 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1959 r = manager_setup_wall_message_timer(m);
1963 if (!isempty(type)) {
1964 r = update_schedule_file(m);
1968 (void) unlink("/run/systemd/shutdown/scheduled");
1970 return sd_bus_reply_method_return(message, NULL);
1973 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1974 Manager *m = userdata;
1980 cancelled = m->scheduled_shutdown_type != NULL;
1982 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1983 m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
1984 m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
1985 free(m->scheduled_shutdown_type);
1986 m->scheduled_shutdown_type = NULL;
1987 m->scheduled_shutdown_timeout = 0;
1989 if (m->unlink_nologin) {
1990 (void) unlink("/run/nologin");
1991 m->unlink_nologin = false;
1995 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1996 const char *tty = NULL;
2000 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
2002 (void) sd_bus_creds_get_uid(creds, &uid);
2003 (void) sd_bus_creds_get_tty(creds, &tty);
2006 utmp_wall("The system shutdown has been cancelled",
2007 lookup_uid(uid), tty, logind_wall_tty_filter, m);
2010 return sd_bus_reply_method_return(message, "b", cancelled);
2013 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2014 Manager *m = userdata;
2016 return method_do_shutdown_or_sleep(
2018 SPECIAL_HIBERNATE_TARGET,
2020 "org.freedesktop.login1.hibernate",
2021 "org.freedesktop.login1.hibernate-multiple-sessions",
2022 "org.freedesktop.login1.hibernate-ignore-inhibit",
2027 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2028 Manager *m = userdata;
2030 return method_do_shutdown_or_sleep(
2032 SPECIAL_HYBRID_SLEEP_TARGET,
2034 "org.freedesktop.login1.hibernate",
2035 "org.freedesktop.login1.hibernate-multiple-sessions",
2036 "org.freedesktop.login1.hibernate-ignore-inhibit",
2041 static int method_can_shutdown_or_sleep(
2043 sd_bus_message *message,
2046 const char *action_multiple_sessions,
2047 const char *action_ignore_inhibit,
2048 const char *sleep_verb,
2049 sd_bus_error *error) {
2051 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2052 bool multiple_sessions, challenge, blocked;
2053 const char *result = NULL;
2060 assert(w <= _INHIBIT_WHAT_MAX);
2062 assert(action_multiple_sessions);
2063 assert(action_ignore_inhibit);
2066 r = can_sleep(sleep_verb);
2070 return sd_bus_reply_method_return(message, "s", "na");
2073 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2077 r = sd_bus_creds_get_euid(creds, &uid);
2081 r = have_multiple_sessions(m, uid);
2085 multiple_sessions = r > 0;
2086 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2088 if (multiple_sessions) {
2089 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
2096 result = "challenge";
2102 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
2106 if (r > 0 && !result)
2108 else if (challenge && (!result || streq(result, "yes")))
2109 result = "challenge";
2114 if (!multiple_sessions && !blocked) {
2115 /* If neither inhibit nor multiple sessions
2116 * apply then just check the normal policy */
2118 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
2125 result = "challenge";
2130 return sd_bus_reply_method_return(message, "s", result);
2133 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2134 Manager *m = userdata;
2136 return method_can_shutdown_or_sleep(
2139 "org.freedesktop.login1.power-off",
2140 "org.freedesktop.login1.power-off-multiple-sessions",
2141 "org.freedesktop.login1.power-off-ignore-inhibit",
2146 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2147 Manager *m = userdata;
2149 return method_can_shutdown_or_sleep(
2152 "org.freedesktop.login1.reboot",
2153 "org.freedesktop.login1.reboot-multiple-sessions",
2154 "org.freedesktop.login1.reboot-ignore-inhibit",
2159 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2160 Manager *m = userdata;
2162 return method_can_shutdown_or_sleep(
2165 "org.freedesktop.login1.suspend",
2166 "org.freedesktop.login1.suspend-multiple-sessions",
2167 "org.freedesktop.login1.suspend-ignore-inhibit",
2172 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2173 Manager *m = userdata;
2175 return method_can_shutdown_or_sleep(
2178 "org.freedesktop.login1.hibernate",
2179 "org.freedesktop.login1.hibernate-multiple-sessions",
2180 "org.freedesktop.login1.hibernate-ignore-inhibit",
2185 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2186 Manager *m = userdata;
2188 return method_can_shutdown_or_sleep(
2191 "org.freedesktop.login1.hibernate",
2192 "org.freedesktop.login1.hibernate-multiple-sessions",
2193 "org.freedesktop.login1.hibernate-ignore-inhibit",
2198 static int property_get_reboot_to_firmware_setup(
2201 const char *interface,
2202 const char *property,
2203 sd_bus_message *reply,
2205 sd_bus_error *error) {
2212 r = efi_get_reboot_to_firmware();
2213 if (r < 0 && r != -EOPNOTSUPP)
2216 return sd_bus_message_append(reply, "b", r > 0);
2219 static int method_set_reboot_to_firmware_setup(
2220 sd_bus_message *message,
2222 sd_bus_error *error) {
2225 Manager *m = userdata;
2230 r = sd_bus_message_read(message, "b", &b);
2234 r = bus_verify_polkit_async(message,
2236 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2239 &m->polkit_registry,
2244 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2246 r = efi_set_reboot_to_firmware(b);
2250 return sd_bus_reply_method_return(message, NULL);
2253 static int method_can_reboot_to_firmware_setup(
2254 sd_bus_message *message,
2256 sd_bus_error *error) {
2261 Manager *m = userdata;
2266 r = efi_reboot_to_firmware_supported();
2267 if (r == -EOPNOTSUPP)
2268 return sd_bus_reply_method_return(message, "s", "na");
2272 r = bus_test_polkit(message,
2274 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2284 result = "challenge";
2288 return sd_bus_reply_method_return(message, "s", result);
2291 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2292 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2293 const char *who, *why, *what, *mode;
2294 _cleanup_free_ char *id = NULL;
2295 _cleanup_close_ int fifo_fd = -1;
2296 Manager *m = userdata;
2297 Inhibitor *i = NULL;
2307 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2311 w = inhibit_what_from_string(what);
2313 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2315 mm = inhibit_mode_from_string(mode);
2317 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2319 /* Delay is only supported for shutdown/sleep */
2320 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2321 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2323 /* Don't allow taking delay locks while we are already
2324 * executing the operation. We shouldn't create the impression
2325 * that the lock was successful if the machine is about to go
2326 * down/suspend any moment. */
2327 if (m->action_what & w)
2328 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2330 r = bus_verify_polkit_async(
2333 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2334 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2335 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
2336 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
2337 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2338 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2339 "org.freedesktop.login1.inhibit-handle-lid-switch",
2342 &m->polkit_registry,
2347 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2349 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2353 r = sd_bus_creds_get_euid(creds, &uid);
2357 r = sd_bus_creds_get_pid(creds, &pid);
2365 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2368 } while (hashmap_get(m->inhibitors, id));
2370 r = manager_add_inhibitor(m, id, &i);
2378 i->why = strdup(why);
2379 i->who = strdup(who);
2381 if (!i->why || !i->who) {
2386 fifo_fd = inhibitor_create_fifo(i);
2394 return sd_bus_reply_method_return(message, "h", fifo_fd);
2403 const sd_bus_vtable manager_vtable[] = {
2404 SD_BUS_VTABLE_START(0),
2406 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2407 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2409 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2410 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2411 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2412 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2413 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2414 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2415 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2416 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2417 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2418 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2419 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2420 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2421 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2422 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2423 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2424 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2425 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2426 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2427 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2428 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2429 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2430 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2431 SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
2433 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2434 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2435 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2436 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2437 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2438 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2439 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2440 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2441 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2442 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2443 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2444 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2445 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2446 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2447 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2448 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2449 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2450 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2451 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2452 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2453 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2454 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2455 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2456 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2457 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2458 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2459 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2460 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2461 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2462 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2463 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2464 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2465 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2466 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2467 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2468 SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2469 SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2470 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2471 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2472 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2474 SD_BUS_SIGNAL("SessionNew", "so", 0),
2475 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2476 SD_BUS_SIGNAL("UserNew", "uo", 0),
2477 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2478 SD_BUS_SIGNAL("SeatNew", "so", 0),
2479 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2480 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2481 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2486 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2495 if (streq(result, "done"))
2496 r = session_send_create_reply(s, NULL);
2498 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2500 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2501 r = session_send_create_reply(s, &e);
2507 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2508 const char *path, *result, *unit;
2509 Manager *m = userdata;
2518 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2520 bus_log_parse_error(r);
2524 if (m->action_job && streq(m->action_job, path)) {
2525 log_info("Operation finished.");
2527 /* Tell people that they now may take a lock again */
2528 send_prepare_for(m, m->action_what, false);
2530 free(m->action_job);
2531 m->action_job = NULL;
2532 m->action_unit = NULL;
2537 session = hashmap_get(m->session_units, unit);
2540 if (streq_ptr(path, session->scope_job)) {
2541 free(session->scope_job);
2542 session->scope_job = NULL;
2545 session_jobs_reply(session, unit, result);
2547 session_save(session);
2548 user_save(session->user);
2549 session_add_to_gc_queue(session);
2552 user = hashmap_get(m->user_units, unit);
2555 if (streq_ptr(path, user->service_job)) {
2556 free(user->service_job);
2557 user->service_job = NULL;
2560 if (streq_ptr(path, user->slice_job)) {
2561 free(user->slice_job);
2562 user->slice_job = NULL;
2565 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2566 session_jobs_reply(session, unit, result);
2570 user_add_to_gc_queue(user);
2576 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2577 const char *path, *unit;
2578 Manager *m = userdata;
2586 r = sd_bus_message_read(message, "so", &unit, &path);
2588 bus_log_parse_error(r);
2592 session = hashmap_get(m->session_units, unit);
2594 session_add_to_gc_queue(session);
2596 user = hashmap_get(m->user_units, unit);
2598 user_add_to_gc_queue(user);
2603 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2604 _cleanup_free_ char *unit = NULL;
2605 Manager *m = userdata;
2614 path = sd_bus_message_get_path(message);
2618 r = unit_name_from_dbus_path(path, &unit);
2619 if (r == -EINVAL) /* not a unit */
2624 session = hashmap_get(m->session_units, unit);
2626 session_add_to_gc_queue(session);
2628 user = hashmap_get(m->user_units, unit);
2630 user_add_to_gc_queue(user);
2635 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2636 Manager *m = userdata;
2644 r = sd_bus_message_read(message, "b", &b);
2646 bus_log_parse_error(r);
2653 /* systemd finished reloading, let's recheck all our sessions */
2654 log_debug("System manager has been reloaded, rechecking sessions...");
2656 HASHMAP_FOREACH(session, m->sessions, i)
2657 session_add_to_gc_queue(session);
2662 int match_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2663 const char *name, *old, *new;
2664 Manager *m = userdata;
2673 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2675 bus_log_parse_error(r);
2679 if (isempty(old) || !isempty(new))
2682 key = set_remove(m->busnames, (char*) old);
2686 /* Drop all controllers owned by this name */
2690 HASHMAP_FOREACH(session, m->sessions, i)
2691 if (session_is_controller(session, old))
2692 session_drop_controller(session);
2697 int manager_send_changed(Manager *manager, const char *property, ...) {
2702 l = strv_from_stdarg_alloca(property);
2704 return sd_bus_emit_properties_changed_strv(
2706 "/org/freedesktop/login1",
2707 "org.freedesktop.login1.Manager",
2711 int manager_start_scope(
2716 const char *description,
2717 const char *after, const char *after2,
2718 sd_bus_error *error,
2721 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2728 r = sd_bus_message_new_method_call(
2731 "org.freedesktop.systemd1",
2732 "/org/freedesktop/systemd1",
2733 "org.freedesktop.systemd1.Manager",
2734 "StartTransientUnit");
2738 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2742 r = sd_bus_message_open_container(m, 'a', "(sv)");
2746 if (!isempty(slice)) {
2747 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2752 if (!isempty(description)) {
2753 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2758 if (!isempty(after)) {
2759 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2764 if (!isempty(after2)) {
2765 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2770 /* cgroup empty notification is not available in containers
2771 * currently. To make this less problematic, let's shorten the
2772 * stop timeout for sessions, so that we don't wait
2775 /* Make sure that the session shells are terminated with
2776 * SIGHUP since bash and friends tend to ignore SIGTERM */
2777 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2781 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2785 r = sd_bus_message_close_container(m);
2789 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2793 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2801 r = sd_bus_message_read(reply, "o", &j);
2815 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2816 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2822 r = sd_bus_call_method(
2824 "org.freedesktop.systemd1",
2825 "/org/freedesktop/systemd1",
2826 "org.freedesktop.systemd1.Manager",
2830 "ss", unit, "fail");
2838 r = sd_bus_message_read(reply, "o", &j);
2852 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2853 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2859 r = sd_bus_call_method(
2861 "org.freedesktop.systemd1",
2862 "/org/freedesktop/systemd1",
2863 "org.freedesktop.systemd1.Manager",
2867 "ss", unit, "fail");
2869 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2870 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2875 sd_bus_error_free(error);
2886 r = sd_bus_message_read(reply, "o", &j);
2900 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2901 _cleanup_free_ char *path = NULL;
2907 path = unit_dbus_path_from_name(scope);
2911 r = sd_bus_call_method(
2913 "org.freedesktop.systemd1",
2915 "org.freedesktop.systemd1.Scope",
2921 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2922 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2923 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2924 sd_bus_error_free(error);
2934 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2938 return sd_bus_call_method(
2940 "org.freedesktop.systemd1",
2941 "/org/freedesktop/systemd1",
2942 "org.freedesktop.systemd1.Manager",
2946 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2949 int manager_unit_is_active(Manager *manager, const char *unit) {
2950 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2951 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2952 _cleanup_free_ char *path = NULL;
2959 path = unit_dbus_path_from_name(unit);
2963 r = sd_bus_get_property(
2965 "org.freedesktop.systemd1",
2967 "org.freedesktop.systemd1.Unit",
2973 /* systemd might have droppped off momentarily, let's
2974 * not make this an error */
2975 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2976 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2979 /* If the unit is already unloaded then it's not
2981 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2982 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2988 r = sd_bus_message_read(reply, "s", &state);
2992 return !streq(state, "inactive") && !streq(state, "failed");
2995 int manager_job_is_active(Manager *manager, const char *path) {
2996 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2997 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3003 r = sd_bus_get_property(
3005 "org.freedesktop.systemd1",
3007 "org.freedesktop.systemd1.Job",
3013 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3014 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3017 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3023 /* We don't actually care about the state really. The fact
3024 * that we could read the job state is enough for us */