dbus-manager.c revision 128c3c5881e5708b3f15517ee24dd8c0a1c6307e
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/***
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering This file is part of systemd.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Copyright 2010 Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (at your option) any later version.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is distributed in the hope that it will be useful, but
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Lesser General Public License for more details.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering***/
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering#include <errno.h>
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering#include <unistd.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "log.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "strv.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "build.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "install.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "selinux-access.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "watchdog.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "hwclock.h"
3c70e3bb022f0de3317f3600c9366a2f4597339eLennart Poettering#include "path-util.h"
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#include "virt.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "env-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "dbus.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "dbus-manager.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "dbus-unit.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "dbus-snapshot.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "dbus-client-track.h"
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering#include "dbus-execute.h"
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack#include "bus-errors.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int property_get_version(
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus *bus,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *path,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *interface,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *property,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_message *reply,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering void *userdata,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int property_get_features(
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering sd_bus *bus,
4f10118016f9b2fd7e1d26c9ef7d91eb33fba694Lennart Poettering const char *path,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *interface,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *property,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_message *reply,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering void *userdata,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(reply);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_message_append(reply, "s", SYSTEMD_FEATURES);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int property_get_virtualization(
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus *bus,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *path,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *interface,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *property,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_message *reply,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering void *userdata,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *id = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(reply);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering detect_virtualization(&id);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_message_append(reply, "s", id);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int property_get_tainted(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus *bus,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *path,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *interface,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *property,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_message *reply,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering void *userdata,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_error *error) {
a1e58e8ee1c84b633d6d6d651d5328d4dd4eba5bLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char buf[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e = buf;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _cleanup_free_ char *p = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (m->taint_usr)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering e = stpcpy(e, "split-usr:");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (readlink_malloc("/etc/mtab", &p) < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering e = stpcpy(e, "mtab-not-symlink:");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (access("/proc/cgroups", F_OK) < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering e = stpcpy(e, "cgroups-missing:");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (hwclock_is_localtime() > 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering e = stpcpy(e, "local-hwclock:");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* remove the last ':' */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (e != buf)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering e[-1] = 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_message_append(reply, "s", buf);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int property_get_log_target(
920b52e4909d9dc812817fd8b82f83ca23a11c91Thomas Hindoe Paaboel Andersen sd_bus *bus,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *path,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *interface,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *property,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_message *reply,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering void *userdata,
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen sd_bus_error *error) {
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen assert(bus);
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen assert(reply);
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int property_set_log_target(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus *bus,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *path,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *interface,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *property,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_message *value,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering void *userdata,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering const char *t;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(value);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_read(value, "s", &t);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return log_set_target_from_string(t);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int property_get_log_level(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus *bus,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *path,
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering const char *interface,
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering const char *property,
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering sd_bus_message *reply,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering void *userdata,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *t = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(reply);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack r = log_level_to_string_alloc(log_get_max_level(), &t);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return sd_bus_message_append(reply, "s", t);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack}
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mackstatic int property_set_log_level(
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack sd_bus *bus,
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack const char *path,
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack const char *interface,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *property,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_message *value,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering void *userdata,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *t;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(value);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_read(value, "s", &t);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return log_set_max_level_from_string(t);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int property_get_n_names(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus *bus,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *path,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *interface,
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering const char *property,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_message *reply,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering void *userdata,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_error *error) {
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int property_get_n_jobs(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus *bus,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *path,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *interface,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *property,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_message *reply,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering void *userdata,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int property_get_progress(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus *bus,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *path,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *interface,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *property,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_message *reply,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering void *userdata,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering double d;
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack assert(bus);
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering assert(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering if (dual_timestamp_is_set(&m->finish_timestamp))
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack d = 1.0;
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering else
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_message_append(reply, "d", d);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int property_set_runtime_watchdog(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus *bus,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *path,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *interface,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *property,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_message *value,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering void *userdata,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering usec_t *t = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(value);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert_cc(sizeof(usec_t) == sizeof(uint64_t));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_read(value, "t", t);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return watchdog_set_timeout(t);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering _cleanup_free_ char *path = NULL;
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering Manager *m = userdata;
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering const char *name;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Unit *u;
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering int r;
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering
cfa9677bd164574600d29a9bf99f9d1f28a7a170Mantas MikulÄ—nas assert(bus);
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering assert(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_read(message, "s", &name);
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering if (r < 0)
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering return r;
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering u = manager_get_unit(m, name);
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering if (!u)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_unit_access_check(u, bus, message, "status", error);
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek if (r < 0)
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek return r;
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering path = unit_dbus_path(u);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!path)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -ENOMEM;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, "o", path);
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering}
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidtstatic int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering _cleanup_free_ char *path = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering pid_t pid;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Unit *u;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert_cc(sizeof(pid_t) == sizeof(uint32_t));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "u", &pid);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (pid == 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering u = manager_get_unit_by_pid(m, pid);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!u)
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_unit_access_check(u, bus, message, "status", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
be847e82cf95bf8eb589778df2aa2b3d1d7ae99eLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering path = unit_dbus_path(u);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!path)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -ENOMEM;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, "o", path);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *path = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *name;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Unit *u;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "s", &name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = manager_load_unit(m, name, NULL, error, &u);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_unit_access_check(u, bus, message, "status", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering path = unit_dbus_path(u);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!path)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -ENOMEM;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, "o", path);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_start_unit_generic(sd_bus *bus, sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *name;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Unit *u;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "s", &name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = manager_load_unit(m, name, NULL, error, &u);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
ce30c8dcb41dfe9264f79f30c7f51c0e74576638Lennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
ce30c8dcb41dfe9264f79f30c7f51c0e74576638Lennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *old_name;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Unit *u;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_read(message, "s", &old_name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering u = manager_get_unit(m, old_name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!u || !u->job || u->job->type != JOB_START)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return method_start_unit_generic(bus, message, m, JOB_START, false, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *name;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Unit *u;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
db2cb23b5b179707000d28a11efb3d888d06ee80Umut Tezduyar Lindskog
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering r = sd_bus_message_read(message, "s", &name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering u = manager_get_unit(m, name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!u)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return bus_unit_method_kill(bus, message, u, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *name;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Unit *u;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "s", &name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering u = manager_get_unit(m, name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!u)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return bus_unit_method_reset_failed(bus, message, u, error);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack}
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mackstatic int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack Manager *m = userdata;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack const char *name;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack Unit *u;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack int r;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "s", &name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering u = manager_get_unit(m, name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!u)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return bus_unit_method_set_properties(bus, message, u, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *name, *smode;
8d0e0ddda6501479eb69164687c83c1a7667b33aJan Engelhardt Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering JobMode mode;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering UnitType t;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Unit *u;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "ss", &name, &smode);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
8d0e0ddda6501479eb69164687c83c1a7667b33aJan Engelhardt
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering t = unit_name_to_type(name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (t < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering if (!unit_vtable[t]->can_transient)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering mode = job_mode_from_string(smode);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (mode < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = selinux_access_check(bus, message, "start", error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = manager_load_unit(m, name, NULL, error, &u);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (u->load_state != UNIT_NOT_FOUND || set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* OK, the unit failed to load and is unreferenced, now let's
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * fill in the transient data instead */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = unit_make_transient(u);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return r;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack /* Set our properties */
05a08cb60f02970e8476306074c70ee4e6a57fb3Thomas Hindoe Paaboel Andersen r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering /* And load this stub fully */
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering r = unit_load(u);
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering if (r < 0)
ff975efb2e88dcd5221a2f0d76c4c87e85b821a8Lennart Poettering return r;
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering manager_dispatch_load_queue(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Finally, start it */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *path = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering uint32_t id;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Job *j;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
995c5e96cdf9e6054a4df04960253d897f4d7cc2Lennart Poettering assert(bus);
995c5e96cdf9e6054a4df04960253d897f4d7cc2Lennart Poettering assert(message);
995c5e96cdf9e6054a4df04960253d897f4d7cc2Lennart Poettering assert(m);
995c5e96cdf9e6054a4df04960253d897f4d7cc2Lennart Poettering
995c5e96cdf9e6054a4df04960253d897f4d7cc2Lennart Poettering r = sd_bus_message_read(message, "u", &id);
995c5e96cdf9e6054a4df04960253d897f4d7cc2Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering j = manager_get_job(m, id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!j)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_unit_access_check(j->unit, bus, message, "status", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering path = job_dbus_path(j);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!path)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -ENOMEM;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, "o", path);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering uint32_t id;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Job *j;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack r = sd_bus_message_read(message, "u", &id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering j = manager_get_job(m, id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!j)
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_unit_access_check(j->unit, bus, message, "stop", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering job_finish_and_invalidate(j, JOB_CANCELED, true);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_return(message, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
82a2b6bb5e4e5d294f09af778c48974a7857afb6Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = selinux_access_check(bus, message, "reboot", error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering manager_clear_jobs(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_return(message, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
82a2b6bb5e4e5d294f09af778c48974a7857afb6Lennart Poettering assert(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_access_check(bus, message, "reload", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
a34ceba66fc0e856d8f76f340389a4768b57a365Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering manager_reset_failed(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *k;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Iterator i;
a34ceba66fc0e856d8f76f340389a4768b57a365Lennart Poettering Unit *u;
a34ceba66fc0e856d8f76f340389a4768b57a365Lennart Poettering int r;
a34ceba66fc0e856d8f76f340389a4768b57a365Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_access_check(bus, message, "status", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_new_method_return(message, &reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering HASHMAP_FOREACH_KEY(u, k, m->units, i) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Unit *following;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (k != u->id)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering following = unit_following(u);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering unit_path = unit_dbus_path(u);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!unit_path)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -ENOMEM;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (u->job) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering job_path = job_dbus_path(u->job);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!job_path)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -ENOMEM;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_append(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering reply, "(ssssssouso)",
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering u->id,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unit_description(u),
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unit_load_state_to_string(u->load_state),
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering unit_active_state_to_string(unit_active_state(u)),
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unit_sub_state_to_string(u),
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering following ? following->id : "",
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unit_path,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering u->job ? u->job->id : 0,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering u->job ? job_type_to_string(u->job->type) : "",
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering job_path ? job_path : "/");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_close_container(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_send(bus, reply, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Iterator i;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Job *j;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering int r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
94e15fdc4d9d96fa6607bfb4eaaea164a3aec417David Herrmann assert(bus);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(message);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(m);
e24e415e5f3af2fe86d2be9a1f1a2e8d5f8c96bfDaniel Mack
e24e415e5f3af2fe86d2be9a1f1a2e8d5f8c96bfDaniel Mack r = selinux_access_check(bus, message, "status", error);
e24e415e5f3af2fe86d2be9a1f1a2e8d5f8c96bfDaniel Mack if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = sd_bus_message_new_method_return(message, &reply);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering return r;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering HASHMAP_FOREACH(j, m->jobs, i) {
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering job_path = job_dbus_path(j);
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering if (!job_path)
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering return -ENOMEM;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering unit_path = unit_dbus_path(j->unit);
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering if (!unit_path)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return -ENOMEM;
94e15fdc4d9d96fa6607bfb4eaaea164a3aec417David Herrmann
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = sd_bus_message_append(
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering reply, "(usssoo)",
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering j->id,
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering j->unit->id,
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering job_type_to_string(j->type),
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering job_state_to_string(j->state),
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering job_path,
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering unit_path);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = sd_bus_message_close_container(reply);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
a9c8343e83ec09f80a76930573b2592f97ae4283Daniel Mack return r;
a9c8343e83ec09f80a76930573b2592f97ae4283Daniel Mack
a9c8343e83ec09f80a76930573b2592f97ae4283Daniel Mack return sd_bus_send(bus, reply, NULL);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering}
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poetteringstatic int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering Manager *m = userdata;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering int r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(bus);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(message);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(m);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = selinux_access_check(bus, message, "status", error);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = bus_client_track(&m->subscribed, bus, sd_bus_message_get_sender(message));
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r == 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return sd_bus_reply_method_return(message, NULL);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering}
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poetteringstatic int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering Manager *m = userdata;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering int r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(bus);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(message);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(m);
a9c8343e83ec09f80a76930573b2592f97ae4283Daniel Mack
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering r = selinux_access_check(bus, message, "status", error);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = bus_client_untrack(m->subscribed, bus, sd_bus_message_get_sender(message));
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *dump = NULL;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering size_t size;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(message);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_access_check(bus, message, "status", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering f = open_memstream(&dump, &size);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!f)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -ENOMEM;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering manager_dump_units(m, f, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering manager_dump_jobs(m, f, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering fflush(f);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (ferror(f))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -ENOMEM;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_return(message, "s", dump);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _cleanup_free_ char *path = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *name;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int cleanup;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Snapshot *s;
deffddf1df29a5ed047feff3a0f2b765006fb71bLukas Nykryn int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering r = selinux_access_check(bus, message, "start", error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "sb", &name, &cleanup);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (isempty(name))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering name = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = snapshot_create(m, name, cleanup, error, &s);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering path = unit_dbus_path(UNIT(s));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!path)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -ENOMEM;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_return(message, "o", path);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *name;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Unit *u;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = selinux_access_check(bus, message, "stop", error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering r = sd_bus_message_read(message, "s", &name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering u = manager_get_unit(m, name);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering if (!u)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (u->type != UNIT_SNAPSHOT)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return bus_snapshot_method_remove(bus, message, u, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_access_check(bus, message, "reload", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Instead of sending the reply back right away, we just
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * remember that we need to and then send it after the reload
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * is finished. That way the caller knows when the reload
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * finished. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(!m->queued_message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_new_method_return(message, &m->queued_message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->queued_message_bus = sd_bus_ref(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->exit_code = MANAGER_RELOAD;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering assert(message);
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering assert(m);
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering r = selinux_access_check(bus, message, "reload", error);
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering if (r < 0)
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering return r;
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* We don't send a reply back here, the client should
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * just wait for us disconnecting. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering m->exit_code = MANAGER_REEXECUTE;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 1;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(bus);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = selinux_access_check(bus, message, "halt", error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (m->running_as == SYSTEMD_SYSTEM)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
1c2e9646e4a1720fc8ad35c705c195ae1a2c5ce0Lennart Poettering
d69a7ceaed77992105342a056fe68769c2e6d3bdJohannes Hölzl m->exit_code = MANAGER_EXIT;
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering return sd_bus_reply_method_return(message, NULL);
d79acc309327f8c0863bd3da8b93d926a1c93ba1David Herrmann}
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poetteringstatic int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering Manager *m = userdata;
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = selinux_access_check(bus, message, "reboot", error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
700ff4d97311902a440109a2c081731ab6ae8a20Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (m->running_as != SYSTEMD_SYSTEM)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->exit_code = MANAGER_REBOOT;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e05ad7bcc87f652cea321224f8eeb32e21d18e0cLennart Poettering
e05ad7bcc87f652cea321224f8eeb32e21d18e0cLennart Poettering assert(bus);
e05ad7bcc87f652cea321224f8eeb32e21d18e0cLennart Poettering assert(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_access_check(bus, message, "halt", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (m->running_as != SYSTEMD_SYSTEM)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->exit_code = MANAGER_POWEROFF;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_return(message, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = selinux_access_check(bus, message, "halt", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (m->running_as != SYSTEMD_SYSTEM)
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering m->exit_code = MANAGER_HALT;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(bus);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
r = selinux_access_check(bus, message, "reboot", error);
if (r < 0)
return r;
if (m->running_as != SYSTEMD_SYSTEM)
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
m->exit_code = MANAGER_KEXEC;
return sd_bus_reply_method_return(message, NULL);
}
static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
char *ri = NULL, *rt = NULL;
const char *root, *init;
Manager *m = userdata;
int r;
assert(bus);
assert(message);
assert(m);
r = selinux_access_check(bus, message, "reboot", error);
if (r < 0)
return r;
if (m->running_as != SYSTEMD_SYSTEM)
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
r = sd_bus_message_read(message, "ss", &root, &init);
if (r < 0)
return r;
if (path_equal(root, "/") || !path_is_absolute(root))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
/* Safety check */
if (isempty(init)) {
if (! path_is_os_tree(root))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. /etc/os-release is missing.", root);
} else {
_cleanup_free_ char *p = NULL;
if (!path_is_absolute(init))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
p = strappend(root, init);
if (!p)
return -ENOMEM;
if (access(p, X_OK) < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
}
rt = strdup(root);
if (!rt)
return -ENOMEM;
if (!isempty(init)) {
ri = strdup(init);
if (!ri) {
free(rt);
return -ENOMEM;
}
}
free(m->switch_root);
m->switch_root = rt;
free(m->switch_root_init);
m->switch_root_init = ri;
m->exit_code = MANAGER_SWITCH_ROOT;
return sd_bus_reply_method_return(message, NULL);
}
static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_strv_free_ char **plus = NULL;
Manager *m = userdata;
int r;
assert(bus);
assert(message);
assert(m);
r = selinux_access_check(bus, message, "reload", error);
if (r < 0)
return r;
r = sd_bus_message_read_strv(message, &plus);
if (r < 0)
return r;
if (!strv_env_is_valid(plus))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
r = manager_environment_add(m, NULL, plus);
if (r < 0)
return r;
return sd_bus_reply_method_return(message, NULL);
}
static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_strv_free_ char **minus = NULL;
Manager *m = userdata;
int r;
assert(bus);
assert(message);
assert(m);
r = selinux_access_check(bus, message, "reload", error);
if (r < 0)
return r;
r = sd_bus_message_read_strv(message, &minus);
if (r < 0)
return r;
if (!strv_env_name_or_assignment_is_valid(minus))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
r = manager_environment_add(m, minus, NULL);
if (r < 0)
return r;
return sd_bus_reply_method_return(message, NULL);
}
static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_strv_free_ char **minus = NULL, **plus = NULL;
Manager *m = userdata;
int r;
assert(bus);
assert(message);
assert(m);
r = selinux_access_check(bus, message, "reload", error);
if (r < 0)
return r;
r = sd_bus_message_read_strv(message, &plus);
if (r < 0)
return r;
r = sd_bus_message_read_strv(message, &minus);
if (r < 0)
return r;
if (!strv_env_is_valid(plus))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
if (!strv_env_name_or_assignment_is_valid(minus))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
r = manager_environment_add(m, minus, plus);
if (r < 0)
return r;
return sd_bus_reply_method_return(message, NULL);
}
static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
Manager *m = userdata;
UnitFileList *item;
Hashmap *h;
Iterator i;
int r;
assert(bus);
assert(message);
assert(m);
r = selinux_access_check(bus, message, "status", error);
if (r < 0)
return r;
r = sd_bus_message_new_method_return(message, &reply);
if (r < 0)
return r;
h = hashmap_new(string_hash_func, string_compare_func);
if (!h)
return -ENOMEM;
r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
if (r < 0)
goto fail;
r = sd_bus_message_open_container(reply, 'a', "(ss)");
if (r < 0)
goto fail;
HASHMAP_FOREACH(item, h, i) {
r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
if (r < 0)
goto fail;
}
unit_file_list_free(h);
r = sd_bus_message_close_container(reply);
if (r < 0)
return r;
return sd_bus_send(bus, reply, NULL);
fail:
unit_file_list_free(h);
return r;
}
static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
const char *name;
UnitFileState state;
UnitFileScope scope;
int r;
assert(bus);
assert(message);
assert(m);
r = selinux_access_check(bus, message, "status", error);
if (r < 0)
return r;
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return r;
scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
state = unit_file_get_state(scope, NULL, name);
if (state < 0)
return state;
return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
}
static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *default_target = NULL;
Manager *m = userdata;
UnitFileScope scope;
int r;
assert(bus);
assert(message);
assert(m);
r = selinux_access_check(bus, message, "status", error);
if (r < 0)
return r;
scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
r = unit_file_get_default(scope, NULL, &default_target);
if (r < 0)
return r;
return sd_bus_reply_method_return(message, "s", default_target);
}
static int send_unit_files_changed(sd_bus *bus, const char *destination, void *userdata) {
_cleanup_bus_message_unref_ sd_bus_message *message = NULL;
int r;
assert(bus);
r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged", &message);
if (r < 0)
return r;
return sd_bus_send_to(bus, message, destination, NULL);
}
static int reply_unit_file_changes_and_free(
Manager *m,
sd_bus *bus,
sd_bus_message *message,
int carries_install_info,
UnitFileChange *changes,
unsigned n_changes) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
unsigned i;
int r;
if (n_changes > 0)
bus_manager_foreach_client(m, send_unit_files_changed, NULL);
r = sd_bus_message_new_method_return(message, &reply);
if (r < 0)
goto fail;
if (carries_install_info >= 0) {
r = sd_bus_message_append(reply, "b", carries_install_info);
if (r < 0)
goto fail;
}
r = sd_bus_message_open_container(reply, 'a', "(sss)");
if (r < 0)
goto fail;
for (i = 0; i < n_changes; i++) {
r = sd_bus_message_append(
reply, "(sss)",
unit_file_change_type_to_string(changes[i].type),
changes[i].path,
changes[i].source);
if (r < 0)
goto fail;
}
r = sd_bus_message_close_container(reply);
if (r < 0)
goto fail;
return sd_bus_send(bus, reply, NULL);
fail:
unit_file_changes_free(changes, n_changes);
return r;
}
static int method_enable_unit_files_generic(
sd_bus *bus,
sd_bus_message *message,
Manager *m, const
char *verb,
int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
bool carries_install_info,
sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
UnitFileScope scope;
int runtime, force, r;
assert(bus);
assert(message);
assert(m);
r = selinux_access_check(bus, message, verb, error);
if (r < 0)
return r;
r = sd_bus_message_read_strv(message, &l);
if (r < 0)
return r;
r = sd_bus_message_read(message, "bb", &runtime, &force);
if (r < 0)
return r;
scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
if (r < 0)
return r;
return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
}
static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
}
static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
}
static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
}
static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset, true, error);
}
static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
}
static int method_disable_unit_files_generic(
sd_bus *bus,
sd_bus_message *message,
Manager *m, const
char *verb,
int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
UnitFileScope scope;
int r, runtime;
assert(bus);
assert(message);
assert(m);
r = selinux_access_check(bus, message, verb, error);
if (r < 0)
return r;
r = sd_bus_message_read_strv(message, &l);
if (r < 0)
return r;
r = sd_bus_message_read(message, "b", &runtime);
if (r < 0)
return r;
scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
r = call(scope, runtime, NULL, l, &changes, &n_changes);
if (r < 0)
return r;
return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
}
static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
}
static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
}
static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
Manager *m = userdata;
UnitFileScope scope;
const char *name;
int force, r;
assert(bus);
assert(message);
assert(m);
r = selinux_access_check(bus, message, "enable", error);
if (r < 0)
return r;
r = sd_bus_message_read(message, "sb", &name, &force);
if (r < 0)
return r;
scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
if (r < 0)
return r;
return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
}
const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Version", "s", property_get_version, 0, 0),
SD_BUS_PROPERTY("Features", "s", property_get_features, 0, 0),
SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, 0),
SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, 0),
BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), 0),
SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), 0),
SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), 0),
SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), 0),
SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), 0),
SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), 0),
SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, 0),
SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, 0),
SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, 0),
SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, 0),
SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, 0),
SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, 0),
SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, 0),
SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, 0),
SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, 0),
SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, 0),
SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, 0),
SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, 0),
SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, 0),
SD_BUS_METHOD("SetUnitProperties", "sb", "a(sv)", method_set_unit_properties, 0),
SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, 0),
SD_BUS_METHOD("GetJob", "u", "o", method_get_job, 0),
SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, 0),
SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, 0),
SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, 0),
SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, 0),
SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, 0),
SD_BUS_METHOD("Dump", NULL, "s", method_dump, 0),
SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
SD_BUS_METHOD("Reload", NULL, NULL, method_reload, 0),
SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, 0),
SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, 0),
SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, 0),
SD_BUS_METHOD("Halt", NULL, NULL, method_halt, 0),
SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, 0),
SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, 0),
SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, 0),
SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, 0),
SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, 0),
SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, 0),
SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, 0),
SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, 0),
SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, 0),
SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, 0),
SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, 0),
SD_BUS_SIGNAL("UnitNew", "so", 0),
SD_BUS_SIGNAL("UnitRemoved", "so", 0),
SD_BUS_SIGNAL("JobNew", "uos", 0),
SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
SD_BUS_SIGNAL("Reloading", "b", 0),
SD_BUS_VTABLE_END
};
int bus_manager_foreach_client(Manager *m, int (*send_message)(sd_bus *bus, const char *destination, void *userdata), void *userdata) {
Iterator i;
sd_bus *b;
unsigned n;
int r;
n = set_size(m->subscribed);
if (n <= 0)
return 0;
if (n == 1) {
BusTrackedClient *d;
assert_se(d = set_first(m->subscribed));
return send_message(d->bus, isempty(d->name) ? NULL : d->name, userdata);
}
/* Send to everybody */
SET_FOREACH(b, m->private_buses, i) {
r = send_message(b, NULL, userdata);
if (r < 0)
return r;
}
if (m->api_bus)
return send_message(m->api_bus, NULL, userdata);
return 0;
}
static int send_finished(sd_bus *bus, const char *destination, void *userdata) {
_cleanup_bus_message_unref_ sd_bus_message *message = NULL;
usec_t *times = userdata;
int r;
assert(bus);
assert(times);
r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished", &message);
if (r < 0)
return r;
r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
if (r < 0)
return r;
return sd_bus_send_to(bus, message, destination, NULL);
}
int bus_manager_send_finished(
Manager *m,
usec_t firmware_usec,
usec_t loader_usec,
usec_t kernel_usec,
usec_t initrd_usec,
usec_t userspace_usec,
usec_t total_usec) {
assert(m);
return bus_manager_foreach_client(m, send_finished,
(usec_t[6]) { firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec });
}
static int send_reloading(sd_bus *bus, const char *destination, void *userdata) {
_cleanup_bus_message_unref_ sd_bus_message *message = NULL;
int r;
assert(bus);
r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading", &message);
if (r < 0)
return r;
r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
if (r < 0)
return r;
return sd_bus_send_to(bus, message, destination, NULL);
}
int bus_manager_send_reloading(Manager *m, bool active) {
assert(m);
return bus_manager_foreach_client(m, send_reloading, INT_TO_PTR(active));
}