LCOV - code coverage report
Current view: top level - core - dbus-scope.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 0 105 0.0 %
Date: 2015-07-29 18:47:03 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
       2             : 
       3             : /***
       4             :   This file is part of systemd.
       5             : 
       6             :   Copyright 2013 Lennart Poettering
       7             : 
       8             :   systemd is free software; you can redistribute it and/or modify it
       9             :   under the terms of the GNU Lesser General Public License as published by
      10             :   the Free Software Foundation; either version 2.1 of the License, or
      11             :   (at your option) any later version.
      12             : 
      13             :   systemd is distributed in the hope that it will be useful, but
      14             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      16             :   Lesser General Public License for more details.
      17             : 
      18             :   You should have received a copy of the GNU Lesser General Public License
      19             :   along with systemd; If not, see <http://www.gnu.org/licenses/>.
      20             : ***/
      21             : 
      22             : #include "selinux-access.h"
      23             : #include "unit.h"
      24             : #include "scope.h"
      25             : #include "dbus.h"
      26             : #include "bus-util.h"
      27             : #include "bus-internal.h"
      28             : #include "bus-common-errors.h"
      29             : #include "dbus-unit.h"
      30             : #include "dbus-cgroup.h"
      31             : #include "dbus-kill.h"
      32             : #include "dbus-scope.h"
      33             : 
      34           0 : static int bus_scope_abandon(sd_bus_message *message, void *userdata, sd_bus_error *error) {
      35           0 :         Scope *s = userdata;
      36             :         int r;
      37             : 
      38           0 :         assert(message);
      39           0 :         assert(s);
      40             : 
      41           0 :         r = mac_selinux_unit_access_check(UNIT(s), message, "stop", error);
      42           0 :         if (r < 0)
      43           0 :                 return r;
      44             : 
      45           0 :         r = bus_verify_manage_units_async(UNIT(s)->manager, message, error);
      46           0 :         if (r < 0)
      47           0 :                 return r;
      48           0 :         if (r == 0)
      49           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
      50             : 
      51           0 :         r = scope_abandon(s);
      52           0 :         if (r == -ESTALE)
      53           0 :                 return sd_bus_error_setf(error, BUS_ERROR_SCOPE_NOT_RUNNING, "Scope %s is not running, cannot abandon.", UNIT(s)->id);
      54           0 :         if (r < 0)
      55           0 :                 return r;
      56             : 
      57           0 :         return sd_bus_reply_method_return(message, NULL);
      58             : }
      59             : 
      60           0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, scope_result, ScopeResult);
      61             : 
      62             : const sd_bus_vtable bus_scope_vtable[] = {
      63             :         SD_BUS_VTABLE_START(0),
      64             :         SD_BUS_PROPERTY("Controller", "s", NULL, offsetof(Scope, controller), SD_BUS_VTABLE_PROPERTY_CONST),
      65             :         SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Scope, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
      66             :         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Scope, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
      67             :         SD_BUS_SIGNAL("RequestStop", NULL, 0),
      68             :         SD_BUS_METHOD("Abandon", NULL, NULL, bus_scope_abandon, SD_BUS_VTABLE_UNPRIVILEGED),
      69             :         SD_BUS_VTABLE_END
      70             : };
      71             : 
      72           0 : static int bus_scope_set_transient_property(
      73             :                 Scope *s,
      74             :                 const char *name,
      75             :                 sd_bus_message *message,
      76             :                 UnitSetPropertiesMode mode,
      77             :                 sd_bus_error *error) {
      78             : 
      79             :         int r;
      80             : 
      81           0 :         assert(s);
      82           0 :         assert(name);
      83           0 :         assert(message);
      84             : 
      85           0 :         if (streq(name, "PIDs")) {
      86           0 :                 unsigned n = 0;
      87             :                 uint32_t pid;
      88             : 
      89           0 :                 r = sd_bus_message_enter_container(message, 'a', "u");
      90           0 :                 if (r < 0)
      91           0 :                         return r;
      92             : 
      93           0 :                 while ((r = sd_bus_message_read(message, "u", &pid)) > 0) {
      94             : 
      95           0 :                         if (pid <= 1)
      96           0 :                                 return -EINVAL;
      97             : 
      98           0 :                         if (mode != UNIT_CHECK) {
      99           0 :                                 r = unit_watch_pid(UNIT(s), pid);
     100           0 :                                 if (r < 0 && r != -EEXIST)
     101           0 :                                         return r;
     102             :                         }
     103             : 
     104           0 :                         n++;
     105             :                 }
     106           0 :                 if (r < 0)
     107           0 :                         return r;
     108             : 
     109           0 :                 r = sd_bus_message_exit_container(message);
     110           0 :                 if (r < 0)
     111           0 :                         return r;
     112             : 
     113           0 :                 if (n <= 0)
     114           0 :                         return -EINVAL;
     115             : 
     116           0 :                 return 1;
     117             : 
     118           0 :         } else if (streq(name, "Controller")) {
     119             :                 const char *controller;
     120             :                 char *c;
     121             : 
     122           0 :                 r = sd_bus_message_read(message, "s", &controller);
     123           0 :                 if (r < 0)
     124           0 :                         return r;
     125             : 
     126           0 :                 if (!isempty(controller) && !service_name_is_valid(controller))
     127           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller);
     128             : 
     129           0 :                 if (mode != UNIT_CHECK) {
     130           0 :                         if (isempty(controller))
     131           0 :                                 c = NULL;
     132             :                         else {
     133           0 :                                 c = strdup(controller);
     134           0 :                                 if (!c)
     135           0 :                                         return -ENOMEM;
     136             :                         }
     137             : 
     138           0 :                         free(s->controller);
     139           0 :                         s->controller = c;
     140             :                 }
     141             : 
     142           0 :                 return 1;
     143             : 
     144           0 :         } else if (streq(name, "TimeoutStopUSec")) {
     145             : 
     146           0 :                 if (mode != UNIT_CHECK) {
     147           0 :                         r = sd_bus_message_read(message, "t", &s->timeout_stop_usec);
     148           0 :                         if (r < 0)
     149           0 :                                 return r;
     150             : 
     151           0 :                         unit_write_drop_in_format(UNIT(s), mode, name, "[Scope]\nTimeoutStopSec="USEC_FMT"us\n", s->timeout_stop_usec);
     152             :                 } else {
     153           0 :                         r = sd_bus_message_skip(message, "t");
     154           0 :                         if (r < 0)
     155           0 :                                 return r;
     156             :                 }
     157             : 
     158           0 :                 return 1;
     159             :         }
     160             : 
     161           0 :         return 0;
     162             : }
     163             : 
     164           0 : int bus_scope_set_property(
     165             :                 Unit *u,
     166             :                 const char *name,
     167             :                 sd_bus_message *message,
     168             :                 UnitSetPropertiesMode mode,
     169             :                 sd_bus_error *error) {
     170             : 
     171           0 :         Scope *s = SCOPE(u);
     172             :         int r;
     173             : 
     174           0 :         assert(s);
     175           0 :         assert(name);
     176           0 :         assert(message);
     177             : 
     178           0 :         r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
     179           0 :         if (r != 0)
     180           0 :                 return r;
     181             : 
     182           0 :         if (u->load_state == UNIT_STUB) {
     183             :                 /* While we are created we still accept PIDs */
     184             : 
     185           0 :                 r = bus_scope_set_transient_property(s, name, message, mode, error);
     186           0 :                 if (r != 0)
     187           0 :                         return r;
     188             : 
     189           0 :                 r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
     190           0 :                 if (r != 0)
     191           0 :                         return r;
     192             :         }
     193             : 
     194           0 :         return 0;
     195             : }
     196             : 
     197           0 : int bus_scope_commit_properties(Unit *u) {
     198           0 :         assert(u);
     199             : 
     200           0 :         unit_update_cgroup_members_masks(u);
     201           0 :         unit_realize_cgroup(u);
     202             : 
     203           0 :         return 0;
     204             : }
     205             : 
     206           0 : int bus_scope_send_request_stop(Scope *s) {
     207           0 :         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
     208           0 :         _cleanup_free_ char *p = NULL;
     209             :         int r;
     210             : 
     211           0 :         assert(s);
     212             : 
     213           0 :         if (!s->controller)
     214           0 :                 return 0;
     215             : 
     216           0 :         p = unit_dbus_path(UNIT(s));
     217           0 :         if (!p)
     218           0 :                 return -ENOMEM;
     219             : 
     220           0 :         r = sd_bus_message_new_signal(
     221           0 :                         UNIT(s)->manager->api_bus,
     222             :                         &m,
     223             :                         p,
     224             :                         "org.freedesktop.systemd1.Scope",
     225             :                         "RequestStop");
     226           0 :         if (r < 0)
     227           0 :                 return r;
     228             : 
     229           0 :         return sd_bus_send_to(UNIT(s)->manager->api_bus, m, /* s->controller */ NULL, NULL);
     230             : }

Generated by: LCOV version 1.11