| File: | build-scan/../src/core/dbus.c |
| Warning: | line 514, column 33 Potential leak of memory pointed to by 'l' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
| 2 | ||||
| 3 | #include <errno(*__errno_location ()).h> | |||
| 4 | #include <sys/epoll.h> | |||
| 5 | #include <unistd.h> | |||
| 6 | ||||
| 7 | #include "sd-bus.h" | |||
| 8 | ||||
| 9 | #include "alloc-util.h" | |||
| 10 | #include "bus-common-errors.h" | |||
| 11 | #include "bus-error.h" | |||
| 12 | #include "bus-internal.h" | |||
| 13 | #include "bus-util.h" | |||
| 14 | #include "dbus-automount.h" | |||
| 15 | #include "dbus-cgroup.h" | |||
| 16 | #include "dbus-device.h" | |||
| 17 | #include "dbus-execute.h" | |||
| 18 | #include "dbus-job.h" | |||
| 19 | #include "dbus-kill.h" | |||
| 20 | #include "dbus-manager.h" | |||
| 21 | #include "dbus-mount.h" | |||
| 22 | #include "dbus-path.h" | |||
| 23 | #include "dbus-scope.h" | |||
| 24 | #include "dbus-service.h" | |||
| 25 | #include "dbus-slice.h" | |||
| 26 | #include "dbus-socket.h" | |||
| 27 | #include "dbus-swap.h" | |||
| 28 | #include "dbus-target.h" | |||
| 29 | #include "dbus-timer.h" | |||
| 30 | #include "dbus-unit.h" | |||
| 31 | #include "dbus.h" | |||
| 32 | #include "fd-util.h" | |||
| 33 | #include "fs-util.h" | |||
| 34 | #include "log.h" | |||
| 35 | #include "missing.h" | |||
| 36 | #include "mkdir.h" | |||
| 37 | #include "process-util.h" | |||
| 38 | #include "selinux-access.h" | |||
| 39 | #include "service.h" | |||
| 40 | #include "special.h" | |||
| 41 | #include "string-util.h" | |||
| 42 | #include "strv.h" | |||
| 43 | #include "strxcpyx.h" | |||
| 44 | #include "user-util.h" | |||
| 45 | ||||
| 46 | #define CONNECTIONS_MAX4096 4096 | |||
| 47 | ||||
| 48 | static void destroy_bus(Manager *m, sd_bus **bus); | |||
| 49 | ||||
| 50 | int bus_send_pending_reload_message(Manager *m) { | |||
| 51 | int r; | |||
| 52 | ||||
| 53 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 53, __PRETTY_FUNCTION__ ); } while (0); | |||
| 54 | ||||
| 55 | if (!m->pending_reload_message) | |||
| 56 | return 0; | |||
| 57 | ||||
| 58 | /* If we cannot get rid of this message we won't dispatch any D-Bus messages, so that we won't end up wanting | |||
| 59 | * to queue another message. */ | |||
| 60 | ||||
| 61 | r = sd_bus_send(NULL((void*)0), m->pending_reload_message, NULL((void*)0)); | |||
| 62 | if (r < 0) | |||
| 63 | log_warning_errno(r, "Failed to send queued message, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 63, __func__, "Failed to send queued message, ignoring: %m" ) : -abs(_e); }); | |||
| 64 | ||||
| 65 | m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message); | |||
| 66 | ||||
| 67 | return 0; | |||
| 68 | } | |||
| 69 | ||||
| 70 | int bus_forward_agent_released(Manager *m, const char *path) { | |||
| 71 | int r; | |||
| 72 | ||||
| 73 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 73, __PRETTY_FUNCTION__ ); } while (0); | |||
| 74 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 74, __PRETTY_FUNCTION__ ); } while (0); | |||
| 75 | ||||
| 76 | if (!MANAGER_IS_SYSTEM(m)((m)->unit_file_scope == UNIT_FILE_SYSTEM)) | |||
| 77 | return 0; | |||
| 78 | ||||
| 79 | if (!m->system_bus) | |||
| 80 | return 0; | |||
| 81 | ||||
| 82 | /* If we are running a system instance we forward the agent message on the system bus, so that the user | |||
| 83 | * instances get notified about this, too */ | |||
| 84 | ||||
| 85 | r = sd_bus_emit_signal(m->system_bus, | |||
| 86 | "/org/freedesktop/systemd1/agent", | |||
| 87 | "org.freedesktop.systemd1.Agent", | |||
| 88 | "Released", | |||
| 89 | "s", path); | |||
| 90 | if (r < 0) | |||
| 91 | return log_debug_errno(r, "Failed to propagate agent release message: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 91, __func__, "Failed to propagate agent release message: %m" ) : -abs(_e); }); | |||
| 92 | ||||
| 93 | return 1; | |||
| 94 | } | |||
| 95 | ||||
| 96 | static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |||
| 97 | _cleanup_(sd_bus_creds_unrefp)__attribute__((cleanup(sd_bus_creds_unrefp))) sd_bus_creds *creds = NULL((void*)0); | |||
| 98 | Manager *m = userdata; | |||
| 99 | const char *cgroup; | |||
| 100 | uid_t sender_uid; | |||
| 101 | int r; | |||
| 102 | ||||
| 103 | assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("message"), "../src/core/dbus.c", 103, __PRETTY_FUNCTION__ ); } while (0); | |||
| 104 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 104, __PRETTY_FUNCTION__ ); } while (0); | |||
| 105 | ||||
| 106 | /* only accept org.freedesktop.systemd1.Agent from UID=0 */ | |||
| 107 | r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds); | |||
| 108 | if (r < 0) | |||
| 109 | return r; | |||
| 110 | ||||
| 111 | r = sd_bus_creds_get_euid(creds, &sender_uid); | |||
| 112 | if (r < 0 || sender_uid != 0) | |||
| 113 | return 0; | |||
| 114 | ||||
| 115 | /* parse 'cgroup-empty' notification */ | |||
| 116 | r = sd_bus_message_read(message, "s", &cgroup); | |||
| 117 | if (r < 0) { | |||
| 118 | bus_log_parse_error(r); | |||
| 119 | return 0; | |||
| 120 | } | |||
| 121 | ||||
| 122 | manager_notify_cgroup_empty(m, cgroup); | |||
| 123 | return 0; | |||
| 124 | } | |||
| 125 | ||||
| 126 | static int signal_disconnected(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |||
| 127 | Manager *m = userdata; | |||
| 128 | sd_bus *bus; | |||
| 129 | ||||
| 130 | assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("message"), "../src/core/dbus.c", 130, __PRETTY_FUNCTION__ ); } while (0); | |||
| 131 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 131, __PRETTY_FUNCTION__ ); } while (0); | |||
| 132 | assert_se(bus = sd_bus_message_get_bus(message))do { if ((__builtin_expect(!!(!(bus = sd_bus_message_get_bus( message))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("bus = sd_bus_message_get_bus(message)" ), "../src/core/dbus.c", 132, __PRETTY_FUNCTION__); } while ( 0); | |||
| 133 | ||||
| 134 | if (bus == m->api_bus) | |||
| 135 | bus_done_api(m); | |||
| 136 | if (bus == m->system_bus) | |||
| 137 | bus_done_system(m); | |||
| 138 | ||||
| 139 | if (set_remove(m->private_buses, bus)) { | |||
| 140 | log_debug("Got disconnect on private connection.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 140, __func__, "Got disconnect on private connection." ) : -abs(_e); }); | |||
| 141 | destroy_bus(m, &bus); | |||
| 142 | } | |||
| 143 | ||||
| 144 | return 0; | |||
| 145 | } | |||
| 146 | ||||
| 147 | static int signal_activation_request(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) { | |||
| 148 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); | |||
| 149 | _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *reply = NULL((void*)0); | |||
| 150 | Manager *m = userdata; | |||
| 151 | const char *name; | |||
| 152 | Unit *u; | |||
| 153 | int r; | |||
| 154 | ||||
| 155 | assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("message"), "../src/core/dbus.c", 155, __PRETTY_FUNCTION__ ); } while (0); | |||
| 156 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 156, __PRETTY_FUNCTION__ ); } while (0); | |||
| 157 | ||||
| 158 | r = sd_bus_message_read(message, "s", &name); | |||
| 159 | if (r < 0) { | |||
| 160 | bus_log_parse_error(r); | |||
| 161 | return 0; | |||
| 162 | } | |||
| 163 | ||||
| 164 | if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE"dbus.service") || | |||
| 165 | manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET"dbus.socket")) { | |||
| 166 | r = sd_bus_error_setf(&error, BUS_ERROR_SHUTTING_DOWN"org.freedesktop.systemd1.ShuttingDown", "Refusing activation, D-Bus is shutting down."); | |||
| 167 | goto failed; | |||
| 168 | } | |||
| 169 | ||||
| 170 | r = manager_load_unit(m, name, NULL((void*)0), &error, &u); | |||
| 171 | if (r < 0) | |||
| 172 | goto failed; | |||
| 173 | ||||
| 174 | if (u->refuse_manual_start) { | |||
| 175 | r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY"org.freedesktop.systemd1.OnlyByDependency", "Operation refused, %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id); | |||
| 176 | goto failed; | |||
| 177 | } | |||
| 178 | ||||
| 179 | r = manager_add_job(m, JOB_START, u, JOB_REPLACE, NULL((void*)0), &error, NULL((void*)0)); | |||
| 180 | if (r < 0) | |||
| 181 | goto failed; | |||
| 182 | ||||
| 183 | /* Successfully queued, that's it for us */ | |||
| 184 | return 0; | |||
| 185 | ||||
| 186 | failed: | |||
| 187 | if (!sd_bus_error_is_set(&error)) | |||
| 188 | sd_bus_error_set_errno(&error, r); | |||
| 189 | ||||
| 190 | log_debug("D-Bus activation failed for %s: %s", name, bus_error_message(&error, r))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 190, __func__, "D-Bus activation failed for %s: %s" , name, bus_error_message(&error, r)) : -abs(_e); }); | |||
| 191 | ||||
| 192 | r = sd_bus_message_new_signal(sd_bus_message_get_bus(message), &reply, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure"); | |||
| 193 | if (r < 0) { | |||
| 194 | bus_log_create_error(r); | |||
| 195 | return 0; | |||
| 196 | } | |||
| 197 | ||||
| 198 | r = sd_bus_message_append(reply, "sss", name, error.name, error.message); | |||
| 199 | if (r < 0) { | |||
| 200 | bus_log_create_error(r); | |||
| 201 | return 0; | |||
| 202 | } | |||
| 203 | ||||
| 204 | r = sd_bus_send_to(NULL((void*)0), reply, "org.freedesktop.DBus", NULL((void*)0)); | |||
| 205 | if (r < 0) | |||
| 206 | return log_error_errno(r, "Failed to respond with to bus activation request: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 206, __func__, "Failed to respond with to bus activation request: %m" ) : -abs(_e); }); | |||
| 207 | ||||
| 208 | return 0; | |||
| 209 | } | |||
| 210 | ||||
| 211 | #if HAVE_SELINUX1 | |||
| 212 | static int mac_selinux_filter(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |||
| 213 | Manager *m = userdata; | |||
| 214 | const char *verb, *path; | |||
| 215 | Unit *u = NULL((void*)0); | |||
| 216 | Job *j; | |||
| 217 | int r; | |||
| 218 | ||||
| 219 | assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("message"), "../src/core/dbus.c", 219, __PRETTY_FUNCTION__ ); } while (0); | |||
| 220 | ||||
| 221 | /* Our own method calls are all protected individually with | |||
| 222 | * selinux checks, but the built-in interfaces need to be | |||
| 223 | * protected too. */ | |||
| 224 | ||||
| 225 | if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set")) | |||
| 226 | verb = "reload"; | |||
| 227 | else if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", NULL((void*)0)) || | |||
| 228 | sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", NULL((void*)0)) || | |||
| 229 | sd_bus_message_is_method_call(message, "org.freedesktop.DBus.ObjectManager", NULL((void*)0)) || | |||
| 230 | sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Peer", NULL((void*)0))) | |||
| 231 | verb = "status"; | |||
| 232 | else | |||
| 233 | return 0; | |||
| 234 | ||||
| 235 | path = sd_bus_message_get_path(message); | |||
| 236 | ||||
| 237 | if (object_path_startswith("/org/freedesktop/systemd1", path)) { | |||
| 238 | r = mac_selinux_access_check(message, verb, error)mac_selinux_generic_access_check((message), ((void*)0), (verb ), (error)); | |||
| 239 | if (r < 0) | |||
| 240 | return r; | |||
| 241 | ||||
| 242 | return 0; | |||
| 243 | } | |||
| 244 | ||||
| 245 | if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) { | |||
| 246 | _cleanup_(sd_bus_creds_unrefp)__attribute__((cleanup(sd_bus_creds_unrefp))) sd_bus_creds *creds = NULL((void*)0); | |||
| 247 | pid_t pid; | |||
| 248 | ||||
| 249 | r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds); | |||
| 250 | if (r < 0) | |||
| 251 | return 0; | |||
| 252 | ||||
| 253 | r = sd_bus_creds_get_pid(creds, &pid); | |||
| 254 | if (r < 0) | |||
| 255 | return 0; | |||
| 256 | ||||
| 257 | u = manager_get_unit_by_pid(m, pid); | |||
| 258 | } else { | |||
| 259 | r = manager_get_job_from_dbus_path(m, path, &j); | |||
| 260 | if (r >= 0) | |||
| 261 | u = j->unit; | |||
| 262 | else | |||
| 263 | manager_load_unit_from_dbus_path(m, path, NULL((void*)0), &u); | |||
| 264 | } | |||
| 265 | if (!u) | |||
| 266 | return 0; | |||
| 267 | ||||
| 268 | r = mac_selinux_unit_access_check(u, message, verb, error)mac_selinux_generic_access_check((message), unit_label_path(u ), (verb), (error)); | |||
| 269 | if (r < 0) | |||
| 270 | return r; | |||
| 271 | ||||
| 272 | return 0; | |||
| 273 | } | |||
| 274 | #endif | |||
| 275 | ||||
| 276 | static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { | |||
| 277 | Manager *m = userdata; | |||
| 278 | Job *j; | |||
| 279 | int r; | |||
| 280 | ||||
| 281 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 281, __PRETTY_FUNCTION__ ); } while (0); | |||
| 282 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 282, __PRETTY_FUNCTION__ ); } while (0); | |||
| 283 | assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 283, __PRETTY_FUNCTION__); } while (0); | |||
| 284 | assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 284, __PRETTY_FUNCTION__ ); } while (0); | |||
| 285 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 285, __PRETTY_FUNCTION__ ); } while (0); | |||
| 286 | ||||
| 287 | r = manager_get_job_from_dbus_path(m, path, &j); | |||
| 288 | if (r < 0) | |||
| 289 | return 0; | |||
| 290 | ||||
| 291 | *found = j; | |||
| 292 | return 1; | |||
| 293 | } | |||
| 294 | ||||
| 295 | static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) { | |||
| 296 | Unit *u = NULL((void*)0); /* just to appease gcc, initialization is not really necessary */ | |||
| 297 | int r; | |||
| 298 | ||||
| 299 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 299, __PRETTY_FUNCTION__ ); } while (0); | |||
| 300 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 300, __PRETTY_FUNCTION__ ); } while (0); | |||
| 301 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 301, __PRETTY_FUNCTION__ ); } while (0); | |||
| 302 | ||||
| 303 | if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) { | |||
| 304 | _cleanup_(sd_bus_creds_unrefp)__attribute__((cleanup(sd_bus_creds_unrefp))) sd_bus_creds *creds = NULL((void*)0); | |||
| 305 | sd_bus_message *message; | |||
| 306 | pid_t pid; | |||
| 307 | ||||
| 308 | message = sd_bus_get_current_message(bus); | |||
| 309 | if (!message) | |||
| 310 | return 0; | |||
| 311 | ||||
| 312 | r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds); | |||
| 313 | if (r < 0) | |||
| 314 | return r; | |||
| 315 | ||||
| 316 | r = sd_bus_creds_get_pid(creds, &pid); | |||
| 317 | if (r < 0) | |||
| 318 | return r; | |||
| 319 | ||||
| 320 | u = manager_get_unit_by_pid(m, pid); | |||
| 321 | if (!u) | |||
| 322 | return 0; | |||
| 323 | } else { | |||
| 324 | r = manager_load_unit_from_dbus_path(m, path, error, &u); | |||
| 325 | if (r < 0) | |||
| 326 | return 0; | |||
| 327 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/core/dbus.c", 327, __PRETTY_FUNCTION__ ); } while (0); | |||
| 328 | } | |||
| 329 | ||||
| 330 | *unit = u; | |||
| 331 | return 1; | |||
| 332 | } | |||
| 333 | ||||
| 334 | static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { | |||
| 335 | Manager *m = userdata; | |||
| 336 | ||||
| 337 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 337, __PRETTY_FUNCTION__ ); } while (0); | |||
| 338 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 338, __PRETTY_FUNCTION__ ); } while (0); | |||
| 339 | assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 339, __PRETTY_FUNCTION__); } while (0); | |||
| 340 | assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 340, __PRETTY_FUNCTION__ ); } while (0); | |||
| 341 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 341, __PRETTY_FUNCTION__ ); } while (0); | |||
| 342 | ||||
| 343 | return find_unit(m, bus, path, (Unit**) found, error); | |||
| 344 | } | |||
| 345 | ||||
| 346 | static int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { | |||
| 347 | Manager *m = userdata; | |||
| 348 | Unit *u; | |||
| 349 | int r; | |||
| 350 | ||||
| 351 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 351, __PRETTY_FUNCTION__ ); } while (0); | |||
| 352 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 352, __PRETTY_FUNCTION__ ); } while (0); | |||
| 353 | assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 353, __PRETTY_FUNCTION__); } while (0); | |||
| 354 | assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 354, __PRETTY_FUNCTION__ ); } while (0); | |||
| 355 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 355, __PRETTY_FUNCTION__ ); } while (0); | |||
| 356 | ||||
| 357 | r = find_unit(m, bus, path, &u, error); | |||
| 358 | if (r <= 0) | |||
| 359 | return r; | |||
| 360 | ||||
| 361 | if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type))) | |||
| 362 | return 0; | |||
| 363 | ||||
| 364 | *found = u; | |||
| 365 | return 1; | |||
| 366 | } | |||
| 367 | ||||
| 368 | static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { | |||
| 369 | Manager *m = userdata; | |||
| 370 | Unit *u; | |||
| 371 | int r; | |||
| 372 | ||||
| 373 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 373, __PRETTY_FUNCTION__ ); } while (0); | |||
| 374 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 374, __PRETTY_FUNCTION__ ); } while (0); | |||
| 375 | assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 375, __PRETTY_FUNCTION__); } while (0); | |||
| 376 | assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 376, __PRETTY_FUNCTION__ ); } while (0); | |||
| 377 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 377, __PRETTY_FUNCTION__ ); } while (0); | |||
| 378 | ||||
| 379 | r = find_unit(m, bus, path, &u, error); | |||
| 380 | if (r <= 0) | |||
| 381 | return r; | |||
| 382 | ||||
| 383 | if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type))) | |||
| 384 | return 0; | |||
| 385 | ||||
| 386 | if (!UNIT_HAS_CGROUP_CONTEXT(u)(unit_vtable[(u)->type]->cgroup_context_offset > 0)) | |||
| 387 | return 0; | |||
| 388 | ||||
| 389 | *found = u; | |||
| 390 | return 1; | |||
| 391 | } | |||
| 392 | ||||
| 393 | static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { | |||
| 394 | Manager *m = userdata; | |||
| 395 | CGroupContext *c; | |||
| 396 | Unit *u; | |||
| 397 | int r; | |||
| 398 | ||||
| 399 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 399, __PRETTY_FUNCTION__ ); } while (0); | |||
| 400 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 400, __PRETTY_FUNCTION__ ); } while (0); | |||
| 401 | assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 401, __PRETTY_FUNCTION__); } while (0); | |||
| 402 | assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 402, __PRETTY_FUNCTION__ ); } while (0); | |||
| 403 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 403, __PRETTY_FUNCTION__ ); } while (0); | |||
| 404 | ||||
| 405 | r = find_unit(m, bus, path, &u, error); | |||
| 406 | if (r <= 0) | |||
| 407 | return r; | |||
| 408 | ||||
| 409 | if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type))) | |||
| 410 | return 0; | |||
| 411 | ||||
| 412 | c = unit_get_cgroup_context(u); | |||
| 413 | if (!c) | |||
| 414 | return 0; | |||
| 415 | ||||
| 416 | *found = c; | |||
| 417 | return 1; | |||
| 418 | } | |||
| 419 | ||||
| 420 | static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { | |||
| 421 | Manager *m = userdata; | |||
| 422 | ExecContext *c; | |||
| 423 | Unit *u; | |||
| 424 | int r; | |||
| 425 | ||||
| 426 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 426, __PRETTY_FUNCTION__ ); } while (0); | |||
| 427 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 427, __PRETTY_FUNCTION__ ); } while (0); | |||
| 428 | assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 428, __PRETTY_FUNCTION__); } while (0); | |||
| 429 | assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 429, __PRETTY_FUNCTION__ ); } while (0); | |||
| 430 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 430, __PRETTY_FUNCTION__ ); } while (0); | |||
| 431 | ||||
| 432 | r = find_unit(m, bus, path, &u, error); | |||
| 433 | if (r <= 0) | |||
| 434 | return r; | |||
| 435 | ||||
| 436 | if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type))) | |||
| 437 | return 0; | |||
| 438 | ||||
| 439 | c = unit_get_exec_context(u); | |||
| 440 | if (!c) | |||
| 441 | return 0; | |||
| 442 | ||||
| 443 | *found = c; | |||
| 444 | return 1; | |||
| 445 | } | |||
| 446 | ||||
| 447 | static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { | |||
| 448 | Manager *m = userdata; | |||
| 449 | KillContext *c; | |||
| 450 | Unit *u; | |||
| 451 | int r; | |||
| 452 | ||||
| 453 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 453, __PRETTY_FUNCTION__ ); } while (0); | |||
| 454 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 454, __PRETTY_FUNCTION__ ); } while (0); | |||
| 455 | assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 455, __PRETTY_FUNCTION__); } while (0); | |||
| 456 | assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 456, __PRETTY_FUNCTION__ ); } while (0); | |||
| 457 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 457, __PRETTY_FUNCTION__ ); } while (0); | |||
| 458 | ||||
| 459 | r = find_unit(m, bus, path, &u, error); | |||
| 460 | if (r <= 0) | |||
| 461 | return r; | |||
| 462 | ||||
| 463 | if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type))) | |||
| 464 | return 0; | |||
| 465 | ||||
| 466 | c = unit_get_kill_context(u); | |||
| 467 | if (!c) | |||
| 468 | return 0; | |||
| 469 | ||||
| 470 | *found = c; | |||
| 471 | return 1; | |||
| 472 | } | |||
| 473 | ||||
| 474 | static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { | |||
| 475 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **l = NULL((void*)0); | |||
| 476 | Manager *m = userdata; | |||
| 477 | unsigned k = 0; | |||
| 478 | Iterator i; | |||
| 479 | Job *j; | |||
| 480 | ||||
| 481 | l = new0(char*, hashmap_size(m->jobs)+1)((char**) calloc((hashmap_size(m->jobs)+1), sizeof(char*)) ); | |||
| 482 | if (!l) | |||
| 483 | return -ENOMEM12; | |||
| 484 | ||||
| 485 | HASHMAP_FOREACH(j, m->jobs, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); hashmap_iterate((m->jobs), & (i), (void**)&(j), ((void*)0)); ) { | |||
| 486 | l[k] = job_dbus_path(j); | |||
| 487 | if (!l[k]) | |||
| 488 | return -ENOMEM12; | |||
| 489 | ||||
| 490 | k++; | |||
| 491 | } | |||
| 492 | ||||
| 493 | assert(hashmap_size(m->jobs) == k)do { if ((__builtin_expect(!!(!(hashmap_size(m->jobs) == k )),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("hashmap_size(m->jobs) == k" ), "../src/core/dbus.c", 493, __PRETTY_FUNCTION__); } while ( 0); | |||
| 494 | ||||
| 495 | *nodes = TAKE_PTR(l)({ typeof(l) _ptr_ = (l); (l) = ((void*)0); _ptr_; }); | |||
| 496 | ||||
| 497 | return k; | |||
| 498 | } | |||
| 499 | ||||
| 500 | static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { | |||
| 501 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **l = NULL((void*)0); | |||
| 502 | Manager *m = userdata; | |||
| 503 | unsigned k = 0; | |||
| 504 | Iterator i; | |||
| 505 | Unit *u; | |||
| 506 | ||||
| 507 | l = new0(char*, hashmap_size(m->units)+1)((char**) calloc((hashmap_size(m->units)+1), sizeof(char*) )); | |||
| ||||
| 508 | if (!l) | |||
| 509 | return -ENOMEM12; | |||
| 510 | ||||
| 511 | HASHMAP_FOREACH(u, m->units, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); hashmap_iterate((m->units), & (i), (void**)&(u), ((void*)0)); ) { | |||
| 512 | l[k] = unit_dbus_path(u); | |||
| 513 | if (!l[k]) | |||
| 514 | return -ENOMEM12; | |||
| ||||
| 515 | ||||
| 516 | k++; | |||
| 517 | } | |||
| 518 | ||||
| 519 | *nodes = TAKE_PTR(l)({ typeof(l) _ptr_ = (l); (l) = ((void*)0); _ptr_; }); | |||
| 520 | ||||
| 521 | return k; | |||
| 522 | } | |||
| 523 | ||||
| 524 | static int bus_setup_api_vtables(Manager *m, sd_bus *bus) { | |||
| 525 | UnitType t; | |||
| 526 | int r; | |||
| 527 | ||||
| 528 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 528, __PRETTY_FUNCTION__ ); } while (0); | |||
| 529 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 529, __PRETTY_FUNCTION__ ); } while (0); | |||
| 530 | ||||
| 531 | #if HAVE_SELINUX1 | |||
| 532 | r = sd_bus_add_filter(bus, NULL((void*)0), mac_selinux_filter, m); | |||
| 533 | if (r < 0) | |||
| 534 | return log_error_errno(r, "Failed to add SELinux access filter: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 534, __func__, "Failed to add SELinux access filter: %m" ) : -abs(_e); }); | |||
| 535 | #endif | |||
| 536 | ||||
| 537 | r = sd_bus_add_object_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m); | |||
| 538 | if (r < 0) | |||
| 539 | return log_error_errno(r, "Failed to register Manager vtable: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 539, __func__, "Failed to register Manager vtable: %m" ) : -abs(_e); }); | |||
| 540 | ||||
| 541 | r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m); | |||
| 542 | if (r < 0) | |||
| 543 | return log_error_errno(r, "Failed to register Job vtable: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 543, __func__, "Failed to register Job vtable: %m" ) : -abs(_e); }); | |||
| 544 | ||||
| 545 | r = sd_bus_add_node_enumerator(bus, NULL((void*)0), "/org/freedesktop/systemd1/job", bus_job_enumerate, m); | |||
| 546 | if (r < 0) | |||
| 547 | return log_error_errno(r, "Failed to add job enumerator: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 547, __func__, "Failed to add job enumerator: %m" ) : -abs(_e); }); | |||
| 548 | ||||
| 549 | r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m); | |||
| 550 | if (r < 0) | |||
| 551 | return log_error_errno(r, "Failed to register Unit vtable: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 551, __func__, "Failed to register Unit vtable: %m" ) : -abs(_e); }); | |||
| 552 | ||||
| 553 | r = sd_bus_add_node_enumerator(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m); | |||
| 554 | if (r < 0) | |||
| 555 | return log_error_errno(r, "Failed to add job enumerator: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 555, __func__, "Failed to add job enumerator: %m" ) : -abs(_e); }); | |||
| 556 | ||||
| 557 | for (t = 0; t < _UNIT_TYPE_MAX; t++) { | |||
| 558 | const char *interface; | |||
| 559 | ||||
| 560 | assert_se(interface = unit_dbus_interface_from_type(t))do { if ((__builtin_expect(!!(!(interface = unit_dbus_interface_from_type (t))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("interface = unit_dbus_interface_from_type(t)" ), "../src/core/dbus.c", 560, __PRETTY_FUNCTION__); } while ( 0); | |||
| 561 | ||||
| 562 | r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m); | |||
| 563 | if (r < 0) | |||
| 564 | return log_error_errno(r, "Failed to register type specific vtable for %s: %m", interface)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 564, __func__, "Failed to register type specific vtable for %s: %m" , interface) : -abs(_e); }); | |||
| 565 | ||||
| 566 | if (unit_vtable[t]->cgroup_context_offset > 0) { | |||
| 567 | r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m); | |||
| 568 | if (r < 0) | |||
| 569 | return log_error_errno(r, "Failed to register control group unit vtable for %s: %m", interface)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 569, __func__, "Failed to register control group unit vtable for %s: %m" , interface) : -abs(_e); }); | |||
| 570 | ||||
| 571 | r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", interface, bus_cgroup_vtable, bus_cgroup_context_find, m); | |||
| 572 | if (r < 0) | |||
| 573 | return log_error_errno(r, "Failed to register control group vtable for %s: %m", interface)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 573, __func__, "Failed to register control group vtable for %s: %m" , interface) : -abs(_e); }); | |||
| 574 | } | |||
| 575 | ||||
| 576 | if (unit_vtable[t]->exec_context_offset > 0) { | |||
| 577 | r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", interface, bus_exec_vtable, bus_exec_context_find, m); | |||
| 578 | if (r < 0) | |||
| 579 | return log_error_errno(r, "Failed to register execute vtable for %s: %m", interface)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 579, __func__, "Failed to register execute vtable for %s: %m" , interface) : -abs(_e); }); | |||
| 580 | } | |||
| 581 | ||||
| 582 | if (unit_vtable[t]->kill_context_offset > 0) { | |||
| 583 | r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", interface, bus_kill_vtable, bus_kill_context_find, m); | |||
| 584 | if (r < 0) | |||
| 585 | return log_error_errno(r, "Failed to register kill vtable for %s: %m", interface)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 585, __func__, "Failed to register kill vtable for %s: %m" , interface) : -abs(_e); }); | |||
| 586 | } | |||
| 587 | } | |||
| 588 | ||||
| 589 | return 0; | |||
| 590 | } | |||
| 591 | ||||
| 592 | static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) { | |||
| 593 | int r; | |||
| 594 | ||||
| 595 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 595, __PRETTY_FUNCTION__ ); } while (0); | |||
| 596 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 596, __PRETTY_FUNCTION__ ); } while (0); | |||
| 597 | ||||
| 598 | r = sd_bus_match_signal_async( | |||
| 599 | bus, | |||
| 600 | NULL((void*)0), | |||
| 601 | "org.freedesktop.DBus.Local", | |||
| 602 | "/org/freedesktop/DBus/Local", | |||
| 603 | "org.freedesktop.DBus.Local", | |||
| 604 | "Disconnected", | |||
| 605 | signal_disconnected, NULL((void*)0), m); | |||
| 606 | if (r < 0) | |||
| 607 | return log_error_errno(r, "Failed to request match for Disconnected message: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 607, __func__, "Failed to request match for Disconnected message: %m" ) : -abs(_e); }); | |||
| 608 | ||||
| 609 | return 0; | |||
| 610 | } | |||
| 611 | ||||
| 612 | static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) { | |||
| 613 | _cleanup_(sd_bus_unrefp)__attribute__((cleanup(sd_bus_unrefp))) sd_bus *bus = NULL((void*)0); | |||
| 614 | _cleanup_close___attribute__((cleanup(closep))) int nfd = -1; | |||
| 615 | Manager *m = userdata; | |||
| 616 | sd_id128_t id; | |||
| 617 | int r; | |||
| 618 | ||||
| 619 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/core/dbus.c", 619, __PRETTY_FUNCTION__ ); } while (0); | |||
| 620 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 620, __PRETTY_FUNCTION__ ); } while (0); | |||
| 621 | ||||
| 622 | nfd = accept4(fd, NULL((void*)0), NULL((void*)0), SOCK_NONBLOCKSOCK_NONBLOCK|SOCK_CLOEXECSOCK_CLOEXEC); | |||
| 623 | if (nfd < 0) { | |||
| 624 | log_warning_errno(errno, "Failed to accept private connection, ignoring: %m")({ int _level = ((4)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/core/dbus.c", 624, __func__, "Failed to accept private connection, ignoring: %m" ) : -abs(_e); }); | |||
| 625 | return 0; | |||
| 626 | } | |||
| 627 | ||||
| 628 | if (set_size(m->private_buses) >= CONNECTIONS_MAX4096) { | |||
| 629 | log_warning("Too many concurrent connections, refusing")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 629, __func__, "Too many concurrent connections, refusing" ) : -abs(_e); }); | |||
| 630 | return 0; | |||
| 631 | } | |||
| 632 | ||||
| 633 | r = set_ensure_allocated(&m->private_buses, NULL)internal_set_ensure_allocated(&m->private_buses, ((void *)0) ); | |||
| 634 | if (r < 0) { | |||
| 635 | log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/core/dbus.c", 635 , __func__); | |||
| 636 | return 0; | |||
| 637 | } | |||
| 638 | ||||
| 639 | r = sd_bus_new(&bus); | |||
| 640 | if (r < 0) { | |||
| 641 | log_warning_errno(r, "Failed to allocate new private connection bus: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 641, __func__, "Failed to allocate new private connection bus: %m" ) : -abs(_e); }); | |||
| 642 | return 0; | |||
| 643 | } | |||
| 644 | ||||
| 645 | (void) sd_bus_set_description(bus, "private-bus-connection"); | |||
| 646 | ||||
| 647 | r = sd_bus_set_fd(bus, nfd, nfd); | |||
| 648 | if (r < 0) { | |||
| 649 | log_warning_errno(r, "Failed to set fd on new connection bus: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 649, __func__, "Failed to set fd on new connection bus: %m" ) : -abs(_e); }); | |||
| 650 | return 0; | |||
| 651 | } | |||
| 652 | ||||
| 653 | nfd = -1; | |||
| 654 | ||||
| 655 | r = bus_check_peercred(bus); | |||
| 656 | if (r < 0) { | |||
| 657 | log_warning_errno(r, "Incoming private connection from unprivileged client, refusing: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 657, __func__, "Incoming private connection from unprivileged client, refusing: %m" ) : -abs(_e); }); | |||
| 658 | return 0; | |||
| 659 | } | |||
| 660 | ||||
| 661 | assert_se(sd_id128_randomize(&id) >= 0)do { if ((__builtin_expect(!!(!(sd_id128_randomize(&id) >= 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("sd_id128_randomize(&id) >= 0" ), "../src/core/dbus.c", 661, __PRETTY_FUNCTION__); } while ( 0); | |||
| 662 | ||||
| 663 | r = sd_bus_set_server(bus, 1, id); | |||
| 664 | if (r < 0) { | |||
| 665 | log_warning_errno(r, "Failed to enable server support for new connection bus: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 665, __func__, "Failed to enable server support for new connection bus: %m" ) : -abs(_e); }); | |||
| 666 | return 0; | |||
| 667 | } | |||
| 668 | ||||
| 669 | r = sd_bus_negotiate_creds(bus, 1, | |||
| 670 | SD_BUS_CREDS_PID|SD_BUS_CREDS_UID| | |||
| 671 | SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS| | |||
| 672 | SD_BUS_CREDS_SELINUX_CONTEXT); | |||
| 673 | if (r < 0) { | |||
| 674 | log_warning_errno(r, "Failed to enable credentials for new connection: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 674, __func__, "Failed to enable credentials for new connection: %m" ) : -abs(_e); }); | |||
| 675 | return 0; | |||
| 676 | } | |||
| 677 | ||||
| 678 | r = sd_bus_set_sender(bus, "org.freedesktop.systemd1"); | |||
| 679 | if (r < 0) { | |||
| 680 | log_warning_errno(r, "Failed to set direct connection sender: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 680, __func__, "Failed to set direct connection sender: %m" ) : -abs(_e); }); | |||
| 681 | return 0; | |||
| 682 | } | |||
| 683 | ||||
| 684 | r = sd_bus_start(bus); | |||
| 685 | if (r < 0) { | |||
| 686 | log_warning_errno(r, "Failed to start new connection bus: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 686, __func__, "Failed to start new connection bus: %m" ) : -abs(_e); }); | |||
| 687 | return 0; | |||
| 688 | } | |||
| 689 | ||||
| 690 | r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL); | |||
| 691 | if (r < 0) { | |||
| 692 | log_warning_errno(r, "Failed to attach new connection bus to event loop: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 692, __func__, "Failed to attach new connection bus to event loop: %m" ) : -abs(_e); }); | |||
| 693 | return 0; | |||
| 694 | } | |||
| 695 | ||||
| 696 | r = bus_setup_disconnected_match(m, bus); | |||
| 697 | if (r < 0) | |||
| 698 | return 0; | |||
| 699 | ||||
| 700 | r = bus_setup_api_vtables(m, bus); | |||
| 701 | if (r < 0) { | |||
| 702 | log_warning_errno(r, "Failed to set up API vtables on new connection bus: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 702, __func__, "Failed to set up API vtables on new connection bus: %m" ) : -abs(_e); }); | |||
| 703 | return 0; | |||
| 704 | } | |||
| 705 | ||||
| 706 | r = set_put(m->private_buses, bus); | |||
| 707 | if (r < 0) { | |||
| 708 | log_warning_errno(r, "Failed to add new connection bus to set: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 708, __func__, "Failed to add new connection bus to set: %m" ) : -abs(_e); }); | |||
| 709 | return 0; | |||
| 710 | } | |||
| 711 | ||||
| 712 | bus = NULL((void*)0); | |||
| 713 | ||||
| 714 | log_debug("Accepted new private connection.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 714, __func__, "Accepted new private connection." ) : -abs(_e); }); | |||
| 715 | ||||
| 716 | return 0; | |||
| 717 | } | |||
| 718 | ||||
| 719 | static int manager_dispatch_sync_bus_names(sd_event_source *es, void *userdata) { | |||
| 720 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **names = NULL((void*)0); | |||
| 721 | Manager *m = userdata; | |||
| 722 | const char *name; | |||
| 723 | Iterator i; | |||
| 724 | Unit *u; | |||
| 725 | int r; | |||
| 726 | ||||
| 727 | assert(es)do { if ((__builtin_expect(!!(!(es)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("es"), "../src/core/dbus.c", 727, __PRETTY_FUNCTION__ ); } while (0); | |||
| 728 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 728, __PRETTY_FUNCTION__ ); } while (0); | |||
| 729 | assert(m->sync_bus_names_event_source == es)do { if ((__builtin_expect(!!(!(m->sync_bus_names_event_source == es)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("m->sync_bus_names_event_source == es" ), "../src/core/dbus.c", 729, __PRETTY_FUNCTION__); } while ( 0); | |||
| 730 | ||||
| 731 | /* First things first, destroy the defer event so that we aren't triggered again */ | |||
| 732 | m->sync_bus_names_event_source = sd_event_source_unref(m->sync_bus_names_event_source); | |||
| 733 | ||||
| 734 | /* Let's see if there's anything to do still? */ | |||
| 735 | if (!m->api_bus) | |||
| 736 | return 0; | |||
| 737 | if (hashmap_isempty(m->watch_bus)) | |||
| 738 | return 0; | |||
| 739 | ||||
| 740 | /* OK, let's sync up the names. Let's see which names are currently on the bus. */ | |||
| 741 | r = sd_bus_list_names(m->api_bus, &names, NULL((void*)0)); | |||
| 742 | if (r < 0) | |||
| 743 | return log_error_errno(r, "Failed to get initial list of names: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 743, __func__, "Failed to get initial list of names: %m" ) : -abs(_e); }); | |||
| 744 | ||||
| 745 | /* We have to synchronize the current bus names with the | |||
| 746 | * list of active services. To do this, walk the list of | |||
| 747 | * all units with bus names. */ | |||
| 748 | HASHMAP_FOREACH_KEY(u, name, m->watch_bus, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); hashmap_iterate((m->watch_bus), & (i), (void**)&(u), (const void**) &(name)); ) { | |||
| 749 | Service *s = SERVICE(u); | |||
| 750 | ||||
| 751 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/core/dbus.c", 751, __PRETTY_FUNCTION__ ); } while (0); | |||
| 752 | ||||
| 753 | if (!streq_ptr(s->bus_name, name)) { | |||
| 754 | log_unit_warning(u, "Bus name has changed from %s → %s, ignoring.", s->bus_name, name)({ const Unit *_u = (u); _u ? log_object_internal(4, 0, "../src/core/dbus.c" , 754, __func__, _u->manager->unit_log_field, _u->id , _u->manager->invocation_log_field, _u->invocation_id_string , "Bus name has changed from %s → %s, ignoring.", s->bus_name , name) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4))), 0, "../src/core/dbus.c", 754, __func__, "Bus name has changed from %s → %s, ignoring." , s->bus_name, name); }); | |||
| 755 | continue; | |||
| 756 | } | |||
| 757 | ||||
| 758 | /* Check if a service's bus name is in the list of currently | |||
| 759 | * active names */ | |||
| 760 | if (strv_contains(names, name)(!!strv_find((names), (name)))) { | |||
| 761 | _cleanup_(sd_bus_creds_unrefp)__attribute__((cleanup(sd_bus_creds_unrefp))) sd_bus_creds *creds = NULL((void*)0); | |||
| 762 | const char *unique; | |||
| 763 | ||||
| 764 | /* If it is, determine its current owner */ | |||
| 765 | r = sd_bus_get_name_creds(m->api_bus, name, SD_BUS_CREDS_UNIQUE_NAME, &creds); | |||
| 766 | if (r < 0) { | |||
| 767 | log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to get bus name owner %s: %m", name)({ int _level = ((r == -6 ? 7 : 3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 767, __func__, "Failed to get bus name owner %s: %m" , name) : -abs(_e); }); | |||
| 768 | continue; | |||
| 769 | } | |||
| 770 | ||||
| 771 | r = sd_bus_creds_get_unique_name(creds, &unique); | |||
| 772 | if (r < 0) { | |||
| 773 | log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to get unique name for %s: %m", name)({ int _level = ((r == -6 ? 7 : 3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 773, __func__, "Failed to get unique name for %s: %m" , name) : -abs(_e); }); | |||
| 774 | continue; | |||
| 775 | } | |||
| 776 | ||||
| 777 | /* Now, let's compare that to the previous bus owner, and | |||
| 778 | * if it's still the same, all is fine, so just don't | |||
| 779 | * bother the service. Otherwise, the name has apparently | |||
| 780 | * changed, so synthesize a name owner changed signal. */ | |||
| 781 | ||||
| 782 | if (!streq_ptr(unique, s->bus_name_owner)) | |||
| 783 | UNIT_VTABLE(u)unit_vtable[(u)->type]->bus_name_owner_change(u, name, s->bus_name_owner, unique); | |||
| 784 | } else { | |||
| 785 | /* So, the name we're watching is not on the bus. | |||
| 786 | * This either means it simply hasn't appeared yet, | |||
| 787 | * or it was lost during the daemon reload. | |||
| 788 | * Check if the service has a stored name owner, | |||
| 789 | * and synthesize a name loss signal in this case. */ | |||
| 790 | ||||
| 791 | if (s->bus_name_owner) | |||
| 792 | UNIT_VTABLE(u)unit_vtable[(u)->type]->bus_name_owner_change(u, name, s->bus_name_owner, NULL((void*)0)); | |||
| 793 | } | |||
| 794 | } | |||
| 795 | ||||
| 796 | return 0; | |||
| 797 | } | |||
| 798 | ||||
| 799 | int manager_enqueue_sync_bus_names(Manager *m) { | |||
| 800 | int r; | |||
| 801 | ||||
| 802 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 802, __PRETTY_FUNCTION__ ); } while (0); | |||
| 803 | ||||
| 804 | /* Enqueues a request to synchronize the bus names in a later event loop iteration. The callers generally don't | |||
| 805 | * want us to invoke ->bus_name_owner_change() unit calls from their stack frames as this might result in event | |||
| 806 | * dispatching on its own creating loops, hence we simply create a defer event for the event loop and exit. */ | |||
| 807 | ||||
| 808 | if (m->sync_bus_names_event_source) | |||
| 809 | return 0; | |||
| 810 | ||||
| 811 | r = sd_event_add_defer(m->event, &m->sync_bus_names_event_source, manager_dispatch_sync_bus_names, m); | |||
| 812 | if (r < 0) | |||
| 813 | return log_error_errno(r, "Failed to create bus name synchronization event: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 813, __func__, "Failed to create bus name synchronization event: %m" ) : -abs(_e); }); | |||
| 814 | ||||
| 815 | r = sd_event_source_set_priority(m->sync_bus_names_event_source, SD_EVENT_PRIORITY_IDLE); | |||
| 816 | if (r < 0) | |||
| 817 | return log_error_errno(r, "Failed to set event priority: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 817, __func__, "Failed to set event priority: %m" ) : -abs(_e); }); | |||
| 818 | ||||
| 819 | r = sd_event_source_set_enabled(m->sync_bus_names_event_source, SD_EVENT_ONESHOT); | |||
| 820 | if (r < 0) | |||
| 821 | return log_error_errno(r, "Failed to set even to oneshot: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 821, __func__, "Failed to set even to oneshot: %m" ) : -abs(_e); }); | |||
| 822 | ||||
| 823 | (void) sd_event_source_set_description(m->sync_bus_names_event_source, "manager-sync-bus-names"); | |||
| 824 | return 0; | |||
| 825 | } | |||
| 826 | ||||
| 827 | static int bus_setup_api(Manager *m, sd_bus *bus) { | |||
| 828 | Iterator i; | |||
| 829 | char *name; | |||
| 830 | Unit *u; | |||
| 831 | int r; | |||
| 832 | ||||
| 833 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 833, __PRETTY_FUNCTION__ ); } while (0); | |||
| 834 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 834, __PRETTY_FUNCTION__ ); } while (0); | |||
| 835 | ||||
| 836 | /* Let's make sure we have enough credential bits so that we can make security and selinux decisions */ | |||
| 837 | r = sd_bus_negotiate_creds(bus, 1, | |||
| 838 | SD_BUS_CREDS_PID|SD_BUS_CREDS_UID| | |||
| 839 | SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS| | |||
| 840 | SD_BUS_CREDS_SELINUX_CONTEXT); | |||
| 841 | if (r < 0) | |||
| 842 | log_warning_errno(r, "Failed to enable credential passing, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 842, __func__, "Failed to enable credential passing, ignoring: %m" ) : -abs(_e); }); | |||
| 843 | ||||
| 844 | r = bus_setup_api_vtables(m, bus); | |||
| 845 | if (r < 0) | |||
| 846 | return r; | |||
| 847 | ||||
| 848 | HASHMAP_FOREACH_KEY(u, name, m->watch_bus, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); hashmap_iterate((m->watch_bus), & (i), (void**)&(u), (const void**) &(name)); ) { | |||
| 849 | r = unit_install_bus_match(u, bus, name); | |||
| 850 | if (r < 0) | |||
| 851 | log_error_errno(r, "Failed to subscribe to NameOwnerChanged signal for '%s': %m", name)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 851, __func__, "Failed to subscribe to NameOwnerChanged signal for '%s': %m" , name) : -abs(_e); }); | |||
| 852 | } | |||
| 853 | ||||
| 854 | r = sd_bus_match_signal_async( | |||
| 855 | bus, | |||
| 856 | NULL((void*)0), | |||
| 857 | "org.freedesktop.DBus", | |||
| 858 | "/org/freedesktop/DBus", | |||
| 859 | "org.freedesktop.systemd1.Activator", | |||
| 860 | "ActivationRequest", | |||
| 861 | signal_activation_request, NULL((void*)0), m); | |||
| 862 | if (r < 0) | |||
| 863 | log_warning_errno(r, "Failed to subscribe to activation signal: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 863, __func__, "Failed to subscribe to activation signal: %m" ) : -abs(_e); }); | |||
| 864 | ||||
| 865 | /* Allow replacing of our name, to ease implementation of reexecution, where we keep the old connection open | |||
| 866 | * until after the new connection is set up and the name installed to allow clients to synchronously wait for | |||
| 867 | * reexecution to finish */ | |||
| 868 | r = sd_bus_request_name_async(bus, NULL((void*)0), "org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_ALLOW_REPLACEMENT, NULL((void*)0), NULL((void*)0)); | |||
| 869 | if (r < 0) | |||
| 870 | return log_error_errno(r, "Failed to request name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 870, __func__, "Failed to request name: %m" ) : -abs(_e); }); | |||
| 871 | ||||
| 872 | log_debug("Successfully connected to API bus.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 872, __func__, "Successfully connected to API bus." ) : -abs(_e); }); | |||
| 873 | ||||
| 874 | return 0; | |||
| 875 | } | |||
| 876 | ||||
| 877 | int bus_init_api(Manager *m) { | |||
| 878 | _cleanup_(sd_bus_unrefp)__attribute__((cleanup(sd_bus_unrefp))) sd_bus *bus = NULL((void*)0); | |||
| 879 | int r; | |||
| 880 | ||||
| 881 | if (m->api_bus) | |||
| 882 | return 0; | |||
| 883 | ||||
| 884 | /* The API and system bus is the same if we are running in system mode */ | |||
| 885 | if (MANAGER_IS_SYSTEM(m)((m)->unit_file_scope == UNIT_FILE_SYSTEM) && m->system_bus) | |||
| 886 | bus = sd_bus_ref(m->system_bus); | |||
| 887 | else { | |||
| 888 | if (MANAGER_IS_SYSTEM(m)((m)->unit_file_scope == UNIT_FILE_SYSTEM)) | |||
| 889 | r = sd_bus_open_system_with_description(&bus, "bus-api-system"); | |||
| 890 | else | |||
| 891 | r = sd_bus_open_user_with_description(&bus, "bus-api-user"); | |||
| 892 | if (r < 0) | |||
| 893 | return log_error_errno(r, "Failed to connect to API bus: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 893, __func__, "Failed to connect to API bus: %m" ) : -abs(_e); }); | |||
| 894 | ||||
| 895 | r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL); | |||
| 896 | if (r < 0) | |||
| 897 | return log_error_errno(r, "Failed to attach API bus to event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 897, __func__, "Failed to attach API bus to event loop: %m" ) : -abs(_e); }); | |||
| 898 | ||||
| 899 | r = bus_setup_disconnected_match(m, bus); | |||
| 900 | if (r < 0) | |||
| 901 | return r; | |||
| 902 | } | |||
| 903 | ||||
| 904 | r = bus_setup_api(m, bus); | |||
| 905 | if (r < 0) | |||
| 906 | return log_error_errno(r, "Failed to set up API bus: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 906, __func__, "Failed to set up API bus: %m" ) : -abs(_e); }); | |||
| 907 | ||||
| 908 | m->api_bus = TAKE_PTR(bus)({ typeof(bus) _ptr_ = (bus); (bus) = ((void*)0); _ptr_; }); | |||
| 909 | ||||
| 910 | r = manager_enqueue_sync_bus_names(m); | |||
| 911 | if (r < 0) | |||
| 912 | return r; | |||
| 913 | ||||
| 914 | return 0; | |||
| 915 | } | |||
| 916 | ||||
| 917 | static int bus_setup_system(Manager *m, sd_bus *bus) { | |||
| 918 | int r; | |||
| 919 | ||||
| 920 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 920, __PRETTY_FUNCTION__ ); } while (0); | |||
| 921 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 921, __PRETTY_FUNCTION__ ); } while (0); | |||
| 922 | ||||
| 923 | /* if we are a user instance we get the Released message via the system bus */ | |||
| 924 | if (MANAGER_IS_USER(m)((m)->unit_file_scope != UNIT_FILE_SYSTEM)) { | |||
| 925 | r = sd_bus_match_signal_async( | |||
| 926 | bus, | |||
| 927 | NULL((void*)0), | |||
| 928 | NULL((void*)0), | |||
| 929 | "/org/freedesktop/systemd1/agent", | |||
| 930 | "org.freedesktop.systemd1.Agent", | |||
| 931 | "Released", | |||
| 932 | signal_agent_released, NULL((void*)0), m); | |||
| 933 | if (r < 0) | |||
| 934 | log_warning_errno(r, "Failed to request Released match on system bus: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 934, __func__, "Failed to request Released match on system bus: %m" ) : -abs(_e); }); | |||
| 935 | } | |||
| 936 | ||||
| 937 | log_debug("Successfully connected to system bus.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 937, __func__, "Successfully connected to system bus." ) : -abs(_e); }); | |||
| 938 | return 0; | |||
| 939 | } | |||
| 940 | ||||
| 941 | int bus_init_system(Manager *m) { | |||
| 942 | _cleanup_(sd_bus_unrefp)__attribute__((cleanup(sd_bus_unrefp))) sd_bus *bus = NULL((void*)0); | |||
| 943 | int r; | |||
| 944 | ||||
| 945 | if (m->system_bus) | |||
| 946 | return 0; | |||
| 947 | ||||
| 948 | /* The API and system bus is the same if we are running in system mode */ | |||
| 949 | if (MANAGER_IS_SYSTEM(m)((m)->unit_file_scope == UNIT_FILE_SYSTEM) && m->api_bus) | |||
| 950 | bus = sd_bus_ref(m->api_bus); | |||
| 951 | else { | |||
| 952 | r = sd_bus_open_system_with_description(&bus, "bus-system"); | |||
| 953 | if (r < 0) | |||
| 954 | return log_error_errno(r, "Failed to connect to system bus: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 954, __func__, "Failed to connect to system bus: %m" ) : -abs(_e); }); | |||
| 955 | ||||
| 956 | r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL); | |||
| 957 | if (r < 0) | |||
| 958 | return log_error_errno(r, "Failed to attach system bus to event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 958, __func__, "Failed to attach system bus to event loop: %m" ) : -abs(_e); }); | |||
| 959 | ||||
| 960 | r = bus_setup_disconnected_match(m, bus); | |||
| 961 | if (r < 0) | |||
| 962 | return r; | |||
| 963 | } | |||
| 964 | ||||
| 965 | r = bus_setup_system(m, bus); | |||
| 966 | if (r < 0) | |||
| 967 | return log_error_errno(r, "Failed to set up system bus: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 967, __func__, "Failed to set up system bus: %m" ) : -abs(_e); }); | |||
| 968 | ||||
| 969 | m->system_bus = TAKE_PTR(bus)({ typeof(bus) _ptr_ = (bus); (bus) = ((void*)0); _ptr_; }); | |||
| 970 | ||||
| 971 | return 0; | |||
| 972 | } | |||
| 973 | ||||
| 974 | int bus_init_private(Manager *m) { | |||
| 975 | _cleanup_close___attribute__((cleanup(closep))) int fd = -1; | |||
| 976 | union sockaddr_union sa = { | |||
| 977 | .un.sun_family = AF_UNIX1 | |||
| 978 | }; | |||
| 979 | sd_event_source *s; | |||
| 980 | socklen_t salen; | |||
| 981 | int r; | |||
| 982 | ||||
| 983 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 983, __PRETTY_FUNCTION__ ); } while (0); | |||
| 984 | ||||
| 985 | if (m->private_listen_fd >= 0) | |||
| 986 | return 0; | |||
| 987 | ||||
| 988 | if (MANAGER_IS_SYSTEM(m)((m)->unit_file_scope == UNIT_FILE_SYSTEM)) { | |||
| 989 | ||||
| 990 | /* We want the private bus only when running as init */ | |||
| 991 | if (getpid_cached() != 1) | |||
| 992 | return 0; | |||
| 993 | ||||
| 994 | strcpy(sa.un.sun_path, "/run/systemd/private"); | |||
| 995 | salen = SOCKADDR_UN_LEN(sa.un)({ const struct sockaddr_un *_sa = &(sa.un); do { if ((__builtin_expect (!!(!(_sa->sun_family == 1)),0))) log_assert_failed_realm( LOG_REALM_SYSTEMD, ("_sa->sun_family == AF_UNIX"), "../src/core/dbus.c" , 995, __PRETTY_FUNCTION__); } while (0); __builtin_offsetof( struct sockaddr_un, sun_path) + (_sa->sun_path[0] == 0 ? 1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : strnlen (_sa->sun_path, sizeof(_sa->sun_path))); }); | |||
| 996 | } else { | |||
| 997 | size_t left = sizeof(sa.un.sun_path); | |||
| 998 | char *p = sa.un.sun_path; | |||
| 999 | const char *e; | |||
| 1000 | ||||
| 1001 | e = secure_getenv("XDG_RUNTIME_DIR"); | |||
| 1002 | if (!e) { | |||
| 1003 | log_error("Failed to determine XDG_RUNTIME_DIR")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 1003, __func__, "Failed to determine XDG_RUNTIME_DIR" ) : -abs(_e); }); | |||
| 1004 | return -EHOSTDOWN112; | |||
| 1005 | } | |||
| 1006 | ||||
| 1007 | left = strpcpy(&p, left, e); | |||
| 1008 | left = strpcpy(&p, left, "/systemd/private"); | |||
| 1009 | ||||
| 1010 | salen = sizeof(sa.un) - left; | |||
| 1011 | } | |||
| 1012 | ||||
| 1013 | (void) mkdir_parents_label(sa.un.sun_path, 0755); | |||
| 1014 | (void) unlink(sa.un.sun_path); | |||
| 1015 | ||||
| 1016 | fd = socket(AF_UNIX1, SOCK_STREAMSOCK_STREAM|SOCK_CLOEXECSOCK_CLOEXEC|SOCK_NONBLOCKSOCK_NONBLOCK, 0); | |||
| 1017 | if (fd < 0) | |||
| 1018 | return log_error_errno(errno, "Failed to allocate private socket: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/core/dbus.c", 1018, __func__, "Failed to allocate private socket: %m" ) : -abs(_e); }); | |||
| 1019 | ||||
| 1020 | r = bind(fd, &sa.sa, salen); | |||
| 1021 | if (r < 0) | |||
| 1022 | return log_error_errno(errno, "Failed to bind private socket: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/core/dbus.c", 1022, __func__, "Failed to bind private socket: %m" ) : -abs(_e); }); | |||
| 1023 | ||||
| 1024 | r = listen(fd, SOMAXCONN4096); | |||
| 1025 | if (r < 0) | |||
| 1026 | return log_error_errno(errno, "Failed to make private socket listening: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/core/dbus.c", 1026, __func__, "Failed to make private socket listening: %m" ) : -abs(_e); }); | |||
| 1027 | ||||
| 1028 | /* Generate an inotify event in case somebody waits for this socket to appear using inotify() */ | |||
| 1029 | (void) touch(sa.un.sun_path); | |||
| 1030 | ||||
| 1031 | r = sd_event_add_io(m->event, &s, fd, EPOLLINEPOLLIN, bus_on_connection, m); | |||
| 1032 | if (r < 0) | |||
| 1033 | return log_error_errno(r, "Failed to allocate event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 1033, __func__, "Failed to allocate event source: %m" ) : -abs(_e); }); | |||
| 1034 | ||||
| 1035 | (void) sd_event_source_set_description(s, "bus-connection"); | |||
| 1036 | ||||
| 1037 | m->private_listen_fd = fd; | |||
| 1038 | m->private_listen_event_source = s; | |||
| 1039 | fd = -1; | |||
| 1040 | ||||
| 1041 | log_debug("Successfully created private D-Bus server.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 1041, __func__, "Successfully created private D-Bus server." ) : -abs(_e); }); | |||
| 1042 | ||||
| 1043 | return 0; | |||
| 1044 | } | |||
| 1045 | ||||
| 1046 | static void destroy_bus(Manager *m, sd_bus **bus) { | |||
| 1047 | Iterator i; | |||
| 1048 | Unit *u; | |||
| 1049 | Job *j; | |||
| 1050 | ||||
| 1051 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 1051, __PRETTY_FUNCTION__ ); } while (0); | |||
| 1052 | assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 1052, __PRETTY_FUNCTION__ ); } while (0); | |||
| 1053 | ||||
| 1054 | if (!*bus) | |||
| 1055 | return; | |||
| 1056 | ||||
| 1057 | /* Make sure all bus slots watching names are released. */ | |||
| 1058 | HASHMAP_FOREACH(u, m->watch_bus, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); hashmap_iterate((m->watch_bus), & (i), (void**)&(u), ((void*)0)); ) { | |||
| 1059 | if (!u->match_bus_slot) | |||
| 1060 | continue; | |||
| 1061 | ||||
| 1062 | if (sd_bus_slot_get_bus(u->match_bus_slot) != *bus) | |||
| 1063 | continue; | |||
| 1064 | ||||
| 1065 | u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot); | |||
| 1066 | } | |||
| 1067 | ||||
| 1068 | /* Get rid of tracked clients on this bus */ | |||
| 1069 | if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus) | |||
| 1070 | m->subscribed = sd_bus_track_unref(m->subscribed); | |||
| 1071 | ||||
| 1072 | HASHMAP_FOREACH(j, m->jobs, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); hashmap_iterate((m->jobs), & (i), (void**)&(j), ((void*)0)); ) | |||
| 1073 | if (j->bus_track && sd_bus_track_get_bus(j->bus_track) == *bus) | |||
| 1074 | j->bus_track = sd_bus_track_unref(j->bus_track); | |||
| 1075 | ||||
| 1076 | HASHMAP_FOREACH(u, m->units, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); hashmap_iterate((m->units), & (i), (void**)&(u), ((void*)0)); ) { | |||
| 1077 | if (u->bus_track && sd_bus_track_get_bus(u->bus_track) == *bus) | |||
| 1078 | u->bus_track = sd_bus_track_unref(u->bus_track); | |||
| 1079 | ||||
| 1080 | /* Get rid of pending freezer messages on this bus */ | |||
| 1081 | if (u->pending_freezer_message && sd_bus_message_get_bus(u->pending_freezer_message) == *bus) | |||
| 1082 | u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message); | |||
| 1083 | } | |||
| 1084 | ||||
| 1085 | /* Get rid of queued message on this bus */ | |||
| 1086 | if (m->pending_reload_message && sd_bus_message_get_bus(m->pending_reload_message) == *bus) | |||
| 1087 | m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message); | |||
| 1088 | ||||
| 1089 | /* Possibly flush unwritten data, but only if we are | |||
| 1090 | * unprivileged, since we don't want to sync here */ | |||
| 1091 | if (!MANAGER_IS_SYSTEM(m)((m)->unit_file_scope == UNIT_FILE_SYSTEM)) | |||
| 1092 | sd_bus_flush(*bus); | |||
| 1093 | ||||
| 1094 | /* And destroy the object */ | |||
| 1095 | sd_bus_close(*bus); | |||
| 1096 | *bus = sd_bus_unref(*bus); | |||
| 1097 | } | |||
| 1098 | ||||
| 1099 | void bus_done_api(Manager *m) { | |||
| 1100 | destroy_bus(m, &m->api_bus); | |||
| 1101 | } | |||
| 1102 | ||||
| 1103 | void bus_done_system(Manager *m) { | |||
| 1104 | destroy_bus(m, &m->system_bus); | |||
| 1105 | } | |||
| 1106 | ||||
| 1107 | void bus_done_private(Manager *m) { | |||
| 1108 | sd_bus *b; | |||
| 1109 | ||||
| 1110 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 1110, __PRETTY_FUNCTION__ ); } while (0); | |||
| 1111 | ||||
| 1112 | while ((b = set_steal_first(m->private_buses))) | |||
| 1113 | destroy_bus(m, &b); | |||
| 1114 | ||||
| 1115 | m->private_buses = set_free(m->private_buses); | |||
| 1116 | ||||
| 1117 | m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source); | |||
| 1118 | m->private_listen_fd = safe_close(m->private_listen_fd); | |||
| 1119 | } | |||
| 1120 | ||||
| 1121 | void bus_done(Manager *m) { | |||
| 1122 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 1122, __PRETTY_FUNCTION__ ); } while (0); | |||
| 1123 | ||||
| 1124 | bus_done_api(m); | |||
| 1125 | bus_done_system(m); | |||
| 1126 | bus_done_private(m); | |||
| 1127 | ||||
| 1128 | assert(!m->subscribed)do { if ((__builtin_expect(!!(!(!m->subscribed)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("!m->subscribed"), "../src/core/dbus.c" , 1128, __PRETTY_FUNCTION__); } while (0); | |||
| 1129 | ||||
| 1130 | m->deserialized_subscribed = strv_free(m->deserialized_subscribed); | |||
| 1131 | bus_verify_polkit_async_registry_free(m->polkit_registry); | |||
| 1132 | } | |||
| 1133 | ||||
| 1134 | int bus_fdset_add_all(Manager *m, FDSet *fds) { | |||
| 1135 | Iterator i; | |||
| 1136 | sd_bus *b; | |||
| 1137 | int fd; | |||
| 1138 | ||||
| 1139 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 1139, __PRETTY_FUNCTION__ ); } while (0); | |||
| 1140 | assert(fds)do { if ((__builtin_expect(!!(!(fds)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("fds"), "../src/core/dbus.c", 1140, __PRETTY_FUNCTION__ ); } while (0); | |||
| 1141 | ||||
| 1142 | /* When we are about to reexecute we add all D-Bus fds to the | |||
| 1143 | * set to pass over to the newly executed systemd. They won't | |||
| 1144 | * be used there however, except thatt they are closed at the | |||
| 1145 | * very end of deserialization, those making it possible for | |||
| 1146 | * clients to synchronously wait for systemd to reexec by | |||
| 1147 | * simply waiting for disconnection */ | |||
| 1148 | ||||
| 1149 | if (m->api_bus) { | |||
| 1150 | fd = sd_bus_get_fd(m->api_bus); | |||
| 1151 | if (fd >= 0) { | |||
| 1152 | fd = fdset_put_dup(fds, fd); | |||
| 1153 | if (fd < 0) | |||
| 1154 | return fd; | |||
| 1155 | } | |||
| 1156 | } | |||
| 1157 | ||||
| 1158 | SET_FOREACH(b, m->private_buses, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); set_iterate((m->private_buses), & (i), (void**)&(b)); ) { | |||
| 1159 | fd = sd_bus_get_fd(b); | |||
| 1160 | if (fd >= 0) { | |||
| 1161 | fd = fdset_put_dup(fds, fd); | |||
| 1162 | if (fd < 0) | |||
| 1163 | return fd; | |||
| 1164 | } | |||
| 1165 | } | |||
| 1166 | ||||
| 1167 | /* We don't offer any APIs on the system bus (well, unless it | |||
| 1168 | * is the same as the API bus) hence we don't bother with it | |||
| 1169 | * here */ | |||
| 1170 | ||||
| 1171 | return 0; | |||
| 1172 | } | |||
| 1173 | ||||
| 1174 | int bus_foreach_bus( | |||
| 1175 | Manager *m, | |||
| 1176 | sd_bus_track *subscribed2, | |||
| 1177 | int (*send_message)(sd_bus *bus, void *userdata), | |||
| 1178 | void *userdata) { | |||
| 1179 | ||||
| 1180 | Iterator i; | |||
| 1181 | sd_bus *b; | |||
| 1182 | int r, ret = 0; | |||
| 1183 | ||||
| 1184 | /* Send to all direct buses, unconditionally */ | |||
| 1185 | SET_FOREACH(b, m->private_buses, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); set_iterate((m->private_buses), & (i), (void**)&(b)); ) { | |||
| 1186 | ||||
| 1187 | /* Don't bother with enqueing these messages to clients that haven't started yet */ | |||
| 1188 | if (sd_bus_is_ready(b) <= 0) | |||
| 1189 | continue; | |||
| 1190 | ||||
| 1191 | r = send_message(b, userdata); | |||
| 1192 | if (r < 0) | |||
| 1193 | ret = r; | |||
| 1194 | } | |||
| 1195 | ||||
| 1196 | /* Send to API bus, but only if somebody is subscribed */ | |||
| 1197 | if (m->api_bus && | |||
| 1198 | (sd_bus_track_count(m->subscribed) > 0 || | |||
| 1199 | sd_bus_track_count(subscribed2) > 0)) { | |||
| 1200 | r = send_message(m->api_bus, userdata); | |||
| 1201 | if (r < 0) | |||
| 1202 | ret = r; | |||
| 1203 | } | |||
| 1204 | ||||
| 1205 | return ret; | |||
| 1206 | } | |||
| 1207 | ||||
| 1208 | void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix) { | |||
| 1209 | const char *n; | |||
| 1210 | ||||
| 1211 | assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("f"), "../src/core/dbus.c", 1211, __PRETTY_FUNCTION__ ); } while (0); | |||
| 1212 | assert(prefix)do { if ((__builtin_expect(!!(!(prefix)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("prefix"), "../src/core/dbus.c", 1212, __PRETTY_FUNCTION__ ); } while (0); | |||
| 1213 | ||||
| 1214 | for (n = sd_bus_track_first(t); n; n = sd_bus_track_next(t)) { | |||
| 1215 | int c, j; | |||
| 1216 | ||||
| 1217 | c = sd_bus_track_count_name(t, n); | |||
| 1218 | ||||
| 1219 | for (j = 0; j < c; j++) { | |||
| 1220 | fputs(prefix, f); | |||
| 1221 | fputc('=', f); | |||
| 1222 | fputs(n, f); | |||
| 1223 | fputc('\n', f); | |||
| 1224 | } | |||
| 1225 | } | |||
| 1226 | } | |||
| 1227 | ||||
| 1228 | int bus_track_coldplug(Manager *m, sd_bus_track **t, bool_Bool recursive, char **l) { | |||
| 1229 | int r = 0; | |||
| 1230 | ||||
| 1231 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 1231, __PRETTY_FUNCTION__ ); } while (0); | |||
| 1232 | assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("t"), "../src/core/dbus.c", 1232, __PRETTY_FUNCTION__ ); } while (0); | |||
| 1233 | ||||
| 1234 | if (strv_isempty(l)) | |||
| 1235 | return 0; | |||
| 1236 | ||||
| 1237 | if (!m->api_bus) | |||
| 1238 | return 0; | |||
| 1239 | ||||
| 1240 | if (!*t) { | |||
| 1241 | r = sd_bus_track_new(m->api_bus, t, NULL((void*)0), NULL((void*)0)); | |||
| 1242 | if (r < 0) | |||
| 1243 | return r; | |||
| 1244 | } | |||
| 1245 | ||||
| 1246 | r = sd_bus_track_set_recursive(*t, recursive); | |||
| 1247 | if (r < 0) | |||
| 1248 | return r; | |||
| 1249 | ||||
| 1250 | return bus_track_add_name_many(*t, l); | |||
| 1251 | } | |||
| 1252 | ||||
| 1253 | int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error *error) { | |||
| 1254 | return bus_verify_polkit_async(call, CAP_SYS_ADMIN21, "org.freedesktop.systemd1.manage-units", NULL((void*)0), false0, UID_INVALID((uid_t) -1), &m->polkit_registry, error); | |||
| 1255 | } | |||
| 1256 | ||||
| 1257 | int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error) { | |||
| 1258 | return bus_verify_polkit_async(call, CAP_SYS_ADMIN21, "org.freedesktop.systemd1.manage-unit-files", NULL((void*)0), false0, UID_INVALID((uid_t) -1), &m->polkit_registry, error); | |||
| 1259 | } | |||
| 1260 | ||||
| 1261 | int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error) { | |||
| 1262 | return bus_verify_polkit_async(call, CAP_SYS_ADMIN21, "org.freedesktop.systemd1.reload-daemon", NULL((void*)0), false0, UID_INVALID((uid_t) -1), &m->polkit_registry, error); | |||
| 1263 | } | |||
| 1264 | ||||
| 1265 | int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error) { | |||
| 1266 | return bus_verify_polkit_async(call, CAP_SYS_ADMIN21, "org.freedesktop.systemd1.set-environment", NULL((void*)0), false0, UID_INVALID((uid_t) -1), &m->polkit_registry, error); | |||
| 1267 | } | |||
| 1268 | ||||
| 1269 | uint64_t manager_bus_n_queued_write(Manager *m) { | |||
| 1270 | uint64_t c = 0; | |||
| 1271 | Iterator i; | |||
| 1272 | sd_bus *b; | |||
| 1273 | int r; | |||
| 1274 | ||||
| 1275 | /* Returns the total number of messages queued for writing on all our direct and API busses. */ | |||
| 1276 | ||||
| 1277 | SET_FOREACH(b, m->private_buses, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); set_iterate((m->private_buses), & (i), (void**)&(b)); ) { | |||
| 1278 | uint64_t k; | |||
| 1279 | ||||
| 1280 | r = sd_bus_get_n_queued_write(b, &k); | |||
| 1281 | if (r < 0) | |||
| 1282 | log_debug_errno(r, "Failed to query queued messages for private bus: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 1282, __func__, "Failed to query queued messages for private bus: %m" ) : -abs(_e); }); | |||
| 1283 | else | |||
| 1284 | c += k; | |||
| 1285 | } | |||
| 1286 | ||||
| 1287 | if (m->api_bus) { | |||
| 1288 | uint64_t k; | |||
| 1289 | ||||
| 1290 | r = sd_bus_get_n_queued_write(m->api_bus, &k); | |||
| 1291 | if (r < 0) | |||
| 1292 | log_debug_errno(r, "Failed to query queued messages for API bus: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/dbus.c", 1292, __func__, "Failed to query queued messages for API bus: %m" ) : -abs(_e); }); | |||
| 1293 | else | |||
| 1294 | c += k; | |||
| 1295 | } | |||
| 1296 | ||||
| 1297 | return c; | |||
| 1298 | } | |||
| 1299 | ||||
| 1300 | static void vtable_dump_bus_properties(FILE *f, const sd_bus_vtable *table) { | |||
| 1301 | const sd_bus_vtable *i; | |||
| 1302 | ||||
| 1303 | for (i = table; i->type != _SD_BUS_VTABLE_END; i++) { | |||
| 1304 | if (!IN_SET(i->type, _SD_BUS_VTABLE_PROPERTY, _SD_BUS_VTABLE_WRITABLE_PROPERTY)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){_SD_BUS_VTABLE_PROPERTY, _SD_BUS_VTABLE_WRITABLE_PROPERTY })/sizeof(int)]; switch(i->type) { case _SD_BUS_VTABLE_PROPERTY : case _SD_BUS_VTABLE_WRITABLE_PROPERTY: _found = 1; break; default : break; } _found; }) || | |||
| 1305 | (i->flags & (SD_BUS_VTABLE_DEPRECATED | SD_BUS_VTABLE_HIDDEN)) != 0) | |||
| 1306 | continue; | |||
| 1307 | ||||
| 1308 | fprintf(f, "%s\n", i->x.property.member); | |||
| 1309 | } | |||
| 1310 | } | |||
| 1311 | ||||
| 1312 | void dump_bus_properties(FILE *f) { | |||
| 1313 | assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("f"), "../src/core/dbus.c", 1313, __PRETTY_FUNCTION__ ); } while (0); | |||
| 1314 | ||||
| 1315 | vtable_dump_bus_properties(f, bus_automount_vtable); | |||
| 1316 | vtable_dump_bus_properties(f, bus_cgroup_vtable); | |||
| 1317 | vtable_dump_bus_properties(f, bus_device_vtable); | |||
| 1318 | vtable_dump_bus_properties(f, bus_exec_vtable); | |||
| 1319 | vtable_dump_bus_properties(f, bus_job_vtable); | |||
| 1320 | vtable_dump_bus_properties(f, bus_kill_vtable); | |||
| 1321 | vtable_dump_bus_properties(f, bus_manager_vtable); | |||
| 1322 | vtable_dump_bus_properties(f, bus_mount_vtable); | |||
| 1323 | vtable_dump_bus_properties(f, bus_path_vtable); | |||
| 1324 | vtable_dump_bus_properties(f, bus_scope_vtable); | |||
| 1325 | vtable_dump_bus_properties(f, bus_service_vtable); | |||
| 1326 | vtable_dump_bus_properties(f, bus_slice_vtable); | |||
| 1327 | vtable_dump_bus_properties(f, bus_socket_vtable); | |||
| 1328 | vtable_dump_bus_properties(f, bus_swap_vtable); | |||
| 1329 | vtable_dump_bus_properties(f, bus_target_vtable); | |||
| 1330 | vtable_dump_bus_properties(f, bus_timer_vtable); | |||
| 1331 | vtable_dump_bus_properties(f, bus_unit_vtable); | |||
| 1332 | vtable_dump_bus_properties(f, bus_unit_cgroup_vtable); | |||
| 1333 | } |