dbus-unit.c revision b170dd803d334234ad7edd0dc7bb34860832bc07
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/***
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering This file is part of systemd.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Copyright 2010 Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is free software; you can redistribute it and/or modify it
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering under the terms of the GNU Lesser General Public License as published by
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering (at your option) any later version.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is distributed in the hope that it will be useful, but
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Lesser General Public License for more details.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering You should have received a copy of the GNU Lesser General Public License
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering***/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell#include <errno.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "dbus.h"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "log.h"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "dbus-unit.h"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "bus-errors.h"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "dbus-common.h"
13790add4bf648fed816361794d8277a75253410Lennart Poettering#include "selinux-access.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "cgroup-util.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "strv.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "path-util.h"
a09561746f15b84da9471b5c4be74e53d19e4f3fLennart Poettering#include "fileio.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poetteringconst char bus_unit_interface[] _introspect_("Unit") = BUS_UNIT_INTERFACE;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
afc5dbf37fd2399d37976388d9dd9ab470ecf446Lennart Poettering#define INVALIDATING_PROPERTIES \
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering "LoadState\0" \
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering "ActiveState\0" \
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "SubState\0" \
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering "InactiveExitTimestamp\0" \
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering "ActiveEnterTimestamp\0" \
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen "ActiveExitTimestamp\0" \
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering "InactiveEnterTimestamp\0" \
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering "Job\0" \
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering "NeedDaemonReload\0"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering
15a5e95075a7f6007dd97b2a165c8ed16fe683dfLennart Poetteringstatic int bus_unit_append_names(DBusMessageIter *i, const char *property, void *data) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering char *t;
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering Iterator j;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering DBusMessageIter sub;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Unit *u = data;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering SET_FOREACH(t, u->names, j)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &t))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_close_container(i, &sub))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int bus_unit_append_following(DBusMessageIter *i, const char *property, void *data) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Unit *u = data, *f;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const char *d;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(i);
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek assert(property);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(u);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering f = unit_following(u);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering d = f ? f->id : "";
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int bus_unit_append_slice(DBusMessageIter *i, const char *property, void *data) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Unit *u = data;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const char *d;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering assert(i);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(property);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(u);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering d = strempty(unit_slice_name(u));
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOMEM;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int bus_unit_append_dependencies(DBusMessageIter *i, const char *property, void *data) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering Unit *u;
13790add4bf648fed816361794d8277a75253410Lennart Poettering Iterator j;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering DBusMessageIter sub;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering Set *s = data;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOMEM;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering SET_FOREACH(u, s, j)
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &u->id))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOMEM;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!dbus_message_iter_close_container(i, &sub))
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek return -ENOMEM;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int bus_unit_append_description(DBusMessageIter *i, const char *property, void *data) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering Unit *u = data;
13790add4bf648fed816361794d8277a75253410Lennart Poettering const char *d;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(i);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(property);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering d = unit_description(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOMEM;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_unit_append_load_state, unit_load_state, UnitLoadState);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int bus_unit_append_active_state(DBusMessageIter *i, const char *property, void *data) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering Unit *u = data;
13790add4bf648fed816361794d8277a75253410Lennart Poettering const char *state;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(i);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(property);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering state = unit_active_state_to_string(unit_active_state(u));
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOMEM;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int bus_unit_append_sub_state(DBusMessageIter *i, const char *property, void *data) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering Unit *u = data;
13790add4bf648fed816361794d8277a75253410Lennart Poettering const char *state;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(i);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(property);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(u);
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering state = unit_sub_state_to_string(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOMEM;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int bus_unit_append_file_state(DBusMessageIter *i, const char *property, void *data) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering Unit *u = data;
13790add4bf648fed816361794d8277a75253410Lennart Poettering const char *state;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(i);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(property);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering state = strempty(unit_file_state_to_string(unit_get_unit_file_state(u)));
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOMEM;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int bus_unit_append_can_start(DBusMessageIter *i, const char *property, void *data) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering Unit *u = data;
13790add4bf648fed816361794d8277a75253410Lennart Poettering dbus_bool_t b;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(i);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(property);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering b = unit_can_start(u) &&
13790add4bf648fed816361794d8277a75253410Lennart Poettering !u->refuse_manual_start;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOMEM;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int bus_unit_append_can_stop(DBusMessageIter *i, const char *property, void *data) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering Unit *u = data;
13790add4bf648fed816361794d8277a75253410Lennart Poettering dbus_bool_t b;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(i);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(property);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(u);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering /* On the lower levels we assume that every unit we can start
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering * we can also stop */
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering b = unit_can_start(u) &&
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering !u->refuse_manual_stop;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOMEM;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poetteringstatic int bus_unit_append_can_reload(DBusMessageIter *i, const char *property, void *data) {
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering Unit *u = data;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering dbus_bool_t b;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(i);
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering assert(property);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering b = unit_can_reload(u);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek return -ENOMEM;
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek return 0;
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek}
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int bus_unit_append_can_isolate(DBusMessageIter *i, const char *property, void *data) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Unit *u = data;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering dbus_bool_t b;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(i);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(property);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(u);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering b = unit_can_isolate(u) &&
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering !u->refuse_manual_start;
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int bus_unit_append_job(DBusMessageIter *i, const char *property, void *data) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Unit *u = data;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering DBusMessageIter sub;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering _cleanup_free_ char *p = NULL;
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen assert(i);
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen assert(property);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(u);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub))
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek if (u->job) {
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek p = job_dbus_path(u->job);
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek if (!p)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &u->job->id) ||
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering uint32_t id = 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* No job, so let's fill in some placeholder
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * data. Since we need to fill in a valid path we
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * simple point to ourselves. */
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek p = unit_dbus_path(u);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!p)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &id) ||
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_close_container(i, &sub))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int bus_unit_append_need_daemon_reload(DBusMessageIter *i, const char *property, void *data) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Unit *u = data;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering dbus_bool_t b;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(i);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(property);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(u);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering b = unit_need_daemon_reload(u);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int bus_unit_append_load_error(DBusMessageIter *i, const char *property, void *data) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Unit *u = data;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const char *name, *message;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering DBusMessageIter sub;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(i);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(property);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(u);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (u->load_error != 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering name = bus_errno_to_dbus(u->load_error);
41891700e02daf0cab9e86908c76ac6f411bbd57Lennart Poettering message = strempty(strerror(-u->load_error));
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering name = message = "";
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub) ||
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &name) ||
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &message) ||
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering !dbus_message_iter_close_container(i, &sub))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *connection, DBusMessage *message) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering DBusError error;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering JobType job_type = _JOB_TYPE_INVALID;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering bool reload_if_possible = false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering dbus_error_init(&error);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Start"))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering job_type = JOB_START;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Stop"))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering job_type = JOB_STOP;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Reload"))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering job_type = JOB_RELOAD;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Restart"))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering job_type = JOB_RESTART;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "TryRestart"))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering job_type = JOB_TRY_RESTART;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ReloadOrRestart")) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering reload_if_possible = true;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering job_type = JOB_RESTART;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ReloadOrTryRestart")) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering reload_if_possible = true;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering job_type = JOB_TRY_RESTART;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Kill")) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const char *swho;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int32_t signo;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering KillWho who;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_get_args(
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering message,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering &error,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering DBUS_TYPE_STRING, &swho,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering DBUS_TYPE_INT32, &signo,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering DBUS_TYPE_INVALID))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return bus_send_error_reply(connection, message, &error, -EINVAL);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (isempty(swho))
13790add4bf648fed816361794d8277a75253410Lennart Poettering who = KILL_ALL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering who = kill_who_from_string(swho);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (who < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return bus_send_error_reply(connection, message, &error, -EINVAL);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (signo <= 0 || signo >= _NSIG)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return bus_send_error_reply(connection, message, &error, -EINVAL);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "stop");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = unit_kill(u, who, signo, &error);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return bus_send_error_reply(connection, message, &error, r);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering reply = dbus_message_new_method_return(message);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!reply)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering goto oom;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ResetFailed")) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "reload");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering unit_reset_failed(u);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering reply = dbus_message_new_method_return(message);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!reply)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering goto oom;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "SetProperties")) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering DBusMessageIter iter;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering dbus_bool_t runtime;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_iter_init(message, &iter))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering goto oom;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &runtime, true) < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return bus_send_error_reply(connection, message, NULL, -EINVAL);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "start");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = bus_unit_set_properties(u, &iter, runtime ? UNIT_RUNTIME : UNIT_PERSISTENT, true, &error);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return bus_send_error_reply(connection, message, &error, r);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering reply = dbus_message_new_method_return(message);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!reply)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering goto oom;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else if (UNIT_VTABLE(u)->bus_message_handler)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return UNIT_VTABLE(u)->bus_message_handler(u, connection, message);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (job_type != _JOB_TYPE_INVALID) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const char *smode;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering JobMode mode;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_get_args(
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering message,
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering &error,
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering DBUS_TYPE_STRING, &smode,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering DBUS_TYPE_INVALID))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return bus_send_error_reply(connection, message, &error, -EINVAL);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering mode = job_mode_from_string(smode);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (mode < 0) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering dbus_set_error(&error, BUS_ERROR_INVALID_JOB_MODE, "Job mode %s is invalid.", smode);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return bus_send_error_reply(connection, message, &error, -EINVAL);
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return bus_unit_queue_job(connection, message, u, job_type, mode, reload_if_possible);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (reply)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!bus_maybe_send_reply(connection, message, reply))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering goto oom;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt return DBUS_HANDLER_RESULT_HANDLED;
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringoom:
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering dbus_error_free(&error);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return DBUS_HANDLER_RESULT_NEED_MEMORY;
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering}
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic DBusHandlerResult bus_unit_message_handler(DBusConnection *connection, DBusMessage *message, void *data) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Manager *m = data;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Unit *u;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering DBusError error;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(connection);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(message);
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering assert(m);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering dbus_error_init(&error);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (streq(dbus_message_get_path(message), "/org/freedesktop/systemd1/unit")) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Be nice to gdbus and return introspection data for our mid-level paths */
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering SELINUX_ACCESS_CHECK(connection, message, "status");
13790add4bf648fed816361794d8277a75253410Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering char *introspection = NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering FILE *f;
13790add4bf648fed816361794d8277a75253410Lennart Poettering Iterator i;
13790add4bf648fed816361794d8277a75253410Lennart Poettering const char *k;
13790add4bf648fed816361794d8277a75253410Lennart Poettering size_t size;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering reply = dbus_message_new_method_return(message);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!reply)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering goto oom;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* We roll our own introspection code here, instead of
13790add4bf648fed816361794d8277a75253410Lennart Poettering * relying on bus_default_message_handler() because we
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * need to generate our introspection string
13790add4bf648fed816361794d8277a75253410Lennart Poettering * dynamically. */
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek f = open_memstream(&introspection, &size);
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek if (!f)
13790add4bf648fed816361794d8277a75253410Lennart Poettering goto oom;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
13790add4bf648fed816361794d8277a75253410Lennart Poettering "<node>\n", f);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering fputs(BUS_INTROSPECTABLE_INTERFACE, f);
13790add4bf648fed816361794d8277a75253410Lennart Poettering fputs(BUS_PEER_INTERFACE, f);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering HASHMAP_FOREACH_KEY(u, k, m->units, i) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering char *p;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (k != u->id)
13790add4bf648fed816361794d8277a75253410Lennart Poettering continue;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering p = bus_path_escape(k);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!p) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering fclose(f);
13790add4bf648fed816361794d8277a75253410Lennart Poettering free(introspection);
13790add4bf648fed816361794d8277a75253410Lennart Poettering goto oom;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering fprintf(f, "<node name=\"%s\"/>", p);
13790add4bf648fed816361794d8277a75253410Lennart Poettering free(p);
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering fputs("</node>\n", f);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (ferror(f)) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering fclose(f);
13790add4bf648fed816361794d8277a75253410Lennart Poettering free(introspection);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering goto oom;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering fclose(f);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (!introspection)
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering goto oom;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering free(introspection);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering goto oom;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
e1427b138fbf7b7f13bb61187635b882be3ca2b2Michal Schmidt free(introspection);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!bus_maybe_send_reply(connection, message, reply))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering goto oom;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return DBUS_HANDLER_RESULT_HANDLED;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = manager_load_unit_from_dbus_path(m, dbus_message_get_path(message), &error, &u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r == -ENOMEM)
13790add4bf648fed816361794d8277a75253410Lennart Poettering goto oom;
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return bus_send_error_reply(connection, message, &error, r);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return bus_unit_message_dispatch(u, connection, message);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringoom:
13790add4bf648fed816361794d8277a75253410Lennart Poettering dbus_error_free(&error);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return DBUS_HANDLER_RESULT_NEED_MEMORY;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringconst DBusObjectPathVTable bus_unit_vtable = {
13790add4bf648fed816361794d8277a75253410Lennart Poettering .message_function = bus_unit_message_handler
13790add4bf648fed816361794d8277a75253410Lennart Poettering};
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringvoid bus_unit_send_change_signal(Unit *u) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_dbus_message_unref_ DBusMessage *m = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_free_ char *p = NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (u->in_dbus_queue) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering u->in_dbus_queue = false;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!u->id)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!bus_has_subscriber(u->manager)) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering u->sent_dbus_new_signal = true;
13790add4bf648fed816361794d8277a75253410Lennart Poettering return;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering p = unit_dbus_path(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!p) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_oom();
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (u->sent_dbus_new_signal) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Send a properties changed signal. First for the
13790add4bf648fed816361794d8277a75253410Lennart Poettering * specific type, then for the generic unit. The
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering * clients may rely on this order to get atomic
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * behavior if needed. */
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (UNIT_VTABLE(u)->bus_invalidating_properties) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering m = bus_properties_changed_new(p,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering UNIT_VTABLE(u)->bus_interface,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering UNIT_VTABLE(u)->bus_invalidating_properties);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!m) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_oom();
13790add4bf648fed816361794d8277a75253410Lennart Poettering return;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = bus_broadcast(u->manager, m);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_error("Failed to broadcast change message: %s", strerror(-r));
13790add4bf648fed816361794d8277a75253410Lennart Poettering return;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering dbus_message_unref(m);
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Unit",
13790add4bf648fed816361794d8277a75253410Lennart Poettering INVALIDATING_PROPERTIES);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!m) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_oom();
13790add4bf648fed816361794d8277a75253410Lennart Poettering return;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering } else {
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Send a new signal */
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering m = dbus_message_new_signal("/org/freedesktop/systemd1",
13790add4bf648fed816361794d8277a75253410Lennart Poettering "org.freedesktop.systemd1.Manager",
13790add4bf648fed816361794d8277a75253410Lennart Poettering "UnitNew");
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!m) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_oom();
13790add4bf648fed816361794d8277a75253410Lennart Poettering return;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!dbus_message_append_args(m,
13790add4bf648fed816361794d8277a75253410Lennart Poettering DBUS_TYPE_STRING, &u->id,
13790add4bf648fed816361794d8277a75253410Lennart Poettering DBUS_TYPE_OBJECT_PATH, &p,
13790add4bf648fed816361794d8277a75253410Lennart Poettering DBUS_TYPE_INVALID)) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_oom();
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmek r = bus_broadcast(u->manager, m);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_error("Failed to broadcast UnitNew/PropertiesChanged message.");
13790add4bf648fed816361794d8277a75253410Lennart Poettering return;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering u->sent_dbus_new_signal = true;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringvoid bus_unit_send_removed_signal(Unit *u) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_free_ char *p = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_dbus_message_unref_ DBusMessage *m = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!bus_has_subscriber(u->manager))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!u->sent_dbus_new_signal)
13790add4bf648fed816361794d8277a75253410Lennart Poettering bus_unit_send_change_signal(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!u->id)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering p = unit_dbus_path(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!p)
13790add4bf648fed816361794d8277a75253410Lennart Poettering goto oom;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering m = dbus_message_new_signal("/org/freedesktop/systemd1",
13790add4bf648fed816361794d8277a75253410Lennart Poettering "org.freedesktop.systemd1.Manager",
13790add4bf648fed816361794d8277a75253410Lennart Poettering "UnitRemoved");
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!m)
13790add4bf648fed816361794d8277a75253410Lennart Poettering goto oom;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!dbus_message_append_args(m,
13790add4bf648fed816361794d8277a75253410Lennart Poettering DBUS_TYPE_STRING, &u->id,
13790add4bf648fed816361794d8277a75253410Lennart Poettering DBUS_TYPE_OBJECT_PATH, &p,
13790add4bf648fed816361794d8277a75253410Lennart Poettering DBUS_TYPE_INVALID))
13790add4bf648fed816361794d8277a75253410Lennart Poettering goto oom;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (bus_broadcast(u->manager, m) < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering goto oom;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringoom:
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_oom();
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart PoetteringDBusHandlerResult bus_unit_queue_job(
13790add4bf648fed816361794d8277a75253410Lennart Poettering DBusConnection *connection,
13790add4bf648fed816361794d8277a75253410Lennart Poettering DBusMessage *message,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Unit *u,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering JobType type,
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmek JobMode mode,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering bool reload_if_possible) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering _cleanup_free_ char *path = NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Job *j;
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek JobBusClient *cl;
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek DBusError error;
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek int r;
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(connection);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(message);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt assert(u);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt assert(type >= 0 && type < _JOB_TYPE_MAX);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(mode >= 0 && mode < _JOB_MODE_MAX);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering dbus_error_init(&error);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (reload_if_possible && unit_can_reload(u)) {
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (type == JOB_RESTART)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering type = JOB_RELOAD_OR_START;
4a61c3e51e96a747c30598d78ee3a24e7c569e9fZbigniew Jędrzejewski-Szmek else if (type == JOB_TRY_RESTART)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering type = JOB_RELOAD;
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt }
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering SELINUX_UNIT_ACCESS_CHECK(u, connection, message,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering (type == JOB_START || type == JOB_RESTART || type == JOB_TRY_RESTART) ? "start" :
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering type == JOB_STOP ? "stop" : "reload");
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt if (type == JOB_STOP && (u->load_state == UNIT_NOT_FOUND || u->load_state == UNIT_ERROR) && unit_active_state(u) == UNIT_INACTIVE) {
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return bus_send_error_reply(connection, message, &error, -EPERM);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering }
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt if ((type == JOB_START && u->refuse_manual_start) ||
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering (type == JOB_STOP && u->refuse_manual_stop) ||
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering ((type == JOB_RESTART || type == JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop))) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering dbus_set_error(&error, BUS_ERROR_ONLY_BY_DEPENDENCY,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering "Operation refused, unit %s may be requested by dependency only.", u->id);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return bus_send_error_reply(connection, message, &error, -EPERM);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering }
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering r = manager_add_job(u->manager, type, u, mode, true, &error, &j);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (r < 0)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return bus_send_error_reply(connection, message, &error, r);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering cl = job_bus_client_new(connection, bus_message_get_sender_with_fallback(message));
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (!cl)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering goto oom;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering LIST_PREPEND(JobBusClient, client, j->bus_client_list, cl);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering reply = dbus_message_new_method_return(message);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (!reply)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering goto oom;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering path = job_dbus_path(j);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (!path)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering goto oom;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (!dbus_message_append_args(
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering reply,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering DBUS_TYPE_OBJECT_PATH, &path,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering DBUS_TYPE_INVALID))
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering goto oom;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (!bus_maybe_send_reply(connection, message, reply))
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering goto oom;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return DBUS_HANDLER_RESULT_HANDLED;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringoom:
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering dbus_error_free(&error);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return DBUS_HANDLER_RESULT_NEED_MEMORY;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering}
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringstatic int bus_unit_set_transient_property(
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering Unit *u,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering const char *name,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering DBusMessageIter *i,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering UnitSetPropertiesMode mode,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering DBusError *error) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering int r;
assert(u);
assert(name);
assert(i);
if (streq(name, "Description")) {
if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING)
return -EINVAL;
if (mode != UNIT_CHECK) {
const char *description;
dbus_message_iter_get_basic(i, &description);
r = unit_set_description(u, description);
if (r < 0)
return r;
}
return 1;
} else if (streq(name, "Slice") && unit_get_cgroup_context(u)) {
const char *s;
Unit *slice;
if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING)
return -EINVAL;
dbus_message_iter_get_basic(i, &s);
if (isempty(s)) {
if (mode != UNIT_CHECK)
unit_ref_unset(&u->slice);
} else {
r = manager_load_unit(u->manager, s, NULL, error, &slice);
if (r < 0)
return r;
if (slice->type != UNIT_SLICE)
return -EINVAL;
if (mode != UNIT_CHECK)
unit_ref_set(&u->slice, slice);
}
return 1;
}
return 0;
}
int bus_unit_set_properties(
Unit *u,
DBusMessageIter *iter,
UnitSetPropertiesMode mode,
bool commit,
DBusError *error) {
bool for_real = false;
DBusMessageIter sub;
unsigned n = 0;
int r;
assert(u);
assert(iter);
if (u->transient)
mode &= UNIT_RUNTIME;
/* We iterate through the array twice. First run we just check
* if all passed data is valid, second run actually applies
* it. This is to implement transaction-like behaviour without
* actually providing full transactions. */
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY ||
dbus_message_iter_get_element_type(iter) != DBUS_TYPE_STRUCT)
return -EINVAL;
dbus_message_iter_recurse(iter, &sub);
for (;;) {
DBusMessageIter sub2, sub3;
const char *name;
if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_INVALID) {
if (for_real)
break;
/* Reached EOF. Let's try again, and this time for realz... */
dbus_message_iter_recurse(iter, &sub);
for_real = true;
continue;
}
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT)
return -EINVAL;
dbus_message_iter_recurse(&sub, &sub2);
if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0 ||
dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT)
return -EINVAL;
if (!UNIT_VTABLE(u)->bus_set_property) {
dbus_set_error(error, DBUS_ERROR_PROPERTY_READ_ONLY, "Objects of this type do not support setting properties.");
return -ENOENT;
}
dbus_message_iter_recurse(&sub2, &sub3);
r = UNIT_VTABLE(u)->bus_set_property(u, name, &sub3, for_real ? mode : UNIT_CHECK, error);
if (r == 0 && u->transient && u->load_state == UNIT_STUB)
r = bus_unit_set_transient_property(u, name, &sub3, for_real ? mode : UNIT_CHECK, error);
if (r < 0)
return r;
if (r == 0) {
dbus_set_error(error, DBUS_ERROR_PROPERTY_READ_ONLY, "Cannot set property %s, or unknown property.", name);
return -ENOENT;
}
dbus_message_iter_next(&sub);
n += for_real;
}
if (commit && n > 0 && UNIT_VTABLE(u)->bus_commit_properties)
UNIT_VTABLE(u)->bus_commit_properties(u);
return n;
}
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 },
{ "BindsTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BINDS_TO]), true },
{ "PartOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PART_OF]), 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 },
{ "ConsistsOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONSISTS_OF]), 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 },
{ "PropagatesReloadTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]), true },
{ "ReloadPropagatedFrom", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_RELOAD_PROPAGATED_FROM]), true },
{ "RequiresMountsFor", bus_property_append_strv, "as", offsetof(Unit, requires_mounts_for), true },
{ "Documentation", bus_property_append_strv, "as", offsetof(Unit, documentation), 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 },
{ "SourcePath", bus_property_append_string, "s", offsetof(Unit, source_path), true },
{ "DropInPaths", bus_property_append_strv, "as", offsetof(Unit, dropin_paths), 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) },
{ "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 },
{ "Transient", bus_property_append_bool, "b", offsetof(Unit, transient) },
{ NULL, }
};
const BusProperty bus_unit_cgroup_properties[] = {
{ "Slice", bus_unit_append_slice, "s", 0 },
{ "ControlGroup", bus_property_append_string, "s", offsetof(Unit, cgroup_path), true },
};