X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fdbus.c;h=4365bca7bf6de7253587046ddb46348c2662a600;hp=340e6af2c79c2e004904a893aee8d5ad947226c4;hb=7af53310dd9154ba76be7808292d9a046b849e43;hpb=d6c9574fb558d9e304699b1cc7522c3b133adfc9 diff --git a/src/dbus.c b/src/dbus.c index 340e6af2c..4365bca7b 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -43,6 +43,7 @@ #include "dbus-timer.h" #include "dbus-path.h" #include "bus-errors.h" +#include "special.h" #define CONNECTIONS_MAX 52 @@ -346,7 +347,7 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBus dbus_message_get_path(message)); if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { - log_error("Warning! API D-Bus connection terminated."); + log_debug("API D-Bus connection terminated."); bus_done_api(m); } else if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) { @@ -383,18 +384,24 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBus log_debug("Got D-Bus activation request for %s", name); - r = manager_load_unit(m, name, NULL, &error, &u); + if (manager_unit_pending_inactive(m, SPECIAL_DBUS_SERVICE) || + manager_unit_pending_inactive(m, SPECIAL_DBUS_SOCKET)) { + r = -EADDRNOTAVAIL; + dbus_set_error(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down."); + } else { + r = manager_load_unit(m, name, NULL, &error, &u); - if (r >= 0 && u->meta.refuse_manual_start) - r = -EPERM; + if (r >= 0 && u->meta.refuse_manual_start) + r = -EPERM; - if (r >= 0) - r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL); + if (r >= 0) + r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL); + } if (r < 0) { const char *id, *text; - log_warning("D-Bus activation failed for %s: %s", name, strerror(-r)); + log_debug("D-Bus activation failed for %s: %s", name, strerror(-r)); if (!(reply = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure"))) goto oom; @@ -457,7 +464,9 @@ static DBusHandlerResult system_bus_message_filter(DBusConnection *connection, D log_debug("System D-Bus connection terminated."); bus_done_system(m); - } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { + } else if (m->running_as != MANAGER_SYSTEM && + dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { + const char *cgroup; if (!dbus_message_get_args(message, &error, @@ -491,7 +500,9 @@ static DBusHandlerResult private_bus_message_filter(DBusConnection *connection, if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) shutdown_connection(m, connection); - else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { + else if (m->running_as == MANAGER_SYSTEM && + dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { + const char *cgroup; if (!dbus_message_get_args(message, &error, @@ -500,6 +511,12 @@ static DBusHandlerResult private_bus_message_filter(DBusConnection *connection, log_error("Failed to parse Released message: %s", error.message); else cgroup_notify_empty(m, cgroup); + + /* Forward the message to the system bus, so that user + * instances are notified as well */ + + if (m->system_bus) + dbus_connection_send(m->system_bus, message, NULL); } dbus_error_free(&error); @@ -801,17 +818,19 @@ static int bus_init_system(Manager *m) { goto fail; } - dbus_bus_add_match(m->system_bus, - "type='signal'," - "interface='org.freedesktop.systemd1.Agent'," - "member='Released'," - "path='/org/freedesktop/systemd1/agent'", - &error); - - if (dbus_error_is_set(&error)) { - log_error("Failed to register match: %s", error.message); - r = -EIO; - goto fail; + if (m->running_as != MANAGER_SYSTEM) { + dbus_bus_add_match(m->system_bus, + "type='signal'," + "interface='org.freedesktop.systemd1.Agent'," + "member='Released'," + "path='/org/freedesktop/systemd1/agent'", + &error); + + if (dbus_error_is_set(&error)) { + log_error("Failed to register match: %s", error.message); + r = -EIO; + goto fail; + } } if (m->api_bus != m->system_bus) { @@ -1247,6 +1266,7 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu if (!dbus_message_iter_close_container(&iter, &sub)) goto oom; } + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "GetAll") && properties) { const char *interface; const BusProperty *p; @@ -1611,3 +1631,41 @@ bool bus_connection_has_subscriber(Manager *m, DBusConnection *c) { return !set_isempty(BUS_CONNECTION_SUBSCRIBED(m, c)); } + +DBusMessage* bus_properties_changed_new(const char *path, const char *interface, const char *properties) { + DBusMessage *m; + DBusMessageIter iter, sub; + const char *i; + + assert(interface); + assert(properties); + + if (!(m = dbus_message_new_signal(path, "org.freedesktop.DBus.Properties", "PropertiesChanged"))) + goto oom; + + dbus_message_iter_init_append(m, &iter); + + /* We won't send any property values, since they might be + * large and sometimes not cheap to generated */ + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub) || + !dbus_message_iter_close_container(&iter, &sub) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) + goto oom; + + NULSTR_FOREACH(i, properties) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &i)) + goto oom; + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + return m; + +oom: + if (m) + dbus_message_unref(m); + + return NULL; +}