]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus-scope.c
core: allow setting of the description string for transient units
[thirdparty/systemd.git] / src / core / dbus-scope.c
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 <errno.h>
23
24 #include "dbus-unit.h"
25 #include "dbus-common.h"
26 #include "dbus-cgroup.h"
27 #include "dbus-kill.h"
28 #include "selinux-access.h"
29 #include "dbus-scope.h"
30
31 #define BUS_SCOPE_INTERFACE \
32 " <interface name=\"org.freedesktop.systemd1.Scope\">\n" \
33 " <property name=\"TimeoutStopUSec\" type=\"t\" access=\"read\"/>\n" \
34 BUS_KILL_CONTEXT_INTERFACE \
35 BUS_CGROUP_CONTEXT_INTERFACE \
36 " <property name=\"Result\" type=\"s\" access=\"read\"/>\n" \
37 " </interface>\n"
38
39 #define INTROSPECTION \
40 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
41 "<node>\n" \
42 BUS_UNIT_INTERFACE \
43 BUS_SCOPE_INTERFACE \
44 BUS_PROPERTIES_INTERFACE \
45 BUS_PEER_INTERFACE \
46 BUS_INTROSPECTABLE_INTERFACE \
47 "</node>\n"
48
49 #define INTERFACES_LIST \
50 BUS_UNIT_INTERFACES_LIST \
51 "org.freedesktop.systemd1.Scope\0"
52
53 const char bus_scope_interface[] _introspect_("Scope") = BUS_SCOPE_INTERFACE;
54
55 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_scope_append_scope_result, scope_result, ScopeResult);
56
57 static const BusProperty bus_scope_properties[] = {
58 { "TimeoutStopUSec", bus_property_append_usec, "t", offsetof(Scope, timeout_stop_usec) },
59 { "Result", bus_scope_append_scope_result, "s", offsetof(Scope, result) },
60 {}
61 };
62
63 DBusHandlerResult bus_scope_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
64 Scope *s = SCOPE(u);
65
66 const BusBoundProperties bps[] = {
67 { "org.freedesktop.systemd1.Unit", bus_unit_properties, u },
68 { "org.freedesktop.systemd1.Scope", bus_scope_properties, s },
69 { "org.freedesktop.systemd1.Scope", bus_cgroup_context_properties, &s->cgroup_context },
70 { "org.freedesktop.systemd1.Scope", bus_kill_context_properties, &s->kill_context },
71 {}
72 };
73
74 SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
75
76 return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
77 }
78
79 static int bus_scope_set_transient_property(
80 Scope *s,
81 const char *name,
82 DBusMessageIter *i,
83 UnitSetPropertiesMode mode,
84 DBusError *error) {
85
86 int r;
87
88 assert(name);
89 assert(s);
90 assert(i);
91
92 if (streq(name, "PIDs")) {
93 DBusMessageIter sub;
94
95 if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY ||
96 dbus_message_iter_get_element_type(i) != DBUS_TYPE_UINT32)
97 return -EINVAL;
98
99 r = set_ensure_allocated(&s->pids, trivial_hash_func, trivial_compare_func);
100 if (r < 0)
101 return r;
102
103 dbus_message_iter_recurse(i, &sub);
104 while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32) {
105 uint32_t pid;
106
107 dbus_message_iter_get_basic(&sub, &pid);
108
109 if (pid <= 1)
110 return -EINVAL;
111
112 r = set_put(s->pids, LONG_TO_PTR(pid));
113 if (r < 0 && r != -EEXIST)
114 return r;
115
116 dbus_message_iter_next(&sub);
117 }
118
119 if (set_size(s->pids) <= 0)
120 return -EINVAL;
121
122 return 1;
123 }
124
125 return 0;
126 }
127
128 int bus_scope_set_property(
129 Unit *u,
130 const char *name,
131 DBusMessageIter *i,
132 UnitSetPropertiesMode mode,
133 DBusError *error) {
134
135 Scope *s = SCOPE(u);
136 int r;
137
138 assert(name);
139 assert(u);
140 assert(i);
141
142 r = bus_cgroup_set_property(u, &s->cgroup_context, name, i, mode, error);
143 if (r != 0)
144 return r;
145
146 if (u->load_state == UNIT_STUB) {
147 /* While we are created we still accept PIDs */
148
149 r = bus_scope_set_transient_property(s, name, i, mode, error);
150 if (r != 0)
151 return r;
152 }
153
154 return 0;
155 }
156
157 int bus_scope_commit_properties(Unit *u) {
158 assert(u);
159
160 unit_realize_cgroup(u);
161 return 0;
162 }