]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-scope.c
core: watch SIGCHLD more closely to track processes of units with no reliable cgroup...
[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
718db961
LP
22#include "unit.h"
23#include "scope.h"
6c12b52e 24#include "dbus-unit.h"
6c12b52e
LP
25#include "dbus-cgroup.h"
26#include "dbus-kill.h"
6c12b52e 27#include "dbus-scope.h"
718db961 28#include "bus-util.h"
2d4a39e7 29#include "bus-internal.h"
6c12b52e 30
a911bb9a
LP
31static int bus_scope_abandon(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
32 Scope *s = userdata;
33
34 assert(bus);
35 assert(message);
36 assert(s);
37
38 return scope_abandon(s);
39}
40
718db961 41static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, scope_result, ScopeResult);
6c12b52e 42
718db961
LP
43const sd_bus_vtable bus_scope_vtable[] = {
44 SD_BUS_VTABLE_START(0),
2d4a39e7 45 SD_BUS_PROPERTY("Controller", "s", NULL, offsetof(Scope, controller), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc 46 SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Scope, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
718db961 47 SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Scope, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2d4a39e7 48 SD_BUS_SIGNAL("RequestStop", NULL, 0),
a911bb9a 49 SD_BUS_METHOD("Abandon", NULL, NULL, bus_scope_abandon, 0),
718db961
LP
50 SD_BUS_VTABLE_END
51};
6c12b52e 52
9f2e86af 53static int bus_scope_set_transient_property(
6c12b52e
LP
54 Scope *s,
55 const char *name,
718db961 56 sd_bus_message *message,
6c12b52e 57 UnitSetPropertiesMode mode,
718db961 58 sd_bus_error *error) {
6c12b52e
LP
59
60 int r;
61
6c12b52e 62 assert(s);
718db961
LP
63 assert(name);
64 assert(message);
6c12b52e
LP
65
66 if (streq(name, "PIDs")) {
294a90cc 67 unsigned n = 0;
718db961 68 uint32_t pid;
6c12b52e 69
718db961
LP
70 r = sd_bus_message_enter_container(message, 'a', "u");
71 if (r < 0)
72 return r;
6c12b52e 73
718db961 74 while ((r = sd_bus_message_read(message, "u", &pid)) > 0) {
6c12b52e
LP
75
76 if (pid <= 1)
77 return -EINVAL;
78
adb3a45d 79 if (mode != UNIT_CHECK) {
a911bb9a 80 r = unit_watch_pid(UNIT(s), pid);
adb3a45d
LP
81 if (r < 0 && r != -EEXIST)
82 return r;
83 }
6c12b52e 84
adb3a45d 85 n++;
6c12b52e 86 }
718db961
LP
87 if (r < 0)
88 return r;
89
90 r = sd_bus_message_exit_container(message);
91 if (r < 0)
92 return r;
6c12b52e 93
adb3a45d 94 if (n <= 0)
6c12b52e
LP
95 return -EINVAL;
96
97 return 1;
cc23f9f1 98
2d4a39e7
LP
99 } else if (streq(name, "Controller")) {
100 const char *controller;
101 char *c;
102
103 r = sd_bus_message_read(message, "s", &controller);
104 if (r < 0)
105 return r;
106
107 if (!isempty(controller) && !service_name_is_valid(controller))
108 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller);
109
110 if (mode != UNIT_CHECK) {
111 if (isempty(controller))
112 c = NULL;
113 else {
114 c = strdup(controller);
115 if (!c)
116 return -ENOMEM;
117 }
118
119 free(s->controller);
120 s->controller = c;
121 }
122
123 return 1;
124
cc23f9f1
LP
125 } else if (streq(name, "TimeoutStopUSec")) {
126
cc23f9f1 127 if (mode != UNIT_CHECK) {
718db961
LP
128 r = sd_bus_message_read(message, "t", &s->timeout_stop_usec);
129 if (r < 0)
130 return r;
131
132 unit_write_drop_in_format(UNIT(s), mode, name, "[Scope]\nTimeoutStopSec=%lluus\n", (unsigned long long) s->timeout_stop_usec);
133 } else {
134 r = sd_bus_message_skip(message, "t");
135 if (r < 0)
136 return r;
cc23f9f1
LP
137 }
138
139 return 1;
6c12b52e
LP
140 }
141
142 return 0;
143}
144
145int bus_scope_set_property(
146 Unit *u,
147 const char *name,
718db961 148 sd_bus_message *message,
6c12b52e 149 UnitSetPropertiesMode mode,
718db961 150 sd_bus_error *error) {
6c12b52e
LP
151
152 Scope *s = SCOPE(u);
153 int r;
154
718db961 155 assert(s);
6c12b52e 156 assert(name);
718db961 157 assert(message);
6c12b52e 158
718db961 159 r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
6c12b52e
LP
160 if (r != 0)
161 return r;
162
163 if (u->load_state == UNIT_STUB) {
164 /* While we are created we still accept PIDs */
165
718db961 166 r = bus_scope_set_transient_property(s, name, message, mode, error);
6c12b52e
LP
167 if (r != 0)
168 return r;
a6c0353b 169
718db961 170 r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
a6c0353b
LP
171 if (r != 0)
172 return r;
6c12b52e
LP
173 }
174
175 return 0;
176}
177
178int bus_scope_commit_properties(Unit *u) {
179 assert(u);
180
181 unit_realize_cgroup(u);
182 return 0;
183}
2d4a39e7
LP
184
185int bus_scope_send_request_stop(Scope *s) {
186 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
187 _cleanup_free_ char *p = NULL;
188 int r;
189
190 assert(s);
191
192 if (!s->controller)
193 return 0;
194
195 p = unit_dbus_path(UNIT(s));
196 if (!p)
197 return -ENOMEM;
198
199 r = sd_bus_message_new_signal(
200 UNIT(s)->manager->api_bus,
201 p,
202 "org.freedesktop.systemd1.Scope",
203 "RequestStop",
204 &m);
205 if (r < 0)
206 return r;
207
208 return sd_bus_send_to(UNIT(s)->manager->api_bus, m, /* s->controller */ NULL, NULL);
209}