summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-06-02 04:24:16 +0200
committerLennart Poettering <lennart@poettering.net>2010-06-02 04:24:16 +0200
commit0034c15c60ba5c30cf2786c5693c71f99dfffbc3 (patch)
treeeadbf161b1a8ccf42f882aafcecf1bdfdba45675
parent9a9a438596e6f57cda87fc7045971197fd2b3078 (diff)
dbus: implement systemd side of dbus activation glue
-rw-r--r--fixme4
-rw-r--r--src/dbus.c82
2 files changed, 78 insertions, 8 deletions
diff --git a/fixme b/fixme
index 87068c4..b6752d9 100644
--- a/fixme
+++ b/fixme
@@ -64,10 +64,6 @@
* tcpwrap
-* dbus intzerface files und so weiter müssen NICHT nach prefixdir
-
-* fix den kram mit rootdir..
-
Regularly:
* look for close() vs. close_nointr() vs. close_nointr_nofail()
diff --git a/src/dbus.c b/src/dbus.c
index f5bbc58..7916817 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -65,6 +65,8 @@ const char *const bus_interface_table[] = {
NULL
};
+static const char *error_to_dbus(int error);
+
static void api_bus_dispatch_status(DBusConnection *bus, DBusDispatchStatus status, void *data) {
Manager *m = data;
@@ -333,6 +335,7 @@ static void bus_toggle_timeout(DBusTimeout *timeout, void *data) {
static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) {
Manager *m = data;
DBusError error;
+ DBusMessage *reply = NULL;
assert(connection);
assert(message);
@@ -340,10 +343,10 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBu
dbus_error_init(&error);
- /* log_debug("Got D-Bus request: %s.%s() on %s", */
- /* dbus_message_get_interface(message), */
- /* dbus_message_get_member(message), */
- /* dbus_message_get_path(message)); */
+ log_debug("Got D-Bus request: %s.%s() on %s",
+ dbus_message_get_interface(message),
+ dbus_message_get_member(message),
+ dbus_message_get_path(message));
if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
log_error("Warning! API D-Bus connection terminated.");
@@ -370,10 +373,65 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBu
manager_dispatch_bus_name_owner_changed(m, name, old_owner, new_owner);
}
+ } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Activator", "ActivationRequest")) {
+ const char *name;
+
+ if (!dbus_message_get_args(message, &error,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID))
+ log_error("Failed to parse ActivationRequest message: %s", error.message);
+ else {
+ int r;
+ Unit *u;
+
+ r = manager_load_unit(m, name, NULL, &u);
+
+ if (r >= 0 && u->meta.only_by_dependency)
+ r = -EPERM;
+
+ if (r >= 0)
+ r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, NULL);
+
+ if (r < 0) {
+ const char *id, *text;
+
+ if (!(reply = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure")))
+ goto oom;
+
+ id = error_to_dbus(r);
+ text = strerror(-r);
+
+ if (!dbus_message_set_destination(reply, DBUS_SERVICE_DBUS) ||
+ !dbus_message_append_args(reply,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &id,
+ DBUS_TYPE_STRING, &text,
+ DBUS_TYPE_INVALID))
+ goto oom;
+ }
+
+ /* On success we don't do anything, the service will be spwaned now */
+ }
}
dbus_error_free(&error);
+
+ if (reply) {
+ if (!dbus_connection_send(connection, reply, NULL))
+ goto oom;
+
+ dbus_message_unref(reply);
+ }
+
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+oom:
+ if (reply)
+ dbus_message_unref(reply);
+
+ dbus_error_free(&error);
+
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
static DBusHandlerResult system_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) {
@@ -642,6 +700,7 @@ int bus_init_api(Manager *m) {
return -ENOMEM;
}
+ /* Get NameOwnerChange messages */
dbus_bus_add_match(m->api_bus,
"type='signal',"
"sender='"DBUS_SERVICE_DBUS"',"
@@ -656,6 +715,21 @@ int bus_init_api(Manager *m) {
return -ENOMEM;
}
+ /* Get activation requests */
+ dbus_bus_add_match(m->api_bus,
+ "type='signal',"
+ "sender='"DBUS_SERVICE_DBUS"',"
+ "interface='org.freedesktop.systemd1.Activator',"
+ "path='"DBUS_PATH_DBUS"'",
+ &error);
+
+ if (dbus_error_is_set(&error)) {
+ log_error("Failed to register match: %s", error.message);
+ dbus_error_free(&error);
+ bus_done_api(m);
+ return -ENOMEM;
+ }
+
if ((r = request_name(m)) < 0) {
bus_done_api(m);
return r;