1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include "sd-messages.h"
30 #include "path-util.h"
32 #include "sleep-config.h"
33 #include "fileio-label.h"
34 #include "unit-name.h"
37 #include "bus-error.h"
38 #include "bus-common-errors.h"
39 #include "udev-util.h"
40 #include "selinux-util.h"
43 #include "formats-util.h"
44 #include "process-util.h"
45 #include "terminal-util.h"
46 #include "utmp-wtmp.h"
48 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
49 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
58 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
62 r = sd_bus_creds_get_session(creds, &name);
67 session = hashmap_get(m->sessions, name);
69 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
75 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
83 if (uid == UID_INVALID) {
84 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
86 /* Note that we get the owner UID of the session, not the actual client UID here! */
87 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
91 r = sd_bus_creds_get_owner_uid(creds, &uid);
96 user = hashmap_get(m->users, UID_TO_PTR(uid));
98 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
104 int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
115 r = manager_get_session_from_creds(m, message, NULL, error, &session);
119 seat = session->seat;
122 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
124 seat = hashmap_get(m->seats, name);
126 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
133 static int property_get_idle_hint(
136 const char *interface,
137 const char *property,
138 sd_bus_message *reply,
140 sd_bus_error *error) {
142 Manager *m = userdata;
148 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
151 static int property_get_idle_since_hint(
154 const char *interface,
155 const char *property,
156 sd_bus_message *reply,
158 sd_bus_error *error) {
160 Manager *m = userdata;
161 dual_timestamp t = DUAL_TIMESTAMP_NULL;
167 manager_get_idle_hint(m, &t);
169 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
172 static int property_get_inhibited(
175 const char *interface,
176 const char *property,
177 sd_bus_message *reply,
179 sd_bus_error *error) {
181 Manager *m = userdata;
188 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
190 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
193 static int property_get_preparing(
196 const char *interface,
197 const char *property,
198 sd_bus_message *reply,
200 sd_bus_error *error) {
202 Manager *m = userdata;
209 if (streq(property, "PreparingForShutdown"))
210 b = !!(m->action_what & INHIBIT_SHUTDOWN);
212 b = !!(m->action_what & INHIBIT_SLEEP);
214 return sd_bus_message_append(reply, "b", b);
217 static int property_get_scheduled_shutdown(
220 const char *interface,
221 const char *property,
222 sd_bus_message *reply,
224 sd_bus_error *error) {
226 Manager *m = userdata;
233 r = sd_bus_message_open_container(reply, 'r', "st");
237 r = sd_bus_message_append(reply, "st", m->scheduled_shutdown_type, m->scheduled_shutdown_timeout);
241 return sd_bus_message_close_container(reply);
244 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
246 static int property_get_docked(
249 const char *interface,
250 const char *property,
251 sd_bus_message *reply,
253 sd_bus_error *error) {
255 Manager *m = userdata;
261 return sd_bus_message_append(reply, "b", manager_is_docked_or_external_displays(m));
264 static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
265 _cleanup_free_ char *p = NULL;
266 Manager *m = userdata;
274 r = sd_bus_message_read(message, "s", &name);
278 r = manager_get_session_from_creds(m, message, name, error, &session);
282 p = session_bus_path(session);
286 return sd_bus_reply_method_return(message, "o", p);
289 static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
290 _cleanup_free_ char *p = NULL;
291 Session *session = NULL;
292 Manager *m = userdata;
299 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
301 r = sd_bus_message_read(message, "u", &pid);
306 r = manager_get_session_from_creds(m, message, NULL, error, &session);
310 r = manager_get_session_by_pid(m, pid, &session);
315 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
318 p = session_bus_path(session);
322 return sd_bus_reply_method_return(message, "o", p);
325 static int method_get_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
326 _cleanup_free_ char *p = NULL;
327 Manager *m = userdata;
335 r = sd_bus_message_read(message, "u", &uid);
339 r = manager_get_user_from_creds(m, message, uid, error, &user);
343 p = user_bus_path(user);
347 return sd_bus_reply_method_return(message, "o", p);
350 static int method_get_user_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
351 _cleanup_free_ char *p = NULL;
352 Manager *m = userdata;
360 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
362 r = sd_bus_message_read(message, "u", &pid);
367 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
371 r = manager_get_user_by_pid(m, pid, &user);
375 return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID "PID_FMT" does not belong to any known or logged in user", pid);
378 p = user_bus_path(user);
382 return sd_bus_reply_method_return(message, "o", p);
385 static int method_get_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
386 _cleanup_free_ char *p = NULL;
387 Manager *m = userdata;
395 r = sd_bus_message_read(message, "s", &name);
399 r = manager_get_seat_from_creds(m, message, name, error, &seat);
403 p = seat_bus_path(seat);
407 return sd_bus_reply_method_return(message, "o", p);
410 static int method_list_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
411 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
412 Manager *m = userdata;
420 r = sd_bus_message_new_method_return(message, &reply);
424 r = sd_bus_message_open_container(reply, 'a', "(susso)");
428 HASHMAP_FOREACH(session, m->sessions, i) {
429 _cleanup_free_ char *p = NULL;
431 p = session_bus_path(session);
435 r = sd_bus_message_append(reply, "(susso)",
437 (uint32_t) session->user->uid,
439 session->seat ? session->seat->id : "",
445 r = sd_bus_message_close_container(reply);
449 return sd_bus_send(NULL, reply, NULL);
452 static int method_list_users(sd_bus_message *message, void *userdata, sd_bus_error *error) {
453 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
454 Manager *m = userdata;
462 r = sd_bus_message_new_method_return(message, &reply);
466 r = sd_bus_message_open_container(reply, 'a', "(uso)");
470 HASHMAP_FOREACH(user, m->users, i) {
471 _cleanup_free_ char *p = NULL;
473 p = user_bus_path(user);
477 r = sd_bus_message_append(reply, "(uso)",
478 (uint32_t) user->uid,
485 r = sd_bus_message_close_container(reply);
489 return sd_bus_send(NULL, reply, NULL);
492 static int method_list_seats(sd_bus_message *message, void *userdata, sd_bus_error *error) {
493 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
494 Manager *m = userdata;
502 r = sd_bus_message_new_method_return(message, &reply);
506 r = sd_bus_message_open_container(reply, 'a', "(so)");
510 HASHMAP_FOREACH(seat, m->seats, i) {
511 _cleanup_free_ char *p = NULL;
513 p = seat_bus_path(seat);
517 r = sd_bus_message_append(reply, "(so)", seat->id, p);
522 r = sd_bus_message_close_container(reply);
526 return sd_bus_send(NULL, reply, NULL);
529 static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
530 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
531 Manager *m = userdata;
532 Inhibitor *inhibitor;
539 r = sd_bus_message_new_method_return(message, &reply);
543 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
547 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
549 r = sd_bus_message_append(reply, "(ssssuu)",
550 strempty(inhibit_what_to_string(inhibitor->what)),
551 strempty(inhibitor->who),
552 strempty(inhibitor->why),
553 strempty(inhibit_mode_to_string(inhibitor->mode)),
554 (uint32_t) inhibitor->uid,
555 (uint32_t) inhibitor->pid);
560 r = sd_bus_message_close_container(reply);
564 return sd_bus_send(NULL, reply, NULL);
567 static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
568 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
569 uint32_t uid, leader, audit_id = 0;
570 _cleanup_free_ char *id = NULL;
571 Session *session = NULL;
572 Manager *m = userdata;
584 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
589 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
592 t = _SESSION_TYPE_INVALID;
594 t = session_type_from_string(type);
596 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
600 c = _SESSION_CLASS_INVALID;
602 c = session_class_from_string(class);
604 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
607 if (isempty(desktop))
610 if (!string_is_safe(desktop))
611 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
617 seat = hashmap_get(m->seats, cseat);
619 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
622 if (tty_is_vc(tty)) {
627 else if (seat != m->seat0)
628 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat->id);
630 v = vtnr_from_tty(tty);
632 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
636 else if (vtnr != (uint32_t) v)
637 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
639 } else if (tty_is_console(tty)) {
643 else if (seat != m->seat0)
644 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
647 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
651 if (seat_has_vts(seat)) {
652 if (!vtnr || vtnr > 63)
653 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
656 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
660 r = sd_bus_message_enter_container(message, 'a', "(sv)");
664 if (t == _SESSION_TYPE_INVALID) {
665 if (!isempty(display))
667 else if (!isempty(tty))
670 t = SESSION_UNSPECIFIED;
673 if (c == _SESSION_CLASS_INVALID) {
674 if (t == SESSION_UNSPECIFIED)
675 c = SESSION_BACKGROUND;
681 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
683 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
687 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
692 manager_get_session_by_pid(m, leader, &session);
693 if (!session && vtnr > 0 && vtnr < m->seat0->position_count) {
694 session = m->seat0->positions[vtnr];
696 * Old gdm and lightdm start the user-session on the same VT as
697 * the greeter session. But they destroy the greeter session
698 * after the user-session and want the user-session to take
699 * over the VT. We need to support this for
700 * backwards-compatibility, so make sure we allow new sessions
701 * on a VT that a greeter is running on.
703 if (session && session->class == SESSION_GREETER)
707 _cleanup_free_ char *path = NULL;
708 _cleanup_close_ int fifo_fd = -1;
710 /* Session already exists, client is probably
711 * something like "su" which changes uid but is still
712 * the same session */
714 fifo_fd = session_create_fifo(session);
718 path = session_bus_path(session);
722 log_debug("Sending reply about an existing session: "
723 "id=%s object_path=%s uid=%u runtime_path=%s "
724 "session_fd=%d seat=%s vtnr=%u",
727 (uint32_t) session->user->uid,
728 session->user->runtime_path,
730 session->seat ? session->seat->id : "",
731 (uint32_t) session->vtnr);
733 return sd_bus_reply_method_return(
737 session->user->runtime_path,
739 (uint32_t) session->user->uid,
740 session->seat ? session->seat->id : "",
741 (uint32_t) session->vtnr,
745 audit_session_from_pid(leader, &audit_id);
747 /* Keep our session IDs and the audit session IDs in sync */
749 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
752 /* Wut? There's already a session by this name and we
753 * didn't find it above? Weird, then let's not trust
754 * the audit data and let's better register a new
756 if (hashmap_get(m->sessions, id)) {
757 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
770 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
773 } while (hashmap_get(m->sessions, id));
776 r = manager_add_user_by_uid(m, uid, &user);
780 r = manager_add_session(m, id, &session);
784 session_set_user(session, user);
786 session->leader = leader;
787 session->audit_id = audit_id;
790 session->remote = remote;
791 session->vtnr = vtnr;
794 session->tty = strdup(tty);
801 if (!isempty(display)) {
802 session->display = strdup(display);
803 if (!session->display) {
809 if (!isempty(remote_user)) {
810 session->remote_user = strdup(remote_user);
811 if (!session->remote_user) {
817 if (!isempty(remote_host)) {
818 session->remote_host = strdup(remote_host);
819 if (!session->remote_host) {
825 if (!isempty(service)) {
826 session->service = strdup(service);
827 if (!session->service) {
833 if (!isempty(desktop)) {
834 session->desktop = strdup(desktop);
835 if (!session->desktop) {
842 r = seat_attach_session(seat, session);
847 r = session_start(session);
851 session->create_message = sd_bus_message_ref(message);
853 /* Now, let's wait until the slice unit and stuff got
854 * created. We send the reply back from
855 * session_send_create_reply(). */
861 session_add_to_gc_queue(session);
864 user_add_to_gc_queue(user);
869 static int method_release_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 r = session_release(session);
890 return sd_bus_reply_method_return(message, NULL);
893 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
894 Manager *m = userdata;
902 r = sd_bus_message_read(message, "s", &name);
906 r = manager_get_session_from_creds(m, message, name, error, &session);
910 return bus_session_method_activate(message, session, error);
913 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
914 const char *session_name, *seat_name;
915 Manager *m = userdata;
923 /* Same as ActivateSession() but refuses to work if
924 * the seat doesn't match */
926 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
930 r = manager_get_session_from_creds(m, message, session_name, error, &session);
934 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
938 if (session->seat != seat)
939 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
941 r = session_activate(session);
945 return sd_bus_reply_method_return(message, NULL);
948 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
949 Manager *m = userdata;
957 r = sd_bus_message_read(message, "s", &name);
961 r = manager_get_session_from_creds(m, message, name, error, &session);
965 return bus_session_method_lock(message, session, error);
968 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
969 Manager *m = userdata;
975 r = bus_verify_polkit_async(
978 "org.freedesktop.login1.lock-sessions",
986 return 1; /* Will call us back */
988 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
992 return sd_bus_reply_method_return(message, NULL);
995 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
997 Manager *m = userdata;
1004 r = sd_bus_message_read(message, "s", &name);
1008 r = manager_get_session_from_creds(m, message, name, error, &session);
1012 return bus_session_method_kill(message, session, error);
1015 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1016 Manager *m = userdata;
1024 r = sd_bus_message_read(message, "u", &uid);
1028 r = manager_get_user_from_creds(m, message, uid, error, &user);
1032 return bus_user_method_kill(message, user, error);
1035 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1036 Manager *m = userdata;
1044 r = sd_bus_message_read(message, "s", &name);
1048 r = manager_get_session_from_creds(m, message, name, error, &session);
1052 return bus_session_method_terminate(message, session, error);
1055 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1056 Manager *m = userdata;
1064 r = sd_bus_message_read(message, "u", &uid);
1068 r = manager_get_user_from_creds(m, message, uid, error, &user);
1072 return bus_user_method_terminate(message, user, error);
1075 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1076 Manager *m = userdata;
1084 r = sd_bus_message_read(message, "s", &name);
1088 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1092 return bus_seat_method_terminate(message, seat, error);
1095 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1096 _cleanup_free_ char *cc = NULL;
1097 Manager *m = userdata;
1107 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1111 if (uid == UID_INVALID) {
1112 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1114 /* Note that we get the owner UID of the session, not the actual client UID here! */
1115 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1119 r = sd_bus_creds_get_owner_uid(creds, &uid);
1127 return errno ? -errno : -ENOENT;
1129 r = bus_verify_polkit_async(
1132 "org.freedesktop.login1.set-user-linger",
1135 &m->polkit_registry,
1140 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1142 mkdir_p_label("/var/lib/systemd", 0755);
1144 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1148 cc = cescape(pw->pw_name);
1152 path = strjoina("/var/lib/systemd/linger/", cc);
1160 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1167 if (r < 0 && errno != ENOENT)
1170 u = hashmap_get(m->users, UID_TO_PTR(uid));
1172 user_add_to_gc_queue(u);
1175 return sd_bus_reply_method_return(message, NULL);
1178 static int trigger_device(Manager *m, struct udev_device *d) {
1179 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1180 struct udev_list_entry *first, *item;
1185 e = udev_enumerate_new(m->udev);
1190 r = udev_enumerate_add_match_parent(e, d);
1195 r = udev_enumerate_scan_devices(e);
1199 first = udev_enumerate_get_list_entry(e);
1200 udev_list_entry_foreach(item, first) {
1201 _cleanup_free_ char *t = NULL;
1204 p = udev_list_entry_get_name(item);
1206 t = strappend(p, "/uevent");
1210 write_string_file(t, "change", WRITE_STRING_FILE_CREATE);
1216 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1217 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1218 _cleanup_free_ char *rule = NULL, *file = NULL;
1219 const char *id_for_seat;
1226 d = udev_device_new_from_syspath(m->udev, sysfs);
1230 if (!udev_device_has_tag(d, "seat"))
1233 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1237 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1240 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1243 mkdir_p_label("/etc/udev/rules.d", 0755);
1244 mac_selinux_init("/etc");
1245 r = write_string_file_atomic_label(file, rule);
1249 return trigger_device(m, d);
1252 static int flush_devices(Manager *m) {
1253 _cleanup_closedir_ DIR *d;
1257 d = opendir("/etc/udev/rules.d");
1259 if (errno != ENOENT)
1260 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1264 while ((de = readdir(d))) {
1266 if (!dirent_is_file(de))
1269 if (!startswith(de->d_name, "72-seat-"))
1272 if (!endswith(de->d_name, ".rules"))
1275 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1276 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1280 return trigger_device(m, NULL);
1283 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1284 const char *sysfs, *seat;
1285 Manager *m = userdata;
1291 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1295 if (!path_startswith(sysfs, "/sys"))
1296 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1298 if (!seat_name_is_valid(seat))
1299 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1301 r = bus_verify_polkit_async(
1304 "org.freedesktop.login1.attach-device",
1307 &m->polkit_registry,
1312 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1314 r = attach_device(m, seat, sysfs);
1318 return sd_bus_reply_method_return(message, NULL);
1321 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1322 Manager *m = userdata;
1328 r = sd_bus_message_read(message, "b", &interactive);
1332 r = bus_verify_polkit_async(
1335 "org.freedesktop.login1.flush-devices",
1338 &m->polkit_registry,
1343 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1345 r = flush_devices(m);
1349 return sd_bus_reply_method_return(message, NULL);
1352 static int have_multiple_sessions(
1361 /* Check for other users' sessions. Greeter sessions do not
1362 * count, and non-login sessions do not count either. */
1363 HASHMAP_FOREACH(session, m->sessions, i)
1364 if (session->class == SESSION_USER &&
1365 session->user->uid != uid)
1371 static int bus_manager_log_shutdown(
1374 const char *unit_name) {
1381 if (w != INHIBIT_SHUTDOWN)
1384 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1385 p = "MESSAGE=System is powering down.";
1386 q = "SHUTDOWN=power-off";
1387 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1388 p = "MESSAGE=System is halting.";
1389 q = "SHUTDOWN=halt";
1390 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1391 p = "MESSAGE=System is rebooting.";
1392 q = "SHUTDOWN=reboot";
1393 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1394 p = "MESSAGE=System is rebooting with kexec.";
1395 q = "SHUTDOWN=kexec";
1397 p = "MESSAGE=System is shutting down.";
1401 return log_struct(LOG_NOTICE,
1402 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1408 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1409 Manager *m = userdata;
1414 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1418 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1423 if (until <= now(CLOCK_MONOTONIC))
1426 /* We want to ignore the lid switch for a while after each
1427 * suspend, and after boot-up. Hence let's install a timer for
1428 * this. As long as the event source exists we ignore the lid
1431 if (m->lid_switch_ignore_event_source) {
1434 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1441 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1443 r = sd_event_add_time(
1445 &m->lid_switch_ignore_event_source,
1448 lid_switch_ignore_handler, m);
1453 static int execute_shutdown_or_sleep(
1456 const char *unit_name,
1457 sd_bus_error *error) {
1459 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1466 assert(w < _INHIBIT_WHAT_MAX);
1469 bus_manager_log_shutdown(m, w, unit_name);
1471 r = sd_bus_call_method(
1473 "org.freedesktop.systemd1",
1474 "/org/freedesktop/systemd1",
1475 "org.freedesktop.systemd1.Manager",
1479 "ss", unit_name, "replace-irreversibly");
1483 r = sd_bus_message_read(reply, "o", &p);
1491 m->action_unit = unit_name;
1492 free(m->action_job);
1496 /* Make sure the lid switch is ignored for a while */
1497 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1502 int manager_dispatch_delayed(Manager *manager, bool timeout) {
1504 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1505 Inhibitor *offending = NULL;
1510 if (manager->action_what == 0 || manager->action_job)
1513 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1514 _cleanup_free_ char *comm = NULL, *u = NULL;
1519 (void) get_process_comm(offending->pid, &comm);
1520 u = uid_to_name(offending->uid);
1522 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1523 offending->uid, strna(u),
1524 offending->pid, strna(comm));
1527 /* Actually do the operation */
1528 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
1530 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1532 manager->action_unit = NULL;
1533 manager->action_what = 0;
1540 static int manager_inhibit_timeout_handler(
1545 Manager *manager = userdata;
1549 assert(manager->inhibit_timeout_source == s);
1551 r = manager_dispatch_delayed(manager, true);
1552 return (r < 0) ? r : 0;
1555 static int delay_shutdown_or_sleep(
1558 const char *unit_name) {
1565 assert(w < _INHIBIT_WHAT_MAX);
1568 timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1570 if (m->inhibit_timeout_source) {
1571 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1573 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1575 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1577 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1579 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1580 timeout_val, 0, manager_inhibit_timeout_handler, m);
1585 m->action_unit = unit_name;
1591 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1593 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1594 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1595 [INHIBIT_SLEEP] = "PrepareForSleep"
1598 int active = _active;
1602 assert(w < _INHIBIT_WHAT_MAX);
1603 assert(signal_name[w]);
1605 return sd_bus_emit_signal(m->bus,
1606 "/org/freedesktop/login1",
1607 "org.freedesktop.login1.Manager",
1613 int bus_manager_shutdown_or_sleep_now_or_later(
1615 const char *unit_name,
1617 sd_bus_error *error) {
1625 assert(w <= _INHIBIT_WHAT_MAX);
1626 assert(!m->action_job);
1628 /* Tell everybody to prepare for shutdown/sleep */
1629 send_prepare_for(m, w, true);
1632 m->inhibit_delay_max > 0 &&
1633 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1636 /* Shutdown is delayed, keep in mind what we
1637 * want to do, and start a timeout */
1638 r = delay_shutdown_or_sleep(m, w, unit_name);
1640 /* Shutdown is not delayed, execute it
1642 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1647 static int verify_shutdown_creds(
1649 sd_bus_message *message,
1653 const char *action_multiple_sessions,
1654 const char *action_ignore_inhibit,
1655 sd_bus_error *error) {
1657 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1658 bool multiple_sessions, blocked;
1665 assert(w <= _INHIBIT_WHAT_MAX);
1667 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1671 r = sd_bus_creds_get_euid(creds, &uid);
1675 r = have_multiple_sessions(m, uid);
1679 multiple_sessions = r > 0;
1680 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1682 if (multiple_sessions && action_multiple_sessions) {
1683 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1687 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1690 if (blocked && action_ignore_inhibit) {
1691 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1695 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1698 if (!multiple_sessions && !blocked && action) {
1699 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1703 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1709 static int method_do_shutdown_or_sleep(
1711 sd_bus_message *message,
1712 const char *unit_name,
1715 const char *action_multiple_sessions,
1716 const char *action_ignore_inhibit,
1717 const char *sleep_verb,
1718 sd_bus_error *error) {
1726 assert(w <= _INHIBIT_WHAT_MAX);
1728 r = sd_bus_message_read(message, "b", &interactive);
1732 /* Don't allow multiple jobs being executed at the same time */
1734 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1737 r = can_sleep(sleep_verb);
1742 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1745 r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1746 action_ignore_inhibit, error);
1750 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1754 return sd_bus_reply_method_return(message, NULL);
1757 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1758 Manager *m = userdata;
1760 return method_do_shutdown_or_sleep(
1762 SPECIAL_POWEROFF_TARGET,
1764 "org.freedesktop.login1.power-off",
1765 "org.freedesktop.login1.power-off-multiple-sessions",
1766 "org.freedesktop.login1.power-off-ignore-inhibit",
1771 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1772 Manager *m = userdata;
1774 return method_do_shutdown_or_sleep(
1776 SPECIAL_REBOOT_TARGET,
1778 "org.freedesktop.login1.reboot",
1779 "org.freedesktop.login1.reboot-multiple-sessions",
1780 "org.freedesktop.login1.reboot-ignore-inhibit",
1785 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1786 Manager *m = userdata;
1788 return method_do_shutdown_or_sleep(
1790 SPECIAL_SUSPEND_TARGET,
1792 "org.freedesktop.login1.suspend",
1793 "org.freedesktop.login1.suspend-multiple-sessions",
1794 "org.freedesktop.login1.suspend-ignore-inhibit",
1799 static int nologin_timeout_handler(
1804 Manager *m = userdata;
1807 log_info("Creating /run/nologin, blocking further logins...");
1809 r = write_string_file("/run/nologin", "System is going down.", WRITE_STRING_FILE_ATOMIC);
1811 log_error_errno(r, "Failed to create /run/nologin: %m");
1813 m->unlink_nologin = true;
1818 static int update_schedule_file(Manager *m) {
1821 _cleanup_fclose_ FILE *f = NULL;
1822 _cleanup_free_ char *t = NULL, *temp_path = NULL;
1826 r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1828 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1830 t = cescape(m->wall_message);
1834 r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1836 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1838 (void) fchmod(fileno(f), 0644);
1844 m->scheduled_shutdown_timeout,
1845 m->enable_wall_messages,
1846 m->scheduled_shutdown_type);
1848 if (!isempty(m->wall_message))
1849 fprintf(f, "WALL_MESSAGE=%s\n", t);
1851 (void) fflush_and_check(f);
1853 if (ferror(f) || rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1854 log_error_errno(errno, "Failed to write information about scheduled shutdowns: %m");
1857 (void) unlink(temp_path);
1858 (void) unlink("/run/systemd/shutdown/scheduled");
1864 static int manager_scheduled_shutdown_handler(
1869 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1870 Manager *m = userdata;
1876 if (isempty(m->scheduled_shutdown_type))
1879 if (streq(m->scheduled_shutdown_type, "halt"))
1880 target = SPECIAL_HALT_TARGET;
1881 else if (streq(m->scheduled_shutdown_type, "poweroff"))
1882 target = SPECIAL_POWEROFF_TARGET;
1884 target = SPECIAL_REBOOT_TARGET;
1886 r = execute_shutdown_or_sleep(m, 0, target, &error);
1888 return log_error_errno(r, "Unable to execute transition to %s: %m", target);
1893 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1894 Manager *m = userdata;
1895 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1896 const char *action_multiple_sessions = NULL;
1897 const char *action_ignore_inhibit = NULL;
1898 const char *action = NULL;
1906 r = sd_bus_message_read(message, "st", &type, &elapse);
1910 if (streq(type, "reboot")) {
1911 action = "org.freedesktop.login1.reboot";
1912 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1913 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1914 } else if (streq(type, "halt")) {
1915 action = "org.freedesktop.login1.halt";
1916 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1917 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1918 } else if (streq(type, "poweroff")) {
1919 action = "org.freedesktop.login1.poweroff";
1920 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1921 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1923 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1925 r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1926 action, action_multiple_sessions, action_ignore_inhibit, error);
1930 if (m->scheduled_shutdown_timeout_source) {
1931 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1933 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1935 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1937 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1939 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1940 CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1942 return log_error_errno(r, "sd_event_add_time() failed: %m");
1945 r = free_and_strdup(&m->scheduled_shutdown_type, type);
1947 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1951 if (m->nologin_timeout_source) {
1952 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1954 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1956 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1958 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1960 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1961 CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1963 return log_error_errno(r, "sd_event_add_time() failed: %m");
1966 m->scheduled_shutdown_timeout = elapse;
1968 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1972 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1973 (void) sd_bus_creds_get_tty(creds, &tty);
1975 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1977 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1982 r = manager_setup_wall_message_timer(m);
1986 if (!isempty(type)) {
1987 r = update_schedule_file(m);
1991 (void) unlink("/run/systemd/shutdown/scheduled");
1993 return sd_bus_reply_method_return(message, NULL);
1996 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1997 Manager *m = userdata;
2003 cancelled = m->scheduled_shutdown_type != NULL;
2005 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
2006 m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
2007 m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
2008 free(m->scheduled_shutdown_type);
2009 m->scheduled_shutdown_type = NULL;
2010 m->scheduled_shutdown_timeout = 0;
2012 if (m->unlink_nologin) {
2013 (void) unlink("/run/nologin");
2014 m->unlink_nologin = false;
2018 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2019 const char *tty = NULL;
2023 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
2025 (void) sd_bus_creds_get_uid(creds, &uid);
2026 (void) sd_bus_creds_get_tty(creds, &tty);
2029 utmp_wall("The system shutdown has been cancelled",
2030 lookup_uid(uid), tty, logind_wall_tty_filter, m);
2033 return sd_bus_reply_method_return(message, "b", cancelled);
2036 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2037 Manager *m = userdata;
2039 return method_do_shutdown_or_sleep(
2041 SPECIAL_HIBERNATE_TARGET,
2043 "org.freedesktop.login1.hibernate",
2044 "org.freedesktop.login1.hibernate-multiple-sessions",
2045 "org.freedesktop.login1.hibernate-ignore-inhibit",
2050 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2051 Manager *m = userdata;
2053 return method_do_shutdown_or_sleep(
2055 SPECIAL_HYBRID_SLEEP_TARGET,
2057 "org.freedesktop.login1.hibernate",
2058 "org.freedesktop.login1.hibernate-multiple-sessions",
2059 "org.freedesktop.login1.hibernate-ignore-inhibit",
2064 static int method_can_shutdown_or_sleep(
2066 sd_bus_message *message,
2069 const char *action_multiple_sessions,
2070 const char *action_ignore_inhibit,
2071 const char *sleep_verb,
2072 sd_bus_error *error) {
2074 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2075 bool multiple_sessions, challenge, blocked;
2076 const char *result = NULL;
2083 assert(w <= _INHIBIT_WHAT_MAX);
2085 assert(action_multiple_sessions);
2086 assert(action_ignore_inhibit);
2089 r = can_sleep(sleep_verb);
2093 return sd_bus_reply_method_return(message, "s", "na");
2096 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2100 r = sd_bus_creds_get_euid(creds, &uid);
2104 r = have_multiple_sessions(m, uid);
2108 multiple_sessions = r > 0;
2109 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2111 if (multiple_sessions) {
2112 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
2119 result = "challenge";
2125 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
2129 if (r > 0 && !result)
2131 else if (challenge && (!result || streq(result, "yes")))
2132 result = "challenge";
2137 if (!multiple_sessions && !blocked) {
2138 /* If neither inhibit nor multiple sessions
2139 * apply then just check the normal policy */
2141 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
2148 result = "challenge";
2153 return sd_bus_reply_method_return(message, "s", result);
2156 static int method_can_poweroff(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.power-off",
2163 "org.freedesktop.login1.power-off-multiple-sessions",
2164 "org.freedesktop.login1.power-off-ignore-inhibit",
2169 static int method_can_reboot(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.reboot",
2176 "org.freedesktop.login1.reboot-multiple-sessions",
2177 "org.freedesktop.login1.reboot-ignore-inhibit",
2182 static int method_can_suspend(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.suspend",
2189 "org.freedesktop.login1.suspend-multiple-sessions",
2190 "org.freedesktop.login1.suspend-ignore-inhibit",
2195 static int method_can_hibernate(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 method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2209 Manager *m = userdata;
2211 return method_can_shutdown_or_sleep(
2214 "org.freedesktop.login1.hibernate",
2215 "org.freedesktop.login1.hibernate-multiple-sessions",
2216 "org.freedesktop.login1.hibernate-ignore-inhibit",
2221 static int property_get_reboot_to_firmware_setup(
2224 const char *interface,
2225 const char *property,
2226 sd_bus_message *reply,
2228 sd_bus_error *error) {
2235 r = efi_get_reboot_to_firmware();
2236 if (r < 0 && r != -EOPNOTSUPP)
2239 return sd_bus_message_append(reply, "b", r > 0);
2242 static int method_set_reboot_to_firmware_setup(
2243 sd_bus_message *message,
2245 sd_bus_error *error) {
2248 Manager *m = userdata;
2253 r = sd_bus_message_read(message, "b", &b);
2257 r = bus_verify_polkit_async(message,
2259 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2262 &m->polkit_registry,
2267 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2269 r = efi_set_reboot_to_firmware(b);
2273 return sd_bus_reply_method_return(message, NULL);
2276 static int method_can_reboot_to_firmware_setup(
2277 sd_bus_message *message,
2279 sd_bus_error *error) {
2284 Manager *m = userdata;
2289 r = efi_reboot_to_firmware_supported();
2290 if (r == -EOPNOTSUPP)
2291 return sd_bus_reply_method_return(message, "s", "na");
2295 r = bus_test_polkit(message,
2297 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2307 result = "challenge";
2311 return sd_bus_reply_method_return(message, "s", result);
2314 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2315 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2316 const char *who, *why, *what, *mode;
2317 _cleanup_free_ char *id = NULL;
2318 _cleanup_close_ int fifo_fd = -1;
2319 Manager *m = userdata;
2320 Inhibitor *i = NULL;
2330 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2334 w = inhibit_what_from_string(what);
2336 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2338 mm = inhibit_mode_from_string(mode);
2340 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2342 /* Delay is only supported for shutdown/sleep */
2343 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2344 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2346 /* Don't allow taking delay locks while we are already
2347 * executing the operation. We shouldn't create the impression
2348 * that the lock was successful if the machine is about to go
2349 * down/suspend any moment. */
2350 if (m->action_what & w)
2351 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2353 r = bus_verify_polkit_async(
2356 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2357 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2358 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
2359 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
2360 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2361 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2362 "org.freedesktop.login1.inhibit-handle-lid-switch",
2365 &m->polkit_registry,
2370 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2372 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2376 r = sd_bus_creds_get_euid(creds, &uid);
2380 r = sd_bus_creds_get_pid(creds, &pid);
2388 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2391 } while (hashmap_get(m->inhibitors, id));
2393 r = manager_add_inhibitor(m, id, &i);
2401 i->why = strdup(why);
2402 i->who = strdup(who);
2404 if (!i->why || !i->who) {
2409 fifo_fd = inhibitor_create_fifo(i);
2417 return sd_bus_reply_method_return(message, "h", fifo_fd);
2426 const sd_bus_vtable manager_vtable[] = {
2427 SD_BUS_VTABLE_START(0),
2429 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2430 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2432 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2433 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2434 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2435 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2436 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2437 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2438 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2439 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2440 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2441 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2442 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2443 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2444 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2445 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2446 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2447 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2448 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2449 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2450 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2451 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2452 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2453 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2454 SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
2456 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2457 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2458 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2459 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2460 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2461 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2462 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2463 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2464 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2465 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2466 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2467 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2468 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2469 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2470 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2471 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2472 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2473 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2474 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2475 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2476 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2477 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2478 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2479 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2480 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2481 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2482 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2483 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2484 SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2485 SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2486 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2487 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2488 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2489 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2490 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2491 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2492 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2493 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2494 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2495 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2497 SD_BUS_SIGNAL("SessionNew", "so", 0),
2498 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2499 SD_BUS_SIGNAL("UserNew", "uo", 0),
2500 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2501 SD_BUS_SIGNAL("SeatNew", "so", 0),
2502 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2503 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2504 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2509 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2518 if (streq(result, "done"))
2519 r = session_send_create_reply(s, NULL);
2521 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2523 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2524 r = session_send_create_reply(s, &e);
2530 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2531 const char *path, *result, *unit;
2532 Manager *m = userdata;
2541 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2543 bus_log_parse_error(r);
2547 if (m->action_job && streq(m->action_job, path)) {
2548 log_info("Operation finished.");
2550 /* Tell people that they now may take a lock again */
2551 send_prepare_for(m, m->action_what, false);
2553 free(m->action_job);
2554 m->action_job = NULL;
2555 m->action_unit = NULL;
2560 session = hashmap_get(m->session_units, unit);
2563 if (streq_ptr(path, session->scope_job)) {
2564 free(session->scope_job);
2565 session->scope_job = NULL;
2568 session_jobs_reply(session, unit, result);
2570 session_save(session);
2571 user_save(session->user);
2572 session_add_to_gc_queue(session);
2575 user = hashmap_get(m->user_units, unit);
2578 if (streq_ptr(path, user->service_job)) {
2579 free(user->service_job);
2580 user->service_job = NULL;
2583 if (streq_ptr(path, user->slice_job)) {
2584 free(user->slice_job);
2585 user->slice_job = NULL;
2588 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2589 session_jobs_reply(session, unit, result);
2593 user_add_to_gc_queue(user);
2599 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2600 const char *path, *unit;
2601 Manager *m = userdata;
2609 r = sd_bus_message_read(message, "so", &unit, &path);
2611 bus_log_parse_error(r);
2615 session = hashmap_get(m->session_units, unit);
2617 session_add_to_gc_queue(session);
2619 user = hashmap_get(m->user_units, unit);
2621 user_add_to_gc_queue(user);
2626 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2627 _cleanup_free_ char *unit = NULL;
2628 Manager *m = userdata;
2637 path = sd_bus_message_get_path(message);
2641 r = unit_name_from_dbus_path(path, &unit);
2642 if (r == -EINVAL) /* not a unit */
2647 session = hashmap_get(m->session_units, unit);
2649 session_add_to_gc_queue(session);
2651 user = hashmap_get(m->user_units, unit);
2653 user_add_to_gc_queue(user);
2658 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2659 Manager *m = userdata;
2667 r = sd_bus_message_read(message, "b", &b);
2669 bus_log_parse_error(r);
2676 /* systemd finished reloading, let's recheck all our sessions */
2677 log_debug("System manager has been reloaded, rechecking sessions...");
2679 HASHMAP_FOREACH(session, m->sessions, i)
2680 session_add_to_gc_queue(session);
2685 int match_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2686 const char *name, *old, *new;
2687 Manager *m = userdata;
2696 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2698 bus_log_parse_error(r);
2702 if (isempty(old) || !isempty(new))
2705 key = set_remove(m->busnames, (char*) old);
2709 /* Drop all controllers owned by this name */
2713 HASHMAP_FOREACH(session, m->sessions, i)
2714 if (session_is_controller(session, old))
2715 session_drop_controller(session);
2720 int manager_send_changed(Manager *manager, const char *property, ...) {
2725 l = strv_from_stdarg_alloca(property);
2727 return sd_bus_emit_properties_changed_strv(
2729 "/org/freedesktop/login1",
2730 "org.freedesktop.login1.Manager",
2734 int manager_start_scope(
2739 const char *description,
2740 const char *after, const char *after2,
2741 sd_bus_error *error,
2744 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2751 r = sd_bus_message_new_method_call(
2754 "org.freedesktop.systemd1",
2755 "/org/freedesktop/systemd1",
2756 "org.freedesktop.systemd1.Manager",
2757 "StartTransientUnit");
2761 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2765 r = sd_bus_message_open_container(m, 'a', "(sv)");
2769 if (!isempty(slice)) {
2770 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2775 if (!isempty(description)) {
2776 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2781 if (!isempty(after)) {
2782 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2787 if (!isempty(after2)) {
2788 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2793 /* cgroup empty notification is not available in containers
2794 * currently. To make this less problematic, let's shorten the
2795 * stop timeout for sessions, so that we don't wait
2798 /* Make sure that the session shells are terminated with
2799 * SIGHUP since bash and friends tend to ignore SIGTERM */
2800 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2804 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2808 r = sd_bus_message_close_container(m);
2812 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2816 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2824 r = sd_bus_message_read(reply, "o", &j);
2838 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2839 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2845 r = sd_bus_call_method(
2847 "org.freedesktop.systemd1",
2848 "/org/freedesktop/systemd1",
2849 "org.freedesktop.systemd1.Manager",
2853 "ss", unit, "fail");
2861 r = sd_bus_message_read(reply, "o", &j);
2875 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2876 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2882 r = sd_bus_call_method(
2884 "org.freedesktop.systemd1",
2885 "/org/freedesktop/systemd1",
2886 "org.freedesktop.systemd1.Manager",
2890 "ss", unit, "fail");
2892 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2893 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2898 sd_bus_error_free(error);
2909 r = sd_bus_message_read(reply, "o", &j);
2923 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2924 _cleanup_free_ char *path = NULL;
2930 path = unit_dbus_path_from_name(scope);
2934 r = sd_bus_call_method(
2936 "org.freedesktop.systemd1",
2938 "org.freedesktop.systemd1.Scope",
2944 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2945 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2946 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2947 sd_bus_error_free(error);
2957 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2961 return sd_bus_call_method(
2963 "org.freedesktop.systemd1",
2964 "/org/freedesktop/systemd1",
2965 "org.freedesktop.systemd1.Manager",
2969 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2972 int manager_unit_is_active(Manager *manager, const char *unit) {
2973 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2974 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2975 _cleanup_free_ char *path = NULL;
2982 path = unit_dbus_path_from_name(unit);
2986 r = sd_bus_get_property(
2988 "org.freedesktop.systemd1",
2990 "org.freedesktop.systemd1.Unit",
2996 /* systemd might have droppped off momentarily, let's
2997 * not make this an error */
2998 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2999 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3002 /* If the unit is already unloaded then it's not
3004 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
3005 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
3011 r = sd_bus_message_read(reply, "s", &state);
3015 return !streq(state, "inactive") && !streq(state, "failed");
3018 int manager_job_is_active(Manager *manager, const char *path) {
3019 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3020 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3026 r = sd_bus_get_property(
3028 "org.freedesktop.systemd1",
3030 "org.freedesktop.systemd1.Job",
3036 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3037 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3040 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3046 /* We don't actually care about the state really. The fact
3047 * that we could read the job state is enough for us */