dbus-scope.c revision 4afd3348c7506dd1d36305b7bcb9feb8952b9d6b
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/***
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering This file is part of systemd.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Copyright 2013 Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is free software; you can redistribute it and/or modify it
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering under the terms of the GNU Lesser General Public License as published by
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering (at your option) any later version.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is distributed in the hope that it will be useful, but
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Lesser General Public License for more details.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering You should have received a copy of the GNU Lesser General Public License
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering***/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell#include "alloc-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "bus-common-errors.h"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "bus-internal.h"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "bus-util.h"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "dbus-cgroup.h"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "dbus-kill.h"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "dbus-scope.h"
13790add4bf648fed816361794d8277a75253410Lennart Poettering#include "dbus-unit.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "dbus.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "scope.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "selinux-access.h"
a09561746f15b84da9471b5c4be74e53d19e4f3fLennart Poettering#include "unit.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poetteringstatic int bus_scope_abandon(sd_bus_message *message, void *userdata, sd_bus_error *error) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering Scope *s = userdata;
afc5dbf37fd2399d37976388d9dd9ab470ecf446Lennart Poettering int r;
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering assert(message);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = mac_selinux_unit_access_check(UNIT(s), message, "stop", error);
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen if (r < 0)
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering return r;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering r = bus_verify_manage_units_async(UNIT(s)->manager, message, error);
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering if (r < 0)
15a5e95075a7f6007dd97b2a165c8ed16fe683dfLennart Poettering return r;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering if (r == 0)
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = scope_abandon(s);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r == -ESTALE)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_SCOPE_NOT_RUNNING, "Scope %s is not running, cannot abandon.", UNIT(s)->id);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return sd_bus_reply_method_return(message, NULL);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, scope_result, ScopeResult);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringconst sd_bus_vtable bus_scope_vtable[] = {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering SD_BUS_VTABLE_START(0),
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering SD_BUS_PROPERTY("Controller", "s", NULL, offsetof(Scope, controller), SD_BUS_VTABLE_PROPERTY_CONST),
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Scope, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Scope, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering SD_BUS_SIGNAL("RequestStop", NULL, 0),
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering SD_BUS_METHOD("Abandon", NULL, NULL, bus_scope_abandon, SD_BUS_VTABLE_UNPRIVILEGED),
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering SD_BUS_VTABLE_END
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering};
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int bus_scope_set_transient_property(
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Scope *s,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const char *name,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering sd_bus_message *message,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering UnitSetPropertiesMode mode,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering sd_bus_error *error) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(name);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(message);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (streq(name, "PIDs")) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering unsigned n = 0;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering uint32_t pid;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = sd_bus_message_enter_container(message, 'a', "u");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering while ((r = sd_bus_message_read(message, "u", &pid)) > 0) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (pid <= 1)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -EINVAL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (mode != UNIT_CHECK) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = unit_watch_pid(UNIT(s), pid);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0 && r != -EEXIST)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return r;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering }
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering n++;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = sd_bus_message_exit_container(message);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek if (n <= 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -EINVAL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 1;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering } else if (streq(name, "Controller")) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering const char *controller;
13790add4bf648fed816361794d8277a75253410Lennart Poettering char *c;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = sd_bus_message_read(message, "s", &controller);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!isempty(controller) && !service_name_is_valid(controller))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (mode != UNIT_CHECK) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (isempty(controller))
13790add4bf648fed816361794d8277a75253410Lennart Poettering c = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering else {
13790add4bf648fed816361794d8277a75253410Lennart Poettering c = strdup(controller);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!c)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOMEM;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering free(s->controller);
13790add4bf648fed816361794d8277a75253410Lennart Poettering s->controller = c;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 1;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering } else if (streq(name, "TimeoutStopUSec")) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (mode != UNIT_CHECK) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = sd_bus_message_read(message, "t", &s->timeout_stop_usec);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering unit_write_drop_in_format(UNIT(s), mode, name, "[Scope]\nTimeoutStopSec="USEC_FMT"us\n", s->timeout_stop_usec);
13790add4bf648fed816361794d8277a75253410Lennart Poettering } else {
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = sd_bus_message_skip(message, "t");
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 1;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringint bus_scope_set_property(
13790add4bf648fed816361794d8277a75253410Lennart Poettering Unit *u,
13790add4bf648fed816361794d8277a75253410Lennart Poettering const char *name,
13790add4bf648fed816361794d8277a75253410Lennart Poettering sd_bus_message *message,
13790add4bf648fed816361794d8277a75253410Lennart Poettering UnitSetPropertiesMode mode,
13790add4bf648fed816361794d8277a75253410Lennart Poettering sd_bus_error *error) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering Scope *s = SCOPE(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering int r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(name);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(message);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r != 0)
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering return r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (u->load_state == UNIT_STUB) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* While we are created we still accept PIDs */
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = bus_scope_set_transient_property(s, name, message, mode, error);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r != 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r != 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return r;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringint bus_scope_commit_properties(Unit *u) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering unit_update_cgroup_members_masks(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering unit_realize_cgroup(u);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringint bus_scope_send_request_stop(Scope *s) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering _cleanup_free_ char *p = NULL;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering int r;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(s);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (!s->controller)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return 0;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering p = unit_dbus_path(UNIT(s));
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!p)
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering return -ENOMEM;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering r = sd_bus_message_new_signal(
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering UNIT(s)->manager->api_bus,
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering &m,
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering p,
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering "org.freedesktop.systemd1.Scope",
13790add4bf648fed816361794d8277a75253410Lennart Poettering "RequestStop");
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return sd_bus_send_to(UNIT(s)->manager->api_bus, m, /* s->controller */ NULL, NULL);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering