#include "log.h"
#include "dbus-unit.h"
#include "bus-errors.h"
+#include "dbus-common.h"
const char bus_unit_interface[] _introspect_("Unit") = BUS_UNIT_INTERFACE;
"Job\0" \
"NeedDaemonReload\0"
-int bus_unit_append_names(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+int bus_unit_append_names(DBusMessageIter *i, const char *property, void *data) {
char *t;
Iterator j;
DBusMessageIter sub;
if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub))
return -ENOMEM;
- SET_FOREACH(t, u->meta.names, j)
+ SET_FOREACH(t, u->names, j)
if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &t))
return -ENOMEM;
return 0;
}
-int bus_unit_append_following(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+int bus_unit_append_following(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 : "";
+ d = f ? f->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) {
+int bus_unit_append_dependencies(DBusMessageIter *i, const char *property, void *data) {
Unit *u;
Iterator j;
DBusMessageIter sub;
return -ENOMEM;
SET_FOREACH(u, s, j)
- if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &u->meta.id))
+ if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &u->id))
return -ENOMEM;
if (!dbus_message_iter_close_container(i, &sub))
return 0;
}
-int bus_unit_append_description(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+int bus_unit_append_description(DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
const char *d;
- assert(m);
assert(i);
assert(property);
assert(u);
DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_unit_append_load_state, unit_load_state, UnitLoadState);
-int bus_unit_append_active_state(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+int bus_unit_append_active_state(DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
const char *state;
- assert(m);
assert(i);
assert(property);
assert(u);
return 0;
}
-int bus_unit_append_sub_state(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+int bus_unit_append_sub_state(DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
const char *state;
- assert(m);
assert(i);
assert(property);
assert(u);
return 0;
}
-int bus_unit_append_can_start(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+int bus_unit_append_file_state(DBusMessageIter *i, const char *property, void *data) {
+ Unit *u = data;
+ const char *state;
+
+ assert(i);
+ assert(property);
+ assert(u);
+
+ state = strempty(unit_file_state_to_string(unit_get_unit_file_state(u)));
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
+ return -ENOMEM;
+
+ return 0;
+}
+
+int bus_unit_append_can_start(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_start(u) &&
- !u->meta.refuse_manual_start;
+ !u->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) {
+int bus_unit_append_can_stop(DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
dbus_bool_t b;
- assert(m);
assert(i);
assert(property);
assert(u);
* we can also stop */
b = unit_can_start(u) &&
- !u->meta.refuse_manual_stop;
+ !u->refuse_manual_stop;
if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
return -ENOMEM;
return 0;
}
-int bus_unit_append_can_reload(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+int bus_unit_append_can_reload(DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
dbus_bool_t b;
- assert(m);
assert(i);
assert(property);
assert(u);
return 0;
}
-int bus_unit_append_can_isolate(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+int bus_unit_append_can_isolate(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;
+ !u->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) {
+int bus_unit_append_job(DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
DBusMessageIter sub;
char *p;
- assert(m);
assert(i);
assert(property);
assert(u);
if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub))
return -ENOMEM;
- if (u->meta.job) {
+ if (u->job) {
- if (!(p = job_dbus_path(u->meta.job)))
+ if (!(p = job_dbus_path(u->job)))
return -ENOMEM;
- if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &u->meta.job->id) ||
+ if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &u->job->id) ||
!dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) {
free(p);
return -ENOMEM;
return 0;
}
-int bus_unit_append_default_cgroup(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+int bus_unit_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
char *t;
CGroupBonding *cgb;
bool success;
- assert(m);
assert(i);
assert(property);
assert(u);
return success ? 0 : -ENOMEM;
}
-int bus_unit_append_cgroups(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+int bus_unit_append_cgroups(DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
CGroupBonding *cgb;
DBusMessageIter sub;
if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub))
return -ENOMEM;
- LIST_FOREACH(by_unit, cgb, u->meta.cgroup_bondings) {
+ LIST_FOREACH(by_unit, cgb, u->cgroup_bondings) {
char *t;
bool success;
return 0;
}
-int bus_unit_append_need_daemon_reload(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+int bus_unit_append_cgroup_attrs(DBusMessageIter *i, const char *property, void *data) {
+ Unit *u = data;
+ CGroupAttribute *a;
+ DBusMessageIter sub, sub2;
+
+ if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sss)", &sub))
+ return -ENOMEM;
+
+ LIST_FOREACH(by_unit, a, u->cgroup_attributes) {
+ char *v = NULL;
+ bool success;
+
+ if (a->map_callback)
+ a->map_callback(a->controller, a->name, a->value, &v);
+
+ success =
+ dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) &&
+ dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &a->controller) &&
+ dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &a->name) &&
+ dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, v ? &v : &a->value) &&
+ dbus_message_iter_close_container(&sub, &sub2);
+
+ free(v);
+
+ if (!success)
+ return -ENOMEM;
+ }
+
+ if (!dbus_message_iter_close_container(i, &sub))
+ return -ENOMEM;
+
+ return 0;
+}
+
+int bus_unit_append_need_daemon_reload(DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
dbus_bool_t b;
- assert(m);
assert(i);
assert(property);
assert(u);
return 0;
}
+int bus_unit_append_load_error(DBusMessageIter *i, const char *property, void *data) {
+ Unit *u = data;
+ const char *name, *message;
+ DBusMessageIter sub;
+
+ assert(i);
+ assert(property);
+ assert(u);
+
+ if (u->load_error != 0) {
+ name = bus_errno_to_dbus(u->load_error);
+ message = strempty(strerror(-u->load_error));
+ } else
+ name = message = "";
+
+ if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub) ||
+ !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &name) ||
+ !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &message) ||
+ !dbus_message_iter_close_container(i, &sub))
+ return -ENOMEM;
+
+ return 0;
+}
+
static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *connection, DBusMessage *message) {
DBusMessage *reply = NULL;
- Manager *m = u->meta.manager;
+ Manager *m = u->manager;
DBusError error;
JobType job_type = _JOB_TYPE_INVALID;
char *path = NULL;
DBUS_TYPE_STRING, &smode,
DBUS_TYPE_INT32, &signo,
DBUS_TYPE_INVALID))
- return bus_send_error_reply(m, connection, message, &error, -EINVAL);
+ return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+ if (isempty(swho))
+ who = KILL_ALL;
+ else {
+ who = kill_who_from_string(swho);
+ if (who < 0)
+ return bus_send_error_reply(connection, message, &error, -EINVAL);
+ }
+
+ if (isempty(smode))
+ mode = KILL_CONTROL_GROUP;
+ else {
+ mode = kill_mode_from_string(smode);
+ if (mode < 0)
+ return bus_send_error_reply(connection, message, &error, -EINVAL);
+ }
- if ((mode = kill_mode_from_string(smode)) < 0 ||
- (who = kill_who_from_string(swho)) < 0 ||
- signo <= 0 ||
- signo >= _NSIG)
- return bus_send_error_reply(m, connection, message, &error, -EINVAL);
+ if (signo <= 0 || signo >= _NSIG)
+ return bus_send_error_reply(connection, message, &error, -EINVAL);
if ((r = unit_kill(u, who, mode, signo, &error)) < 0)
- return bus_send_error_reply(m, connection, message, &error, r);
+ return bus_send_error_reply(connection, message, &error, r);
if (!(reply = dbus_message_new_method_return(message)))
goto oom;
Job *j;
int r;
- if ((job_type == JOB_START && u->meta.refuse_manual_start) ||
- (job_type == JOB_STOP && u->meta.refuse_manual_stop) ||
+ if ((job_type == JOB_START && u->refuse_manual_start) ||
+ (job_type == JOB_STOP && u->refuse_manual_stop) ||
((job_type == JOB_RESTART || job_type == JOB_TRY_RESTART) &&
- (u->meta.refuse_manual_start || u->meta.refuse_manual_stop))) {
+ (u->refuse_manual_start || u->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);
+ return bus_send_error_reply(connection, message, &error, -EPERM);
}
if (!dbus_message_get_args(
&error,
DBUS_TYPE_STRING, &smode,
DBUS_TYPE_INVALID))
- return bus_send_error_reply(m, connection, message, &error, -EINVAL);
+ return bus_send_error_reply(connection, message, &error, -EINVAL);
if (reload_if_possible && unit_can_reload(u)) {
if (job_type == JOB_RESTART)
if ((mode = job_mode_from_string(smode)) == _JOB_MODE_INVALID) {
dbus_set_error(&error, BUS_ERROR_INVALID_JOB_MODE, "Job mode %s is invalid.", smode);
- return bus_send_error_reply(m, connection, message, &error, -EINVAL);
+ return bus_send_error_reply(connection, message, &error, -EINVAL);
}
if ((r = manager_add_job(m, job_type, u, mode, true, &error, &j)) < 0)
- return bus_send_error_reply(m, connection, message, &error, r);
+ return bus_send_error_reply(connection, message, &error, r);
if (!(reply = dbus_message_new_method_return(message)))
goto oom;
goto oom;
}
- free(path);
-
if (reply) {
if (!dbus_connection_send(connection, reply, NULL))
goto oom;
dbus_message_unref(reply);
}
+ free(path);
+
return DBUS_HANDLER_RESULT_HANDLED;
oom:
HASHMAP_FOREACH_KEY(u, k, m->units, i) {
char *p;
- if (k != u->meta.id)
+ if (k != u->id)
continue;
if (!(p = bus_path_escape(k))) {
if (r == -ENOENT) {
DBusError e;
+
+ dbus_error_init(&e);
dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown unit");
- return bus_send_error_reply(m, connection, message, &e, r);
+ return bus_send_error_reply(connection, message, &e, r);
}
- return bus_send_error_reply(m, connection, message, NULL, r);
+ return bus_send_error_reply(connection, message, NULL, r);
}
return bus_unit_message_dispatch(u, connection, message);
assert(u);
- if (u->meta.in_dbus_queue) {
- LIST_REMOVE(Meta, dbus_queue, u->meta.manager->dbus_unit_queue, &u->meta);
- u->meta.in_dbus_queue = false;
+ if (u->in_dbus_queue) {
+ LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
+ u->in_dbus_queue = false;
}
- if (!u->meta.id)
+ if (!u->id)
return;
- if (!bus_has_subscriber(u->meta.manager)) {
- u->meta.sent_dbus_new_signal = true;
+ if (!bus_has_subscriber(u->manager)) {
+ u->sent_dbus_new_signal = true;
return;
}
if (!(p = unit_dbus_path(u)))
goto oom;
- if (u->meta.sent_dbus_new_signal) {
+ if (u->sent_dbus_new_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
UNIT_VTABLE(u)->bus_invalidating_properties)))
goto oom;
- if (bus_broadcast(u->meta.manager, m) < 0)
+ if (bus_broadcast(u->manager, m) < 0)
goto oom;
dbus_message_unref(m);
goto oom;
if (!dbus_message_append_args(m,
- DBUS_TYPE_STRING, &u->meta.id,
+ DBUS_TYPE_STRING, &u->id,
DBUS_TYPE_OBJECT_PATH, &p,
DBUS_TYPE_INVALID))
goto oom;
}
- if (bus_broadcast(u->meta.manager, m) < 0)
+ if (bus_broadcast(u->manager, m) < 0)
goto oom;
free(p);
dbus_message_unref(m);
- u->meta.sent_dbus_new_signal = true;
+ u->sent_dbus_new_signal = true;
return;
assert(u);
- if (!bus_has_subscriber(u->meta.manager))
+ if (!bus_has_subscriber(u->manager))
return;
- if (!u->meta.sent_dbus_new_signal)
+ if (!u->sent_dbus_new_signal)
bus_unit_send_change_signal(u);
- if (!u->meta.id)
+ if (!u->id)
return;
if (!(p = unit_dbus_path(u)))
goto oom;
if (!dbus_message_append_args(m,
- DBUS_TYPE_STRING, &u->meta.id,
+ DBUS_TYPE_STRING, &u->id,
DBUS_TYPE_OBJECT_PATH, &p,
DBUS_TYPE_INVALID))
goto oom;
- if (bus_broadcast(u->meta.manager, m) < 0)
+ if (bus_broadcast(u->manager, m) < 0)
goto oom;
free(p);