dbus: implement start/stop/restart/reload/cancel D-Bus calls

This commit is contained in:
Lennart Poettering 2010-02-03 12:37:42 +01:00
parent dcc47b179f
commit b548631afc
4 changed files with 127 additions and 10 deletions

View File

@ -9,9 +9,10 @@ static const char introspection[] =
DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
"<node>"
" <interface name=\"org.freedesktop.systemd1.Job\">"
" <method name=\"Cancel\"/>"
" <property name=\"Id\" type=\"u\" access=\"read\"/>"
" <property name=\"Unit\" type=\"(so)\" access=\"read\"/>"
" <property name=\"Type\" type=\"s\" access=\"read\"/>"
" <property name=\"JobType\" type=\"s\" access=\"read\"/>"
" <property name=\"State\" type=\"s\" access=\"read\"/>"
" </interface>"
BUS_PROPERTIES_INTERFACE
@ -86,16 +87,40 @@ static int bus_job_append_unit(Manager *m, DBusMessageIter *i, const char *prope
}
static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusMessage *message) {
const BusProperty properties[] = {
{ "org.freedesktop.systemd1.Job", "Id", bus_property_append_uint32, "u", &j->id },
{ "org.freedesktop.systemd1.Job", "State", bus_job_append_state, "s", j },
{ "org.freedesktop.systemd1.Job", "Type", bus_job_append_type, "s", j },
{ "org.freedesktop.systemd1.Job", "Unit", bus_job_append_unit, "(so)", j },
{ "org.freedesktop.systemd1.Job", "Id", bus_property_append_uint32, "u", &j->id },
{ "org.freedesktop.systemd1.Job", "State", bus_job_append_state, "s", j },
{ "org.freedesktop.systemd1.Job", "JobType", bus_job_append_type, "s", j },
{ "org.freedesktop.systemd1.Job", "Unit", bus_job_append_unit, "(so)", j },
{ NULL, NULL, NULL, NULL, NULL }
};
return bus_default_message_handler(j->manager, message, introspection, properties);
DBusMessage *reply = NULL;
Manager *m = j->manager;
if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Job", "Cancel")) {
if (!(reply = dbus_message_new_method_return(message)))
goto oom;
job_free(j);
} else
return bus_default_message_handler(j->manager, message, introspection, properties);
if (reply) {
if (!dbus_connection_send(m->bus, reply, NULL))
goto oom;
dbus_message_unref(reply);
}
return DBUS_HANDLER_RESULT_HANDLED;
oom:
if (reply)
dbus_message_unref(reply);
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBusMessage *message, void *data) {

View File

@ -8,8 +8,23 @@
static const char introspection[] =
DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
"<node>"
" <!-- you suck -->"
" <interface name=\"org.freedesktop.systemd1.Unit\">"
" <method name=\"Start\">"
" <arg name=\"mode\" type=\"s\" direction=\"in\"/>"
" <arg name=\"job\" type=\"o\" direction=\"out\"/>"
" </method>"
" <method name=\"Stop\">"
" <arg name=\"mode\" type=\"s\" direction=\"in\"/>"
" <arg name=\"job\" type=\"o\" direction=\"out\"/>"
" </method>"
" <method name=\"Restart\">"
" <arg name=\"mode\" type=\"s\" direction=\"in\"/>"
" <arg name=\"job\" type=\"o\" direction=\"out\"/>"
" </method>"
" <method name=\"Reload\">"
" <arg name=\"mode\" type=\"s\" direction=\"in\"/>"
" <arg name=\"job\" type=\"o\" direction=\"out\"/>"
" </method>"
" <property name=\"Id\" type=\"s\" access=\"read\"/>"
" <property name=\"Description\" type=\"s\" access=\"read\"/>"
" <property name=\"LoadState\" type=\"s\" access=\"read\"/>"
@ -191,7 +206,73 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message
{ NULL, NULL, NULL, NULL, NULL }
};
return bus_default_message_handler(u->meta.manager, message, introspection, properties);
DBusMessage *reply = NULL;
Manager *m = u->meta.manager;
DBusError error;
JobType job_type = _JOB_TYPE_INVALID;
dbus_error_init(&error);
if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Start"))
job_type = JOB_START;
else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Stop"))
job_type = JOB_STOP;
else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Reload"))
job_type = JOB_RELOAD;
else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Restart"))
job_type = JOB_RESTART;
else
return bus_default_message_handler(u->meta.manager, message, introspection, properties);
if (job_type != _JOB_TYPE_INVALID) {
const char *smode;
JobMode mode;
Job *j;
int r;
char *path;
if (!dbus_message_get_args(
message,
&error,
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_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;
}
if (reply) {
if (!dbus_connection_send(m->bus, reply, NULL))
goto oom;
dbus_message_unref(reply);
}
return DBUS_HANDLER_RESULT_HANDLED;
oom:
if (reply)
dbus_message_unref(reply);
dbus_error_free(&error);
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
static DBusHandlerResult bus_unit_message_handler(DBusConnection *connection, DBusMessage *message, void *data) {

7
job.c
View File

@ -492,3 +492,10 @@ static const char* const job_type_table[_JOB_TYPE_MAX] = {
};
DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
static const char* const job_mode_table[_JOB_MODE_MAX] = {
[JOB_FAIL] = "fail",
[JOB_REPLACE] = "replace"
};
DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);

6
job.h
View File

@ -46,7 +46,8 @@ enum JobState {
enum JobMode {
JOB_FAIL,
JOB_REPLACE,
_JOB_MODE_MAX
_JOB_MODE_MAX,
_JOB_MODE_INVALID = -1
};
struct JobDependency {
@ -114,6 +115,9 @@ JobType job_type_from_string(const char *s);
const char* job_state_to_string(JobState t);
JobState job_state_from_string(const char *s);
const char* job_mode_to_string(JobMode t);
JobMode job_mode_from_string(const char *s);
char *job_dbus_path(Job *j);
#endif