dbus-unit.c revision aec8de63b14a93b91b85dc15bf879604352fbbe1
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen This file is part of systemd.
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen Copyright 2010 Lennart Poettering
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen systemd is free software; you can redistribute it and/or modify it
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen under the terms of the GNU Lesser General Public License as published by
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen the Free Software Foundation; either version 2.1 of the License, or
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen (at your option) any later version.
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen systemd is distributed in the hope that it will be useful, but
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen WITHOUT ANY WARRANTY; without even the implied warranty of
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen Lesser General Public License for more details.
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen You should have received a copy of the GNU Lesser General Public License
a336a7912ecb62fb9310c4f3e50dc622aea4951cKnut Anders Hatlen along with systemd; If not, see <http://www.gnu.org/licenses/>.
#include "log.h"
#include "selinux-access.h"
#include "cgroup-util.h"
#include "strv.h"
#include "path-util.h"
#include "fileio.h"
#include "dbus-unit.h"
#include "dbus-manager.h"
#include "bus-errors.h"
#include "dbus-client-track.h"
static int property_get_names(
const char *path,
const char *interface,
const char *property,
void *userdata,
Iterator i;
assert(u);
static int property_get_following(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
f = unit_following(u);
static int property_get_dependencies(
const char *path,
const char *interface,
const char *property,
void *userdata,
Iterator j;
Unit *u;
SET_FOREACH(u, s, j) {
static int property_get_description(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
static int property_get_active_state(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
static int property_get_sub_state(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
static int property_get_unit_file_state(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
static int property_get_can_start(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
static int property_get_can_stop(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
static int property_get_can_reload(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
static int property_get_can_isolate(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
static int property_get_job(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
if (!u->job)
return -ENOMEM;
static int property_get_need_daemon_reload(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
static int property_get_conditions(
const char *path,
const char *interface,
const char *property,
void *userdata,
Condition *c;
assert(u);
static int property_get_load_error(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
if (u->load_error != 0)
int bus_unit_method_start_generic(sd_bus *bus, sd_bus_message *message, Unit *u, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
const char *smode;
assert(u);
if (mode < 0)
static int method_start(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
static int method_restart(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
static int method_try_restart(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
static int method_reload_or_restart(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
static int method_reload_or_try_restart(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
int bus_unit_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *swho;
assert(u);
if (who < 0)
int bus_unit_method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(u);
int bus_unit_method_set_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
int runtime, r;
assert(u);
SD_BUS_PROPERTY("Requires", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRES]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RequiresOverridable", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Requisite", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUISITE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RequisiteOverridable", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUISITE_OVERRIDABLE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Wants", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_WANTS]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("BindsTo", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_BINDS_TO]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PartOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_PART_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RequiredBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RequiredByOverridable", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("WantedBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_WANTED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("BoundBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_BOUND_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ConsistsOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_CONSISTS_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Conflicts", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_CONFLICTS]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ConflictedBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Before", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_BEFORE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("After", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_AFTER]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OnFailure", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_ON_FAILURE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Triggers", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_TRIGGERS]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TriggeredBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PropagatesReloadTo", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ReloadPropagatedFrom", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_RELOAD_PROPAGATED_FROM]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JoinsNamespaceOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_JOINS_NAMESPACE_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RequiresMountsFor", "as", NULL, offsetof(Unit, requires_mounts_for), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Documentation", "as", NULL, offsetof(Unit, documentation), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LoadState", "s", property_get_load_state, offsetof(Unit, load_state), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ActiveState", "s", property_get_active_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("FragmentPath", "s", NULL, offsetof(Unit, fragment_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Unit, source_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("DropInPaths", "as", NULL, offsetof(Unit, dropin_paths), SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("InactiveExitTimestamp", offsetof(Unit, inactive_exit_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
BUS_PROPERTY_DUAL_TIMESTAMP("ActiveEnterTimestamp", offsetof(Unit, active_enter_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
BUS_PROPERTY_DUAL_TIMESTAMP("ActiveExitTimestamp", offsetof(Unit, active_exit_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
BUS_PROPERTY_DUAL_TIMESTAMP("InactiveEnterTimestamp", offsetof(Unit, inactive_enter_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("StopWhenUnneeded", "b", bus_property_get_bool, offsetof(Unit, stop_when_unneeded), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RefuseManualStart", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_start), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RefuseManualStop", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_stop), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("AllowIsolate", "b", bus_property_get_bool, offsetof(Unit, allow_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("DefaultDependencies", "b", bus_property_get_bool, offsetof(Unit, default_dependencies), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OnFailureJobMode", "s", property_get_job_mode, offsetof(Unit, on_failure_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IgnoreOnIsolate", "b", bus_property_get_bool, offsetof(Unit, ignore_on_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IgnoreOnSnapshot", "b", bus_property_get_bool, offsetof(Unit, ignore_on_snapshot), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ConditionResult", "b", bus_property_get_bool, offsetof(Unit, condition_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
BUS_PROPERTY_DUAL_TIMESTAMP("ConditionTimestamp", offsetof(Unit, condition_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST),
static int property_get_slice(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(u);
assert(u);
p = unit_dbus_path(u);
return -ENOMEM;
bus,
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
assert(u);
p = unit_dbus_path(u);
return -ENOMEM;
bus, p,
NULL);
log_warning("Failed to send out specific PropertiesChanged signal for %s: %s", u->id, strerror(-r));
bus, p,
"org.freedesktop.systemd1.Unit",
NULL);
assert(u);
if (u->in_dbus_queue) {
u->in_dbus_queue = false;
if (!u->id)
r = bus_manager_foreach_client(u->manager, u->sent_dbus_new_signal ? send_changed_signal : send_new_signal, u);
u->sent_dbus_new_signal = true;
assert(u);
p = unit_dbus_path(u);
return -ENOMEM;
bus,
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
assert(u);
if (!u->sent_dbus_new_signal)
if (!u->id)
int bus_unit_queue_job(
Unit *u,
bool reload_if_possible,
Job *j;
assert(u);
((type == JOB_RESTART || type == JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)))
return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only.", u->id);
if (!path)
return -ENOMEM;
static int bus_unit_set_transient_property(
Unit *u,
const char *name,
assert(u);
r = unit_set_description(u, d);
if (isempty(s)) {
return -EINVAL;
const char *other;
return -EINVAL;
if (!label)
return -ENOMEM;
Unit *u,
bool commit,
bool for_real = false;
assert(u);
if (u->transient)
const char *name;
for_real = true;
return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Objects of this type do not support setting properties.");
return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Cannot set property %s, or unknown property.", name);
n += for_real;