chiark / gitweb /
job: start job timer when we begin running the job, not already when we add it to...
[elogind.git] / src / dbus-execute.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
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
9   under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 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   General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <dbus/dbus.h>
24 #include <sys/prctl.h>
25
26 #include "dbus-execute.h"
27 #include "missing.h"
28 #include "ioprio.h"
29 #include "strv.h"
30
31 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_kill_mode, kill_mode, KillMode);
32
33 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input, exec_input, ExecInput);
34 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output, exec_output, ExecOutput);
35
36 int bus_execute_append_oom_score_adjust(Manager *m, DBusMessageIter *i, const char *property, void *data) {
37         ExecContext *c = data;
38         int32_t n;
39
40         assert(m);
41         assert(i);
42         assert(property);
43         assert(c);
44
45         if (c->oom_score_adjust_set)
46                 n = c->oom_score_adjust;
47         else {
48                 char *t;
49
50                 n = 0;
51                 if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0) {
52                         safe_atoi(t, &n);
53                         free(t);
54                 } else if (read_one_line_file("/proc/self/oom_adj", &t) >= 0) {
55                         safe_atoi(t, &n);
56                         free(t);
57
58                         if (n == OOM_ADJUST_MAX)
59                                 n = OOM_SCORE_ADJ_MAX;
60                         else
61                                 n = (n * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
62                 }
63         }
64
65         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
66                 return -ENOMEM;
67
68         return 0;
69 }
70
71 int bus_execute_append_nice(Manager *m, DBusMessageIter *i, const char *property, void *data) {
72         ExecContext *c = data;
73         int32_t n;
74
75         assert(m);
76         assert(i);
77         assert(property);
78         assert(c);
79
80         if (c->nice_set)
81                 n = c->nice;
82         else
83                 n = getpriority(PRIO_PROCESS, 0);
84
85         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
86                 return -ENOMEM;
87
88         return 0;
89 }
90
91 int bus_execute_append_ioprio(Manager *m, DBusMessageIter *i, const char *property, void *data) {
92         ExecContext *c = data;
93         int32_t n;
94
95         assert(m);
96         assert(i);
97         assert(property);
98         assert(c);
99
100         if (c->ioprio_set)
101                 n = c->ioprio;
102         else
103                 n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
104
105         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
106                 return -ENOMEM;
107
108         return 0;
109 }
110
111 int bus_execute_append_cpu_sched_policy(Manager *m, DBusMessageIter *i, const char *property, void *data) {
112         ExecContext *c = data;
113         int32_t n;
114
115         assert(m);
116         assert(i);
117         assert(property);
118         assert(c);
119
120         if (c->cpu_sched_set)
121                 n = c->cpu_sched_policy;
122         else
123                 n = sched_getscheduler(0);
124
125         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
126                 return -ENOMEM;
127
128         return 0;
129 }
130
131 int bus_execute_append_cpu_sched_priority(Manager *m, DBusMessageIter *i, const char *property, void *data) {
132         ExecContext *c = data;
133         int32_t n;
134
135         assert(m);
136         assert(i);
137         assert(property);
138         assert(c);
139
140         if (c->cpu_sched_set)
141                 n = c->cpu_sched_priority;
142         else {
143                 struct sched_param p;
144                 n = 0;
145
146                 zero(p);
147                 if (sched_getparam(0, &p) >= 0)
148                         n = p.sched_priority;
149         }
150
151         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
152                 return -ENOMEM;
153
154         return 0;
155 }
156
157 int bus_execute_append_affinity(Manager *m, DBusMessageIter *i, const char *property, void *data) {
158         ExecContext *c = data;
159         dbus_bool_t b;
160         DBusMessageIter sub;
161
162         assert(m);
163         assert(i);
164         assert(property);
165         assert(c);
166
167         if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "y", &sub))
168                 return -ENOMEM;
169
170         if (c->cpuset)
171                 b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
172         else
173                 b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, 0);
174
175         if (!b)
176                 return -ENOMEM;
177
178         if (!dbus_message_iter_close_container(i, &sub))
179                 return -ENOMEM;
180
181         return 0;
182 }
183
184 int bus_execute_append_timer_slack_nsec(Manager *m, DBusMessageIter *i, const char *property, void *data) {
185         ExecContext *c = data;
186         uint64_t u;
187
188         assert(m);
189         assert(i);
190         assert(property);
191         assert(c);
192
193         if (c->timer_slack_nsec_set)
194                 u = (uint64_t) c->timer_slack_nsec;
195         else
196                 u = (uint64_t) prctl(PR_GET_TIMERSLACK);
197
198         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
199                 return -ENOMEM;
200
201         return 0;
202 }
203
204 int bus_execute_append_capabilities(Manager *m, DBusMessageIter *i, const char *property, void *data) {
205         ExecContext *c = data;
206         char *t = NULL;
207         const char *s;
208         dbus_bool_t b;
209
210         assert(m);
211         assert(i);
212         assert(property);
213         assert(c);
214
215         if (c->capabilities)
216                 s = t = cap_to_text(c->capabilities, NULL);
217         else
218                 s = "";
219
220         if (!s)
221                 return -ENOMEM;
222
223         b = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &s);
224
225         if (t)
226                 cap_free(t);
227
228         if (!b)
229                 return -ENOMEM;
230
231         return 0;
232 }
233
234 int bus_execute_append_rlimits(Manager *m, DBusMessageIter *i, const char *property, void *data) {
235         ExecContext *c = data;
236         int r;
237         uint64_t u;
238
239         assert(m);
240         assert(i);
241         assert(property);
242         assert(c);
243
244         assert_se((r = rlimit_from_string(property)) >= 0);
245
246         if (c->rlimit[r])
247                 u = (uint64_t) c->rlimit[r]->rlim_max;
248         else {
249                 struct rlimit rl;
250
251                 zero(rl);
252                 getrlimit(r, &rl);
253
254                 u = (uint64_t) rl.rlim_max;
255         }
256
257         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
258                 return -ENOMEM;
259
260         return 0;
261 }
262
263 int bus_execute_append_command(Manager *m, DBusMessageIter *i, const char *property, void *data) {
264         ExecCommand *c = data;
265         DBusMessageIter sub, sub2, sub3;
266
267         assert(m);
268         assert(i);
269         assert(property);
270
271         if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sasbttuii)", &sub))
272                 return -ENOMEM;
273
274         LIST_FOREACH(command, c, c) {
275                 char **l;
276                 uint32_t pid;
277                 int32_t code, status;
278
279                 if (!c->path)
280                         continue;
281
282                 if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
283                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &c->path) ||
284                     !dbus_message_iter_open_container(&sub2, DBUS_TYPE_ARRAY, "s", &sub3))
285                         return -ENOMEM;
286
287                 STRV_FOREACH(l, c->argv)
288                         if (!dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, l))
289                                 return -ENOMEM;
290
291                 pid = (uint32_t) c->exec_status.pid;
292                 code = (int32_t) c->exec_status.code;
293                 status = (int32_t) c->exec_status.status;
294
295                 if (!dbus_message_iter_close_container(&sub2, &sub3) ||
296                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_BOOLEAN, &c->ignore) ||
297                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.start_timestamp.realtime) ||
298                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.exit_timestamp.realtime) ||
299                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &pid) ||
300                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &code) ||
301                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &status))
302                         return -ENOMEM;
303
304                 if (!dbus_message_iter_close_container(&sub, &sub2))
305                         return -ENOMEM;
306         }
307
308         if (!dbus_message_iter_close_container(i, &sub))
309                 return -ENOMEM;
310
311         return 0;
312 }