X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fdbus-unit.c;h=b65481d19320645e085eab5e1c109fd6de157ae2;hp=ce34130993872bf018316a1d7003e45724e4a03e;hb=0d37b36b2890fdf8149d12460ebb00822e555977;hpb=064f51fa29c1dfd7c0704feb969eb59119e57854 diff --git a/src/dbus-unit.c b/src/dbus-unit.c index ce3413099..b65481d19 100644 --- a/src/dbus-unit.c +++ b/src/dbus-unit.c @@ -1,4 +1,4 @@ -/*-*- Mode: C; c-basic-offset: 8 -*-*/ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ /*** This file is part of systemd. @@ -28,6 +28,18 @@ const char bus_unit_interface[] = BUS_UNIT_INTERFACE; +#define INVALIDATING_PROPERTIES \ + "LoadState\0" \ + "ActiveState\0" \ + "SubState\0" \ + "InactiveExitTimestamp\0" \ + "ActiveEnterTimestamp\0" \ + "ActiveExitTimestamp\0" \ + "InactiveEnterTimestamp\0" \ + "Job\0" \ + "NeedDaemonReload\0" \ + "\0" + int bus_unit_append_names(Manager *m, DBusMessageIter *i, const char *property, void *data) { char *t; Iterator j; @@ -47,6 +59,24 @@ int bus_unit_append_names(Manager *m, DBusMessageIter *i, const char *property, return 0; } +int bus_unit_append_following(Manager *m, DBusMessageIter *i, const char *property, void *data) { + Unit *u = data, *f; + const char *d; + + assert(m); + assert(i); + assert(property); + assert(u); + + f = unit_following(u); + d = f ? f->meta.id : ""; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) + return -ENOMEM; + + return 0; +} + int bus_unit_append_dependencies(Manager *m, DBusMessageIter *i, const char *property, void *data) { Unit *u; Iterator j; @@ -129,7 +159,28 @@ int bus_unit_append_can_start(Manager *m, DBusMessageIter *i, const char *proper assert(u); b = unit_can_start(u) && - !u->meta.only_by_dependency; + !u->meta.refuse_manual_start; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +int bus_unit_append_can_stop(Manager *m, DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(m); + assert(i); + assert(property); + assert(u); + + /* On the lower levels we assume that every unit we can start + * we can also stop */ + + b = unit_can_start(u) && + !u->meta.refuse_manual_stop; if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) return -ENOMEM; @@ -154,6 +205,24 @@ int bus_unit_append_can_reload(Manager *m, DBusMessageIter *i, const char *prope return 0; } +int bus_unit_append_can_isolate(Manager *m, DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(m); + assert(i); + assert(property); + assert(u); + + b = unit_can_isolate(u) && + !u->meta.refuse_manual_start; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + int bus_unit_append_job(Manager *m, DBusMessageIter *i, const char *property, void *data) { Unit *u = data; DBusMessageIter sub; @@ -298,6 +367,13 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *conn } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ReloadOrTryRestart")) { reload_if_possible = true; job_type = JOB_TRY_RESTART; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ResetFailed")) { + + unit_reset_failed(u); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + } else if (UNIT_VTABLE(u)->bus_message_handler) return UNIT_VTABLE(u)->bus_message_handler(u, connection, message); else @@ -309,8 +385,11 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *conn Job *j; int r; - if (job_type == JOB_START && u->meta.only_by_dependency) { - dbus_set_error(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Unit may be activated by dependency only."); + if ((job_type == JOB_START && u->meta.refuse_manual_start) || + (job_type == JOB_STOP && u->meta.refuse_manual_stop) || + ((job_type == JOB_RESTART || job_type == JOB_TRY_RESTART) && + (u->meta.refuse_manual_start || u->meta.refuse_manual_stop))) { + dbus_set_error(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, may be requested by dependency only."); return bus_send_error_reply(m, connection, message, &error, -EPERM); } @@ -409,6 +488,9 @@ void bus_unit_send_change_signal(Unit *u) { u->meta.in_dbus_queue = false; } + if (!u->meta.id) + return; + if (!bus_has_subscriber(u->meta.manager)) { u->meta.sent_dbus_new_signal = true; return; @@ -418,10 +500,27 @@ void bus_unit_send_change_signal(Unit *u) { goto oom; if (u->meta.sent_dbus_new_signal) { - /* Send a change signal */ + /* Send a properties changed signal. First for the + * specific type, then for the generic unit. The + * clients may rely on this order to get atomic + * behaviour if needed. */ + + if (UNIT_VTABLE(u)->bus_invalidating_properties) { - if (!(m = dbus_message_new_signal(p, "org.freedesktop.systemd1.Unit", "Changed"))) + if (!(m = bus_properties_changed_new(p, + UNIT_VTABLE(u)->bus_interface, + UNIT_VTABLE(u)->bus_invalidating_properties))) + goto oom; + + if (bus_broadcast(u->meta.manager, m) < 0) + goto oom; + + dbus_message_unref(m); + } + + if (!(m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Unit", INVALIDATING_PROPERTIES))) goto oom; + } else { /* Send a new signal */ @@ -466,6 +565,9 @@ void bus_unit_send_removed_signal(Unit *u) { if (!u->meta.sent_dbus_new_signal) bus_unit_send_change_signal(u); + if (!u->meta.id) + return; + if (!(p = unit_dbus_path(u))) goto oom;