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_multiple_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);
694 _cleanup_free_ char *path = NULL;
695 _cleanup_close_ int fifo_fd = -1;
697 /* Session already exists, client is probably
698 * something like "su" which changes uid but is still
699 * the same session */
701 fifo_fd = session_create_fifo(session);
705 path = session_bus_path(session);
709 log_debug("Sending reply about an existing session: "
710 "id=%s object_path=%s uid=%u runtime_path=%s "
711 "session_fd=%d seat=%s vtnr=%u",
714 (uint32_t) session->user->uid,
715 session->user->runtime_path,
717 session->seat ? session->seat->id : "",
718 (uint32_t) session->vtnr);
720 return sd_bus_reply_method_return(
724 session->user->runtime_path,
726 (uint32_t) session->user->uid,
727 session->seat ? session->seat->id : "",
728 (uint32_t) session->vtnr,
732 audit_session_from_pid(leader, &audit_id);
734 /* Keep our session IDs and the audit session IDs in sync */
736 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
739 /* Wut? There's already a session by this name and we
740 * didn't find it above? Weird, then let's not trust
741 * the audit data and let's better register a new
743 if (hashmap_get(m->sessions, id)) {
744 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
757 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
760 } while (hashmap_get(m->sessions, id));
763 r = manager_add_user_by_uid(m, uid, &user);
767 r = manager_add_session(m, id, &session);
771 session_set_user(session, user);
773 session->leader = leader;
774 session->audit_id = audit_id;
777 session->remote = remote;
778 session->vtnr = vtnr;
781 session->tty = strdup(tty);
788 if (!isempty(display)) {
789 session->display = strdup(display);
790 if (!session->display) {
796 if (!isempty(remote_user)) {
797 session->remote_user = strdup(remote_user);
798 if (!session->remote_user) {
804 if (!isempty(remote_host)) {
805 session->remote_host = strdup(remote_host);
806 if (!session->remote_host) {
812 if (!isempty(service)) {
813 session->service = strdup(service);
814 if (!session->service) {
820 if (!isempty(desktop)) {
821 session->desktop = strdup(desktop);
822 if (!session->desktop) {
829 r = seat_attach_session(seat, session);
834 r = session_start(session);
838 session->create_message = sd_bus_message_ref(message);
840 /* Now, let's wait until the slice unit and stuff got
841 * created. We send the reply back from
842 * session_send_create_reply(). */
848 session_add_to_gc_queue(session);
851 user_add_to_gc_queue(user);
856 static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
857 Manager *m = userdata;
865 r = sd_bus_message_read(message, "s", &name);
869 r = manager_get_session_from_creds(m, message, name, error, &session);
873 r = session_release(session);
877 return sd_bus_reply_method_return(message, NULL);
880 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
881 Manager *m = userdata;
889 r = sd_bus_message_read(message, "s", &name);
893 r = manager_get_session_from_creds(m, message, name, error, &session);
897 return bus_session_method_activate(message, session, error);
900 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
901 const char *session_name, *seat_name;
902 Manager *m = userdata;
910 /* Same as ActivateSession() but refuses to work if
911 * the seat doesn't match */
913 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
917 r = manager_get_session_from_creds(m, message, session_name, error, &session);
921 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
925 if (session->seat != seat)
926 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
928 r = session_activate(session);
932 return sd_bus_reply_method_return(message, NULL);
935 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
936 Manager *m = userdata;
944 r = sd_bus_message_read(message, "s", &name);
948 r = manager_get_session_from_creds(m, message, name, error, &session);
952 return bus_session_method_lock(message, session, error);
955 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
956 Manager *m = userdata;
962 r = bus_verify_polkit_async(
965 "org.freedesktop.login1.lock-sessions",
973 return 1; /* Will call us back */
975 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
979 return sd_bus_reply_method_return(message, NULL);
982 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
984 Manager *m = userdata;
991 r = sd_bus_message_read(message, "s", &name);
995 r = manager_get_session_from_creds(m, message, name, error, &session);
999 return bus_session_method_kill(message, session, error);
1002 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1003 Manager *m = userdata;
1011 r = sd_bus_message_read(message, "u", &uid);
1015 r = manager_get_user_from_creds(m, message, uid, error, &user);
1019 return bus_user_method_kill(message, user, error);
1022 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1023 Manager *m = userdata;
1031 r = sd_bus_message_read(message, "s", &name);
1035 r = manager_get_session_from_creds(m, message, name, error, &session);
1039 return bus_session_method_terminate(message, session, error);
1042 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1043 Manager *m = userdata;
1051 r = sd_bus_message_read(message, "u", &uid);
1055 r = manager_get_user_from_creds(m, message, uid, error, &user);
1059 return bus_user_method_terminate(message, user, error);
1062 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1063 Manager *m = userdata;
1071 r = sd_bus_message_read(message, "s", &name);
1075 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1079 return bus_seat_method_terminate(message, seat, error);
1082 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1083 _cleanup_free_ char *cc = NULL;
1084 Manager *m = userdata;
1094 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1098 if (uid == UID_INVALID) {
1099 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1101 /* Note that we get the owner UID of the session, not the actual client UID here! */
1102 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1106 r = sd_bus_creds_get_owner_uid(creds, &uid);
1114 return errno ? -errno : -ENOENT;
1116 r = bus_verify_polkit_async(
1119 "org.freedesktop.login1.set-user-linger",
1122 &m->polkit_registry,
1127 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1129 mkdir_p_label("/var/lib/systemd", 0755);
1131 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1135 cc = cescape(pw->pw_name);
1139 path = strjoina("/var/lib/systemd/linger/", cc);
1147 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1154 if (r < 0 && errno != ENOENT)
1157 u = hashmap_get(m->users, UID_TO_PTR(uid));
1159 user_add_to_gc_queue(u);
1162 return sd_bus_reply_method_return(message, NULL);
1165 static int trigger_device(Manager *m, struct udev_device *d) {
1166 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1167 struct udev_list_entry *first, *item;
1172 e = udev_enumerate_new(m->udev);
1177 r = udev_enumerate_add_match_parent(e, d);
1182 r = udev_enumerate_scan_devices(e);
1186 first = udev_enumerate_get_list_entry(e);
1187 udev_list_entry_foreach(item, first) {
1188 _cleanup_free_ char *t = NULL;
1191 p = udev_list_entry_get_name(item);
1193 t = strappend(p, "/uevent");
1197 write_string_file(t, "change");
1203 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1204 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1205 _cleanup_free_ char *rule = NULL, *file = NULL;
1206 const char *id_for_seat;
1213 d = udev_device_new_from_syspath(m->udev, sysfs);
1217 if (!udev_device_has_tag(d, "seat"))
1220 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1224 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1227 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1230 mkdir_p_label("/etc/udev/rules.d", 0755);
1231 mac_selinux_init("/etc");
1232 r = write_string_file_atomic_label(file, rule);
1236 return trigger_device(m, d);
1239 static int flush_devices(Manager *m) {
1240 _cleanup_closedir_ DIR *d;
1244 d = opendir("/etc/udev/rules.d");
1246 if (errno != ENOENT)
1247 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1251 while ((de = readdir(d))) {
1253 if (!dirent_is_file(de))
1256 if (!startswith(de->d_name, "72-seat-"))
1259 if (!endswith(de->d_name, ".rules"))
1262 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1263 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1267 return trigger_device(m, NULL);
1270 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1271 const char *sysfs, *seat;
1272 Manager *m = userdata;
1278 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1282 if (!path_startswith(sysfs, "/sys"))
1283 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1285 if (!seat_name_is_valid(seat))
1286 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1288 r = bus_verify_polkit_async(
1291 "org.freedesktop.login1.attach-device",
1294 &m->polkit_registry,
1299 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1301 r = attach_device(m, seat, sysfs);
1305 return sd_bus_reply_method_return(message, NULL);
1308 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1309 Manager *m = userdata;
1315 r = sd_bus_message_read(message, "b", &interactive);
1319 r = bus_verify_polkit_async(
1322 "org.freedesktop.login1.flush-devices",
1325 &m->polkit_registry,
1330 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1332 r = flush_devices(m);
1336 return sd_bus_reply_method_return(message, NULL);
1339 static int have_multiple_sessions(
1348 /* Check for other users' sessions. Greeter sessions do not
1349 * count, and non-login sessions do not count either. */
1350 HASHMAP_FOREACH(session, m->sessions, i)
1351 if (session->class == SESSION_USER &&
1352 session->user->uid != uid)
1358 static int bus_manager_log_shutdown(
1361 const char *unit_name) {
1368 if (w != INHIBIT_SHUTDOWN)
1371 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1372 p = "MESSAGE=System is powering down.";
1373 q = "SHUTDOWN=power-off";
1374 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1375 p = "MESSAGE=System is halting.";
1376 q = "SHUTDOWN=halt";
1377 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1378 p = "MESSAGE=System is rebooting.";
1379 q = "SHUTDOWN=reboot";
1380 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1381 p = "MESSAGE=System is rebooting with kexec.";
1382 q = "SHUTDOWN=kexec";
1384 p = "MESSAGE=System is shutting down.";
1388 return log_struct(LOG_NOTICE,
1389 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1395 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1396 Manager *m = userdata;
1401 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1405 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1410 if (until <= now(CLOCK_MONOTONIC))
1413 /* We want to ignore the lid switch for a while after each
1414 * suspend, and after boot-up. Hence let's install a timer for
1415 * this. As long as the event source exists we ignore the lid
1418 if (m->lid_switch_ignore_event_source) {
1421 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1428 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1430 r = sd_event_add_time(
1432 &m->lid_switch_ignore_event_source,
1435 lid_switch_ignore_handler, m);
1440 static int execute_shutdown_or_sleep(
1443 const char *unit_name,
1444 sd_bus_error *error) {
1446 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1453 assert(w < _INHIBIT_WHAT_MAX);
1456 bus_manager_log_shutdown(m, w, unit_name);
1458 r = sd_bus_call_method(
1460 "org.freedesktop.systemd1",
1461 "/org/freedesktop/systemd1",
1462 "org.freedesktop.systemd1.Manager",
1466 "ss", unit_name, "replace-irreversibly");
1470 r = sd_bus_message_read(reply, "o", &p);
1478 m->action_unit = unit_name;
1479 free(m->action_job);
1483 /* Make sure the lid switch is ignored for a while */
1484 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1489 int manager_dispatch_delayed(Manager *manager, bool timeout) {
1491 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1492 Inhibitor *offending = NULL;
1497 if (manager->action_what == 0 || manager->action_job)
1500 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1501 _cleanup_free_ char *comm = NULL, *u = NULL;
1506 (void) get_process_comm(offending->pid, &comm);
1507 u = uid_to_name(offending->uid);
1509 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1510 offending->uid, strna(u),
1511 offending->pid, strna(comm));
1514 /* Actually do the operation */
1515 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
1517 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1519 manager->action_unit = NULL;
1520 manager->action_what = 0;
1527 static int manager_inhibit_timeout_handler(
1532 Manager *manager = userdata;
1536 assert(manager->inhibit_timeout_source == s);
1538 r = manager_dispatch_delayed(manager, true);
1539 return (r < 0) ? r : 0;
1542 static int delay_shutdown_or_sleep(
1545 const char *unit_name) {
1552 assert(w < _INHIBIT_WHAT_MAX);
1555 timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1557 if (m->inhibit_timeout_source) {
1558 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1560 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1562 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1564 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1566 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1567 timeout_val, 0, manager_inhibit_timeout_handler, m);
1572 m->action_unit = unit_name;
1578 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1580 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1581 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1582 [INHIBIT_SLEEP] = "PrepareForSleep"
1585 int active = _active;
1589 assert(w < _INHIBIT_WHAT_MAX);
1590 assert(signal_name[w]);
1592 return sd_bus_emit_signal(m->bus,
1593 "/org/freedesktop/login1",
1594 "org.freedesktop.login1.Manager",
1600 int bus_manager_shutdown_or_sleep_now_or_later(
1602 const char *unit_name,
1604 sd_bus_error *error) {
1612 assert(w <= _INHIBIT_WHAT_MAX);
1613 assert(!m->action_job);
1615 /* Tell everybody to prepare for shutdown/sleep */
1616 send_prepare_for(m, w, true);
1619 m->inhibit_delay_max > 0 &&
1620 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1623 /* Shutdown is delayed, keep in mind what we
1624 * want to do, and start a timeout */
1625 r = delay_shutdown_or_sleep(m, w, unit_name);
1627 /* Shutdown is not delayed, execute it
1629 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1634 static int verify_shutdown_creds(
1636 sd_bus_message *message,
1640 const char *action_multiple_sessions,
1641 const char *action_ignore_inhibit,
1642 sd_bus_error *error) {
1644 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1645 bool multiple_sessions, blocked;
1652 assert(w <= _INHIBIT_WHAT_MAX);
1654 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1658 r = sd_bus_creds_get_euid(creds, &uid);
1662 r = have_multiple_sessions(m, uid);
1666 multiple_sessions = r > 0;
1667 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1669 if (multiple_sessions && action_multiple_sessions) {
1670 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1674 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1677 if (blocked && action_ignore_inhibit) {
1678 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1682 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1685 if (!multiple_sessions && !blocked && action) {
1686 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1690 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1696 static int method_do_shutdown_or_sleep(
1698 sd_bus_message *message,
1699 const char *unit_name,
1702 const char *action_multiple_sessions,
1703 const char *action_ignore_inhibit,
1704 const char *sleep_verb,
1705 sd_bus_error *error) {
1713 assert(w <= _INHIBIT_WHAT_MAX);
1715 r = sd_bus_message_read(message, "b", &interactive);
1719 /* Don't allow multiple jobs being executed at the same time */
1721 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1724 r = can_sleep(sleep_verb);
1729 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1732 r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1733 action_ignore_inhibit, error);
1737 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1741 return sd_bus_reply_method_return(message, NULL);
1744 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1745 Manager *m = userdata;
1747 return method_do_shutdown_or_sleep(
1749 SPECIAL_POWEROFF_TARGET,
1751 "org.freedesktop.login1.power-off",
1752 "org.freedesktop.login1.power-off-multiple-sessions",
1753 "org.freedesktop.login1.power-off-ignore-inhibit",
1758 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1759 Manager *m = userdata;
1761 return method_do_shutdown_or_sleep(
1763 SPECIAL_REBOOT_TARGET,
1765 "org.freedesktop.login1.reboot",
1766 "org.freedesktop.login1.reboot-multiple-sessions",
1767 "org.freedesktop.login1.reboot-ignore-inhibit",
1772 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1773 Manager *m = userdata;
1775 return method_do_shutdown_or_sleep(
1777 SPECIAL_SUSPEND_TARGET,
1779 "org.freedesktop.login1.suspend",
1780 "org.freedesktop.login1.suspend-multiple-sessions",
1781 "org.freedesktop.login1.suspend-ignore-inhibit",
1786 static int nologin_timeout_handler(
1791 Manager *m = userdata;
1794 log_info("Creating /run/nologin, blocking further logins...");
1796 r = write_string_file_atomic("/run/nologin", "System is going down.");
1798 log_error_errno(r, "Failed to create /run/nologin: %m");
1800 m->unlink_nologin = true;
1805 static int update_schedule_file(Manager *m) {
1808 _cleanup_fclose_ FILE *f = NULL;
1809 _cleanup_free_ char *t = NULL, *temp_path = NULL;
1813 r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1815 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1817 t = cescape(m->wall_message);
1821 r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1823 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1825 (void) fchmod(fileno(f), 0644);
1831 m->scheduled_shutdown_timeout,
1832 m->enable_wall_messages,
1833 m->scheduled_shutdown_type);
1835 if (!isempty(m->wall_message))
1836 fprintf(f, "WALL_MESSAGE=%s\n", t);
1838 (void) fflush_and_check(f);
1840 if (ferror(f) || rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1841 log_error_errno(errno, "Failed to write information about scheduled shutdowns: %m");
1844 (void) unlink(temp_path);
1845 (void) unlink("/run/systemd/shutdown/scheduled");
1851 static int manager_scheduled_shutdown_handler(
1856 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1857 Manager *m = userdata;
1863 if (isempty(m->scheduled_shutdown_type))
1866 if (streq(m->scheduled_shutdown_type, "halt"))
1867 target = SPECIAL_HALT_TARGET;
1868 else if (streq(m->scheduled_shutdown_type, "poweroff"))
1869 target = SPECIAL_POWEROFF_TARGET;
1871 target = SPECIAL_REBOOT_TARGET;
1873 r = execute_shutdown_or_sleep(m, 0, target, &error);
1875 return log_error_errno(r, "Unable to execute transition to %s: %m", target);
1880 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1881 Manager *m = userdata;
1882 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1883 const char *action_multiple_sessions = NULL;
1884 const char *action_ignore_inhibit = NULL;
1885 const char *action = NULL;
1893 r = sd_bus_message_read(message, "st", &type, &elapse);
1897 if (streq(type, "reboot")) {
1898 action = "org.freedesktop.login1.reboot";
1899 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1900 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1901 } else if (streq(type, "halt")) {
1902 action = "org.freedesktop.login1.halt";
1903 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1904 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1905 } else if (streq(type, "poweroff")) {
1906 action = "org.freedesktop.login1.poweroff";
1907 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1908 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1910 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1912 r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1913 action, action_multiple_sessions, action_ignore_inhibit, error);
1917 if (m->scheduled_shutdown_timeout_source) {
1918 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1920 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1922 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1924 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1926 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1927 CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1929 return log_error_errno(r, "sd_event_add_time() failed: %m");
1932 r = free_and_strdup(&m->scheduled_shutdown_type, type);
1934 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1938 if (m->nologin_timeout_source) {
1939 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1941 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1943 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1945 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1947 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1948 CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1950 return log_error_errno(r, "sd_event_add_time() failed: %m");
1953 m->scheduled_shutdown_timeout = elapse;
1955 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1959 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1960 (void) sd_bus_creds_get_tty(creds, &tty);
1962 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1964 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1969 r = manager_setup_wall_message_timer(m);
1973 if (!isempty(type)) {
1974 r = update_schedule_file(m);
1978 (void) unlink("/run/systemd/shutdown/scheduled");
1980 return sd_bus_reply_method_return(message, NULL);
1983 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1984 Manager *m = userdata;
1990 cancelled = m->scheduled_shutdown_type != NULL;
1992 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1993 m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
1994 m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
1995 free(m->scheduled_shutdown_type);
1996 m->scheduled_shutdown_type = NULL;
1997 m->scheduled_shutdown_timeout = 0;
1999 if (m->unlink_nologin) {
2000 (void) unlink("/run/nologin");
2001 m->unlink_nologin = false;
2005 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2006 const char *tty = NULL;
2010 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
2012 (void) sd_bus_creds_get_uid(creds, &uid);
2013 (void) sd_bus_creds_get_tty(creds, &tty);
2016 utmp_wall("The system shutdown has been cancelled",
2017 lookup_uid(uid), tty, logind_wall_tty_filter, m);
2020 return sd_bus_reply_method_return(message, "b", cancelled);
2023 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2024 Manager *m = userdata;
2026 return method_do_shutdown_or_sleep(
2028 SPECIAL_HIBERNATE_TARGET,
2030 "org.freedesktop.login1.hibernate",
2031 "org.freedesktop.login1.hibernate-multiple-sessions",
2032 "org.freedesktop.login1.hibernate-ignore-inhibit",
2037 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2038 Manager *m = userdata;
2040 return method_do_shutdown_or_sleep(
2042 SPECIAL_HYBRID_SLEEP_TARGET,
2044 "org.freedesktop.login1.hibernate",
2045 "org.freedesktop.login1.hibernate-multiple-sessions",
2046 "org.freedesktop.login1.hibernate-ignore-inhibit",
2051 static int method_can_shutdown_or_sleep(
2053 sd_bus_message *message,
2056 const char *action_multiple_sessions,
2057 const char *action_ignore_inhibit,
2058 const char *sleep_verb,
2059 sd_bus_error *error) {
2061 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2062 bool multiple_sessions, challenge, blocked;
2063 const char *result = NULL;
2070 assert(w <= _INHIBIT_WHAT_MAX);
2072 assert(action_multiple_sessions);
2073 assert(action_ignore_inhibit);
2076 r = can_sleep(sleep_verb);
2080 return sd_bus_reply_method_return(message, "s", "na");
2083 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2087 r = sd_bus_creds_get_euid(creds, &uid);
2091 r = have_multiple_sessions(m, uid);
2095 multiple_sessions = r > 0;
2096 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2098 if (multiple_sessions) {
2099 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
2106 result = "challenge";
2112 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
2116 if (r > 0 && !result)
2118 else if (challenge && (!result || streq(result, "yes")))
2119 result = "challenge";
2124 if (!multiple_sessions && !blocked) {
2125 /* If neither inhibit nor multiple sessions
2126 * apply then just check the normal policy */
2128 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
2135 result = "challenge";
2140 return sd_bus_reply_method_return(message, "s", result);
2143 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2144 Manager *m = userdata;
2146 return method_can_shutdown_or_sleep(
2149 "org.freedesktop.login1.power-off",
2150 "org.freedesktop.login1.power-off-multiple-sessions",
2151 "org.freedesktop.login1.power-off-ignore-inhibit",
2156 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2157 Manager *m = userdata;
2159 return method_can_shutdown_or_sleep(
2162 "org.freedesktop.login1.reboot",
2163 "org.freedesktop.login1.reboot-multiple-sessions",
2164 "org.freedesktop.login1.reboot-ignore-inhibit",
2169 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2170 Manager *m = userdata;
2172 return method_can_shutdown_or_sleep(
2175 "org.freedesktop.login1.suspend",
2176 "org.freedesktop.login1.suspend-multiple-sessions",
2177 "org.freedesktop.login1.suspend-ignore-inhibit",
2182 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2183 Manager *m = userdata;
2185 return method_can_shutdown_or_sleep(
2188 "org.freedesktop.login1.hibernate",
2189 "org.freedesktop.login1.hibernate-multiple-sessions",
2190 "org.freedesktop.login1.hibernate-ignore-inhibit",
2195 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2196 Manager *m = userdata;
2198 return method_can_shutdown_or_sleep(
2201 "org.freedesktop.login1.hibernate",
2202 "org.freedesktop.login1.hibernate-multiple-sessions",
2203 "org.freedesktop.login1.hibernate-ignore-inhibit",
2208 static int property_get_reboot_to_firmware_setup(
2211 const char *interface,
2212 const char *property,
2213 sd_bus_message *reply,
2215 sd_bus_error *error) {
2222 r = efi_get_reboot_to_firmware();
2223 if (r < 0 && r != -EOPNOTSUPP)
2226 return sd_bus_message_append(reply, "b", r > 0);
2229 static int method_set_reboot_to_firmware_setup(
2230 sd_bus_message *message,
2232 sd_bus_error *error) {
2235 Manager *m = userdata;
2240 r = sd_bus_message_read(message, "b", &b);
2244 r = bus_verify_polkit_async(message,
2246 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2249 &m->polkit_registry,
2254 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2256 r = efi_set_reboot_to_firmware(b);
2260 return sd_bus_reply_method_return(message, NULL);
2263 static int method_can_reboot_to_firmware_setup(
2264 sd_bus_message *message,
2266 sd_bus_error *error) {
2271 Manager *m = userdata;
2276 r = efi_reboot_to_firmware_supported();
2277 if (r == -EOPNOTSUPP)
2278 return sd_bus_reply_method_return(message, "s", "na");
2282 r = bus_test_polkit(message,
2284 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2294 result = "challenge";
2298 return sd_bus_reply_method_return(message, "s", result);
2301 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2302 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2303 const char *who, *why, *what, *mode;
2304 _cleanup_free_ char *id = NULL;
2305 _cleanup_close_ int fifo_fd = -1;
2306 Manager *m = userdata;
2307 Inhibitor *i = NULL;
2317 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2321 w = inhibit_what_from_string(what);
2323 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2325 mm = inhibit_mode_from_string(mode);
2327 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2329 /* Delay is only supported for shutdown/sleep */
2330 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2331 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2333 /* Don't allow taking delay locks while we are already
2334 * executing the operation. We shouldn't create the impression
2335 * that the lock was successful if the machine is about to go
2336 * down/suspend any moment. */
2337 if (m->action_what & w)
2338 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2340 r = bus_verify_polkit_async(
2343 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2344 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2345 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
2346 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
2347 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2348 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2349 "org.freedesktop.login1.inhibit-handle-lid-switch",
2352 &m->polkit_registry,
2357 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2359 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2363 r = sd_bus_creds_get_euid(creds, &uid);
2367 r = sd_bus_creds_get_pid(creds, &pid);
2375 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2378 } while (hashmap_get(m->inhibitors, id));
2380 r = manager_add_inhibitor(m, id, &i);
2388 i->why = strdup(why);
2389 i->who = strdup(who);
2391 if (!i->why || !i->who) {
2396 fifo_fd = inhibitor_create_fifo(i);
2404 return sd_bus_reply_method_return(message, "h", fifo_fd);
2413 const sd_bus_vtable manager_vtable[] = {
2414 SD_BUS_VTABLE_START(0),
2416 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2417 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2419 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2420 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2421 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2422 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2423 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2424 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2425 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2426 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2427 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2428 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2429 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2430 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2431 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2432 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2433 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2434 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2435 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2436 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2437 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2438 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2439 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2440 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2441 SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
2443 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2444 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2445 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2446 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2447 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2448 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2449 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2450 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2451 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2452 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2453 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2454 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2455 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2456 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2457 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2458 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2459 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2460 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2461 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2462 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2463 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2464 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2465 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2466 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2467 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2468 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2469 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2470 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2471 SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2472 SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2473 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2474 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2475 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2476 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2477 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2478 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2479 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2480 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2481 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2482 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2484 SD_BUS_SIGNAL("SessionNew", "so", 0),
2485 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2486 SD_BUS_SIGNAL("UserNew", "uo", 0),
2487 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2488 SD_BUS_SIGNAL("SeatNew", "so", 0),
2489 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2490 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2491 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2496 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2505 if (streq(result, "done"))
2506 r = session_send_create_reply(s, NULL);
2508 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2510 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2511 r = session_send_create_reply(s, &e);
2517 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2518 const char *path, *result, *unit;
2519 Manager *m = userdata;
2528 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2530 bus_log_parse_error(r);
2534 if (m->action_job && streq(m->action_job, path)) {
2535 log_info("Operation finished.");
2537 /* Tell people that they now may take a lock again */
2538 send_prepare_for(m, m->action_what, false);
2540 free(m->action_job);
2541 m->action_job = NULL;
2542 m->action_unit = NULL;
2547 session = hashmap_get(m->session_units, unit);
2550 if (streq_ptr(path, session->scope_job)) {
2551 free(session->scope_job);
2552 session->scope_job = NULL;
2555 session_jobs_reply(session, unit, result);
2557 session_save(session);
2558 user_save(session->user);
2559 session_add_to_gc_queue(session);
2562 user = hashmap_get(m->user_units, unit);
2565 if (streq_ptr(path, user->service_job)) {
2566 free(user->service_job);
2567 user->service_job = NULL;
2570 if (streq_ptr(path, user->slice_job)) {
2571 free(user->slice_job);
2572 user->slice_job = NULL;
2575 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2576 session_jobs_reply(session, unit, result);
2580 user_add_to_gc_queue(user);
2586 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2587 const char *path, *unit;
2588 Manager *m = userdata;
2596 r = sd_bus_message_read(message, "so", &unit, &path);
2598 bus_log_parse_error(r);
2602 session = hashmap_get(m->session_units, unit);
2604 session_add_to_gc_queue(session);
2606 user = hashmap_get(m->user_units, unit);
2608 user_add_to_gc_queue(user);
2613 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2614 _cleanup_free_ char *unit = NULL;
2615 Manager *m = userdata;
2624 path = sd_bus_message_get_path(message);
2628 r = unit_name_from_dbus_path(path, &unit);
2629 if (r == -EINVAL) /* not a unit */
2634 session = hashmap_get(m->session_units, unit);
2636 session_add_to_gc_queue(session);
2638 user = hashmap_get(m->user_units, unit);
2640 user_add_to_gc_queue(user);
2645 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2646 Manager *m = userdata;
2654 r = sd_bus_message_read(message, "b", &b);
2656 bus_log_parse_error(r);
2663 /* systemd finished reloading, let's recheck all our sessions */
2664 log_debug("System manager has been reloaded, rechecking sessions...");
2666 HASHMAP_FOREACH(session, m->sessions, i)
2667 session_add_to_gc_queue(session);
2672 int match_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2673 const char *name, *old, *new;
2674 Manager *m = userdata;
2683 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2685 bus_log_parse_error(r);
2689 if (isempty(old) || !isempty(new))
2692 key = set_remove(m->busnames, (char*) old);
2696 /* Drop all controllers owned by this name */
2700 HASHMAP_FOREACH(session, m->sessions, i)
2701 if (session_is_controller(session, old))
2702 session_drop_controller(session);
2707 int manager_send_changed(Manager *manager, const char *property, ...) {
2712 l = strv_from_stdarg_alloca(property);
2714 return sd_bus_emit_properties_changed_strv(
2716 "/org/freedesktop/login1",
2717 "org.freedesktop.login1.Manager",
2721 int manager_start_scope(
2726 const char *description,
2727 const char *after, const char *after2,
2728 sd_bus_error *error,
2731 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2738 r = sd_bus_message_new_method_call(
2741 "org.freedesktop.systemd1",
2742 "/org/freedesktop/systemd1",
2743 "org.freedesktop.systemd1.Manager",
2744 "StartTransientUnit");
2748 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2752 r = sd_bus_message_open_container(m, 'a', "(sv)");
2756 if (!isempty(slice)) {
2757 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2762 if (!isempty(description)) {
2763 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2768 if (!isempty(after)) {
2769 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2774 if (!isempty(after2)) {
2775 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2780 /* cgroup empty notification is not available in containers
2781 * currently. To make this less problematic, let's shorten the
2782 * stop timeout for sessions, so that we don't wait
2785 /* Make sure that the session shells are terminated with
2786 * SIGHUP since bash and friends tend to ignore SIGTERM */
2787 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2791 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2795 r = sd_bus_message_close_container(m);
2799 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2803 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2811 r = sd_bus_message_read(reply, "o", &j);
2825 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2826 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2832 r = sd_bus_call_method(
2834 "org.freedesktop.systemd1",
2835 "/org/freedesktop/systemd1",
2836 "org.freedesktop.systemd1.Manager",
2840 "ss", unit, "fail");
2848 r = sd_bus_message_read(reply, "o", &j);
2862 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2863 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2869 r = sd_bus_call_method(
2871 "org.freedesktop.systemd1",
2872 "/org/freedesktop/systemd1",
2873 "org.freedesktop.systemd1.Manager",
2877 "ss", unit, "fail");
2879 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2880 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2885 sd_bus_error_free(error);
2896 r = sd_bus_message_read(reply, "o", &j);
2910 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2911 _cleanup_free_ char *path = NULL;
2917 path = unit_dbus_path_from_name(scope);
2921 r = sd_bus_call_method(
2923 "org.freedesktop.systemd1",
2925 "org.freedesktop.systemd1.Scope",
2931 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2932 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2933 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2934 sd_bus_error_free(error);
2944 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2948 return sd_bus_call_method(
2950 "org.freedesktop.systemd1",
2951 "/org/freedesktop/systemd1",
2952 "org.freedesktop.systemd1.Manager",
2956 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2959 int manager_unit_is_active(Manager *manager, const char *unit) {
2960 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2961 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2962 _cleanup_free_ char *path = NULL;
2969 path = unit_dbus_path_from_name(unit);
2973 r = sd_bus_get_property(
2975 "org.freedesktop.systemd1",
2977 "org.freedesktop.systemd1.Unit",
2983 /* systemd might have droppped off momentarily, let's
2984 * not make this an error */
2985 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2986 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2989 /* If the unit is already unloaded then it's not
2991 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2992 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2998 r = sd_bus_message_read(reply, "s", &state);
3002 return !streq(state, "inactive") && !streq(state, "failed");
3005 int manager_job_is_active(Manager *manager, const char *path) {
3006 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3007 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3013 r = sd_bus_get_property(
3015 "org.freedesktop.systemd1",
3017 "org.freedesktop.systemd1.Job",
3023 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3024 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3027 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3033 /* We don't actually care about the state really. The fact
3034 * that we could read the job state is enough for us */