From c87eba546a33ce7ecd66f0e3b61bdf55ae1389f0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Jun 2010 19:47:46 +0200 Subject: [PATCH] dbus: add simplified way to start an arbitrary unit in a single method call --- fixme | 4 ++ src/dbus-manager.c | 79 ++++++++++++++++++++++++++++++++++--- src/dbus-unit.c | 6 ++- src/initctl.c | 31 ++------------- src/systemctl.vala | 25 +++--------- src/systemd-interfaces.vala | 5 +++ 6 files changed, 96 insertions(+), 54 deletions(-) diff --git a/fixme b/fixme index b6752d9bf..87068c4ca 100644 --- a/fixme +++ b/fixme @@ -64,6 +64,10 @@ * 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-manager.c b/src/dbus-manager.c index 6a323019f..c80b22b9e 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -36,6 +36,26 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -184,6 +204,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection DBusError error; DBusMessage *reply = NULL; char * path = NULL; + JobType job_type = _JOB_TYPE_INVALID; assert(connection); assert(message); @@ -248,7 +269,15 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection DBUS_TYPE_INVALID)) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetJob")) { + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnit")) + job_type = JOB_START; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StopUnit")) + job_type = JOB_STOP; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadUnit")) + job_type = JOB_RELOAD; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "RestartUnit")) + job_type = JOB_RESTART; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetJob")) { uint32_t id; Job *j; @@ -297,7 +326,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection HASHMAP_FOREACH_KEY(u, k, m->units, i) { char *u_path, *j_path; - const char *description, *load_state, *active_state, *sub_state, *job_type; + const char *description, *load_state, *active_state, *sub_state, *sjob_type; DBusMessageIter sub2; uint32_t job_id; @@ -323,11 +352,11 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection goto oom; } - job_type = job_type_to_string(u->meta.job->type); + sjob_type = job_type_to_string(u->meta.job->type); } else { job_id = 0; j_path = u_path; - job_type = ""; + sjob_type = ""; } if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &u->meta.id) || @@ -337,7 +366,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &sub_state) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &u_path) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &job_id) || - !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &job_type) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &sjob_type) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &j_path)) { free(u_path); if (u->meta.job) @@ -636,6 +665,46 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection } else return bus_default_message_handler(m, message, NULL, properties); + + if (job_type != _JOB_TYPE_INVALID) { + const char *name, *smode; + JobMode mode; + Job *j; + Unit *u; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &smode, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(m, message, &error, -EINVAL); + + if ((mode = job_mode_from_string(smode)) == _JOB_MODE_INVALID) + return bus_send_error_reply(m, message, NULL, -EINVAL); + + if ((r = manager_load_unit(m, name, NULL, &u)) < 0) + return bus_send_error_reply(m, message, NULL, r); + + if (job_type == JOB_START && u->meta.only_by_dependency) + return bus_send_error_reply(m, message, NULL, -EPERM); + + if ((r = manager_add_job(m, job_type, u, mode, true, &j)) < 0) + return bus_send_error_reply(m, message, NULL, r); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!(path = job_dbus_path(j))) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + } + free(path); if (reply) { diff --git a/src/dbus-unit.c b/src/dbus-unit.c index 87218cd2e..8e35377dc 100644 --- a/src/dbus-unit.c +++ b/src/dbus-unit.c @@ -260,6 +260,7 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message Manager *m = u->meta.manager; DBusError error; JobType job_type = _JOB_TYPE_INVALID; + char *path = NULL; dbus_error_init(&error); @@ -281,7 +282,6 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message JobMode mode; Job *j; int r; - char *path; if (job_type == JOB_START && u->meta.only_by_dependency) return bus_send_error_reply(m, message, NULL, -EPERM); @@ -312,6 +312,8 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message goto oom; } + free(path); + if (reply) { if (!dbus_connection_send(m->api_bus, reply, NULL)) goto oom; @@ -322,6 +324,8 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message return DBUS_HANDLER_RESULT_HANDLED; oom: + free(path); + if (reply) dbus_message_unref(reply); diff --git a/src/initctl.c b/src/initctl.c index 407d32d93..9872437aa 100644 --- a/src/initctl.c +++ b/src/initctl.c @@ -96,7 +96,7 @@ static void change_runlevel(Server *s, int runlevel) { const char *target; DBusMessage *m = NULL, *reply = NULL; DBusError error; - const char *path, *replace = "isolate"; + const char *replace = "replace"; assert(s); @@ -109,44 +109,19 @@ static void change_runlevel(Server *s, int runlevel) { log_debug("Running request %s", target); - if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "LoadUnit"))) { + if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"))) { log_error("Could not allocate message."); goto finish; } if (!dbus_message_append_args(m, DBUS_TYPE_STRING, &target, - DBUS_TYPE_INVALID)) { - log_error("Could not attach group information to signal message."); - goto finish; - } - - if (!(reply = dbus_connection_send_with_reply_and_block(s->bus, m, -1, &error))) { - log_error("Failed to get unit path: %s", error.message); - goto finish; - } - - if (!dbus_message_get_args(reply, &error, - DBUS_TYPE_OBJECT_PATH, &path, - DBUS_TYPE_INVALID)) { - log_error("Failed to parse unit path: %s", error.message); - goto finish; - } - - dbus_message_unref(m); - if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", path, "org.freedesktop.systemd1.Unit", "Start"))) { - log_error("Could not allocate message."); - goto finish; - } - - if (!dbus_message_append_args(m, DBUS_TYPE_STRING, &replace, DBUS_TYPE_INVALID)) { - log_error("Could not attach group information to signal message."); + log_error("Could not attach target and flag information to signal message."); goto finish; } - dbus_message_unref(reply); if (!(reply = dbus_connection_send_with_reply_and_block(s->bus, m, -1, &error))) { log_error("Failed to start unit: %s", error.message); goto finish; diff --git a/src/systemctl.vala b/src/systemctl.vala index e3e675f47..6cce93bec 100644 --- a/src/systemctl.vala +++ b/src/systemctl.vala @@ -252,25 +252,17 @@ int main (string[] args) { for (int i = 2; i < args.length; i++) { - ObjectPath p = manager.load_unit(args[i]); - - Unit u = bus.get_object( - "org.freedesktop.systemd1", - p, - "org.freedesktop.systemd1.Unit") as Unit; - string mode = replace ? "replace" : "fail"; - ObjectPath j = null; if (args[1] == "start") - j = u.start(mode); + j = manager.start_unit(args[i], mode); else if (args[1] == "stop") - j = u.stop(mode); + j = manager.stop_unit(args[i], mode); else if (args[1] == "restart") - j = u.restart(mode); + j = manager.restart_unit(args[i], mode); else if (args[1] == "reload") - j = u.reload(mode); + j = manager.reload_unit(args[i], mode); if (block) jobs.append(j); @@ -283,14 +275,7 @@ int main (string[] args) { return 1; } - ObjectPath p = manager.load_unit(args[2]); - - Unit u = bus.get_object( - "org.freedesktop.systemd1", - p, - "org.freedesktop.systemd1.Unit") as Unit; - - ObjectPath j = u.start("isolate"); + ObjectPath j = manager.start_unit(args[2], "isolate"); if (block) { manager.subscribe(); diff --git a/src/systemd-interfaces.vala b/src/systemd-interfaces.vala index a8aeb7557..744547991 100644 --- a/src/systemd-interfaces.vala +++ b/src/systemd-interfaces.vala @@ -52,6 +52,11 @@ public interface Manager : DBus.Object { public abstract ObjectPath load_unit(string name) throws DBus.Error; public abstract ObjectPath get_job(uint32 id) throws DBus.Error; + public abstract ObjectPath start_unit(string name, string mode) throws DBus.Error; + public abstract ObjectPath stop_unit(string name, string mode) throws DBus.Error; + public abstract ObjectPath reload_unit(string name, string mode) throws DBus.Error; + public abstract ObjectPath restart_unit(string name, string mode) throws DBus.Error; + public abstract void clear_jobs() throws DBus.Error; public abstract void subscribe() throws DBus.Error;