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;
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 method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
247 _cleanup_free_ char *p = NULL;
248 Manager *m = userdata;
256 r = sd_bus_message_read(message, "s", &name);
260 r = manager_get_session_from_creds(m, message, name, error, &session);
264 p = session_bus_path(session);
268 return sd_bus_reply_method_return(message, "o", p);
271 static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
272 _cleanup_free_ char *p = NULL;
273 Session *session = NULL;
274 Manager *m = userdata;
281 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
283 r = sd_bus_message_read(message, "u", &pid);
288 r = manager_get_session_from_creds(m, message, NULL, error, &session);
292 r = manager_get_session_by_pid(m, pid, &session);
297 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
300 p = session_bus_path(session);
304 return sd_bus_reply_method_return(message, "o", p);
307 static int method_get_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
308 _cleanup_free_ char *p = NULL;
309 Manager *m = userdata;
317 r = sd_bus_message_read(message, "u", &uid);
321 r = manager_get_user_from_creds(m, message, uid, error, &user);
325 p = user_bus_path(user);
329 return sd_bus_reply_method_return(message, "o", p);
332 static int method_get_user_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
333 _cleanup_free_ char *p = NULL;
334 Manager *m = userdata;
342 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
344 r = sd_bus_message_read(message, "u", &pid);
349 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
353 r = manager_get_user_by_pid(m, pid, &user);
357 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);
360 p = user_bus_path(user);
364 return sd_bus_reply_method_return(message, "o", p);
367 static int method_get_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
368 _cleanup_free_ char *p = NULL;
369 Manager *m = userdata;
377 r = sd_bus_message_read(message, "s", &name);
381 r = manager_get_seat_from_creds(m, message, name, error, &seat);
385 p = seat_bus_path(seat);
389 return sd_bus_reply_method_return(message, "o", p);
392 static int method_list_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
393 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
394 Manager *m = userdata;
402 r = sd_bus_message_new_method_return(message, &reply);
406 r = sd_bus_message_open_container(reply, 'a', "(susso)");
410 HASHMAP_FOREACH(session, m->sessions, i) {
411 _cleanup_free_ char *p = NULL;
413 p = session_bus_path(session);
417 r = sd_bus_message_append(reply, "(susso)",
419 (uint32_t) session->user->uid,
421 session->seat ? session->seat->id : "",
427 r = sd_bus_message_close_container(reply);
431 return sd_bus_send(NULL, reply, NULL);
434 static int method_list_users(sd_bus_message *message, void *userdata, sd_bus_error *error) {
435 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
436 Manager *m = userdata;
444 r = sd_bus_message_new_method_return(message, &reply);
448 r = sd_bus_message_open_container(reply, 'a', "(uso)");
452 HASHMAP_FOREACH(user, m->users, i) {
453 _cleanup_free_ char *p = NULL;
455 p = user_bus_path(user);
459 r = sd_bus_message_append(reply, "(uso)",
460 (uint32_t) user->uid,
467 r = sd_bus_message_close_container(reply);
471 return sd_bus_send(NULL, reply, NULL);
474 static int method_list_seats(sd_bus_message *message, void *userdata, sd_bus_error *error) {
475 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
476 Manager *m = userdata;
484 r = sd_bus_message_new_method_return(message, &reply);
488 r = sd_bus_message_open_container(reply, 'a', "(so)");
492 HASHMAP_FOREACH(seat, m->seats, i) {
493 _cleanup_free_ char *p = NULL;
495 p = seat_bus_path(seat);
499 r = sd_bus_message_append(reply, "(so)", seat->id, p);
504 r = sd_bus_message_close_container(reply);
508 return sd_bus_send(NULL, reply, NULL);
511 static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
512 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
513 Manager *m = userdata;
514 Inhibitor *inhibitor;
521 r = sd_bus_message_new_method_return(message, &reply);
525 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
529 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
531 r = sd_bus_message_append(reply, "(ssssuu)",
532 strempty(inhibit_what_to_string(inhibitor->what)),
533 strempty(inhibitor->who),
534 strempty(inhibitor->why),
535 strempty(inhibit_mode_to_string(inhibitor->mode)),
536 (uint32_t) inhibitor->uid,
537 (uint32_t) inhibitor->pid);
542 r = sd_bus_message_close_container(reply);
546 return sd_bus_send(NULL, reply, NULL);
549 static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
550 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
551 uint32_t uid, leader, audit_id = 0;
552 _cleanup_free_ char *id = NULL;
553 Session *session = NULL;
554 Manager *m = userdata;
566 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
571 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
574 t = _SESSION_TYPE_INVALID;
576 t = session_type_from_string(type);
578 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
582 c = _SESSION_CLASS_INVALID;
584 c = session_class_from_string(class);
586 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
589 if (isempty(desktop))
592 if (!string_is_safe(desktop))
593 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
599 seat = hashmap_get(m->seats, cseat);
601 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
604 if (tty_is_vc(tty)) {
609 else if (seat != m->seat0)
610 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);
612 v = vtnr_from_tty(tty);
614 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
618 else if (vtnr != (uint32_t) v)
619 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
621 } else if (tty_is_console(tty)) {
625 else if (seat != m->seat0)
626 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
629 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
633 if (seat_has_vts(seat)) {
634 if (!vtnr || vtnr > 63)
635 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
638 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
642 r = sd_bus_message_enter_container(message, 'a', "(sv)");
646 if (t == _SESSION_TYPE_INVALID) {
647 if (!isempty(display))
649 else if (!isempty(tty))
652 t = SESSION_UNSPECIFIED;
655 if (c == _SESSION_CLASS_INVALID) {
656 if (t == SESSION_UNSPECIFIED)
657 c = SESSION_BACKGROUND;
663 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
665 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
669 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
674 manager_get_session_by_pid(m, leader, &session);
676 _cleanup_free_ char *path = NULL;
677 _cleanup_close_ int fifo_fd = -1;
679 /* Session already exists, client is probably
680 * something like "su" which changes uid but is still
681 * the same session */
683 fifo_fd = session_create_fifo(session);
687 path = session_bus_path(session);
691 log_debug("Sending reply about an existing session: "
692 "id=%s object_path=%s uid=%u runtime_path=%s "
693 "session_fd=%d seat=%s vtnr=%u",
696 (uint32_t) session->user->uid,
697 session->user->runtime_path,
699 session->seat ? session->seat->id : "",
700 (uint32_t) session->vtnr);
702 return sd_bus_reply_method_return(
706 session->user->runtime_path,
708 (uint32_t) session->user->uid,
709 session->seat ? session->seat->id : "",
710 (uint32_t) session->vtnr,
714 audit_session_from_pid(leader, &audit_id);
716 /* Keep our session IDs and the audit session IDs in sync */
718 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
721 /* Wut? There's already a session by this name and we
722 * didn't find it above? Weird, then let's not trust
723 * the audit data and let's better register a new
725 if (hashmap_get(m->sessions, id)) {
726 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
737 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
740 } while (hashmap_get(m->sessions, id));
743 r = manager_add_user_by_uid(m, uid, &user);
747 r = manager_add_session(m, id, &session);
751 session_set_user(session, user);
753 session->leader = leader;
754 session->audit_id = audit_id;
757 session->remote = remote;
758 session->vtnr = vtnr;
761 session->tty = strdup(tty);
768 if (!isempty(display)) {
769 session->display = strdup(display);
770 if (!session->display) {
776 if (!isempty(remote_user)) {
777 session->remote_user = strdup(remote_user);
778 if (!session->remote_user) {
784 if (!isempty(remote_host)) {
785 session->remote_host = strdup(remote_host);
786 if (!session->remote_host) {
792 if (!isempty(service)) {
793 session->service = strdup(service);
794 if (!session->service) {
800 if (!isempty(desktop)) {
801 session->desktop = strdup(desktop);
802 if (!session->desktop) {
809 r = seat_attach_session(seat, session);
814 r = session_start(session);
818 session->create_message = sd_bus_message_ref(message);
820 /* Now, let's wait until the slice unit and stuff got
821 * created. We send the reply back from
822 * session_send_create_reply(). */
824 /* Elogind note: replying directly, since we're not actually
825 starting slices and thus we aren't waiting on systemd. */
827 r = session_send_create_reply(session, NULL);
831 session_save(session);
837 session_add_to_gc_queue(session);
840 user_add_to_gc_queue(user);
845 static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
846 Manager *m = userdata;
854 r = sd_bus_message_read(message, "s", &name);
858 r = manager_get_session_from_creds(m, message, name, error, &session);
862 r = session_release(session);
866 return sd_bus_reply_method_return(message, NULL);
869 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
870 Manager *m = userdata;
878 r = sd_bus_message_read(message, "s", &name);
882 r = manager_get_session_from_creds(m, message, name, error, &session);
886 return bus_session_method_activate(message, session, error);
889 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
890 const char *session_name, *seat_name;
891 Manager *m = userdata;
899 /* Same as ActivateSession() but refuses to work if
900 * the seat doesn't match */
902 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
906 r = manager_get_session_from_creds(m, message, session_name, error, &session);
910 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
914 if (session->seat != seat)
915 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
917 r = session_activate(session);
921 return sd_bus_reply_method_return(message, NULL);
924 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
925 Manager *m = userdata;
933 r = sd_bus_message_read(message, "s", &name);
937 r = manager_get_session_from_creds(m, message, name, error, &session);
941 return bus_session_method_lock(message, session, error);
944 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
945 Manager *m = userdata;
951 r = bus_verify_polkit_async(
954 "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",
1113 &m->polkit_registry,
1118 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1120 mkdir_p_label("/var/lib/systemd", 0755);
1122 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1126 cc = cescape(pw->pw_name);
1130 path = strjoina("/var/lib/systemd/linger/", cc);
1138 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1145 if (r < 0 && errno != ENOENT)
1148 u = hashmap_get(m->users, UID_TO_PTR(uid));
1150 user_add_to_gc_queue(u);
1153 return sd_bus_reply_method_return(message, NULL);
1156 static int trigger_device(Manager *m, struct udev_device *d) {
1157 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1158 struct udev_list_entry *first, *item;
1163 e = udev_enumerate_new(m->udev);
1168 r = udev_enumerate_add_match_parent(e, d);
1173 r = udev_enumerate_scan_devices(e);
1177 first = udev_enumerate_get_list_entry(e);
1178 udev_list_entry_foreach(item, first) {
1179 _cleanup_free_ char *t = NULL;
1182 p = udev_list_entry_get_name(item);
1184 t = strappend(p, "/uevent");
1188 write_string_file(t, "change");
1194 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1195 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1196 _cleanup_free_ char *rule = NULL, *file = NULL;
1197 const char *id_for_seat;
1204 d = udev_device_new_from_syspath(m->udev, sysfs);
1208 if (!udev_device_has_tag(d, "seat"))
1211 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1215 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1218 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1221 mkdir_p_label("/etc/udev/rules.d", 0755);
1222 mac_selinux_init("/etc");
1223 r = write_string_file_atomic_label(file, rule);
1227 return trigger_device(m, d);
1230 static int flush_devices(Manager *m) {
1231 _cleanup_closedir_ DIR *d;
1235 d = opendir("/etc/udev/rules.d");
1237 if (errno != ENOENT)
1238 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1242 while ((de = readdir(d))) {
1244 if (!dirent_is_file(de))
1247 if (!startswith(de->d_name, "72-seat-"))
1250 if (!endswith(de->d_name, ".rules"))
1253 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1254 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1258 return trigger_device(m, NULL);
1261 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1262 const char *sysfs, *seat;
1263 Manager *m = userdata;
1269 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1273 if (!path_startswith(sysfs, "/sys"))
1274 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1276 if (!seat_name_is_valid(seat))
1277 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1279 r = bus_verify_polkit_async(
1282 "org.freedesktop.login1.attach-device",
1286 &m->polkit_registry,
1291 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1293 r = attach_device(m, seat, sysfs);
1297 return sd_bus_reply_method_return(message, NULL);
1300 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1301 Manager *m = userdata;
1307 r = sd_bus_message_read(message, "b", &interactive);
1311 r = bus_verify_polkit_async(
1314 "org.freedesktop.login1.flush-devices",
1318 &m->polkit_registry,
1323 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1325 r = flush_devices(m);
1329 return sd_bus_reply_method_return(message, NULL);
1332 static int have_multiple_sessions(
1341 /* Check for other users' sessions. Greeter sessions do not
1342 * count, and non-login sessions do not count either. */
1343 HASHMAP_FOREACH(session, m->sessions, i)
1344 if (session->class == SESSION_USER &&
1345 session->user->uid != uid)
1351 static int bus_manager_log_shutdown(
1354 const char *unit_name) {
1361 if (w != INHIBIT_SHUTDOWN)
1364 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1365 p = "MESSAGE=System is powering down.";
1366 q = "SHUTDOWN=power-off";
1367 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1368 p = "MESSAGE=System is halting.";
1369 q = "SHUTDOWN=halt";
1370 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1371 p = "MESSAGE=System is rebooting.";
1372 q = "SHUTDOWN=reboot";
1373 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1374 p = "MESSAGE=System is rebooting with kexec.";
1375 q = "SHUTDOWN=kexec";
1377 p = "MESSAGE=System is shutting down.";
1381 if (!isempty(m->wall_message))
1382 p = strjoina(p, " (", m->wall_message, ")");
1384 return log_struct(LOG_NOTICE,
1385 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1391 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1392 Manager *m = userdata;
1397 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1401 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1406 if (until <= now(CLOCK_MONOTONIC))
1409 /* We want to ignore the lid switch for a while after each
1410 * suspend, and after boot-up. Hence let's install a timer for
1411 * this. As long as the event source exists we ignore the lid
1414 if (m->lid_switch_ignore_event_source) {
1417 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1424 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1426 r = sd_event_add_time(
1428 &m->lid_switch_ignore_event_source,
1431 lid_switch_ignore_handler, m);
1436 static int execute_shutdown_or_sleep(
1439 const char *unit_name,
1440 sd_bus_error *error) {
1442 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1449 assert(w < _INHIBIT_WHAT_MAX);
1452 bus_manager_log_shutdown(m, w, unit_name);
1454 r = sd_bus_call_method(
1456 "org.freedesktop.systemd1",
1457 "/org/freedesktop/systemd1",
1458 "org.freedesktop.systemd1.Manager",
1462 "ss", unit_name, "replace-irreversibly");
1466 r = sd_bus_message_read(reply, "o", &p);
1474 m->action_unit = unit_name;
1475 free(m->action_job);
1479 /* Make sure the lid switch is ignored for a while */
1480 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1485 static int manager_inhibit_timeout_handler(
1490 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1491 Inhibitor *offending = NULL;
1492 Manager *manager = userdata;
1496 assert(manager->inhibit_timeout_source == s);
1498 if (manager->action_what == 0 || manager->action_job)
1501 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1502 _cleanup_free_ char *comm = NULL, *u = NULL;
1504 (void) get_process_comm(offending->pid, &comm);
1505 u = uid_to_name(offending->uid);
1507 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1508 offending->uid, strna(u),
1509 offending->pid, strna(comm));
1512 /* Actually do the operation */
1513 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
1515 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1517 manager->action_unit = NULL;
1518 manager->action_what = 0;
1524 static int delay_shutdown_or_sleep(
1527 const char *unit_name) {
1534 assert(w < _INHIBIT_WHAT_MAX);
1537 timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1539 if (m->inhibit_timeout_source) {
1540 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1542 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1544 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1546 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1548 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1549 timeout_val, 0, manager_inhibit_timeout_handler, m);
1554 m->action_unit = unit_name;
1560 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1562 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1563 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1564 [INHIBIT_SLEEP] = "PrepareForSleep"
1567 int active = _active;
1571 assert(w < _INHIBIT_WHAT_MAX);
1572 assert(signal_name[w]);
1574 return sd_bus_emit_signal(m->bus,
1575 "/org/freedesktop/login1",
1576 "org.freedesktop.login1.Manager",
1582 int bus_manager_shutdown_or_sleep_now_or_later(
1584 const char *unit_name,
1586 sd_bus_error *error) {
1594 assert(w <= _INHIBIT_WHAT_MAX);
1595 assert(!m->action_job);
1597 /* Tell everybody to prepare for shutdown/sleep */
1598 send_prepare_for(m, w, true);
1601 m->inhibit_delay_max > 0 &&
1602 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1605 /* Shutdown is delayed, keep in mind what we
1606 * want to do, and start a timeout */
1607 r = delay_shutdown_or_sleep(m, w, unit_name);
1609 /* Shutdown is not delayed, execute it
1611 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1616 static int verify_shutdown_creds(
1618 sd_bus_message *message,
1622 const char *action_multiple_sessions,
1623 const char *action_ignore_inhibit,
1624 sd_bus_error *error) {
1626 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1627 bool multiple_sessions, blocked;
1634 assert(w <= _INHIBIT_WHAT_MAX);
1636 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1640 r = sd_bus_creds_get_euid(creds, &uid);
1644 r = have_multiple_sessions(m, uid);
1648 multiple_sessions = r > 0;
1649 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1651 if (multiple_sessions && action_multiple_sessions) {
1652 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1656 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1659 if (blocked && action_ignore_inhibit) {
1660 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, 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 (!multiple_sessions && !blocked && action) {
1668 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, NULL, 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 */
1678 static int method_do_shutdown_or_sleep(
1680 sd_bus_message *message,
1681 const char *unit_name,
1684 const char *action_multiple_sessions,
1685 const char *action_ignore_inhibit,
1686 const char *sleep_verb,
1687 sd_bus_error *error) {
1695 assert(w <= _INHIBIT_WHAT_MAX);
1697 r = sd_bus_message_read(message, "b", &interactive);
1701 /* Don't allow multiple jobs being executed at the same time */
1703 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1706 r = can_sleep(sleep_verb);
1711 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1714 r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1715 action_ignore_inhibit, error);
1719 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1723 return sd_bus_reply_method_return(message, NULL);
1726 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1727 Manager *m = userdata;
1729 return method_do_shutdown_or_sleep(
1731 SPECIAL_POWEROFF_TARGET,
1733 "org.freedesktop.login1.power-off",
1734 "org.freedesktop.login1.power-off-multiple-sessions",
1735 "org.freedesktop.login1.power-off-ignore-inhibit",
1740 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1741 Manager *m = userdata;
1743 return method_do_shutdown_or_sleep(
1745 SPECIAL_REBOOT_TARGET,
1747 "org.freedesktop.login1.reboot",
1748 "org.freedesktop.login1.reboot-multiple-sessions",
1749 "org.freedesktop.login1.reboot-ignore-inhibit",
1754 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1755 Manager *m = userdata;
1757 return method_do_shutdown_or_sleep(
1759 SPECIAL_SUSPEND_TARGET,
1761 "org.freedesktop.login1.suspend",
1762 "org.freedesktop.login1.suspend-multiple-sessions",
1763 "org.freedesktop.login1.suspend-ignore-inhibit",
1768 static int nologin_timeout_handler(
1773 Manager *m = userdata;
1776 log_info("Creating /run/nologin, blocking further logins...");
1778 r = write_string_file_atomic("/run/nologin", "System is going down.");
1780 log_error_errno(r, "Failed to create /run/nologin: %m");
1782 m->unlink_nologin = true;
1787 static int update_schedule_file(Manager *m) {
1788 _cleanup_free_ char *temp_path = NULL;
1789 _cleanup_fclose_ FILE *f = NULL;
1794 r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1796 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1798 r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1800 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1802 (void) fchmod(fileno(f), 0644);
1808 m->scheduled_shutdown_timeout,
1809 m->enable_wall_messages,
1810 m->scheduled_shutdown_type);
1812 if (!isempty(m->wall_message)) {
1813 _cleanup_free_ char *t;
1815 t = cescape(m->wall_message);
1821 fprintf(f, "WALL_MESSAGE=%s\n", t);
1824 r = fflush_and_check(f);
1828 if (rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1836 (void) unlink(temp_path);
1837 (void) unlink("/run/systemd/shutdown/scheduled");
1839 return log_error_errno(r, "Failed to write information about scheduled shutdowns: %m");
1842 static int manager_scheduled_shutdown_handler(
1847 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1848 Manager *m = userdata;
1854 if (isempty(m->scheduled_shutdown_type))
1857 if (streq(m->scheduled_shutdown_type, "halt"))
1858 target = SPECIAL_HALT_TARGET;
1859 else if (streq(m->scheduled_shutdown_type, "poweroff"))
1860 target = SPECIAL_POWEROFF_TARGET;
1862 target = SPECIAL_REBOOT_TARGET;
1864 r = execute_shutdown_or_sleep(m, 0, target, &error);
1866 return log_error_errno(r, "Unable to execute transition to %s: %m", target);
1871 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1872 Manager *m = userdata;
1873 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1874 const char *action_multiple_sessions = NULL;
1875 const char *action_ignore_inhibit = NULL;
1876 const char *action = NULL;
1884 r = sd_bus_message_read(message, "st", &type, &elapse);
1888 if (streq(type, "reboot")) {
1889 action = "org.freedesktop.login1.reboot";
1890 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1891 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1892 } else if (streq(type, "halt")) {
1893 action = "org.freedesktop.login1.halt";
1894 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1895 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1896 } else if (streq(type, "poweroff")) {
1897 action = "org.freedesktop.login1.poweroff";
1898 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1899 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1901 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1903 r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1904 action, action_multiple_sessions, action_ignore_inhibit, error);
1908 if (m->scheduled_shutdown_timeout_source) {
1909 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1911 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1913 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1915 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1917 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1918 CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1920 return log_error_errno(r, "sd_event_add_time() failed: %m");
1923 r = free_and_strdup(&m->scheduled_shutdown_type, type);
1925 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1929 if (m->nologin_timeout_source) {
1930 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1932 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1934 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1936 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1938 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1939 CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1941 return log_error_errno(r, "sd_event_add_time() failed: %m");
1944 m->scheduled_shutdown_timeout = elapse;
1946 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1950 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1951 (void) sd_bus_creds_get_tty(creds, &tty);
1953 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1955 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1960 r = manager_setup_wall_message_timer(m);
1964 if (!isempty(type)) {
1965 r = update_schedule_file(m);
1969 (void) unlink("/run/systemd/shutdown/scheduled");
1971 return sd_bus_reply_method_return(message, NULL);
1974 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1975 Manager *m = userdata;
1981 cancelled = m->scheduled_shutdown_type != NULL;
1983 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1984 m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
1985 m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
1986 free(m->scheduled_shutdown_type);
1987 m->scheduled_shutdown_type = NULL;
1988 m->scheduled_shutdown_timeout = 0;
1991 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1992 const char *tty = NULL;
1996 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1998 (void) sd_bus_creds_get_uid(creds, &uid);
1999 (void) sd_bus_creds_get_tty(creds, &tty);
2002 utmp_wall("The system shutdown has been cancelled",
2003 lookup_uid(uid), tty, logind_wall_tty_filter, m);
2006 return sd_bus_reply_method_return(message, "b", cancelled);
2009 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2010 Manager *m = userdata;
2012 return method_do_shutdown_or_sleep(
2014 SPECIAL_HIBERNATE_TARGET,
2016 "org.freedesktop.login1.hibernate",
2017 "org.freedesktop.login1.hibernate-multiple-sessions",
2018 "org.freedesktop.login1.hibernate-ignore-inhibit",
2023 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2024 Manager *m = userdata;
2026 return method_do_shutdown_or_sleep(
2028 SPECIAL_HYBRID_SLEEP_TARGET,
2030 "org.freedesktop.login1.hibernate",
2031 "org.freedesktop.login1.hibernate-multiple-sessions",
2032 "org.freedesktop.login1.hibernate-ignore-inhibit",
2037 static int method_can_shutdown_or_sleep(
2039 sd_bus_message *message,
2042 const char *action_multiple_sessions,
2043 const char *action_ignore_inhibit,
2044 const char *sleep_verb,
2045 sd_bus_error *error) {
2047 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2048 bool multiple_sessions, challenge, blocked;
2049 const char *result = NULL;
2056 assert(w <= _INHIBIT_WHAT_MAX);
2058 assert(action_multiple_sessions);
2059 assert(action_ignore_inhibit);
2062 r = can_sleep(sleep_verb);
2066 return sd_bus_reply_method_return(message, "s", "na");
2069 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2073 r = sd_bus_creds_get_euid(creds, &uid);
2077 r = have_multiple_sessions(m, uid);
2081 multiple_sessions = r > 0;
2082 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2084 if (multiple_sessions) {
2085 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, UID_INVALID, &challenge, error);
2092 result = "challenge";
2098 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, UID_INVALID, &challenge, error);
2102 if (r > 0 && !result)
2104 else if (challenge && (!result || streq(result, "yes")))
2105 result = "challenge";
2110 if (!multiple_sessions && !blocked) {
2111 /* If neither inhibit nor multiple sessions
2112 * apply then just check the normal policy */
2114 r = bus_test_polkit(message, CAP_SYS_BOOT, action, NULL, UID_INVALID, &challenge, error);
2121 result = "challenge";
2126 return sd_bus_reply_method_return(message, "s", result);
2129 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2130 Manager *m = userdata;
2132 return method_can_shutdown_or_sleep(
2135 "org.freedesktop.login1.power-off",
2136 "org.freedesktop.login1.power-off-multiple-sessions",
2137 "org.freedesktop.login1.power-off-ignore-inhibit",
2142 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2143 Manager *m = userdata;
2145 return method_can_shutdown_or_sleep(
2148 "org.freedesktop.login1.reboot",
2149 "org.freedesktop.login1.reboot-multiple-sessions",
2150 "org.freedesktop.login1.reboot-ignore-inhibit",
2155 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2156 Manager *m = userdata;
2158 return method_can_shutdown_or_sleep(
2161 "org.freedesktop.login1.suspend",
2162 "org.freedesktop.login1.suspend-multiple-sessions",
2163 "org.freedesktop.login1.suspend-ignore-inhibit",
2168 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2169 Manager *m = userdata;
2171 return method_can_shutdown_or_sleep(
2174 "org.freedesktop.login1.hibernate",
2175 "org.freedesktop.login1.hibernate-multiple-sessions",
2176 "org.freedesktop.login1.hibernate-ignore-inhibit",
2181 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2182 Manager *m = userdata;
2184 return method_can_shutdown_or_sleep(
2187 "org.freedesktop.login1.hibernate",
2188 "org.freedesktop.login1.hibernate-multiple-sessions",
2189 "org.freedesktop.login1.hibernate-ignore-inhibit",
2194 static int property_get_reboot_to_firmware_setup(
2197 const char *interface,
2198 const char *property,
2199 sd_bus_message *reply,
2201 sd_bus_error *error) {
2208 r = efi_get_reboot_to_firmware();
2209 if (r < 0 && r != -EOPNOTSUPP)
2212 return sd_bus_message_append(reply, "b", r > 0);
2215 static int method_set_reboot_to_firmware_setup(
2216 sd_bus_message *message,
2218 sd_bus_error *error) {
2221 Manager *m = userdata;
2226 r = sd_bus_message_read(message, "b", &b);
2230 r = bus_verify_polkit_async(message,
2232 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2236 &m->polkit_registry,
2241 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2243 r = efi_set_reboot_to_firmware(b);
2247 return sd_bus_reply_method_return(message, NULL);
2250 static int method_can_reboot_to_firmware_setup(
2251 sd_bus_message *message,
2253 sd_bus_error *error) {
2258 Manager *m = userdata;
2263 r = efi_reboot_to_firmware_supported();
2264 if (r == -EOPNOTSUPP)
2265 return sd_bus_reply_method_return(message, "s", "na");
2269 r = bus_test_polkit(message,
2271 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2282 result = "challenge";
2286 return sd_bus_reply_method_return(message, "s", result);
2289 static int method_set_wall_message(
2290 sd_bus_message *message,
2292 sd_bus_error *error) {
2295 Manager *m = userdata;
2297 int enable_wall_messages;
2302 r = sd_bus_message_read(message, "sb", &wall_message, &enable_wall_messages);
2306 r = bus_verify_polkit_async(message,
2308 "org.freedesktop.login1.set-wall-message",
2312 &m->polkit_registry,
2317 return 1; /* Will call us back */
2319 if (isempty(wall_message))
2320 m->wall_message = mfree(m->wall_message);
2322 r = free_and_strdup(&m->wall_message, wall_message);
2327 m->enable_wall_messages = enable_wall_messages;
2329 return sd_bus_reply_method_return(message, NULL);
2332 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2333 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2334 const char *who, *why, *what, *mode;
2335 _cleanup_free_ char *id = NULL;
2336 _cleanup_close_ int fifo_fd = -1;
2337 Manager *m = userdata;
2338 Inhibitor *i = NULL;
2348 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2352 w = inhibit_what_from_string(what);
2354 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2356 mm = inhibit_mode_from_string(mode);
2358 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2360 /* Delay is only supported for shutdown/sleep */
2361 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2362 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2364 /* Don't allow taking delay locks while we are already
2365 * executing the operation. We shouldn't create the impression
2366 * that the lock was successful if the machine is about to go
2367 * down/suspend any moment. */
2368 if (m->action_what & w)
2369 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2371 r = bus_verify_polkit_async(
2374 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2375 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2376 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
2377 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
2378 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2379 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2380 "org.freedesktop.login1.inhibit-handle-lid-switch",
2384 &m->polkit_registry,
2389 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2391 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2395 r = sd_bus_creds_get_euid(creds, &uid);
2399 r = sd_bus_creds_get_pid(creds, &pid);
2406 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2409 } while (hashmap_get(m->inhibitors, id));
2411 r = manager_add_inhibitor(m, id, &i);
2419 i->why = strdup(why);
2420 i->who = strdup(who);
2422 if (!i->why || !i->who) {
2427 fifo_fd = inhibitor_create_fifo(i);
2435 return sd_bus_reply_method_return(message, "h", fifo_fd);
2444 const sd_bus_vtable manager_vtable[] = {
2445 SD_BUS_VTABLE_START(0),
2447 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2448 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2450 // SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2451 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2452 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2453 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2454 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2455 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2456 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2457 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2458 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2459 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2460 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2461 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2462 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2463 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2464 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2465 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2466 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2467 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2468 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2469 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2470 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2471 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2473 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2474 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2475 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2476 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2477 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2478 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2479 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2480 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2481 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2482 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2483 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2484 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2485 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2486 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2487 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2488 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2489 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2490 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2491 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2492 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2493 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2494 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2495 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2496 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2497 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2498 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2499 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2500 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2501 SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2502 SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2503 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2504 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2505 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2506 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2507 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2508 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2509 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2510 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2511 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2512 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2513 SD_BUS_METHOD("SetWallMessage", "sb", NULL, method_set_wall_message, SD_BUS_VTABLE_UNPRIVILEGED),
2515 SD_BUS_SIGNAL("SessionNew", "so", 0),
2516 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2517 SD_BUS_SIGNAL("UserNew", "uo", 0),
2518 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2519 SD_BUS_SIGNAL("SeatNew", "so", 0),
2520 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2521 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2522 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2527 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2536 if (streq(result, "done"))
2537 r = session_send_create_reply(s, NULL);
2539 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2541 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2542 r = session_send_create_reply(s, &e);
2548 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2549 const char *path, *result, *unit;
2550 Manager *m = userdata;
2559 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2561 bus_log_parse_error(r);
2565 if (m->action_job && streq(m->action_job, path)) {
2566 log_info("Operation finished.");
2568 /* Tell people that they now may take a lock again */
2569 send_prepare_for(m, m->action_what, false);
2571 m->action_job = mfree(m->action_job);
2572 m->action_unit = NULL;
2577 session = hashmap_get(m->session_units, unit);
2580 /// elogind does not support scope jobs
2582 if (streq_ptr(path, session->scope_job))
2583 session->scope_job = mfree(session->scope_job);
2586 session_jobs_reply(session, unit, result);
2588 session_save(session);
2589 session_add_to_gc_queue(session);
2592 user = hashmap_get(m->user_units, unit);
2595 /// elogind does not support slice and service jobs
2597 if (streq_ptr(path, user->service_job))
2598 user->service_job = mfree(user->service_job);
2600 if (streq_ptr(path, user->slice_job))
2601 user->slice_job = mfree(user->slice_job);
2604 LIST_FOREACH(sessions_by_user, session, user->sessions)
2605 session_jobs_reply(session, unit, result);
2608 user_add_to_gc_queue(user);
2614 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2615 const char *path, *unit;
2616 Manager *m = userdata;
2624 r = sd_bus_message_read(message, "so", &unit, &path);
2626 bus_log_parse_error(r);
2630 session = hashmap_get(m->session_units, unit);
2632 session_add_to_gc_queue(session);
2634 user = hashmap_get(m->user_units, unit);
2636 user_add_to_gc_queue(user);
2641 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2642 _cleanup_free_ char *unit = NULL;
2643 Manager *m = userdata;
2652 path = sd_bus_message_get_path(message);
2656 r = unit_name_from_dbus_path(path, &unit);
2657 if (r == -EINVAL) /* not a unit */
2664 session = hashmap_get(m->session_units, unit);
2666 session_add_to_gc_queue(session);
2668 user = hashmap_get(m->user_units, unit);
2670 user_add_to_gc_queue(user);
2675 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2676 Manager *m = userdata;
2684 r = sd_bus_message_read(message, "b", &b);
2686 bus_log_parse_error(r);
2693 /* systemd finished reloading, let's recheck all our sessions */
2694 log_debug("System manager has been reloaded, rechecking sessions...");
2696 HASHMAP_FOREACH(session, m->sessions, i)
2697 session_add_to_gc_queue(session);
2702 int manager_send_changed(Manager *manager, const char *property, ...) {
2707 l = strv_from_stdarg_alloca(property);
2709 return sd_bus_emit_properties_changed_strv(
2711 "/org/freedesktop/login1",
2712 "org.freedesktop.login1.Manager",
2716 /// UNNEEDED by elogind
2718 int manager_start_scope(
2723 const char *description,
2724 const char *after, const char *after2,
2725 sd_bus_error *error,
2728 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2735 r = sd_bus_message_new_method_call(
2738 "org.freedesktop.systemd1",
2739 "/org/freedesktop/systemd1",
2740 "org.freedesktop.systemd1.Manager",
2741 "StartTransientUnit");
2745 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2749 r = sd_bus_message_open_container(m, 'a', "(sv)");
2753 if (!isempty(slice)) {
2754 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2759 if (!isempty(description)) {
2760 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2765 if (!isempty(after)) {
2766 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2771 if (!isempty(after2)) {
2772 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2777 /* cgroup empty notification is not available in containers
2778 * currently. To make this less problematic, let's shorten the
2779 * stop timeout for sessions, so that we don't wait
2782 /* Make sure that the session shells are terminated with
2783 * SIGHUP since bash and friends tend to ignore SIGTERM */
2784 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2788 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2792 r = sd_bus_message_close_container(m);
2796 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2800 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2808 r = sd_bus_message_read(reply, "o", &j);
2822 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2823 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2829 r = sd_bus_call_method(
2831 "org.freedesktop.systemd1",
2832 "/org/freedesktop/systemd1",
2833 "org.freedesktop.systemd1.Manager",
2837 "ss", unit, "fail");
2845 r = sd_bus_message_read(reply, "o", &j);
2859 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2860 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2866 r = sd_bus_call_method(
2868 "org.freedesktop.systemd1",
2869 "/org/freedesktop/systemd1",
2870 "org.freedesktop.systemd1.Manager",
2874 "ss", unit, "fail");
2876 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2877 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2882 sd_bus_error_free(error);
2893 r = sd_bus_message_read(reply, "o", &j);
2907 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2908 _cleanup_free_ char *path = NULL;
2914 path = unit_dbus_path_from_name(scope);
2918 r = sd_bus_call_method(
2920 "org.freedesktop.systemd1",
2922 "org.freedesktop.systemd1.Scope",
2928 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2929 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2930 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2931 sd_bus_error_free(error);
2941 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2945 return sd_bus_call_method(
2947 "org.freedesktop.systemd1",
2948 "/org/freedesktop/systemd1",
2949 "org.freedesktop.systemd1.Manager",
2953 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2956 int manager_unit_is_active(Manager *manager, const char *unit) {
2957 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2958 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2959 _cleanup_free_ char *path = NULL;
2966 path = unit_dbus_path_from_name(unit);
2970 r = sd_bus_get_property(
2972 "org.freedesktop.systemd1",
2974 "org.freedesktop.systemd1.Unit",
2980 /* systemd might have droppped off momentarily, let's
2981 * not make this an error */
2982 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2983 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2986 /* If the unit is already unloaded then it's not
2988 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2989 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2995 r = sd_bus_message_read(reply, "s", &state);
2999 return !streq(state, "inactive") && !streq(state, "failed");
3002 int manager_job_is_active(Manager *manager, const char *path) {
3003 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3004 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3010 r = sd_bus_get_property(
3012 "org.freedesktop.systemd1",
3014 "org.freedesktop.systemd1.Job",
3020 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3021 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3024 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3030 /* We don't actually care about the state really. The fact
3031 * that we could read the job state is enough for us */