X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=dbus-manager.c;h=90ab8d1a0cab509b1d78270191962a65bf0a8842;hp=5f3d9647776e6a10050eac95bf384084f1bb0e3a;hb=67ef7823c651015929d4f20e4c9d59998c5bac7d;hpb=10a94420172b33a7472a16b2e829689dbc570cad diff --git a/dbus-manager.c b/dbus-manager.c index 5f3d96477..90ab8d1a0 100644 --- a/dbus-manager.c +++ b/dbus-manager.c @@ -23,11 +23,13 @@ #include "dbus.h" #include "log.h" +#include "dbus-manager.h" +#include "strv.h" #define INTROSPECTION_BEGIN \ DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ "" \ - " " \ + " " \ " " \ " " \ " " \ @@ -50,6 +52,20 @@ " " \ " " \ " " \ + " " \ + " " \ + " " \ + " " \ + " " \ + " " \ + " " \ + " " \ + " " \ + " " \ + " " \ + " " \ + " " \ + " " \ " " \ " " \ " " \ @@ -69,8 +85,11 @@ " " \ " " \ " " \ - " " \ - " " \ + " " \ + " " \ + " " \ + " " \ + " " \ " " \ BUS_PROPERTIES_INTERFACE \ BUS_INTROSPECTABLE_INTERFACE @@ -78,7 +97,7 @@ #define INTROSPECTION_END \ "" -DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_running_as, manager_running_as, ManagerRunningAs); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_running_as, manager_running_as, ManagerRunningAs); static int bus_manager_append_log_target(Manager *m, DBusMessageIter *i, const char *property, void *data) { const char *t; @@ -110,15 +129,48 @@ static int bus_manager_append_log_level(Manager *m, DBusMessageIter *i, const ch return 0; } +static int bus_manager_append_n_names(Manager *m, DBusMessageIter *i, const char *property, void *data) { + uint32_t u; + + assert(m); + assert(i); + assert(property); + + u = hashmap_size(m->units); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, &u)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_append_n_jobs(Manager *m, DBusMessageIter *i, const char *property, void *data) { + uint32_t u; + + assert(m); + assert(i); + assert(property); + + u = hashmap_size(m->jobs); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, &u)) + return -ENOMEM; + + return 0; +} + static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { Manager *m = data; const BusProperty properties[] = { - { "org.freedesktop.systemd1", "Version", bus_property_append_string, "s", PACKAGE_VERSION }, - { "org.freedesktop.systemd1", "RunningAs", bus_manager_append_running_as, "s", &m->running_as }, - { "org.freedesktop.systemd1", "BootTimestamp", bus_property_append_uint64, "t", &m->boot_timestamp }, - { "org.freedesktop.systemd1", "LogLevel", bus_manager_append_log_level, "s", NULL }, - { "org.freedesktop.systemd1", "LogTarget", bus_manager_append_log_target, "s", NULL }, + { "org.freedesktop.systemd1.Manager", "Version", bus_property_append_string, "s", PACKAGE_STRING }, + { "org.freedesktop.systemd1.Manager", "RunningAs", bus_manager_append_running_as, "s", &m->running_as }, + { "org.freedesktop.systemd1.Manager", "BootTimestamp", bus_property_append_uint64, "t", &m->boot_timestamp }, + { "org.freedesktop.systemd1.Manager", "LogLevel", bus_manager_append_log_level, "s", NULL }, + { "org.freedesktop.systemd1.Manager", "LogTarget", bus_manager_append_log_target, "s", NULL }, + { "org.freedesktop.systemd1.Manager", "NNames", bus_manager_append_n_names, "u", NULL }, + { "org.freedesktop.systemd1.Manager", "NJobs", bus_manager_append_n_jobs, "u", NULL }, + { "org.freedesktop.systemd1.Manager", "Environment", bus_property_append_strv, "as", m->environment }, { NULL, NULL, NULL, NULL, NULL } }; @@ -138,7 +190,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection dbus_message_get_member(message), dbus_message_get_path(message)); - if (dbus_message_is_method_call(message, "org.freedesktop.systemd1", "GetUnit")) { + if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnit")) { const char *name; Unit *u; @@ -164,7 +216,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection DBUS_TYPE_INVALID)) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1", "LoadUnit")) { + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "LoadUnit")) { const char *name; Unit *u; @@ -175,7 +227,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection DBUS_TYPE_INVALID)) return bus_send_error_reply(m, message, &error, -EINVAL); - if ((r = manager_load_unit(m, name, &u)) < 0) + if ((r = manager_load_unit(m, name, NULL, &u)) < 0) return bus_send_error_reply(m, message, NULL, r); if (!(reply = dbus_message_new_method_return(message))) @@ -190,7 +242,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection DBUS_TYPE_INVALID)) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1", "GetJob")) { + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetJob")) { uint32_t id; Job *j; @@ -216,14 +268,14 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection DBUS_TYPE_INVALID)) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1", "ClearJobs")) { + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ClearJobs")) { manager_clear_jobs(m); if (!(reply = dbus_message_new_method_return(message))) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1", "ListUnits")) { + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListUnits")) { DBusMessageIter iter, sub; Iterator i; Unit *u; @@ -239,12 +291,11 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection HASHMAP_FOREACH_KEY(u, k, m->units, i) { char *u_path, *j_path; - const char *id, *description, *load_state, *active_state, *sub_state, *job_type; + const char *description, *load_state, *active_state, *sub_state, *job_type; DBusMessageIter sub2; uint32_t job_id; - id = unit_id(u); - if (k != id) + if (k != u->meta.id) continue; if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) @@ -273,7 +324,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection job_type = ""; } - if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &id) || + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &u->meta.id) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &description) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &load_state) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &active_state) || @@ -299,7 +350,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection if (!dbus_message_iter_close_container(&iter, &sub)) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1", "ListJobs")) { + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListJobs")) { DBusMessageIter iter, sub; Iterator i; Job *j; @@ -314,7 +365,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection HASHMAP_FOREACH(j, m->jobs, i) { char *u_path, *j_path; - const char *unit, *state, *type; + const char *state, *type; uint32_t id; DBusMessageIter sub2; @@ -322,7 +373,6 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection goto oom; id = (uint32_t) j->id; - unit = unit_id(j->unit); state = job_state_to_string(j->state); type = job_type_to_string(j->type); @@ -335,7 +385,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection } if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &id) || - !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &unit) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &j->unit->meta.id) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &type) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &state) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &j_path) || @@ -355,7 +405,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection if (!dbus_message_iter_close_container(&iter, &sub)) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1", "Subscribe")) { + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Subscribe")) { char *client; if (!(client = strdup(dbus_message_get_sender(message)))) @@ -369,7 +419,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection if (!(reply = dbus_message_new_method_return(message))) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1", "Unsubscribe")) { + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Unsubscribe")) { char *client; if (!(client = set_remove(m->subscribed, (char*) dbus_message_get_sender(message)))) @@ -380,7 +430,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection if (!(reply = dbus_message_new_method_return(message))) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1", "Dump")) { + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Dump")) { FILE *f; char *dump = NULL; size_t size; @@ -408,6 +458,36 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection } free(dump); + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "CreateSnapshot")) { + const char *name; + dbus_bool_t cleanup; + Snapshot *s; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_BOOLEAN, &cleanup, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(m, message, &error, -EINVAL); + + if (name && name[0] == 0) + name = NULL; + + if ((r = snapshot_create(m, name, cleanup, &s)) < 0) + return bus_send_error_reply(m, message, NULL, r); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!(path = unit_dbus_path(UNIT(s)))) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { char *introspection = NULL; @@ -434,7 +514,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection HASHMAP_FOREACH_KEY(u, k, m->units, i) { char *p; - if (k != unit_id(u)) + if (k != u->meta.id) continue; if (!(p = bus_path_escape(k))) { @@ -470,6 +550,83 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection free(introspection); + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reload")) { + + assert(!m->queued_message); + + /* Instead of sending the reply back right away, we + * just remember that we need to and then send it + * after the reload is finished. That way the caller + * knows when the reload finished. */ + + if (!(m->queued_message = dbus_message_new_method_return(message))) + goto oom; + + m->exit_code = MANAGER_RELOAD; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reexecute")) { + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + m->exit_code = MANAGER_REEXECUTE; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Exit")) { + + if (m->running_as == MANAGER_INIT) + return bus_send_error_reply(m, message, NULL, -ENOTSUP); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + m->exit_code = MANAGER_EXIT; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetEnvironment")) { + char **l = NULL, **e = NULL; + + if ((r = bus_parse_strv(message, &l)) < 0) { + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(m, message, NULL, r); + } + + e = strv_env_merge(m->environment, l, NULL); + strv_free(l); + + if (!e) + goto oom; + + if (!(reply = dbus_message_new_method_return(message))) { + strv_free(e); + goto oom; + } + + strv_free(m->environment); + m->environment = e; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetEnvironment")) { + char **l = NULL, **e = NULL; + + if ((r = bus_parse_strv(message, &l)) < 0) { + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(m, message, NULL, r); + } + + e = strv_env_delete(m->environment, l, NULL); + strv_free(l); + + if (!e) + goto oom; + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + strv_free(m->environment); + m->environment = e; + } else return bus_default_message_handler(m, message, NULL, properties);