dbus-unit.c revision 80fbf05e75b75b7dd342ec844275efae90c479ec
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering/***
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering This file is part of systemd.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Copyright 2010 Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering systemd is free software; you can redistribute it and/or modify it
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering under the terms of the GNU Lesser General Public License as published by
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering (at your option) any later version.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering systemd is distributed in the hope that it will be useful, but
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Lesser General Public License for more details.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering You should have received a copy of the GNU Lesser General Public License
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering***/
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include <errno.h>
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include "dbus.h"
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek#include "log.h"
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek#include "dbus-unit.h"
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include "bus-errors.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "dbus-common.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringconst char bus_unit_interface[] _introspect_("Unit") = BUS_UNIT_INTERFACE;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#define INVALIDATING_PROPERTIES \
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "LoadState\0" \
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "ActiveState\0" \
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "SubState\0" \
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "InactiveExitTimestamp\0" \
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "ActiveEnterTimestamp\0" \
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "ActiveExitTimestamp\0" \
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "InactiveEnterTimestamp\0" \
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "Job\0" \
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "NeedDaemonReload\0"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int bus_unit_append_names(DBusMessageIter *i, const char *property, void *data) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering char *t;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Iterator j;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering DBusMessageIter sub;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Unit *u = data;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering SET_FOREACH(t, u->names, j)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &t))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_close_container(i, &sub))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int bus_unit_append_following(DBusMessageIter *i, const char *property, void *data) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Unit *u = data, *f;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *d;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(i);
39883f622f392d8579f4428fc5a789a102efbb10Lennart Poettering assert(property);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering f = unit_following(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering d = f ? f->id : "";
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int bus_unit_append_dependencies(DBusMessageIter *i, const char *property, void *data) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Unit *u;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Iterator j;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering DBusMessageIter sub;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Set *s = data;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering SET_FOREACH(u, s, j)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &u->id))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_close_container(i, &sub))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int bus_unit_append_description(DBusMessageIter *i, const char *property, void *data) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Unit *u = data;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *d;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(i);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(property);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering d = unit_description(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_unit_append_load_state, unit_load_state, UnitLoadState);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int bus_unit_append_active_state(DBusMessageIter *i, const char *property, void *data) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Unit *u = data;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *state;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(i);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(property);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering state = unit_active_state_to_string(unit_active_state(u));
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int bus_unit_append_sub_state(DBusMessageIter *i, const char *property, void *data) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Unit *u = data;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *state;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(i);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(property);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering state = unit_sub_state_to_string(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int bus_unit_append_file_state(DBusMessageIter *i, const char *property, void *data) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Unit *u = data;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *state;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(i);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(property);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering state = strempty(unit_file_state_to_string(unit_get_unit_file_state(u)));
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int bus_unit_append_can_start(DBusMessageIter *i, const char *property, void *data) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Unit *u = data;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering dbus_bool_t b;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(i);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(property);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering b = unit_can_start(u) &&
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering !u->refuse_manual_start;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int bus_unit_append_can_stop(DBusMessageIter *i, const char *property, void *data) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Unit *u = data;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering dbus_bool_t b;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(i);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(property);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* On the lower levels we assume that every unit we can start
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering * we can also stop */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering b = unit_can_start(u) &&
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering !u->refuse_manual_stop;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return -ENOMEM;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return 0;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering}
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringstatic int bus_unit_append_can_reload(DBusMessageIter *i, const char *property, void *data) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Unit *u = data;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering dbus_bool_t b;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering assert(i);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering assert(property);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering assert(u);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering b = unit_can_reload(u);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return -ENOMEM;
ef5bfcf668e6029faa78534dfeb2591df854cdefLennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return 0;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering}
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringstatic int bus_unit_append_can_isolate(DBusMessageIter *i, const char *property, void *data) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Unit *u = data;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering dbus_bool_t b;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek assert(i);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek assert(property);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering assert(u);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering b = unit_can_isolate(u) &&
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering !u->refuse_manual_start;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int bus_unit_append_job(DBusMessageIter *i, const char *property, void *data) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Unit *u = data;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering DBusMessageIter sub;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering char *p;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(i);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(property);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub))
875c6e1b48f37a07dfbb80d6653c73f205e94260Lennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (u->job) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!(p = job_dbus_path(u->job)))
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &u->job->id) ||
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering free(p);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return -ENOMEM;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering }
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering } else {
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering uint32_t id = 0;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering /* No job, so let's fill in some placeholder
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering * data. Since we need to fill in a valid path we
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering * simple point to ourselves. */
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering if (!(p = unit_dbus_path(u)))
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return -ENOMEM;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &id) ||
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) {
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering free(p);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return -ENOMEM;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering }
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering }
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering free(p);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering if (!dbus_message_iter_close_container(i, &sub))
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return -ENOMEM;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return 0;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering}
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmekstatic int bus_unit_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Unit *u = data;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering char *t;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering CGroupBonding *cgb;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering bool success;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(i);
73e231abde39f22097df50542c745e01de879836Jan Engelhardt assert(property);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if ((cgb = unit_get_default_cgroup(u))) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!(t = cgroup_bonding_to_string(cgb)))
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering return -ENOMEM;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering } else
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering t = (char*) "";
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (cgb)
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering free(t);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return success ? 0 : -ENOMEM;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek}
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringstatic int bus_unit_append_cgroups(DBusMessageIter *i, const char *property, void *data) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek Unit *u = data;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering CGroupBonding *cgb;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering DBusMessageIter sub;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub))
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return -ENOMEM;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering LIST_FOREACH(by_unit, cgb, u->cgroup_bondings) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering char *t;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering bool success;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (!(t = cgroup_bonding_to_string(cgb)))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -ENOMEM;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering success = dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &t);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering free(t);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (!success)
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return -ENOMEM;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering }
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (!dbus_message_iter_close_container(i, &sub))
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return -ENOMEM;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return 0;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering}
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringstatic int bus_unit_append_cgroup_attrs(DBusMessageIter *i, const char *property, void *data) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Unit *u = data;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering CGroupAttribute *a;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering DBusMessageIter sub, sub2;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sss)", &sub))
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return -ENOMEM;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering 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;
}
static int bus_unit_append_need_daemon_reload(DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
dbus_bool_t b;
assert(i);
assert(property);
assert(u);
b = unit_need_daemon_reload(u);
if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
return -ENOMEM;
return 0;
}
static 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->manager;
DBusError error;
JobType job_type = _JOB_TYPE_INVALID;
char *path = NULL;
bool reload_if_possible = false;
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 if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "TryRestart"))
job_type = JOB_TRY_RESTART;
else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ReloadOrRestart")) {
reload_if_possible = true;
job_type = JOB_RESTART;
} 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", "Kill")) {
const char *swho, *smode;
int32_t signo;
KillMode mode;
KillWho who;
int r;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &swho,
DBUS_TYPE_STRING, &smode,
DBUS_TYPE_INT32, &signo,
DBUS_TYPE_INVALID))
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 (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(connection, message, &error, r);
if (!(reply = dbus_message_new_method_return(message)))
goto oom;
} 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
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if (job_type != _JOB_TYPE_INVALID) {
const char *smode;
JobMode mode;
Job *j;
int r;
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->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(connection, message, &error, -EPERM);
}
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &smode,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
if (reload_if_possible && unit_can_reload(u)) {
if (job_type == JOB_RESTART)
job_type = JOB_RELOAD_OR_START;
else if (job_type == JOB_TRY_RESTART)
job_type = JOB_RELOAD;
}
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(connection, message, &error, -EINVAL);
}
if ((r = manager_add_job(m, job_type, u, mode, true, &error, &j)) < 0)
return bus_send_error_reply(connection, message, &error, 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(connection, reply, NULL))
goto oom;
dbus_message_unref(reply);
}
free(path);
return DBUS_HANDLER_RESULT_HANDLED;
oom:
free(path);
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) {
Manager *m = data;
Unit *u;
int r;
DBusMessage *reply = NULL;
DBusError error;
assert(connection);
assert(message);
assert(m);
dbus_error_init(&error);
if (streq(dbus_message_get_path(message), "/org/freedesktop/systemd1/unit")) {
/* Be nice to gdbus and return introspection data for our mid-level paths */
if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
char *introspection = NULL;
FILE *f;
Iterator i;
const char *k;
size_t size;
if (!(reply = dbus_message_new_method_return(message)))
goto oom;
/* We roll our own introspection code here, instead of
* relying on bus_default_message_handler() because we
* need to generate our introspection string
* dynamically. */
if (!(f = open_memstream(&introspection, &size)))
goto oom;
fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
"<node>\n", f);
fputs(BUS_INTROSPECTABLE_INTERFACE, f);
fputs(BUS_PEER_INTERFACE, f);
HASHMAP_FOREACH_KEY(u, k, m->units, i) {
char *p;
if (k != u->id)
continue;
if (!(p = bus_path_escape(k))) {
fclose(f);
free(introspection);
goto oom;
}
fprintf(f, "<node name=\"%s\"/>", p);
free(p);
}
fputs("</node>\n", f);
if (ferror(f)) {
fclose(f);
free(introspection);
goto oom;
}
fclose(f);
if (!introspection)
goto oom;
if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) {
free(introspection);
goto oom;
}
free(introspection);
if (!dbus_connection_send(connection, reply, NULL))
goto oom;
dbus_message_unref(reply);
return DBUS_HANDLER_RESULT_HANDLED;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
r = manager_load_unit_from_dbus_path(m, dbus_message_get_path(message), &error, &u);
if (r < 0) {
if (r == -ENOMEM)
goto oom;
return bus_send_error_reply(connection, message, &error, r);
}
return bus_unit_message_dispatch(u, connection, message);
oom:
if (reply)
dbus_message_unref(reply);
dbus_error_free(&error);
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
const DBusObjectPathVTable bus_unit_vtable = {
.message_function = bus_unit_message_handler
};
void bus_unit_send_change_signal(Unit *u) {
char *p = NULL;
DBusMessage *m = NULL;
assert(u);
if (u->in_dbus_queue) {
LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
u->in_dbus_queue = false;
}
if (!u->id)
return;
if (!bus_has_subscriber(u->manager)) {
u->sent_dbus_new_signal = true;
return;
}
if (!(p = unit_dbus_path(u)))
goto oom;
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
* behaviour if needed. */
if (UNIT_VTABLE(u)->bus_invalidating_properties) {
if (!(m = bus_properties_changed_new(p,
UNIT_VTABLE(u)->bus_interface,
UNIT_VTABLE(u)->bus_invalidating_properties)))
goto oom;
if (bus_broadcast(u->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 */
if (!(m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitNew")))
goto oom;
if (!dbus_message_append_args(m,
DBUS_TYPE_STRING, &u->id,
DBUS_TYPE_OBJECT_PATH, &p,
DBUS_TYPE_INVALID))
goto oom;
}
if (bus_broadcast(u->manager, m) < 0)
goto oom;
free(p);
dbus_message_unref(m);
u->sent_dbus_new_signal = true;
return;
oom:
free(p);
if (m)
dbus_message_unref(m);
log_error("Failed to allocate unit change/new signal.");
}
void bus_unit_send_removed_signal(Unit *u) {
char *p = NULL;
DBusMessage *m = NULL;
assert(u);
if (!bus_has_subscriber(u->manager))
return;
if (!u->sent_dbus_new_signal)
bus_unit_send_change_signal(u);
if (!u->id)
return;
if (!(p = unit_dbus_path(u)))
goto oom;
if (!(m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitRemoved")))
goto oom;
if (!dbus_message_append_args(m,
DBUS_TYPE_STRING, &u->id,
DBUS_TYPE_OBJECT_PATH, &p,
DBUS_TYPE_INVALID))
goto oom;
if (bus_broadcast(u->manager, m) < 0)
goto oom;
free(p);
dbus_message_unref(m);
return;
oom:
free(p);
if (m)
dbus_message_unref(m);
log_error("Failed to allocate unit remove signal.");
}
const BusProperty bus_unit_properties[] = {
{ "Id", bus_property_append_string, "s", offsetof(Unit, id), true },
{ "Names", bus_unit_append_names, "as", 0 },
{ "Following", bus_unit_append_following, "s", 0 },
{ "Requires", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES]), true },
{ "RequiresOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]), true },
{ "Requisite", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE]), true },
{ "RequisiteOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE_OVERRIDABLE]), true },
{ "Wants", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTS]), true },
{ "BindTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BIND_TO]), true },
{ "RequiredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), true },
{ "RequiredByOverridable",bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), true },
{ "WantedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTED_BY]), true },
{ "BoundBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BOUND_BY]), true },
{ "Conflicts", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTS]), true },
{ "ConflictedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]), true },
{ "Before", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BEFORE]), true },
{ "After", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_AFTER]), true },
{ "OnFailure", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_ON_FAILURE]), true },
{ "Triggers", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERS]), true },
{ "TriggeredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]), true },
{ "PropagateReloadTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_TO]), true },
{ "PropagateReloadFrom", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_FROM]), true },
{ "RequiresMountsFor", bus_property_append_strv, "as", offsetof(Unit, requires_mounts_for), true },
{ "Description", bus_unit_append_description, "s", 0 },
{ "LoadState", bus_unit_append_load_state, "s", offsetof(Unit, load_state) },
{ "ActiveState", bus_unit_append_active_state, "s", 0 },
{ "SubState", bus_unit_append_sub_state, "s", 0 },
{ "FragmentPath", bus_property_append_string, "s", offsetof(Unit, fragment_path), true },
{ "UnitFileState", bus_unit_append_file_state, "s", 0 },
{ "InactiveExitTimestamp",bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.realtime) },
{ "InactiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.monotonic) },
{ "ActiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.realtime) },
{ "ActiveEnterTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.monotonic) },
{ "ActiveExitTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.realtime) },
{ "ActiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.monotonic) },
{ "InactiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.realtime) },
{ "InactiveEnterTimestampMonotonic",bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.monotonic) },
{ "CanStart", bus_unit_append_can_start, "b", 0 },
{ "CanStop", bus_unit_append_can_stop, "b", 0 },
{ "CanReload", bus_unit_append_can_reload, "b", 0 },
{ "CanIsolate", bus_unit_append_can_isolate, "b", 0 },
{ "Job", bus_unit_append_job, "(uo)", 0 },
{ "StopWhenUnneeded", bus_property_append_bool, "b", offsetof(Unit, stop_when_unneeded) },
{ "RefuseManualStart", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_start) },
{ "RefuseManualStop", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_stop) },
{ "AllowIsolate", bus_property_append_bool, "b", offsetof(Unit, allow_isolate) },
{ "DefaultDependencies", bus_property_append_bool, "b", offsetof(Unit, default_dependencies) },
{ "OnFailureIsolate", bus_property_append_bool, "b", offsetof(Unit, on_failure_isolate) },
{ "IgnoreOnIsolate", bus_property_append_bool, "b", offsetof(Unit, ignore_on_isolate) },
{ "IgnoreOnSnapshot", bus_property_append_bool, "b", offsetof(Unit, ignore_on_snapshot) },
{ "DefaultControlGroup", bus_unit_append_default_cgroup, "s", 0 },
{ "ControlGroup", bus_unit_append_cgroups, "as", 0 },
{ "ControlGroupAttributes", bus_unit_append_cgroup_attrs,"a(sss)", 0 },
{ "NeedDaemonReload", bus_unit_append_need_daemon_reload, "b", 0 },
{ "JobTimeoutUSec", bus_property_append_usec, "t", offsetof(Unit, job_timeout) },
{ "ConditionTimestamp", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.realtime) },
{ "ConditionTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.monotonic) },
{ "ConditionResult", bus_property_append_bool, "b", offsetof(Unit, condition_result) },
{ "LoadError", bus_unit_append_load_error, "(ss)", 0 },
{ NULL, }
};