1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include "sd-messages.h"
30 #include "path-util.h"
32 #include "sleep-config.h"
33 #include "fileio-label.h"
34 #include "unit-name.h"
37 #include "bus-error.h"
38 #include "bus-common-errors.h"
39 #include "udev-util.h"
40 #include "selinux-util.h"
43 #include "formats-util.h"
44 #include "process-util.h"
45 #include "terminal-util.h"
46 #include "utmp-wtmp.h"
48 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
49 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
58 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
62 r = sd_bus_creds_get_session(creds, &name);
67 session = hashmap_get(m->sessions, name);
69 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
75 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
83 if (uid == UID_INVALID) {
84 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
86 /* Note that we get the owner UID of the session, not the actual client UID here! */
87 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
91 r = sd_bus_creds_get_owner_uid(creds, &uid);
96 user = hashmap_get(m->users, UID_TO_PTR(uid));
98 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
104 int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
115 r = manager_get_session_from_creds(m, message, NULL, error, &session);
119 seat = session->seat;
122 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
124 seat = hashmap_get(m->seats, name);
126 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
133 static int property_get_idle_hint(
136 const char *interface,
137 const char *property,
138 sd_bus_message *reply,
140 sd_bus_error *error) {
142 Manager *m = userdata;
148 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
151 static int property_get_idle_since_hint(
154 const char *interface,
155 const char *property,
156 sd_bus_message *reply,
158 sd_bus_error *error) {
160 Manager *m = userdata;
161 dual_timestamp t = DUAL_TIMESTAMP_NULL;
167 manager_get_idle_hint(m, &t);
169 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
172 static int property_get_inhibited(
175 const char *interface,
176 const char *property,
177 sd_bus_message *reply,
179 sd_bus_error *error) {
181 Manager *m = userdata;
188 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
190 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
193 static int property_get_preparing(
196 const char *interface,
197 const char *property,
198 sd_bus_message *reply,
200 sd_bus_error *error) {
202 Manager *m = userdata;
209 if (streq(property, "PreparingForShutdown"))
210 b = !!(m->action_what & INHIBIT_SHUTDOWN);
212 b = !!(m->action_what & INHIBIT_SLEEP);
214 return sd_bus_message_append(reply, "b", b);
217 static int property_get_scheduled_shutdown(
220 const char *interface,
221 const char *property,
222 sd_bus_message *reply,
224 sd_bus_error *error) {
226 Manager *m = userdata;
233 r = sd_bus_message_open_container(reply, 'r', "st");
237 r = sd_bus_message_append(reply, "st", m->scheduled_shutdown_type, m->scheduled_shutdown_timeout);
241 return sd_bus_message_close_container(reply);
244 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
246 static int property_get_docked(
249 const char *interface,
250 const char *property,
251 sd_bus_message *reply,
253 sd_bus_error *error) {
255 Manager *m = userdata;
261 return sd_bus_message_append(reply, "b", manager_is_docked_or_external_displays(m));
264 static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
265 _cleanup_free_ char *p = NULL;
266 Manager *m = userdata;
274 r = sd_bus_message_read(message, "s", &name);
278 r = manager_get_session_from_creds(m, message, name, error, &session);
282 p = session_bus_path(session);
286 return sd_bus_reply_method_return(message, "o", p);
289 static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
290 _cleanup_free_ char *p = NULL;
291 Session *session = NULL;
292 Manager *m = userdata;
299 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
301 r = sd_bus_message_read(message, "u", &pid);
306 r = manager_get_session_from_creds(m, message, NULL, error, &session);
310 r = manager_get_session_by_pid(m, pid, &session);
315 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
318 p = session_bus_path(session);
322 return sd_bus_reply_method_return(message, "o", p);
325 static int method_get_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
326 _cleanup_free_ char *p = NULL;
327 Manager *m = userdata;
335 r = sd_bus_message_read(message, "u", &uid);
339 r = manager_get_user_from_creds(m, message, uid, error, &user);
343 p = user_bus_path(user);
347 return sd_bus_reply_method_return(message, "o", p);
350 static int method_get_user_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
351 _cleanup_free_ char *p = NULL;
352 Manager *m = userdata;
360 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
362 r = sd_bus_message_read(message, "u", &pid);
367 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
371 r = manager_get_user_by_pid(m, pid, &user);
375 return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID "PID_FMT" does not belong to any known or logged in user", pid);
378 p = user_bus_path(user);
382 return sd_bus_reply_method_return(message, "o", p);
385 static int method_get_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
386 _cleanup_free_ char *p = NULL;
387 Manager *m = userdata;
395 r = sd_bus_message_read(message, "s", &name);
399 r = manager_get_seat_from_creds(m, message, name, error, &seat);
403 p = seat_bus_path(seat);
407 return sd_bus_reply_method_return(message, "o", p);
410 static int method_list_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
411 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
412 Manager *m = userdata;
420 r = sd_bus_message_new_method_return(message, &reply);
424 r = sd_bus_message_open_container(reply, 'a', "(susso)");
428 HASHMAP_FOREACH(session, m->sessions, i) {
429 _cleanup_free_ char *p = NULL;
431 p = session_bus_path(session);
435 r = sd_bus_message_append(reply, "(susso)",
437 (uint32_t) session->user->uid,
439 session->seat ? session->seat->id : "",
445 r = sd_bus_message_close_container(reply);
449 return sd_bus_send(NULL, reply, NULL);
452 static int method_list_users(sd_bus_message *message, void *userdata, sd_bus_error *error) {
453 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
454 Manager *m = userdata;
462 r = sd_bus_message_new_method_return(message, &reply);
466 r = sd_bus_message_open_container(reply, 'a', "(uso)");
470 HASHMAP_FOREACH(user, m->users, i) {
471 _cleanup_free_ char *p = NULL;
473 p = user_bus_path(user);
477 r = sd_bus_message_append(reply, "(uso)",
478 (uint32_t) user->uid,
485 r = sd_bus_message_close_container(reply);
489 return sd_bus_send(NULL, reply, NULL);
492 static int method_list_seats(sd_bus_message *message, void *userdata, sd_bus_error *error) {
493 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
494 Manager *m = userdata;
502 r = sd_bus_message_new_method_return(message, &reply);
506 r = sd_bus_message_open_container(reply, 'a', "(so)");
510 HASHMAP_FOREACH(seat, m->seats, i) {
511 _cleanup_free_ char *p = NULL;
513 p = seat_bus_path(seat);
517 r = sd_bus_message_append(reply, "(so)", seat->id, p);
522 r = sd_bus_message_close_container(reply);
526 return sd_bus_send(NULL, reply, NULL);
529 static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
530 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
531 Manager *m = userdata;
532 Inhibitor *inhibitor;
539 r = sd_bus_message_new_method_return(message, &reply);
543 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
547 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
549 r = sd_bus_message_append(reply, "(ssssuu)",
550 strempty(inhibit_what_to_string(inhibitor->what)),
551 strempty(inhibitor->who),
552 strempty(inhibitor->why),
553 strempty(inhibit_mode_to_string(inhibitor->mode)),
554 (uint32_t) inhibitor->uid,
555 (uint32_t) inhibitor->pid);
560 r = sd_bus_message_close_container(reply);
564 return sd_bus_send(NULL, reply, NULL);
567 static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
568 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
569 uint32_t uid, leader, audit_id = 0;
570 _cleanup_free_ char *id = NULL;
571 Session *session = NULL;
572 Manager *m = userdata;
584 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
589 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
592 t = _SESSION_TYPE_INVALID;
594 t = session_type_from_string(type);
596 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
600 c = _SESSION_CLASS_INVALID;
602 c = session_class_from_string(class);
604 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
607 if (isempty(desktop))
610 if (!string_is_safe(desktop))
611 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
617 seat = hashmap_get(m->seats, cseat);
619 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
622 if (tty_is_vc(tty)) {
627 else if (seat != m->seat0)
628 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat->id);
630 v = vtnr_from_tty(tty);
632 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
636 else if (vtnr != (uint32_t) v)
637 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
639 } else if (tty_is_console(tty)) {
643 else if (seat != m->seat0)
644 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
647 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
651 if (seat_has_vts(seat)) {
652 if (!vtnr || vtnr > 63)
653 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
656 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
660 r = sd_bus_message_enter_container(message, 'a', "(sv)");
664 if (t == _SESSION_TYPE_INVALID) {
665 if (!isempty(display))
667 else if (!isempty(tty))
670 t = SESSION_UNSPECIFIED;
673 if (c == _SESSION_CLASS_INVALID) {
674 if (t == SESSION_UNSPECIFIED)
675 c = SESSION_BACKGROUND;
681 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
683 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
687 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
692 r = manager_get_session_by_pid(m, leader, NULL);
694 return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session");
697 * Old gdm and lightdm start the user-session on the same VT as
698 * the greeter session. But they destroy the greeter session
699 * after the user-session and want the user-session to take
700 * over the VT. We need to support this for
701 * backwards-compatibility, so make sure we allow new sessions
702 * on a VT that a greeter is running on. Furthermore, to allow
703 * re-logins, we have to allow a greeter to take over a used VT for
704 * the exact same reasons.
706 if (c != SESSION_GREETER &&
708 vtnr < m->seat0->position_count &&
709 m->seat0->positions[vtnr] &&
710 m->seat0->positions[vtnr]->class != SESSION_GREETER)
711 return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session");
713 audit_session_from_pid(leader, &audit_id);
715 /* Keep our session IDs and the audit session IDs in sync */
717 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
720 /* Wut? There's already a session by this name and we
721 * didn't find it above? Weird, then let's not trust
722 * the audit data and let's better register a new
724 if (hashmap_get(m->sessions, id)) {
725 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
738 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
741 } while (hashmap_get(m->sessions, id));
744 r = manager_add_user_by_uid(m, uid, &user);
748 r = manager_add_session(m, id, &session);
752 session_set_user(session, user);
754 session->leader = leader;
755 session->audit_id = audit_id;
758 session->remote = remote;
759 session->vtnr = vtnr;
762 session->tty = strdup(tty);
769 if (!isempty(display)) {
770 session->display = strdup(display);
771 if (!session->display) {
777 if (!isempty(remote_user)) {
778 session->remote_user = strdup(remote_user);
779 if (!session->remote_user) {
785 if (!isempty(remote_host)) {
786 session->remote_host = strdup(remote_host);
787 if (!session->remote_host) {
793 if (!isempty(service)) {
794 session->service = strdup(service);
795 if (!session->service) {
801 if (!isempty(desktop)) {
802 session->desktop = strdup(desktop);
803 if (!session->desktop) {
810 r = seat_attach_session(seat, session);
815 r = session_start(session);
819 session->create_message = sd_bus_message_ref(message);
821 /* Now, let's wait until the slice unit and stuff got
822 * created. We send the reply back from
823 * session_send_create_reply(). */
829 session_add_to_gc_queue(session);
832 user_add_to_gc_queue(user);
837 static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
838 Manager *m = userdata;
846 r = sd_bus_message_read(message, "s", &name);
850 r = manager_get_session_from_creds(m, message, name, error, &session);
854 r = session_release(session);
858 return sd_bus_reply_method_return(message, NULL);
861 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
862 Manager *m = userdata;
870 r = sd_bus_message_read(message, "s", &name);
874 r = manager_get_session_from_creds(m, message, name, error, &session);
878 return bus_session_method_activate(message, session, error);
881 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
882 const char *session_name, *seat_name;
883 Manager *m = userdata;
891 /* Same as ActivateSession() but refuses to work if
892 * the seat doesn't match */
894 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
898 r = manager_get_session_from_creds(m, message, session_name, error, &session);
902 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
906 if (session->seat != seat)
907 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
909 r = session_activate(session);
913 return sd_bus_reply_method_return(message, NULL);
916 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
917 Manager *m = userdata;
925 r = sd_bus_message_read(message, "s", &name);
929 r = manager_get_session_from_creds(m, message, name, error, &session);
933 return bus_session_method_lock(message, session, error);
936 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
937 Manager *m = userdata;
943 r = bus_verify_polkit_async(
946 "org.freedesktop.login1.lock-sessions",
954 return 1; /* Will call us back */
956 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
960 return sd_bus_reply_method_return(message, NULL);
963 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
965 Manager *m = userdata;
972 r = sd_bus_message_read(message, "s", &name);
976 r = manager_get_session_from_creds(m, message, name, error, &session);
980 return bus_session_method_kill(message, session, error);
983 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
984 Manager *m = userdata;
992 r = sd_bus_message_read(message, "u", &uid);
996 r = manager_get_user_from_creds(m, message, uid, error, &user);
1000 return bus_user_method_kill(message, user, error);
1003 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1004 Manager *m = userdata;
1012 r = sd_bus_message_read(message, "s", &name);
1016 r = manager_get_session_from_creds(m, message, name, error, &session);
1020 return bus_session_method_terminate(message, session, error);
1023 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1024 Manager *m = userdata;
1032 r = sd_bus_message_read(message, "u", &uid);
1036 r = manager_get_user_from_creds(m, message, uid, error, &user);
1040 return bus_user_method_terminate(message, user, error);
1043 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1044 Manager *m = userdata;
1052 r = sd_bus_message_read(message, "s", &name);
1056 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1060 return bus_seat_method_terminate(message, seat, error);
1063 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1064 _cleanup_free_ char *cc = NULL;
1065 Manager *m = userdata;
1075 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1079 if (uid == UID_INVALID) {
1080 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1082 /* Note that we get the owner UID of the session, not the actual client UID here! */
1083 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1087 r = sd_bus_creds_get_owner_uid(creds, &uid);
1095 return errno ? -errno : -ENOENT;
1097 r = bus_verify_polkit_async(
1100 "org.freedesktop.login1.set-user-linger",
1103 &m->polkit_registry,
1108 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1110 mkdir_p_label("/var/lib/systemd", 0755);
1112 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1116 cc = cescape(pw->pw_name);
1120 path = strjoina("/var/lib/systemd/linger/", cc);
1128 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1135 if (r < 0 && errno != ENOENT)
1138 u = hashmap_get(m->users, UID_TO_PTR(uid));
1140 user_add_to_gc_queue(u);
1143 return sd_bus_reply_method_return(message, NULL);
1146 static int trigger_device(Manager *m, struct udev_device *d) {
1147 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1148 struct udev_list_entry *first, *item;
1153 e = udev_enumerate_new(m->udev);
1158 r = udev_enumerate_add_match_parent(e, d);
1163 r = udev_enumerate_scan_devices(e);
1167 first = udev_enumerate_get_list_entry(e);
1168 udev_list_entry_foreach(item, first) {
1169 _cleanup_free_ char *t = NULL;
1172 p = udev_list_entry_get_name(item);
1174 t = strappend(p, "/uevent");
1178 write_string_file(t, "change", WRITE_STRING_FILE_CREATE);
1184 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1185 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1186 _cleanup_free_ char *rule = NULL, *file = NULL;
1187 const char *id_for_seat;
1194 d = udev_device_new_from_syspath(m->udev, sysfs);
1198 if (!udev_device_has_tag(d, "seat"))
1201 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1205 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1208 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1211 mkdir_p_label("/etc/udev/rules.d", 0755);
1212 mac_selinux_init("/etc");
1213 r = write_string_file_atomic_label(file, rule);
1217 return trigger_device(m, d);
1220 static int flush_devices(Manager *m) {
1221 _cleanup_closedir_ DIR *d;
1225 d = opendir("/etc/udev/rules.d");
1227 if (errno != ENOENT)
1228 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1232 while ((de = readdir(d))) {
1234 if (!dirent_is_file(de))
1237 if (!startswith(de->d_name, "72-seat-"))
1240 if (!endswith(de->d_name, ".rules"))
1243 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1244 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1248 return trigger_device(m, NULL);
1251 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1252 const char *sysfs, *seat;
1253 Manager *m = userdata;
1259 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1263 if (!path_startswith(sysfs, "/sys"))
1264 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1266 if (!seat_name_is_valid(seat))
1267 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1269 r = bus_verify_polkit_async(
1272 "org.freedesktop.login1.attach-device",
1275 &m->polkit_registry,
1280 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1282 r = attach_device(m, seat, sysfs);
1286 return sd_bus_reply_method_return(message, NULL);
1289 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1290 Manager *m = userdata;
1296 r = sd_bus_message_read(message, "b", &interactive);
1300 r = bus_verify_polkit_async(
1303 "org.freedesktop.login1.flush-devices",
1306 &m->polkit_registry,
1311 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1313 r = flush_devices(m);
1317 return sd_bus_reply_method_return(message, NULL);
1320 static int have_multiple_sessions(
1329 /* Check for other users' sessions. Greeter sessions do not
1330 * count, and non-login sessions do not count either. */
1331 HASHMAP_FOREACH(session, m->sessions, i)
1332 if (session->class == SESSION_USER &&
1333 session->user->uid != uid)
1339 static int bus_manager_log_shutdown(
1342 const char *unit_name) {
1349 if (w != INHIBIT_SHUTDOWN)
1352 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1353 p = "MESSAGE=System is powering down.";
1354 q = "SHUTDOWN=power-off";
1355 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1356 p = "MESSAGE=System is halting.";
1357 q = "SHUTDOWN=halt";
1358 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1359 p = "MESSAGE=System is rebooting.";
1360 q = "SHUTDOWN=reboot";
1361 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1362 p = "MESSAGE=System is rebooting with kexec.";
1363 q = "SHUTDOWN=kexec";
1365 p = "MESSAGE=System is shutting down.";
1369 return log_struct(LOG_NOTICE,
1370 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1376 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1377 Manager *m = userdata;
1382 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1386 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1391 if (until <= now(CLOCK_MONOTONIC))
1394 /* We want to ignore the lid switch for a while after each
1395 * suspend, and after boot-up. Hence let's install a timer for
1396 * this. As long as the event source exists we ignore the lid
1399 if (m->lid_switch_ignore_event_source) {
1402 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1409 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1411 r = sd_event_add_time(
1413 &m->lid_switch_ignore_event_source,
1416 lid_switch_ignore_handler, m);
1421 static int execute_shutdown_or_sleep(
1424 const char *unit_name,
1425 sd_bus_error *error) {
1427 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1434 assert(w < _INHIBIT_WHAT_MAX);
1437 bus_manager_log_shutdown(m, w, unit_name);
1439 r = sd_bus_call_method(
1441 "org.freedesktop.systemd1",
1442 "/org/freedesktop/systemd1",
1443 "org.freedesktop.systemd1.Manager",
1447 "ss", unit_name, "replace-irreversibly");
1451 r = sd_bus_message_read(reply, "o", &p);
1459 m->action_unit = unit_name;
1460 free(m->action_job);
1464 /* Make sure the lid switch is ignored for a while */
1465 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1470 int manager_dispatch_delayed(Manager *manager, bool timeout) {
1472 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1473 Inhibitor *offending = NULL;
1478 if (manager->action_what == 0 || manager->action_job)
1481 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1482 _cleanup_free_ char *comm = NULL, *u = NULL;
1487 (void) get_process_comm(offending->pid, &comm);
1488 u = uid_to_name(offending->uid);
1490 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1491 offending->uid, strna(u),
1492 offending->pid, strna(comm));
1495 /* Actually do the operation */
1496 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
1498 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1500 manager->action_unit = NULL;
1501 manager->action_what = 0;
1508 static int manager_inhibit_timeout_handler(
1513 Manager *manager = userdata;
1517 assert(manager->inhibit_timeout_source == s);
1519 r = manager_dispatch_delayed(manager, true);
1520 return (r < 0) ? r : 0;
1523 static int delay_shutdown_or_sleep(
1526 const char *unit_name) {
1533 assert(w < _INHIBIT_WHAT_MAX);
1536 timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1538 if (m->inhibit_timeout_source) {
1539 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1541 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1543 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1545 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1547 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1548 timeout_val, 0, manager_inhibit_timeout_handler, m);
1553 m->action_unit = unit_name;
1559 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1561 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1562 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1563 [INHIBIT_SLEEP] = "PrepareForSleep"
1566 int active = _active;
1570 assert(w < _INHIBIT_WHAT_MAX);
1571 assert(signal_name[w]);
1573 return sd_bus_emit_signal(m->bus,
1574 "/org/freedesktop/login1",
1575 "org.freedesktop.login1.Manager",
1581 int bus_manager_shutdown_or_sleep_now_or_later(
1583 const char *unit_name,
1585 sd_bus_error *error) {
1593 assert(w <= _INHIBIT_WHAT_MAX);
1594 assert(!m->action_job);
1596 /* Tell everybody to prepare for shutdown/sleep */
1597 send_prepare_for(m, w, true);
1600 m->inhibit_delay_max > 0 &&
1601 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1604 /* Shutdown is delayed, keep in mind what we
1605 * want to do, and start a timeout */
1606 r = delay_shutdown_or_sleep(m, w, unit_name);
1608 /* Shutdown is not delayed, execute it
1610 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1615 static int verify_shutdown_creds(
1617 sd_bus_message *message,
1621 const char *action_multiple_sessions,
1622 const char *action_ignore_inhibit,
1623 sd_bus_error *error) {
1625 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1626 bool multiple_sessions, blocked;
1633 assert(w <= _INHIBIT_WHAT_MAX);
1635 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1639 r = sd_bus_creds_get_euid(creds, &uid);
1643 r = have_multiple_sessions(m, uid);
1647 multiple_sessions = r > 0;
1648 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1650 if (multiple_sessions && action_multiple_sessions) {
1651 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1655 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1658 if (blocked && action_ignore_inhibit) {
1659 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1663 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1666 if (!multiple_sessions && !blocked && action) {
1667 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1671 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1677 static int method_do_shutdown_or_sleep(
1679 sd_bus_message *message,
1680 const char *unit_name,
1683 const char *action_multiple_sessions,
1684 const char *action_ignore_inhibit,
1685 const char *sleep_verb,
1686 sd_bus_error *error) {
1694 assert(w <= _INHIBIT_WHAT_MAX);
1696 r = sd_bus_message_read(message, "b", &interactive);
1700 /* Don't allow multiple jobs being executed at the same time */
1702 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1705 r = can_sleep(sleep_verb);
1710 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1713 r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1714 action_ignore_inhibit, error);
1718 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1722 return sd_bus_reply_method_return(message, NULL);
1725 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1726 Manager *m = userdata;
1728 return method_do_shutdown_or_sleep(
1730 SPECIAL_POWEROFF_TARGET,
1732 "org.freedesktop.login1.power-off",
1733 "org.freedesktop.login1.power-off-multiple-sessions",
1734 "org.freedesktop.login1.power-off-ignore-inhibit",
1739 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1740 Manager *m = userdata;
1742 return method_do_shutdown_or_sleep(
1744 SPECIAL_REBOOT_TARGET,
1746 "org.freedesktop.login1.reboot",
1747 "org.freedesktop.login1.reboot-multiple-sessions",
1748 "org.freedesktop.login1.reboot-ignore-inhibit",
1753 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1754 Manager *m = userdata;
1756 return method_do_shutdown_or_sleep(
1758 SPECIAL_SUSPEND_TARGET,
1760 "org.freedesktop.login1.suspend",
1761 "org.freedesktop.login1.suspend-multiple-sessions",
1762 "org.freedesktop.login1.suspend-ignore-inhibit",
1767 static int nologin_timeout_handler(
1772 Manager *m = userdata;
1775 log_info("Creating /run/nologin, blocking further logins...");
1777 r = write_string_file("/run/nologin", "System is going down.", WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
1779 log_error_errno(r, "Failed to create /run/nologin: %m");
1781 m->unlink_nologin = true;
1786 static int update_schedule_file(Manager *m) {
1789 _cleanup_fclose_ FILE *f = NULL;
1790 _cleanup_free_ char *t = NULL, *temp_path = 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 t = cescape(m->wall_message);
1802 r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1804 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1806 (void) fchmod(fileno(f), 0644);
1812 m->scheduled_shutdown_timeout,
1813 m->enable_wall_messages,
1814 m->scheduled_shutdown_type);
1816 if (!isempty(m->wall_message))
1817 fprintf(f, "WALL_MESSAGE=%s\n", t);
1819 (void) fflush_and_check(f);
1821 if (ferror(f) || rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1822 log_error_errno(errno, "Failed to write information about scheduled shutdowns: %m");
1825 (void) unlink(temp_path);
1826 (void) unlink("/run/systemd/shutdown/scheduled");
1832 static int manager_scheduled_shutdown_handler(
1837 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1838 Manager *m = userdata;
1844 if (isempty(m->scheduled_shutdown_type))
1847 if (streq(m->scheduled_shutdown_type, "halt"))
1848 target = SPECIAL_HALT_TARGET;
1849 else if (streq(m->scheduled_shutdown_type, "poweroff"))
1850 target = SPECIAL_POWEROFF_TARGET;
1852 target = SPECIAL_REBOOT_TARGET;
1854 r = execute_shutdown_or_sleep(m, 0, target, &error);
1856 return log_error_errno(r, "Unable to execute transition to %s: %m", target);
1861 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1862 Manager *m = userdata;
1863 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1864 const char *action_multiple_sessions = NULL;
1865 const char *action_ignore_inhibit = NULL;
1866 const char *action = NULL;
1874 r = sd_bus_message_read(message, "st", &type, &elapse);
1878 if (streq(type, "reboot")) {
1879 action = "org.freedesktop.login1.reboot";
1880 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1881 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1882 } else if (streq(type, "halt")) {
1883 action = "org.freedesktop.login1.halt";
1884 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1885 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1886 } else if (streq(type, "poweroff")) {
1887 action = "org.freedesktop.login1.poweroff";
1888 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1889 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1891 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1893 r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1894 action, action_multiple_sessions, action_ignore_inhibit, error);
1898 if (m->scheduled_shutdown_timeout_source) {
1899 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1901 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1903 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1905 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1907 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1908 CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1910 return log_error_errno(r, "sd_event_add_time() failed: %m");
1913 r = free_and_strdup(&m->scheduled_shutdown_type, type);
1915 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1919 if (m->nologin_timeout_source) {
1920 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1922 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1924 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1926 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1928 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1929 CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1931 return log_error_errno(r, "sd_event_add_time() failed: %m");
1934 m->scheduled_shutdown_timeout = elapse;
1936 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1940 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1941 (void) sd_bus_creds_get_tty(creds, &tty);
1943 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1945 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1950 r = manager_setup_wall_message_timer(m);
1954 if (!isempty(type)) {
1955 r = update_schedule_file(m);
1959 (void) unlink("/run/systemd/shutdown/scheduled");
1961 return sd_bus_reply_method_return(message, NULL);
1964 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1965 Manager *m = userdata;
1971 cancelled = m->scheduled_shutdown_type != NULL;
1973 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1974 m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
1975 m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
1976 free(m->scheduled_shutdown_type);
1977 m->scheduled_shutdown_type = NULL;
1978 m->scheduled_shutdown_timeout = 0;
1980 if (m->unlink_nologin) {
1981 (void) unlink("/run/nologin");
1982 m->unlink_nologin = false;
1986 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1987 const char *tty = NULL;
1991 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1993 (void) sd_bus_creds_get_uid(creds, &uid);
1994 (void) sd_bus_creds_get_tty(creds, &tty);
1997 utmp_wall("The system shutdown has been cancelled",
1998 lookup_uid(uid), tty, logind_wall_tty_filter, m);
2001 return sd_bus_reply_method_return(message, "b", cancelled);
2004 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2005 Manager *m = userdata;
2007 return method_do_shutdown_or_sleep(
2009 SPECIAL_HIBERNATE_TARGET,
2011 "org.freedesktop.login1.hibernate",
2012 "org.freedesktop.login1.hibernate-multiple-sessions",
2013 "org.freedesktop.login1.hibernate-ignore-inhibit",
2018 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2019 Manager *m = userdata;
2021 return method_do_shutdown_or_sleep(
2023 SPECIAL_HYBRID_SLEEP_TARGET,
2025 "org.freedesktop.login1.hibernate",
2026 "org.freedesktop.login1.hibernate-multiple-sessions",
2027 "org.freedesktop.login1.hibernate-ignore-inhibit",
2032 static int method_can_shutdown_or_sleep(
2034 sd_bus_message *message,
2037 const char *action_multiple_sessions,
2038 const char *action_ignore_inhibit,
2039 const char *sleep_verb,
2040 sd_bus_error *error) {
2042 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2043 bool multiple_sessions, challenge, blocked;
2044 const char *result = NULL;
2051 assert(w <= _INHIBIT_WHAT_MAX);
2053 assert(action_multiple_sessions);
2054 assert(action_ignore_inhibit);
2057 r = can_sleep(sleep_verb);
2061 return sd_bus_reply_method_return(message, "s", "na");
2064 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2068 r = sd_bus_creds_get_euid(creds, &uid);
2072 r = have_multiple_sessions(m, uid);
2076 multiple_sessions = r > 0;
2077 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2079 if (multiple_sessions) {
2080 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
2087 result = "challenge";
2093 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
2097 if (r > 0 && !result)
2099 else if (challenge && (!result || streq(result, "yes")))
2100 result = "challenge";
2105 if (!multiple_sessions && !blocked) {
2106 /* If neither inhibit nor multiple sessions
2107 * apply then just check the normal policy */
2109 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
2116 result = "challenge";
2121 return sd_bus_reply_method_return(message, "s", result);
2124 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2125 Manager *m = userdata;
2127 return method_can_shutdown_or_sleep(
2130 "org.freedesktop.login1.power-off",
2131 "org.freedesktop.login1.power-off-multiple-sessions",
2132 "org.freedesktop.login1.power-off-ignore-inhibit",
2137 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2138 Manager *m = userdata;
2140 return method_can_shutdown_or_sleep(
2143 "org.freedesktop.login1.reboot",
2144 "org.freedesktop.login1.reboot-multiple-sessions",
2145 "org.freedesktop.login1.reboot-ignore-inhibit",
2150 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2151 Manager *m = userdata;
2153 return method_can_shutdown_or_sleep(
2156 "org.freedesktop.login1.suspend",
2157 "org.freedesktop.login1.suspend-multiple-sessions",
2158 "org.freedesktop.login1.suspend-ignore-inhibit",
2163 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2164 Manager *m = userdata;
2166 return method_can_shutdown_or_sleep(
2169 "org.freedesktop.login1.hibernate",
2170 "org.freedesktop.login1.hibernate-multiple-sessions",
2171 "org.freedesktop.login1.hibernate-ignore-inhibit",
2176 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2177 Manager *m = userdata;
2179 return method_can_shutdown_or_sleep(
2182 "org.freedesktop.login1.hibernate",
2183 "org.freedesktop.login1.hibernate-multiple-sessions",
2184 "org.freedesktop.login1.hibernate-ignore-inhibit",
2189 static int property_get_reboot_to_firmware_setup(
2192 const char *interface,
2193 const char *property,
2194 sd_bus_message *reply,
2196 sd_bus_error *error) {
2203 r = efi_get_reboot_to_firmware();
2204 if (r < 0 && r != -EOPNOTSUPP)
2207 return sd_bus_message_append(reply, "b", r > 0);
2210 static int method_set_reboot_to_firmware_setup(
2211 sd_bus_message *message,
2213 sd_bus_error *error) {
2216 Manager *m = userdata;
2221 r = sd_bus_message_read(message, "b", &b);
2225 r = bus_verify_polkit_async(message,
2227 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2230 &m->polkit_registry,
2235 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2237 r = efi_set_reboot_to_firmware(b);
2241 return sd_bus_reply_method_return(message, NULL);
2244 static int method_can_reboot_to_firmware_setup(
2245 sd_bus_message *message,
2247 sd_bus_error *error) {
2252 Manager *m = userdata;
2257 r = efi_reboot_to_firmware_supported();
2258 if (r == -EOPNOTSUPP)
2259 return sd_bus_reply_method_return(message, "s", "na");
2263 r = bus_test_polkit(message,
2265 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2275 result = "challenge";
2279 return sd_bus_reply_method_return(message, "s", result);
2282 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2283 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2284 const char *who, *why, *what, *mode;
2285 _cleanup_free_ char *id = NULL;
2286 _cleanup_close_ int fifo_fd = -1;
2287 Manager *m = userdata;
2288 Inhibitor *i = NULL;
2298 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2302 w = inhibit_what_from_string(what);
2304 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2306 mm = inhibit_mode_from_string(mode);
2308 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2310 /* Delay is only supported for shutdown/sleep */
2311 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2312 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2314 /* Don't allow taking delay locks while we are already
2315 * executing the operation. We shouldn't create the impression
2316 * that the lock was successful if the machine is about to go
2317 * down/suspend any moment. */
2318 if (m->action_what & w)
2319 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2321 r = bus_verify_polkit_async(
2324 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2325 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2326 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
2327 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
2328 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2329 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2330 "org.freedesktop.login1.inhibit-handle-lid-switch",
2333 &m->polkit_registry,
2338 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2340 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2344 r = sd_bus_creds_get_euid(creds, &uid);
2348 r = sd_bus_creds_get_pid(creds, &pid);
2356 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2359 } while (hashmap_get(m->inhibitors, id));
2361 r = manager_add_inhibitor(m, id, &i);
2369 i->why = strdup(why);
2370 i->who = strdup(who);
2372 if (!i->why || !i->who) {
2377 fifo_fd = inhibitor_create_fifo(i);
2385 return sd_bus_reply_method_return(message, "h", fifo_fd);
2394 const sd_bus_vtable manager_vtable[] = {
2395 SD_BUS_VTABLE_START(0),
2397 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2398 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2400 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2401 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2402 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2403 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2404 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2405 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2406 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2407 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2408 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2409 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2410 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2411 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2412 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2413 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2414 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2415 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2416 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2417 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2418 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2419 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2420 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2421 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2422 SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
2424 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2425 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2426 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2427 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2428 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2429 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2430 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2431 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2432 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2433 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2434 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2435 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2436 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2437 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2438 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2439 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2440 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2441 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2442 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2443 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2444 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2445 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2446 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2447 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2448 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2449 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2450 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2451 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2452 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2453 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2454 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2455 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2456 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2457 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2458 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2459 SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2460 SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2461 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2462 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2463 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2465 SD_BUS_SIGNAL("SessionNew", "so", 0),
2466 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2467 SD_BUS_SIGNAL("UserNew", "uo", 0),
2468 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2469 SD_BUS_SIGNAL("SeatNew", "so", 0),
2470 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2471 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2472 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2477 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2486 if (streq(result, "done"))
2487 r = session_send_create_reply(s, NULL);
2489 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2491 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2492 r = session_send_create_reply(s, &e);
2498 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2499 const char *path, *result, *unit;
2500 Manager *m = userdata;
2509 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2511 bus_log_parse_error(r);
2515 if (m->action_job && streq(m->action_job, path)) {
2516 log_info("Operation finished.");
2518 /* Tell people that they now may take a lock again */
2519 send_prepare_for(m, m->action_what, false);
2521 free(m->action_job);
2522 m->action_job = NULL;
2523 m->action_unit = NULL;
2528 session = hashmap_get(m->session_units, unit);
2531 if (streq_ptr(path, session->scope_job)) {
2532 free(session->scope_job);
2533 session->scope_job = NULL;
2536 session_jobs_reply(session, unit, result);
2538 session_save(session);
2539 user_save(session->user);
2540 session_add_to_gc_queue(session);
2543 user = hashmap_get(m->user_units, unit);
2546 if (streq_ptr(path, user->service_job)) {
2547 free(user->service_job);
2548 user->service_job = NULL;
2551 if (streq_ptr(path, user->slice_job)) {
2552 free(user->slice_job);
2553 user->slice_job = NULL;
2556 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2557 session_jobs_reply(session, unit, result);
2561 user_add_to_gc_queue(user);
2567 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2568 const char *path, *unit;
2569 Manager *m = userdata;
2577 r = sd_bus_message_read(message, "so", &unit, &path);
2579 bus_log_parse_error(r);
2583 session = hashmap_get(m->session_units, unit);
2585 session_add_to_gc_queue(session);
2587 user = hashmap_get(m->user_units, unit);
2589 user_add_to_gc_queue(user);
2594 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2595 _cleanup_free_ char *unit = NULL;
2596 Manager *m = userdata;
2605 path = sd_bus_message_get_path(message);
2609 r = unit_name_from_dbus_path(path, &unit);
2610 if (r == -EINVAL) /* not a unit */
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_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2627 Manager *m = userdata;
2635 r = sd_bus_message_read(message, "b", &b);
2637 bus_log_parse_error(r);
2644 /* systemd finished reloading, let's recheck all our sessions */
2645 log_debug("System manager has been reloaded, rechecking sessions...");
2647 HASHMAP_FOREACH(session, m->sessions, i)
2648 session_add_to_gc_queue(session);
2653 int match_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2654 const char *name, *old, *new;
2655 Manager *m = userdata;
2664 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2666 bus_log_parse_error(r);
2670 if (isempty(old) || !isempty(new))
2673 key = set_remove(m->busnames, (char*) old);
2677 /* Drop all controllers owned by this name */
2681 HASHMAP_FOREACH(session, m->sessions, i)
2682 if (session_is_controller(session, old))
2683 session_drop_controller(session);
2688 int manager_send_changed(Manager *manager, const char *property, ...) {
2693 l = strv_from_stdarg_alloca(property);
2695 return sd_bus_emit_properties_changed_strv(
2697 "/org/freedesktop/login1",
2698 "org.freedesktop.login1.Manager",
2702 int manager_start_scope(
2707 const char *description,
2708 const char *after, const char *after2,
2709 sd_bus_error *error,
2712 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2719 r = sd_bus_message_new_method_call(
2722 "org.freedesktop.systemd1",
2723 "/org/freedesktop/systemd1",
2724 "org.freedesktop.systemd1.Manager",
2725 "StartTransientUnit");
2729 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2733 r = sd_bus_message_open_container(m, 'a', "(sv)");
2737 if (!isempty(slice)) {
2738 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2743 if (!isempty(description)) {
2744 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2749 if (!isempty(after)) {
2750 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2755 if (!isempty(after2)) {
2756 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2761 /* cgroup empty notification is not available in containers
2762 * currently. To make this less problematic, let's shorten the
2763 * stop timeout for sessions, so that we don't wait
2766 /* Make sure that the session shells are terminated with
2767 * SIGHUP since bash and friends tend to ignore SIGTERM */
2768 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2772 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2776 r = sd_bus_message_close_container(m);
2780 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2784 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2792 r = sd_bus_message_read(reply, "o", &j);
2806 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2807 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2813 r = sd_bus_call_method(
2815 "org.freedesktop.systemd1",
2816 "/org/freedesktop/systemd1",
2817 "org.freedesktop.systemd1.Manager",
2821 "ss", unit, "fail");
2829 r = sd_bus_message_read(reply, "o", &j);
2843 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2844 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2850 r = sd_bus_call_method(
2852 "org.freedesktop.systemd1",
2853 "/org/freedesktop/systemd1",
2854 "org.freedesktop.systemd1.Manager",
2858 "ss", unit, "fail");
2860 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2861 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2866 sd_bus_error_free(error);
2877 r = sd_bus_message_read(reply, "o", &j);
2891 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2892 _cleanup_free_ char *path = NULL;
2898 path = unit_dbus_path_from_name(scope);
2902 r = sd_bus_call_method(
2904 "org.freedesktop.systemd1",
2906 "org.freedesktop.systemd1.Scope",
2912 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2913 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2914 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2915 sd_bus_error_free(error);
2925 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2929 return sd_bus_call_method(
2931 "org.freedesktop.systemd1",
2932 "/org/freedesktop/systemd1",
2933 "org.freedesktop.systemd1.Manager",
2937 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2940 int manager_unit_is_active(Manager *manager, const char *unit) {
2941 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2942 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2943 _cleanup_free_ char *path = NULL;
2950 path = unit_dbus_path_from_name(unit);
2954 r = sd_bus_get_property(
2956 "org.freedesktop.systemd1",
2958 "org.freedesktop.systemd1.Unit",
2964 /* systemd might have droppped off momentarily, let's
2965 * not make this an error */
2966 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2967 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2970 /* If the unit is already unloaded then it's not
2972 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2973 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2979 r = sd_bus_message_read(reply, "s", &state);
2983 return !streq(state, "inactive") && !streq(state, "failed");
2986 int manager_job_is_active(Manager *manager, const char *path) {
2987 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2988 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2994 r = sd_bus_get_property(
2996 "org.freedesktop.systemd1",
2998 "org.freedesktop.systemd1.Job",
3004 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3005 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3008 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3014 /* We don't actually care about the state really. The fact
3015 * that we could read the job state is enough for us */