]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-scope.c
hashmap: be a bit more conservative with pre-allocating hash tables and items
[thirdparty/systemd.git] / src / core / dbus-scope.c
CommitLineData
6c12b52e
LP
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" \
d7550a67 33 BUS_UNIT_CGROUP_INTERFACE \
6c12b52e
LP
34 " <property name=\"TimeoutStopUSec\" type=\"t\" access=\"read\"/>\n" \
35 BUS_KILL_CONTEXT_INTERFACE \
36 BUS_CGROUP_CONTEXT_INTERFACE \
37 " <property name=\"Result\" type=\"s\" access=\"read\"/>\n" \
38 " </interface>\n"
39
40#define INTROSPECTION \
41 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
42 "<node>\n" \
43 BUS_UNIT_INTERFACE \
44 BUS_SCOPE_INTERFACE \
45 BUS_PROPERTIES_INTERFACE \
46 BUS_PEER_INTERFACE \
47 BUS_INTROSPECTABLE_INTERFACE \
48 "</node>\n"
49
50#define INTERFACES_LIST \
51 BUS_UNIT_INTERFACES_LIST \
52 "org.freedesktop.systemd1.Scope\0"
53
ca2871d9 54const char bus_scope_interface[] = BUS_SCOPE_INTERFACE;
6c12b52e
LP
55
56static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_scope_append_scope_result, scope_result, ScopeResult);
57
58static const BusProperty bus_scope_properties[] = {
59 { "TimeoutStopUSec", bus_property_append_usec, "t", offsetof(Scope, timeout_stop_usec) },
60 { "Result", bus_scope_append_scope_result, "s", offsetof(Scope, result) },
61 {}
62};
63
64DBusHandlerResult bus_scope_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
65 Scope *s = SCOPE(u);
66
67 const BusBoundProperties bps[] = {
68 { "org.freedesktop.systemd1.Unit", bus_unit_properties, u },
d7550a67 69 { "org.freedesktop.systemd1.Scope", bus_unit_cgroup_properties, u },
6c12b52e
LP
70 { "org.freedesktop.systemd1.Scope", bus_scope_properties, s },
71 { "org.freedesktop.systemd1.Scope", bus_cgroup_context_properties, &s->cgroup_context },
72 { "org.freedesktop.systemd1.Scope", bus_kill_context_properties, &s->kill_context },
73 {}
74 };
75
76 SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
77
78 return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
79}
80
9f2e86af 81static int bus_scope_set_transient_property(
6c12b52e
LP
82 Scope *s,
83 const char *name,
84 DBusMessageIter *i,
85 UnitSetPropertiesMode mode,
86 DBusError *error) {
87
88 int r;
89
90 assert(name);
91 assert(s);
92 assert(i);
93
94 if (streq(name, "PIDs")) {
95 DBusMessageIter sub;
294a90cc 96 unsigned n = 0;
6c12b52e
LP
97
98 if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY ||
99 dbus_message_iter_get_element_type(i) != DBUS_TYPE_UINT32)
100 return -EINVAL;
101
102 r = set_ensure_allocated(&s->pids, trivial_hash_func, trivial_compare_func);
103 if (r < 0)
104 return r;
105
106 dbus_message_iter_recurse(i, &sub);
107 while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32) {
108 uint32_t pid;
109
110 dbus_message_iter_get_basic(&sub, &pid);
111
112 if (pid <= 1)
113 return -EINVAL;
114
adb3a45d
LP
115 if (mode != UNIT_CHECK) {
116 r = set_put(s->pids, LONG_TO_PTR(pid));
117 if (r < 0 && r != -EEXIST)
118 return r;
119 }
6c12b52e
LP
120
121 dbus_message_iter_next(&sub);
adb3a45d 122 n++;
6c12b52e
LP
123 }
124
adb3a45d 125 if (n <= 0)
6c12b52e
LP
126 return -EINVAL;
127
128 return 1;
cc23f9f1
LP
129
130 } else if (streq(name, "TimeoutStopUSec")) {
131
132 if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_UINT64)
133 return -EINVAL;
134
135 if (mode != UNIT_CHECK) {
136 uint64_t t;
137
138 dbus_message_iter_get_basic(i, &t);
139
140 s->timeout_stop_usec = t;
c3df8d3d
LP
141
142 unit_write_drop_in_format(UNIT(s), mode, name, "[Scope]\nTimeoutStopSec=%lluus\n", (unsigned long long) t);
cc23f9f1
LP
143 }
144
145 return 1;
6c12b52e
LP
146 }
147
148 return 0;
149}
150
151int bus_scope_set_property(
152 Unit *u,
153 const char *name,
154 DBusMessageIter *i,
155 UnitSetPropertiesMode mode,
156 DBusError *error) {
157
158 Scope *s = SCOPE(u);
159 int r;
160
161 assert(name);
162 assert(u);
163 assert(i);
164
165 r = bus_cgroup_set_property(u, &s->cgroup_context, name, i, mode, error);
166 if (r != 0)
167 return r;
168
169 if (u->load_state == UNIT_STUB) {
170 /* While we are created we still accept PIDs */
171
9f2e86af 172 r = bus_scope_set_transient_property(s, name, i, mode, error);
6c12b52e
LP
173 if (r != 0)
174 return r;
a6c0353b
LP
175
176 r = bus_kill_context_set_transient_property(u, &s->kill_context, name, i, mode, error);
177 if (r != 0)
178 return r;
6c12b52e
LP
179 }
180
181 return 0;
182}
183
184int bus_scope_commit_properties(Unit *u) {
185 assert(u);
186
187 unit_realize_cgroup(u);
188 return 0;
189}