]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-execute.c
core: set some event source priorities to enforce dispatching order
[thirdparty/systemd.git] / src / core / dbus-execute.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4139c1b2
LP
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
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
4139c1b2
LP
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
5430f7f2 16 Lesser General Public License for more details.
4139c1b2 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
4139c1b2
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
82c121a4 22#include <sys/prctl.h>
4139c1b2 23
718db961 24#include "bus-util.h"
82c121a4
LP
25#include "missing.h"
26#include "ioprio.h"
fe68089d 27#include "strv.h"
8351ceae 28#include "syscall-list.h"
a5c32cff 29#include "fileio.h"
718db961
LP
30#include "execute.h"
31#include "dbus-execute.h"
4139c1b2 32
718db961 33BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
82c121a4 34
718db961 35static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
8c7be95e 36
718db961
LP
37static int property_get_environment_files(
38 sd_bus *bus,
39 const char *path,
40 const char *interface,
41 const char *property,
42 sd_bus_message *reply,
ebcf1f97
LP
43 void *userdata,
44 sd_bus_error *error) {
8c7be95e 45
718db961
LP
46 ExecContext *c = userdata;
47 char **j;
48 int r;
8c7be95e 49
718db961
LP
50 assert(bus);
51 assert(reply);
52 assert(c);
53
54 r = sd_bus_message_open_container(reply, 'a', "(sb)");
55 if (r < 0)
56 return r;
8c7be95e 57
718db961
LP
58 STRV_FOREACH(j, c->environment_files) {
59 const char *fn = *j;
8c7be95e 60
718db961
LP
61 r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
62 if (r < 0)
63 return r;
8c7be95e
LP
64 }
65
718db961
LP
66 return sd_bus_message_close_container(reply);
67}
68
69static int property_get_rlimit(
70 sd_bus *bus,
71 const char *path,
72 const char *interface,
73 const char *property,
74 sd_bus_message *reply,
ebcf1f97
LP
75 void *userdata,
76 sd_bus_error *error) {
718db961
LP
77
78 struct rlimit *rl;
79 uint64_t u;
80
81 assert(bus);
82 assert(reply);
83 assert(userdata);
8c7be95e 84
718db961
LP
85 rl = *(struct rlimit**) userdata;
86 if (rl)
87 u = (uint64_t) rl->rlim_max;
88 else {
89 struct rlimit buf = {};
90 int z;
91
92 z = rlimit_from_string(property);
93 assert(z >= 0);
94
95 getrlimit(z, &buf);
96
97 u = (uint64_t) buf.rlim_max;
98 }
99
100 return sd_bus_message_append(reply, "t", u);
8c7be95e
LP
101}
102
718db961
LP
103static int property_get_oom_score_adjust(
104 sd_bus *bus,
105 const char *path,
106 const char *interface,
107 const char *property,
108 sd_bus_message *reply,
ebcf1f97
LP
109 void *userdata,
110 sd_bus_error *error) {
718db961
LP
111
112
113 ExecContext *c = userdata;
82c121a4
LP
114 int32_t n;
115
718db961
LP
116 assert(bus);
117 assert(reply);
82c121a4
LP
118 assert(c);
119
dd6c17b1
LP
120 if (c->oom_score_adjust_set)
121 n = c->oom_score_adjust;
82c121a4 122 else {
68eda4bd 123 _cleanup_free_ char *t = NULL;
82c121a4
LP
124
125 n = 0;
718db961 126 if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
82c121a4 127 safe_atoi(t, &n);
82c121a4
LP
128 }
129
718db961 130 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
131}
132
718db961
LP
133static int property_get_nice(
134 sd_bus *bus,
135 const char *path,
136 const char *interface,
137 const char *property,
138 sd_bus_message *reply,
ebcf1f97
LP
139 void *userdata,
140 sd_bus_error *error) {
718db961
LP
141
142
143 ExecContext *c = userdata;
82c121a4
LP
144 int32_t n;
145
718db961
LP
146 assert(bus);
147 assert(reply);
82c121a4
LP
148 assert(c);
149
150 if (c->nice_set)
151 n = c->nice;
718db961
LP
152 else {
153 errno = 0;
82c121a4 154 n = getpriority(PRIO_PROCESS, 0);
718db961
LP
155 if (errno != 0)
156 n = 0;
157 }
82c121a4 158
718db961 159 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
160}
161
718db961
LP
162static int property_get_ioprio(
163 sd_bus *bus,
164 const char *path,
165 const char *interface,
166 const char *property,
167 sd_bus_message *reply,
ebcf1f97
LP
168 void *userdata,
169 sd_bus_error *error) {
718db961
LP
170
171
172 ExecContext *c = userdata;
82c121a4
LP
173 int32_t n;
174
718db961
LP
175 assert(bus);
176 assert(reply);
82c121a4
LP
177 assert(c);
178
179 if (c->ioprio_set)
180 n = c->ioprio;
718db961 181 else {
82c121a4 182 n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
718db961
LP
183 if (n < 0)
184 n = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
185 }
82c121a4 186
718db961 187 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
188}
189
718db961
LP
190static int property_get_cpu_sched_policy(
191 sd_bus *bus,
192 const char *path,
193 const char *interface,
194 const char *property,
195 sd_bus_message *reply,
ebcf1f97
LP
196 void *userdata,
197 sd_bus_error *error) {
718db961
LP
198
199 ExecContext *c = userdata;
82c121a4
LP
200 int32_t n;
201
718db961
LP
202 assert(bus);
203 assert(reply);
82c121a4
LP
204 assert(c);
205
206 if (c->cpu_sched_set)
207 n = c->cpu_sched_policy;
718db961 208 else {
82c121a4 209 n = sched_getscheduler(0);
718db961
LP
210 if (n < 0)
211 n = SCHED_OTHER;
212 }
82c121a4 213
718db961 214 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
215}
216
718db961
LP
217static int property_get_cpu_sched_priority(
218 sd_bus *bus,
219 const char *path,
220 const char *interface,
221 const char *property,
222 sd_bus_message *reply,
ebcf1f97
LP
223 void *userdata,
224 sd_bus_error *error) {
718db961
LP
225
226 ExecContext *c = userdata;
82c121a4
LP
227 int32_t n;
228
718db961
LP
229 assert(bus);
230 assert(reply);
82c121a4
LP
231 assert(c);
232
233 if (c->cpu_sched_set)
234 n = c->cpu_sched_priority;
235 else {
b92bea5d 236 struct sched_param p = {};
82c121a4 237
82c121a4
LP
238 if (sched_getparam(0, &p) >= 0)
239 n = p.sched_priority;
e62d8c39
ZJS
240 else
241 n = 0;
82c121a4
LP
242 }
243
718db961 244 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
245}
246
718db961
LP
247static int property_get_cpu_affinity(
248 sd_bus *bus,
249 const char *path,
250 const char *interface,
251 const char *property,
252 sd_bus_message *reply,
ebcf1f97
LP
253 void *userdata,
254 sd_bus_error *error) {
82c121a4 255
718db961 256 ExecContext *c = userdata;
82c121a4 257
718db961
LP
258 assert(bus);
259 assert(reply);
260 assert(c);
82c121a4
LP
261
262 if (c->cpuset)
718db961 263 return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
82c121a4 264 else
718db961 265 return sd_bus_message_append_array(reply, 'y', NULL, 0);
82c121a4
LP
266}
267
718db961
LP
268static int property_get_timer_slack_nsec(
269 sd_bus *bus,
270 const char *path,
271 const char *interface,
272 const char *property,
273 sd_bus_message *reply,
ebcf1f97
LP
274 void *userdata,
275 sd_bus_error *error) {
718db961
LP
276
277 ExecContext *c = userdata;
82c121a4
LP
278 uint64_t u;
279
718db961
LP
280 assert(bus);
281 assert(reply);
82c121a4
LP
282 assert(c);
283
d88a251b 284 if (c->timer_slack_nsec != (nsec_t) -1)
03fae018 285 u = (uint64_t) c->timer_slack_nsec;
82c121a4
LP
286 else
287 u = (uint64_t) prctl(PR_GET_TIMERSLACK);
288
718db961 289 return sd_bus_message_append(reply, "t", u);
82c121a4
LP
290}
291
718db961
LP
292static int property_get_capability_bounding_set(
293 sd_bus *bus,
294 const char *path,
295 const char *interface,
296 const char *property,
297 sd_bus_message *reply,
ebcf1f97
LP
298 void *userdata,
299 sd_bus_error *error) {
260abb78 300
718db961
LP
301 ExecContext *c = userdata;
302
303 assert(bus);
304 assert(reply);
260abb78
LP
305 assert(c);
306
7c3d67ef 307 /* We store this negated internally, to match the kernel, but
260abb78 308 * we expose it normalized. */
718db961 309 return sd_bus_message_append(reply, "t", ~c->capability_bounding_set_drop);
260abb78
LP
310}
311
718db961
LP
312static int property_get_capabilities(
313 sd_bus *bus,
314 const char *path,
315 const char *interface,
316 const char *property,
317 sd_bus_message *reply,
ebcf1f97
LP
318 void *userdata,
319 sd_bus_error *error) {
718db961
LP
320
321 ExecContext *c = userdata;
82c121a4
LP
322 char *t = NULL;
323 const char *s;
718db961 324 int r;
82c121a4 325
718db961
LP
326 assert(bus);
327 assert(reply);
82c121a4
LP
328 assert(c);
329
330 if (c->capabilities)
331 s = t = cap_to_text(c->capabilities, NULL);
332 else
333 s = "";
334
674cdd19 335 if (!s)
82c121a4
LP
336 return -ENOMEM;
337
718db961 338 r = sd_bus_message_append(reply, "s", s);
674cdd19
LP
339
340 if (t)
341 cap_free(t);
82c121a4 342
718db961 343 return r;
82c121a4
LP
344}
345
718db961
LP
346static int property_get_syscall_filter(
347 sd_bus *bus,
348 const char *path,
349 const char *interface,
350 const char *property,
351 sd_bus_message *reply,
ebcf1f97
LP
352 void *userdata,
353 sd_bus_error *error) {
82c121a4 354
718db961 355 ExecContext *c = userdata;
82c121a4 356
718db961
LP
357 assert(bus);
358 assert(reply);
359 assert(c);
82c121a4 360
718db961
LP
361 if (c->syscall_filter)
362 return sd_bus_message_append_array(reply, 'u', c->syscall_filter, (syscall_max() + 31) >> 4);
363 else
364 return sd_bus_message_append_array(reply, 'u', NULL, 0);
365}
82c121a4 366
718db961
LP
367const sd_bus_vtable bus_exec_vtable[] = {
368 SD_BUS_VTABLE_START(0),
369 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), 0),
370 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, 0),
371 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), 0),
372 SD_BUS_PROPERTY("LimitCPU", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), 0),
373 SD_BUS_PROPERTY("LimitFSIZE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), 0),
374 SD_BUS_PROPERTY("LimitDATA", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), 0),
375 SD_BUS_PROPERTY("LimitSTACK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), 0),
376 SD_BUS_PROPERTY("LimitCORE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), 0),
377 SD_BUS_PROPERTY("LimitRSS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), 0),
378 SD_BUS_PROPERTY("LimitNOFILE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), 0),
379 SD_BUS_PROPERTY("LimitAS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), 0),
380 SD_BUS_PROPERTY("LimitNPROC", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), 0),
381 SD_BUS_PROPERTY("LimitMEMLOCK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), 0),
382 SD_BUS_PROPERTY("LimitLOCKS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), 0),
383 SD_BUS_PROPERTY("LimitSIGPENDING", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), 0),
384 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), 0),
385 SD_BUS_PROPERTY("LimitNICE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), 0),
386 SD_BUS_PROPERTY("LimitRTPRIO", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), 0),
387 SD_BUS_PROPERTY("LimitRTTIME", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), 0),
388 SD_BUS_PROPERTY("WorkingDirectory", "s", NULL, offsetof(ExecContext, working_directory), 0),
389 SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), 0),
390 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, 0),
391 SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, 0),
392 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, 0),
393 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, 0),
394 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, 0),
395 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, 0),
396 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, 0),
397 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), 0),
398 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), 0),
399 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), 0),
400 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), 0),
401 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), 0),
402 SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), 0),
403 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), 0),
404 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), 0),
405 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), 0),
406 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), 0),
407 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), 0),
408 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), 0),
409 SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, 0),
410 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), 0),
411 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, 0),
412 SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), 0),
413 SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), 0),
414 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), 0),
415 SD_BUS_PROPERTY("TCPWrapName", "s", NULL, offsetof(ExecContext, tcpwrap_name), 0),
416 SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), 0),
417 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), 0),
418 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), 0),
419 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), 0),
420 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), 0),
421 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), 0),
422 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), 0),
423 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), 0),
424 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), 0),
425 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), 0),
426 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), 0),
427 SD_BUS_PROPERTY("SystemCallFilter", "au", property_get_syscall_filter, 0, 0),
428 SD_BUS_VTABLE_END
429};
82c121a4 430
718db961
LP
431int bus_property_get_exec_command(
432 sd_bus *bus,
433 const char *path,
434 const char *interface,
435 const char *property,
436 sd_bus_message *reply,
ebcf1f97
LP
437 void *userdata,
438 sd_bus_error *ret_error) {
fe68089d 439
718db961
LP
440 ExecCommand *c = *(ExecCommand**) userdata;
441 int r;
fe68089d 442
718db961
LP
443 assert(bus);
444 assert(reply);
fe68089d 445
718db961
LP
446 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
447 if (r < 0)
448 return r;
fe68089d
LP
449
450 LIST_FOREACH(command, c, c) {
fe68089d
LP
451 if (!c->path)
452 continue;
453
718db961
LP
454 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
455 if (r < 0)
456 return r;
457
458 r = sd_bus_message_append(reply, "s", c->path);
459 if (r < 0)
460 return r;
461
462 r = sd_bus_message_append_strv(reply, c->argv);
463 if (r < 0)
464 return r;
465
466 r = sd_bus_message_append(reply, "bttttuii",
467 c->ignore,
468 c->exec_status.start_timestamp.realtime,
469 c->exec_status.start_timestamp.monotonic,
470 c->exec_status.exit_timestamp.realtime,
471 c->exec_status.exit_timestamp.monotonic,
472 (uint32_t) c->exec_status.pid,
473 (int32_t) c->exec_status.code,
474 (int32_t) c->exec_status.status);
475 if (r < 0)
476 return r;
477
478 r = sd_bus_message_close_container(reply);
479 if (r < 0)
480 return r;
fe68089d
LP
481 }
482
718db961 483 return sd_bus_message_close_container(reply);
8351ceae 484}