• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 14630481637

23 Apr 2025 07:04PM UTC coverage: 72.178% (-0.002%) from 72.18%
14630481637

push

github

DaanDeMeyer
mkosi: Run clangd within the tools tree instead of the build container

Running within the build sandbox has a number of disadvantages:
- We have a separate clangd cache for each distribution/release combo
- It requires to build the full image before clangd can be used
- It breaks every time the image becomes out of date and requires a
  rebuild
- We can't look at system headers as we don't have the knowledge to map
  them from inside the build sandbox to the corresponding path on the host

Instead, let's have mkosi.clangd run clangd within the tools tree. We
already require building systemd for both the host and the target anyway,
and all the dependencies to build systemd are installed in the tools tree
already for that, as well as clangd since it's installed together with the
other clang tooling we install in the tools tree. Unlike the previous approach,
this approach only requires the mkosi tools tree to be built upfront, which has
a much higher chance of not invalidating its cache. We can also trivially map
system header lookups from within the sandbox to the path within mkosi.tools
on the host so that starts working as well.

297054 of 411557 relevant lines covered (72.18%)

686269.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

40.14
/src/core/dbus-manager.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <errno.h>
4
#include <sys/prctl.h>
5
#include <sys/statvfs.h>
6
#include <unistd.h>
7

8
#include "alloc-util.h"
9
#include "architecture.h"
10
#include "bitfield.h"
11
#include "build.h"
12
#include "bus-common-errors.h"
13
#include "bus-get-properties.h"
14
#include "bus-log-control-api.h"
15
#include "bus-message-util.h"
16
#include "bus-util.h"
17
#include "chase.h"
18
#include "confidential-virt.h"
19
#include "dbus-cgroup.h"
20
#include "dbus-execute.h"
21
#include "dbus-job.h"
22
#include "dbus-manager.h"
23
#include "dbus-scope.h"
24
#include "dbus-service.h"
25
#include "dbus-unit.h"
26
#include "dbus-util.h"
27
#include "dbus.h"
28
#include "dynamic-user.h"
29
#include "env-util.h"
30
#include "fd-util.h"
31
#include "fileio.h"
32
#include "format-util.h"
33
#include "initrd-util.h"
34
#include "install.h"
35
#include "locale-util.h"
36
#include "log.h"
37
#include "manager-dump.h"
38
#include "memfd-util.h"
39
#include "os-util.h"
40
#include "parse-util.h"
41
#include "path-util.h"
42
#include "process-util.h"
43
#include "selinux-access.h"
44
#include "stat-util.h"
45
#include "string-util.h"
46
#include "strv.h"
47
#include "syslog-util.h"
48
#include "taint.h"
49
#include "user-util.h"
50
#include "version.h"
51
#include "virt.h"
52
#include "watchdog.h"
53

54
static UnitFileFlags unit_file_bools_to_flags(bool runtime, bool force) {
×
55
        return (runtime ? UNIT_FILE_RUNTIME : 0) |
×
56
               (force   ? UNIT_FILE_FORCE   : 0);
×
57
}
58

59
BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_oom_policy, oom_policy, OOMPolicy);
1,102✔
60
BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_emergency_action, emergency_action, EmergencyAction);
5,941✔
61

62
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_version, "s", GIT_VERSION);
17✔
63
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_features, "s", systemd_features);
17✔
64
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_architecture, "s", architecture_to_string(uname_architecture()));
17✔
65
static BUS_DEFINE_PROPERTY_GET2(property_get_system_state, "s", Manager, manager_state, manager_state_to_string);
17✔
66
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_timer_slack_nsec, "t", (uint64_t) prctl(PR_GET_TIMERSLACK));
17✔
67
static BUS_DEFINE_PROPERTY_GET_REF(property_get_hashmap_size, "u", Hashmap *, hashmap_size);
34✔
68
static BUS_DEFINE_PROPERTY_GET_REF(property_get_set_size, "u", Set *, set_size);
237✔
69
static BUS_DEFINE_PROPERTY_GET(property_get_default_timeout_abort_usec, "t", Manager, manager_default_timeout_abort_usec);
17✔
70
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_watchdog_device, "s", watchdog_get_device());
17✔
71
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_watchdog_last_ping_realtime, "t", watchdog_get_last_ping(CLOCK_REALTIME));
17✔
72
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_watchdog_last_ping_monotonic, "t", watchdog_get_last_ping(CLOCK_MONOTONIC));
17✔
73
static BUS_DEFINE_PROPERTY_GET(property_get_progress, "d", Manager, manager_get_progress);
17✔
74

75
static int property_get_virtualization(
17✔
76
                sd_bus *bus,
77
                const char *path,
78
                const char *interface,
79
                const char *property,
80
                sd_bus_message *reply,
81
                void *userdata,
82
                sd_bus_error *error) {
83

84
        Virtualization v;
17✔
85

86
        assert(bus);
17✔
87
        assert(reply);
17✔
88

89
        v = detect_virtualization();
17✔
90

91
        /* Make sure to return the empty string when we detect no virtualization, as that is the API.
92
         *
93
         * https://github.com/systemd/systemd/issues/1423
94
         */
95

96
        return sd_bus_message_append(
34✔
97
                        reply, "s",
98
                        v == VIRTUALIZATION_NONE ? NULL : virtualization_to_string(v));
17✔
99
}
100

101
static int property_get_confidential_virtualization(
17✔
102
                sd_bus *bus,
103
                const char *path,
104
                const char *interface,
105
                const char *property,
106
                sd_bus_message *reply,
107
                void *userdata,
108
                sd_bus_error *error) {
109

110
        ConfidentialVirtualization v;
17✔
111

112
        assert(bus);
17✔
113
        assert(reply);
17✔
114

115
        v = detect_confidential_virtualization();
17✔
116

117
        return sd_bus_message_append(
17✔
118
                        reply, "s",
119
                        v <= 0 ? NULL : confidential_virtualization_to_string(v));
×
120
}
121

122
static int property_get_tainted(
17✔
123
                sd_bus *bus,
124
                const char *path,
125
                const char *interface,
126
                const char *property,
127
                sd_bus_message *reply,
128
                void *userdata,
129
                sd_bus_error *error) {
130

131
        assert(bus);
17✔
132
        assert(reply);
17✔
133

134
        _cleanup_free_ char *s = taint_string();
34✔
135
        if (!s)
17✔
136
                return log_oom();
×
137

138
        return sd_bus_message_append(reply, "s", s);
17✔
139
}
140

141
static int property_set_log_target(
3✔
142
                sd_bus *bus,
143
                const char *path,
144
                const char *interface,
145
                const char *property,
146
                sd_bus_message *value,
147
                void *userdata,
148
                sd_bus_error *error) {
149

150
        Manager *m = userdata;
3✔
151
        const char *t;
3✔
152
        int r;
3✔
153

154
        assert(bus);
3✔
155
        assert(value);
3✔
156

157
        r = sd_bus_message_read(value, "s", &t);
3✔
158
        if (r < 0)
3✔
159
                return r;
3✔
160

161
        if (isempty(t))
3✔
162
                manager_restore_original_log_target(m);
×
163
        else {
164
                LogTarget target;
3✔
165

166
                target = log_target_from_string(t);
3✔
167
                if (target < 0)
3✔
168
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid log target '%s'", t);
×
169

170
                manager_override_log_target(m, target);
3✔
171
        }
172

173
        return 0;
174
}
175

176
static int property_set_log_level(
13✔
177
                sd_bus *bus,
178
                const char *path,
179
                const char *interface,
180
                const char *property,
181
                sd_bus_message *value,
182
                void *userdata,
183
                sd_bus_error *error) {
184

185
        Manager *m = userdata;
13✔
186
        const char *t;
13✔
187
        int r;
13✔
188

189
        assert(bus);
13✔
190
        assert(value);
13✔
191

192
        r = sd_bus_message_read(value, "s", &t);
13✔
193
        if (r < 0)
13✔
194
                return r;
13✔
195

196
        if (isempty(t))
13✔
197
                manager_restore_original_log_level(m);
×
198
        else {
199
                int level;
13✔
200

201
                level = log_level_from_string(t);
13✔
202
                if (level < 0)
13✔
203
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid log level '%s'", t);
×
204

205
                manager_override_log_level(m, level);
13✔
206
        }
207

208
        return 0;
209
}
210

211
static int property_get_environment(
21✔
212
                sd_bus *bus,
213
                const char *path,
214
                const char *interface,
215
                const char *property,
216
                sd_bus_message *reply,
217
                void *userdata,
218
                sd_bus_error *error) {
219

220
        _cleanup_strv_free_ char **l = NULL;
21✔
221
        Manager *m = ASSERT_PTR(userdata);
21✔
222
        int r;
21✔
223

224
        assert(bus);
21✔
225
        assert(reply);
21✔
226

227
        r = manager_get_effective_environment(m, &l);
21✔
228
        if (r < 0)
21✔
229
                return r;
230

231
        return sd_bus_message_append_strv(reply, l);
21✔
232
}
233

234
static int property_get_show_status(
17✔
235
                sd_bus *bus,
236
                const char *path,
237
                const char *interface,
238
                const char *property,
239
                sd_bus_message *reply,
240
                void *userdata,
241
                sd_bus_error *error) {
242

243
        Manager *m = ASSERT_PTR(userdata);
17✔
244

245
        assert(bus);
17✔
246
        assert(reply);
17✔
247

248
        return sd_bus_message_append(reply, "b", manager_get_show_status_on(m));
17✔
249
}
250

251
static int property_get_runtime_watchdog(
17✔
252
                sd_bus *bus,
253
                const char *path,
254
                const char *interface,
255
                const char *property,
256
                sd_bus_message *reply,
257
                void *userdata,
258
                sd_bus_error *error) {
259

260
        Manager *m = ASSERT_PTR(userdata);
17✔
261

262
        assert(bus);
17✔
263
        assert(reply);
17✔
264

265
        return sd_bus_message_append(reply, "t", manager_get_watchdog(m, WATCHDOG_RUNTIME));
17✔
266
}
267

268
static int property_get_pretimeout_watchdog(
17✔
269
                sd_bus *bus,
270
                const char *path,
271
                const char *interface,
272
                const char *property,
273
                sd_bus_message *reply,
274
                void *userdata,
275
                sd_bus_error *error) {
276

277
        Manager *m = ASSERT_PTR(userdata);
17✔
278

279
        assert(bus);
17✔
280
        assert(reply);
17✔
281

282
        return sd_bus_message_append(reply, "t", manager_get_watchdog(m, WATCHDOG_PRETIMEOUT));
17✔
283
}
284

285
static int property_get_pretimeout_watchdog_governor(
17✔
286
                sd_bus *bus,
287
                const char *path,
288
                const char *interface,
289
                const char *property,
290
                sd_bus_message *reply,
291
                void *userdata,
292
                sd_bus_error *error) {
293

294
        Manager *m = ASSERT_PTR(userdata);
17✔
295

296
        assert(bus);
17✔
297
        assert(reply);
17✔
298

299
        return sd_bus_message_append(reply, "s", m->watchdog_pretimeout_governor);
17✔
300
}
301

302
static int property_get_reboot_watchdog(
17✔
303
                sd_bus *bus,
304
                const char *path,
305
                const char *interface,
306
                const char *property,
307
                sd_bus_message *reply,
308
                void *userdata,
309
                sd_bus_error *error) {
310

311
        Manager *m = ASSERT_PTR(userdata);
17✔
312

313
        assert(bus);
17✔
314
        assert(reply);
17✔
315

316
        return sd_bus_message_append(reply, "t", manager_get_watchdog(m, WATCHDOG_REBOOT));
17✔
317
}
318

319
static int property_get_kexec_watchdog(
17✔
320
                sd_bus *bus,
321
                const char *path,
322
                const char *interface,
323
                const char *property,
324
                sd_bus_message *reply,
325
                void *userdata,
326
                sd_bus_error *error) {
327

328
        Manager *m = ASSERT_PTR(userdata);
17✔
329

330
        assert(bus);
17✔
331
        assert(reply);
17✔
332

333
        return sd_bus_message_append(reply, "t", manager_get_watchdog(m, WATCHDOG_KEXEC));
17✔
334
}
335

336
static int property_set_watchdog(Manager *m, WatchdogType type, sd_bus_message *value) {
×
337
        usec_t timeout;
×
338
        int r;
×
339

340
        assert(m);
×
341
        assert(value);
×
342

343
        assert_cc(sizeof(usec_t) == sizeof(uint64_t));
×
344

345
        r = sd_bus_message_read(value, "t", &timeout);
×
346
        if (r < 0)
×
347
                return r;
×
348

349
        manager_override_watchdog(m, type, timeout);
×
350
        return 0;
351
}
352

353
static int property_set_runtime_watchdog(
×
354
                sd_bus *bus,
355
                const char *path,
356
                const char *interface,
357
                const char *property,
358
                sd_bus_message *value,
359
                void *userdata,
360
                sd_bus_error *error) {
361

362
        return property_set_watchdog(userdata, WATCHDOG_RUNTIME, value);
×
363
}
364

365
static int property_set_pretimeout_watchdog(
×
366
                sd_bus *bus,
367
                const char *path,
368
                const char *interface,
369
                const char *property,
370
                sd_bus_message *value,
371
                void *userdata,
372
                sd_bus_error *error) {
373

374
        return property_set_watchdog(userdata, WATCHDOG_PRETIMEOUT, value);
×
375
}
376

377
static int property_set_pretimeout_watchdog_governor(
×
378
                sd_bus *bus,
379
                const char *path,
380
                const char *interface,
381
                const char *property,
382
                sd_bus_message *value,
383
                void *userdata,
384
                sd_bus_error *error) {
385

386
        Manager *m = ASSERT_PTR(userdata);
×
387
        char *governor;
×
388
        int r;
×
389

390
        r = sd_bus_message_read(value, "s", &governor);
×
391
        if (r < 0)
×
392
                return r;
×
393
        if (!string_is_safe(governor))
×
394
                return -EINVAL;
395

396
        return manager_override_watchdog_pretimeout_governor(m, governor);
×
397
}
398

399
static int property_set_reboot_watchdog(
×
400
                sd_bus *bus,
401
                const char *path,
402
                const char *interface,
403
                const char *property,
404
                sd_bus_message *value,
405
                void *userdata,
406
                sd_bus_error *error) {
407

408
        return property_set_watchdog(userdata, WATCHDOG_REBOOT, value);
×
409
}
410

411
static int property_set_kexec_watchdog(
×
412
                sd_bus *bus,
413
                const char *path,
414
                const char *interface,
415
                const char *property,
416
                sd_bus_message *value,
417
                void *userdata,
418
                sd_bus_error *error) {
419

420
        _unused_ Manager *m = ASSERT_PTR(userdata);
×
421

422
        assert(bus);
×
423
        assert(value);
×
424

425
        return property_set_watchdog(userdata, WATCHDOG_KEXEC, value);
×
426
}
427

428
static int property_get_oom_score_adjust(
17✔
429
                sd_bus *bus,
430
                const char *path,
431
                const char *interface,
432
                const char *property,
433
                sd_bus_message *reply,
434
                void *userdata,
435
                sd_bus_error *error) {
436

437
        Manager *m = ASSERT_PTR(userdata);
17✔
438
        int r, n;
17✔
439

440
        assert(bus);
17✔
441
        assert(reply);
17✔
442

443
        if (m->defaults.oom_score_adjust_set)
17✔
444
                n = m->defaults.oom_score_adjust;
×
445
        else {
446
                n = 0;
17✔
447
                r = get_oom_score_adjust(&n);
17✔
448
                if (r < 0)
17✔
449
                        log_debug_errno(r, "Failed to read current OOM score adjustment value, ignoring: %m");
×
450
        }
451

452
        return sd_bus_message_append(reply, "i", n);
17✔
453
}
454

455
static int bus_get_unit_by_name(Manager *m, sd_bus_message *message, const char *name, Unit **ret_unit, sd_bus_error *error) {
122✔
456
        Unit *u;
122✔
457
        int r;
122✔
458

459
        assert(m);
122✔
460
        assert(message);
122✔
461
        assert(ret_unit);
122✔
462

463
        /* More or less a wrapper around manager_get_unit() that generates nice errors and has one trick up
464
         * its sleeve: if the name is specified empty we use the client's unit. */
465

466
        if (isempty(name)) {
122✔
467
                _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
×
468

469
                r = bus_query_sender_pidref(message, &pidref);
×
470
                if (r < 0)
×
471
                        return r;
472

473
                u = manager_get_unit_by_pidref(m, &pidref);
×
474
                if (!u)
×
475
                        return sd_bus_error_set(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
×
476
        } else {
477
                u = manager_get_unit(m, name);
122✔
478
                if (!u)
122✔
479
                        return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
10✔
480
        }
481

482
        *ret_unit = u;
112✔
483
        return 0;
112✔
484
}
485

486
static int bus_load_unit_by_name(Manager *m, sd_bus_message *message, const char *name, Unit **ret_unit, sd_bus_error *error) {
1✔
487
        assert(m);
1✔
488
        assert(message);
1✔
489
        assert(ret_unit);
1✔
490

491
        /* Pretty much the same as bus_get_unit_by_name(), but we also load the unit if necessary. */
492

493
        if (isempty(name))
1✔
494
                return bus_get_unit_by_name(m, message, name, ret_unit, error);
×
495

496
        return manager_load_unit(m, name, NULL, error, ret_unit);
1✔
497
}
498

499
static int reply_unit_path(Unit *u, sd_bus_message *message, sd_bus_error *error) {
83✔
500
        _cleanup_free_ char *path = NULL;
83✔
501
        int r;
83✔
502

503
        assert(u);
83✔
504
        assert(message);
83✔
505

506
        r = mac_selinux_unit_access_check(u, message, "status", error);
83✔
507
        if (r < 0)
83✔
508
                return r;
509

510
        path = unit_dbus_path(u);
83✔
511
        if (!path)
83✔
512
                return log_oom();
×
513

514
        return sd_bus_reply_method_return(message, "o", path);
83✔
515
}
516

517
static int method_get_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
92✔
518
        Manager *m = ASSERT_PTR(userdata);
92✔
519
        const char *name;
92✔
520
        Unit *u;
92✔
521
        int r;
92✔
522

523
        assert(message);
92✔
524

525
        /* Anyone can call this method */
526

527
        r = sd_bus_message_read(message, "s", &name);
92✔
528
        if (r < 0)
92✔
529
                return r;
92✔
530

531
        r = bus_get_unit_by_name(m, message, name, &u, error);
92✔
532
        if (r < 0)
92✔
533
                return r;
534

535
        return reply_unit_path(u, message, error);
82✔
536
}
537

538
static int method_get_unit_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
539
        Manager *m = ASSERT_PTR(userdata);
×
540
        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
×
541
        Unit *u;
×
542
        int r;
×
543

544
        assert(message);
×
545

546
        assert_cc(sizeof(pid_t) == sizeof(uint32_t));
×
547

548
        /* Anyone can call this method */
549

550
        r = sd_bus_message_read(message, "u", &pidref.pid);
×
551
        if (r < 0)
×
552
                return r;
553
        if (pidref.pid < 0)
×
554
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PID " PID_FMT, pidref.pid);
×
555
        if (pidref.pid == 0) {
×
556
                r = bus_query_sender_pidref(message, &pidref);
×
557
                if (r < 0)
×
558
                        return r;
559
        }
560

561
        u = manager_get_unit_by_pidref(m, &pidref);
×
562
        if (!u)
×
563
                return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pidref.pid);
×
564

565
        return reply_unit_path(u, message, error);
×
566
}
567

568
static int method_get_unit_by_invocation_id(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
569
        _cleanup_free_ char *path = NULL;
×
570
        Manager *m = ASSERT_PTR(userdata);
×
571
        sd_id128_t id;
×
572
        Unit *u;
×
573
        int r;
×
574

575
        assert(message);
×
576

577
        /* Anyone can call this method */
578

579
        if (bus_message_read_id128(message, &id) < 0)
×
580
                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid invocation ID");
×
581

582
        if (sd_id128_is_null(id)) {
×
583
                _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
×
584

585
                r = bus_query_sender_pidref(message, &pidref);
×
586
                if (r < 0)
×
587
                        return r;
588

589
                u = manager_get_unit_by_pidref(m, &pidref);
×
590
                if (!u)
×
591
                        return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT,
×
592
                                                 "Client " PID_FMT " not member of any unit.", pidref.pid);
593
        } else {
594
                u = hashmap_get(m->units_by_invocation_id, &id);
×
595
                if (!u)
×
596
                        return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID, "No unit with the specified invocation ID " SD_ID128_FORMAT_STR " known.", SD_ID128_FORMAT_VAL(id));
×
597
        }
598

599
        r = mac_selinux_unit_access_check(u, message, "status", error);
×
600
        if (r < 0)
×
601
                return r;
602

603
        /* So here's a special trick: the bus path we return actually references the unit by its invocation
604
         * ID instead of the unit name. This means it stays valid only as long as the invocation ID stays the
605
         * same. */
606
        path = unit_dbus_path_invocation_id(u);
×
607
        if (!path)
×
608
                return -ENOMEM;
609

610
        return sd_bus_reply_method_return(message, "o", path);
×
611
}
612

613
static int method_get_unit_by_control_group(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
614
        Manager *m = userdata;
×
615
        const char *cgroup;
×
616
        Unit *u;
×
617
        int r;
×
618

619
        r = sd_bus_message_read(message, "s", &cgroup);
×
620
        if (r < 0)
×
621
                return r;
×
622

623
        u = manager_get_unit_by_cgroup(m, cgroup);
×
624
        if (!u)
×
625
                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT,
×
626
                                         "Control group '%s' is not valid or not managed by this instance",
627
                                         cgroup);
628

629
        return reply_unit_path(u, message, error);
×
630
}
631

632
static int method_get_unit_by_pidfd(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2✔
633
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2✔
634
        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
×
635
        Manager *m = ASSERT_PTR(userdata);
2✔
636
        _cleanup_free_ char *path = NULL;
2✔
637
        int r, pidfd;
2✔
638
        Unit *u;
2✔
639

640
        assert(message);
2✔
641

642
        r = sd_bus_message_read(message, "h", &pidfd);
2✔
643
        if (r < 0)
2✔
644
                return r;
645

646
        r = pidref_set_pidfd(&pidref, pidfd);
2✔
647
        if (r < 0)
2✔
648
                return sd_bus_error_set_errnof(error, r, "Failed to get PID from PIDFD: %m");
×
649

650
        u = manager_get_unit_by_pidref(m, &pidref);
2✔
651
        if (!u)
2✔
652
                return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pidref.pid);
×
653

654
        r = mac_selinux_unit_access_check(u, message, "status", error);
2✔
655
        if (r < 0)
2✔
656
                return r;
657

658
        path = unit_dbus_path(u);
2✔
659
        if (!path)
2✔
660
                return log_oom();
×
661

662
        r = sd_bus_message_new_method_return(message, &reply);
2✔
663
        if (r < 0)
2✔
664
                return r;
665

666
        r = sd_bus_message_append(reply, "os", path, u->id);
2✔
667
        if (r < 0)
2✔
668
                return r;
669

670
        r = sd_bus_message_append_array(reply, 'y', u->invocation_id.bytes, sizeof(u->invocation_id.bytes));
2✔
671
        if (r < 0)
2✔
672
                return r;
673

674
        /* Double-check that the process is still alive and that the PID did not change before returning the
675
         * answer. */
676
        r = pidref_verify(&pidref);
2✔
677
        if (r == -ESRCH)
2✔
678
                return sd_bus_error_setf(error,
×
679
                                         BUS_ERROR_NO_SUCH_PROCESS,
680
                                         "The PIDFD's PID "PID_FMT" changed during the lookup operation.",
681
                                         pidref.pid);
682
        if (r < 0)
2✔
683
                return sd_bus_error_set_errnof(error, r, "Failed to get PID from PIDFD: %m");
×
684

685
        return sd_bus_send(NULL, reply, NULL);
2✔
686
}
687

688
static int method_load_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1✔
689
        Manager *m = ASSERT_PTR(userdata);
1✔
690
        const char *name;
1✔
691
        Unit *u;
1✔
692
        int r;
1✔
693

694
        assert(message);
1✔
695

696
        /* Anyone can call this method */
697

698
        r = sd_bus_message_read(message, "s", &name);
1✔
699
        if (r < 0)
1✔
700
                return r;
1✔
701

702
        r = bus_load_unit_by_name(m, message, name, &u, error);
1✔
703
        if (r < 0)
1✔
704
                return r;
705

706
        return reply_unit_path(u, message, error);
1✔
707
}
708

709
static int method_start_unit_generic(sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
150✔
710
        const char *name;
150✔
711
        Unit *u;
150✔
712
        int r;
150✔
713

714
        assert(message);
150✔
715
        assert(m);
150✔
716

717
        r = sd_bus_message_read(message, "s", &name);
150✔
718
        if (r < 0)
150✔
719
                return r;
150✔
720

721
        r = manager_load_unit(m, name, NULL, error, &u);
150✔
722
        if (r < 0)
150✔
723
                return r;
724

725
        return bus_unit_method_start_generic(message, u, job_type, reload_if_possible, error);
150✔
726
}
727

728
static int method_start_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
99✔
729
        return method_start_unit_generic(message, userdata, JOB_START, /* reload_if_possible = */ false, error);
99✔
730
}
731

732
static int method_stop_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
31✔
733
        return method_start_unit_generic(message, userdata, JOB_STOP, /* reload_if_possible = */ false, error);
31✔
734
}
735

736
static int method_reload_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
3✔
737
        return method_start_unit_generic(message, userdata, JOB_RELOAD, /* reload_if_possible = */ false, error);
3✔
738
}
739

740
static int method_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
17✔
741
        return method_start_unit_generic(message, userdata, JOB_RESTART, /* reload_if_possible = */ false, error);
17✔
742
}
743

744
static int method_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
745
        return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, /* reload_if_possible = */ false, error);
×
746
}
747

748
static int method_reload_or_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
749
        return method_start_unit_generic(message, userdata, JOB_RESTART, /* reload_if_possible = */ true, error);
×
750
}
751

752
static int method_reload_or_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
753
        return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, /* reload_if_possible = */ true, error);
×
754
}
755

756
typedef enum GenericUnitOperationFlags {
757
        GENERIC_UNIT_LOAD            = 1 << 0, /* Load if the unit is not loaded yet */
758
        GENERIC_UNIT_VALIDATE_LOADED = 1 << 1, /* Verify unit is properly loaded before forwarding call */
759
} GenericUnitOperationFlags;
760

761
static int method_generic_unit_operation(
28✔
762
                sd_bus_message *message,
763
                Manager *m,
764
                sd_bus_error *error,
765
                sd_bus_message_handler_t handler,
766
                GenericUnitOperationFlags flags) {
767

768
        const char *name;
28✔
769
        Unit *u;
28✔
770
        int r;
28✔
771

772
        assert(message);
28✔
773
        assert(m);
28✔
774
        assert(handler);
28✔
775

776
        /* Read the first argument from the command and pass the operation to the specified per-unit
777
         * method. */
778

779
        r = sd_bus_message_read(message, "s", &name);
28✔
780
        if (r < 0)
28✔
781
                return r;
28✔
782

783
        if (!isempty(name) && FLAGS_SET(flags, GENERIC_UNIT_LOAD))
56✔
784
                r = manager_load_unit(m, name, NULL, error, &u);
×
785
        else
786
                r = bus_get_unit_by_name(m, message, name, &u, error);
28✔
787
        if (r < 0)
28✔
788
                return r;
789

790
        if (FLAGS_SET(flags, GENERIC_UNIT_VALIDATE_LOADED)) {
28✔
791
                r = bus_unit_validate_load_state(u, error);
×
792
                if (r < 0)
×
793
                        return r;
794
        }
795

796
        return handler(message, u, error);
28✔
797
}
798

799
static int method_enqueue_unit_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
800
        /* We don't bother with GENERIC_UNIT_VALIDATE_LOADED here, as the job logic validates that anyway */
801
        return method_generic_unit_operation(message, userdata, error, bus_unit_method_enqueue_job, GENERIC_UNIT_LOAD);
×
802
}
803

804
static int method_start_unit_replace(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
805
        Manager *m = ASSERT_PTR(userdata);
×
806
        const char *old_name;
×
807
        Unit *u;
×
808
        int r;
×
809

810
        assert(message);
×
811

812
        r = sd_bus_message_read(message, "s", &old_name);
×
813
        if (r < 0)
×
814
                return r;
×
815

816
        r = bus_get_unit_by_name(m, message, old_name, &u, error);
×
817
        if (r < 0)
×
818
                return r;
819
        if (!u->job || u->job->type != JOB_START)
×
820
                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
×
821

822
        return method_start_unit_generic(message, m, JOB_START, /* reload_if_possible = */ false, error);
×
823
}
824

825
static int method_kill_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
4✔
826
        /* We don't bother with GENERIC_UNIT_LOAD nor GENERIC_UNIT_VALIDATE_LOADED here, as it shouldn't
827
         * matter whether a unit is loaded for killing any processes possibly in the unit's cgroup. */
828
        return method_generic_unit_operation(message, userdata, error, bus_unit_method_kill, 0);
4✔
829
}
830

831
static int method_clean_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
832
        /* Load the unit if necessary, in order to load it, and insist on the unit being loaded to be
833
         * cleaned */
834
        return method_generic_unit_operation(message, userdata, error, bus_unit_method_clean, GENERIC_UNIT_LOAD|GENERIC_UNIT_VALIDATE_LOADED);
×
835
}
836

837
static int method_freeze_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
838
        /* Only active units can be frozen, which must be properly loaded already */
839
        return method_generic_unit_operation(message, userdata, error, bus_unit_method_freeze, GENERIC_UNIT_VALIDATE_LOADED);
×
840
}
841

842
static int method_thaw_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
843
        /* Same as freeze above */
844
        return method_generic_unit_operation(message, userdata, error, bus_unit_method_thaw, GENERIC_UNIT_VALIDATE_LOADED);
×
845
}
846

847
static int method_reset_failed_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
848
        /* Don't load the unit (because unloaded units can't be in failed state), and don't insist on the
849
         * unit to be loaded properly (since a failed unit might have its unit file disappeared) */
850
        return method_generic_unit_operation(message, userdata, error, bus_unit_method_reset_failed, 0);
×
851
}
852

853
static int method_set_unit_properties(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
854
        /* Only change properties on fully loaded units, and load them in order to set properties */
855
        return method_generic_unit_operation(message, userdata, error, bus_unit_method_set_properties, GENERIC_UNIT_LOAD|GENERIC_UNIT_VALIDATE_LOADED);
×
856
}
857

858
static int method_bind_mount_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
859
        /* Only add mounts on fully loaded units */
860
        return method_generic_unit_operation(message, userdata, error, bus_service_method_bind_mount, GENERIC_UNIT_VALIDATE_LOADED);
×
861
}
862

863
static int method_mount_image_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
864
        /* Only add mounts on fully loaded units */
865
        return method_generic_unit_operation(message, userdata, error, bus_service_method_mount_image, GENERIC_UNIT_VALIDATE_LOADED);
×
866
}
867

868
static int method_ref_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
869
        /* Only allow reffing of fully loaded units, and make sure reffing a unit loads it. */
870
        return method_generic_unit_operation(message, userdata, error, bus_unit_method_ref, GENERIC_UNIT_LOAD|GENERIC_UNIT_VALIDATE_LOADED);
×
871
}
872

873
static int method_unref_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2✔
874
        /* Dropping a ref OTOH should not require the unit to still be loaded. And since a reffed unit is a
875
         * loaded unit there's no need to load the unit for unreffing it. */
876
        return method_generic_unit_operation(message, userdata, error, bus_unit_method_unref, 0);
2✔
877
}
878

879
static int reply_unit_info(sd_bus_message *reply, Unit *u) {
2,810✔
880
        _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
2,810✔
881
        Unit *following;
2,810✔
882

883
        following = unit_following(u);
2,810✔
884

885
        unit_path = unit_dbus_path(u);
2,810✔
886
        if (!unit_path)
2,810✔
887
                return -ENOMEM;
888

889
        if (u->job) {
2,810✔
890
                job_path = job_dbus_path(u->job);
17✔
891
                if (!job_path)
17✔
892
                        return -ENOMEM;
893
        }
894

895
        return sd_bus_message_append(
2,827✔
896
                        reply, "(ssssssouso)",
897
                        u->id,
898
                        unit_description(u),
899
                        unit_load_state_to_string(u->load_state),
900
                        unit_active_state_to_string(unit_active_state(u)),
901
                        unit_sub_state_to_string(u),
902
                        following ? following->id : "",
903
                        unit_path,
904
                        u->job ? u->job->id : 0,
905
                        u->job ? job_type_to_string(u->job->type) : "",
2,810✔
906
                        empty_to_root(job_path));
907
}
908

909
static int method_list_units_by_names(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
910
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
×
911
        Manager *m = ASSERT_PTR(userdata);
×
912
        int r;
×
913
        _cleanup_strv_free_ char **units = NULL;
×
914

915
        assert(message);
×
916

917
        r = sd_bus_message_read_strv(message, &units);
×
918
        if (r < 0)
×
919
                return r;
920

921
        r = sd_bus_message_new_method_return(message, &reply);
×
922
        if (r < 0)
×
923
                return r;
924

925
        r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
×
926
        if (r < 0)
×
927
                return r;
928

929
        STRV_FOREACH(unit, units) {
×
930
                Unit *u;
×
931

932
                if (!unit_name_is_valid(*unit, UNIT_NAME_ANY))
×
933
                        continue;
×
934

935
                r = bus_load_unit_by_name(m, message, *unit, &u, error);
×
936
                if (r < 0)
×
937
                        return r;
×
938

939
                r = reply_unit_info(reply, u);
×
940
                if (r < 0)
×
941
                        return r;
942
        }
943

944
        r = sd_bus_message_close_container(reply);
×
945
        if (r < 0)
×
946
                return r;
947

948
        return sd_bus_send(NULL, reply, NULL);
×
949
}
950

951
static int method_get_unit_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
22✔
952
        /* Don't load a unit actively (since it won't have any processes if it's not loaded), but don't
953
         * insist on the unit being loaded either (because even improperly loaded units might still have
954
         * processes around). */
955
        return method_generic_unit_operation(message, userdata, error, bus_unit_method_get_processes, /* flags = */ 0);
22✔
956
}
957

958
static int method_attach_processes_to_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
959
        /* Don't allow attaching new processes to units that aren't loaded. Don't bother with loading a unit
960
         * for this purpose though, as an unloaded unit is a stopped unit, and we don't allow attaching
961
         * processes to stopped units anyway. */
962
        return method_generic_unit_operation(message, userdata, error, bus_unit_method_attach_processes, GENERIC_UNIT_VALIDATE_LOADED);
×
963
}
964

965
static int method_remove_subgroup_from_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
966
        /* Don't allow removal of subgroups from units that aren't loaded. But allow loading the unit, since
967
         * this is clean-up work, that is OK to do when the unit is stopped already. */
968
        return method_generic_unit_operation(message, userdata, error, bus_unit_method_remove_subgroup, GENERIC_UNIT_LOAD|GENERIC_UNIT_VALIDATE_LOADED);
×
969
}
970

971
static int transient_unit_from_message(
142✔
972
                Manager *m,
973
                sd_bus_message *message,
974
                const char *name,
975
                Unit **ret_unit,
976
                sd_bus_error *error) {
977

978
        UnitType t;
142✔
979
        Unit *u;
142✔
980
        int r;
142✔
981

982
        assert(m);
142✔
983
        assert(message);
142✔
984
        assert(name);
142✔
985

986
        t = unit_name_to_type(name);
142✔
987
        if (t < 0)
142✔
988
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
989
                                         "Invalid unit name or type.");
990

991
        if (!unit_vtable[t]->can_transient)
142✔
992
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
993
                                         "Unit type %s does not support transient units.",
994
                                         unit_type_to_string(t));
995

996
        r = manager_load_unit(m, name, NULL, error, &u);
142✔
997
        if (r < 0)
142✔
998
                return r;
999

1000
        if (!unit_is_pristine(u))
142✔
1001
                return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
×
1002
                                         "Unit %s was already loaded or has a fragment file.", name);
1003

1004
        /* OK, the unit failed to load and is unreferenced, now let's
1005
         * fill in the transient data instead */
1006
        r = unit_make_transient(u);
142✔
1007
        if (r < 0)
142✔
1008
                return r;
1009

1010
        /* Set our properties */
1011
        r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
142✔
1012
        if (r < 0)
142✔
1013
                return r;
1014

1015
        /* If the client asked for it, automatically add a reference to this unit. */
1016
        if (u->bus_track_add) {
142✔
1017
                r = bus_unit_track_add_sender(u, message);
123✔
1018
                if (r < 0)
123✔
1019
                        return log_error_errno(r, "Failed to watch sender: %m");
×
1020
        }
1021

1022
        /* Now load the missing bits of the unit we just created */
1023
        unit_add_to_load_queue(u);
142✔
1024
        manager_dispatch_load_queue(m);
142✔
1025

1026
        if (ret_unit)
142✔
1027
                *ret_unit = u;
142✔
1028

1029
        return 0;
1030
}
1031

1032
static int transient_aux_units_from_message(
142✔
1033
                Manager *m,
1034
                sd_bus_message *message,
1035
                sd_bus_error *error) {
1036

1037
        int r;
142✔
1038

1039
        assert(m);
142✔
1040
        assert(message);
142✔
1041

1042
        r = sd_bus_message_enter_container(message, 'a', "(sa(sv))");
142✔
1043
        if (r < 0)
142✔
1044
                return r;
1045

1046
        while ((r = sd_bus_message_enter_container(message, 'r', "sa(sv)")) > 0) {
142✔
1047
                const char *name;
×
1048

1049
                r = sd_bus_message_read(message, "s", &name);
×
1050
                if (r < 0)
×
1051
                        return r;
×
1052

1053
                r = transient_unit_from_message(m, message, name, /* unit = */ NULL, error);
×
1054
                if (r < 0)
×
1055
                        return r;
1056

1057
                r = sd_bus_message_exit_container(message);
×
1058
                if (r < 0)
×
1059
                        return r;
1060
        }
1061
        if (r < 0)
142✔
1062
                return r;
1063

1064
        r = sd_bus_message_exit_container(message);
142✔
1065
        if (r < 0)
142✔
1066
                return r;
×
1067

1068
        return 0;
1069
}
1070

1071
static int method_start_transient_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
142✔
1072
        const char *name, *smode;
142✔
1073
        Manager *m = ASSERT_PTR(userdata);
142✔
1074
        JobMode mode;
142✔
1075
        Unit *u;
142✔
1076
        int r;
142✔
1077

1078
        assert(message);
142✔
1079

1080
        r = mac_selinux_access_check(message, "start", error);
142✔
1081
        if (r < 0)
142✔
1082
                return r;
142✔
1083

1084
        r = sd_bus_message_read(message, "ss", &name, &smode);
142✔
1085
        if (r < 0)
142✔
1086
                return r;
1087

1088
        mode = job_mode_from_string(smode);
142✔
1089
        if (mode < 0)
142✔
1090
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
×
1091

1092
        r = bus_verify_manage_units_async_impl(
142✔
1093
                        m,
1094
                        name,
1095
                        "start",
1096
                        N_("Authentication is required to start transient unit '$(unit)'."),
1097
                        message,
1098
                        error);
1099
        if (r < 0)
142✔
1100
                return r;
1101
        if (r == 0)
142✔
1102
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1103

1104
        r = transient_unit_from_message(m, message, name, &u, error);
142✔
1105
        if (r < 0)
142✔
1106
                return r;
1107

1108
        r = transient_aux_units_from_message(m, message, error);
142✔
1109
        if (r < 0)
142✔
1110
                return r;
1111

1112
        /* Finally, start it */
1113
        return bus_unit_queue_job(message, u, JOB_START, mode, 0, error);
142✔
1114
}
1115

1116
static int method_get_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1117
        _cleanup_free_ char *path = NULL;
×
1118
        Manager *m = ASSERT_PTR(userdata);
×
1119
        uint32_t id;
×
1120
        Job *j;
×
1121
        int r;
×
1122

1123
        assert(message);
×
1124

1125
        /* Anyone can call this method */
1126

1127
        r = sd_bus_message_read(message, "u", &id);
×
1128
        if (r < 0)
×
1129
                return r;
1130

1131
        j = manager_get_job(m, id);
×
1132
        if (!j)
×
1133
                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
×
1134

1135
        r = mac_selinux_unit_access_check(j->unit, message, "status", error);
×
1136
        if (r < 0)
×
1137
                return r;
1138

1139
        path = job_dbus_path(j);
×
1140
        if (!path)
×
1141
                return -ENOMEM;
1142

1143
        return sd_bus_reply_method_return(message, "o", path);
×
1144
}
1145

1146
static int method_cancel_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1147
        Manager *m = ASSERT_PTR(userdata);
×
1148
        uint32_t id;
×
1149
        Job *j;
×
1150
        int r;
×
1151

1152
        assert(message);
×
1153

1154
        r = sd_bus_message_read(message, "u", &id);
×
1155
        if (r < 0)
×
1156
                return r;
×
1157

1158
        j = manager_get_job(m, id);
×
1159
        if (!j)
×
1160
                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
×
1161

1162
        return bus_job_method_cancel(message, j, error);
×
1163
}
1164

1165
static int method_clear_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1166
        Manager *m = ASSERT_PTR(userdata);
×
1167
        int r;
×
1168

1169
        assert(message);
×
1170

1171
        r = mac_selinux_access_check(message, "reload", error);
×
1172
        if (r < 0)
×
1173
                return r;
1174

1175
        r = bus_verify_manage_units_async(m, message, error);
×
1176
        if (r < 0)
×
1177
                return r;
1178
        if (r == 0)
×
1179
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1180

1181
        manager_clear_jobs(m);
×
1182

1183
        return sd_bus_reply_method_return(message, NULL);
×
1184
}
1185

1186
static int method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1✔
1187
        Manager *m = ASSERT_PTR(userdata);
1✔
1188
        int r;
1✔
1189

1190
        assert(message);
1✔
1191

1192
        r = mac_selinux_access_check(message, "reload", error);
1✔
1193
        if (r < 0)
1✔
1194
                return r;
1195

1196
        r = bus_verify_manage_units_async(m, message, error);
1✔
1197
        if (r < 0)
1✔
1198
                return r;
1199
        if (r == 0)
1✔
1200
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1201

1202
        manager_reset_failed(m);
1✔
1203

1204
        return sd_bus_reply_method_return(message, NULL);
1✔
1205
}
1206

1207
static int list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) {
14✔
1208
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
14✔
1209
        Manager *m = ASSERT_PTR(userdata);
14✔
1210
        const char *k;
14✔
1211
        Unit *u;
14✔
1212
        int r;
14✔
1213

1214
        assert(message);
14✔
1215

1216
        /* Anyone can call this method */
1217

1218
        r = mac_selinux_access_check(message, "status", error);
14✔
1219
        if (r < 0)
14✔
1220
                return r;
1221

1222
        r = sd_bus_message_new_method_return(message, &reply);
14✔
1223
        if (r < 0)
14✔
1224
                return r;
1225

1226
        r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
14✔
1227
        if (r < 0)
14✔
1228
                return r;
1229

1230
        HASHMAP_FOREACH_KEY(u, k, m->units) {
3,182✔
1231
                if (k != u->id)
3,168✔
1232
                        continue;
131✔
1233

1234
                if (!unit_passes_filter(u, states, patterns))
3,037✔
1235
                        continue;
227✔
1236

1237
                r = reply_unit_info(reply, u);
2,810✔
1238
                if (r < 0)
2,810✔
1239
                        return r;
×
1240
        }
1241

1242
        r = sd_bus_message_close_container(reply);
14✔
1243
        if (r < 0)
14✔
1244
                return r;
1245

1246
        return sd_bus_send(NULL, reply, NULL);
14✔
1247
}
1248

1249
static int method_list_units(sd_bus_message *message, void *userdata, sd_bus_error *error) {
12✔
1250
        return list_units_filtered(message, userdata, error, NULL, NULL);
12✔
1251
}
1252

1253
static int method_list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1254
        _cleanup_strv_free_ char **states = NULL;
×
1255
        int r;
×
1256

1257
        r = sd_bus_message_read_strv(message, &states);
×
1258
        if (r < 0)
×
1259
                return r;
1260

1261
        return list_units_filtered(message, userdata, error, states, NULL);
×
1262
}
1263

1264
static int method_list_units_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2✔
1265
        _cleanup_strv_free_ char **states = NULL;
2✔
1266
        _cleanup_strv_free_ char **patterns = NULL;
2✔
1267
        int r;
2✔
1268

1269
        r = sd_bus_message_read_strv(message, &states);
2✔
1270
        if (r < 0)
2✔
1271
                return r;
1272

1273
        r = sd_bus_message_read_strv(message, &patterns);
2✔
1274
        if (r < 0)
2✔
1275
                return r;
1276

1277
        return list_units_filtered(message, userdata, error, states, patterns);
2✔
1278
}
1279

1280
static int method_list_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1✔
1281
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1✔
1282
        Manager *m = ASSERT_PTR(userdata);
1✔
1283
        Job *j;
1✔
1284
        int r;
1✔
1285

1286
        assert(message);
1✔
1287

1288
        /* Anyone can call this method */
1289

1290
        r = mac_selinux_access_check(message, "status", error);
1✔
1291
        if (r < 0)
1✔
1292
                return r;
1293

1294
        r = sd_bus_message_new_method_return(message, &reply);
1✔
1295
        if (r < 0)
1✔
1296
                return r;
1297

1298
        r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
1✔
1299
        if (r < 0)
1✔
1300
                return r;
1301

1302
        HASHMAP_FOREACH(j, m->jobs) {
3✔
1303
                _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
2✔
1304

1305
                job_path = job_dbus_path(j);
2✔
1306
                if (!job_path)
2✔
1307
                        return -ENOMEM;
1308

1309
                unit_path = unit_dbus_path(j->unit);
2✔
1310
                if (!unit_path)
2✔
1311
                        return -ENOMEM;
1312

1313
                r = sd_bus_message_append(
2✔
1314
                                reply, "(usssoo)",
1315
                                j->id,
1316
                                j->unit->id,
2✔
1317
                                job_type_to_string(j->type),
1318
                                job_state_to_string(j->state),
2✔
1319
                                job_path,
1320
                                unit_path);
1321
                if (r < 0)
2✔
1322
                        return r;
1323
        }
1324

1325
        r = sd_bus_message_close_container(reply);
1✔
1326
        if (r < 0)
1✔
1327
                return r;
1328

1329
        return sd_bus_send(NULL, reply, NULL);
1✔
1330
}
1331

1332
static int method_subscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
75✔
1333
        Manager *m = ASSERT_PTR(userdata);
75✔
1334
        int r;
75✔
1335

1336
        assert(message);
75✔
1337

1338
        /* Anyone can call this method */
1339

1340
        r = mac_selinux_access_check(message, "status", error);
75✔
1341
        if (r < 0)
75✔
1342
                return r;
1343

1344
        if (sd_bus_message_get_bus(message) == m->api_bus) {
75✔
1345

1346
                /* Note that direct bus connection subscribe by
1347
                 * default, we only track peers on the API bus here */
1348

1349
                if (!m->subscribed) {
75✔
1350
                        r = sd_bus_track_new(sd_bus_message_get_bus(message), &m->subscribed, NULL, NULL);
51✔
1351
                        if (r < 0)
51✔
1352
                                return r;
1353
                }
1354

1355
                r = sd_bus_track_add_sender(m->subscribed, message);
75✔
1356
                if (r < 0)
75✔
1357
                        return r;
1358
                if (r == 0)
75✔
1359
                        return sd_bus_error_set(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
×
1360
        }
1361

1362
        return sd_bus_reply_method_return(message, NULL);
75✔
1363
}
1364

1365
static int method_unsubscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1366
        Manager *m = ASSERT_PTR(userdata);
×
1367
        int r;
×
1368

1369
        assert(message);
×
1370

1371
        /* Anyone can call this method */
1372

1373
        r = mac_selinux_access_check(message, "status", error);
×
1374
        if (r < 0)
×
1375
                return r;
1376

1377
        if (sd_bus_message_get_bus(message) == m->api_bus) {
×
1378
                r = sd_bus_track_remove_sender(m->subscribed, message);
×
1379
                if (r < 0)
×
1380
                        return r;
1381
                if (r == 0)
×
1382
                        return sd_bus_error_set(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
×
1383
        }
1384

1385
        return sd_bus_reply_method_return(message, NULL);
×
1386
}
1387

1388
static int dump_impl(
14✔
1389
                sd_bus_message *message,
1390
                void *userdata,
1391
                sd_bus_error *error,
1392
                char **patterns,
1393
                int (*reply)(sd_bus_message *, char *)) {
1394

1395
        _cleanup_free_ char *dump = NULL;
14✔
1396
        Manager *m = ASSERT_PTR(userdata);
14✔
1397
        int r;
14✔
1398

1399
        assert(message);
14✔
1400

1401
        /* 'status' access is the bare minimum always needed for this, as the policy might straight out
1402
         * forbid a client from querying any information from systemd, regardless of any rate limiting. */
1403
        r = mac_selinux_access_check(message, "status", error);
14✔
1404
        if (r < 0)
14✔
1405
                return r;
1406

1407
        /* Rate limit reached? Check if the caller is privileged/allowed by policy to bypass this. We
1408
         * check the rate limit first to avoid the expensive roundtrip to polkit when not needed. */
1409
        if (!ratelimit_below(&m->dump_ratelimit)) {
14✔
1410
                /* We need a way for SELinux to constrain the operation when the rate limit is active, even
1411
                 * if polkit would allow it, but we cannot easily add new named permissions, so we need to
1412
                 * use an existing one. Reload/reexec are also slow but non-destructive/modifying
1413
                 * operations, and can cause PID1 to stall. So it seems similar enough in terms of security
1414
                 * considerations and impact, and thus use the same access check for dumps which, given the
1415
                 * large amount of data to fetch, can stall PID1 for quite some time. */
1416
                r = mac_selinux_access_check(message, "reload", /* error = */ NULL);
4✔
1417
                if (r < 0)
4✔
1418
                        goto ratelimited;
×
1419

1420
                r = bus_verify_bypass_dump_ratelimit_async(m, message, /* error = */ NULL);
4✔
1421
                if (r < 0)
4✔
1422
                        goto ratelimited;
2✔
1423
                if (r == 0)
2✔
1424
                        /* No authorization for now, but the async polkit stuff will call us again when it
1425
                         * has it */
1426
                        return 1;
1427
        }
1428

1429
        r = manager_get_dump_string(m, patterns, &dump);
10✔
1430
        if (r < 0)
10✔
1431
                return r;
1432

1433
        return reply(message, dump);
10✔
1434

1435
ratelimited:
2✔
1436
        log_warning("Dump request rejected due to rate limit on unprivileged callers, blocked for %s.",
2✔
1437
                    FORMAT_TIMESPAN(ratelimit_left(&m->dump_ratelimit), USEC_PER_SEC));
1438
        return sd_bus_error_setf(error,
4✔
1439
                                 SD_BUS_ERROR_LIMITS_EXCEEDED,
1440
                                 "Dump request rejected due to rate limit on unprivileged callers, blocked for %s.",
1441
                                 FORMAT_TIMESPAN(ratelimit_left(&m->dump_ratelimit), USEC_PER_SEC));
2✔
1442
}
1443

1444
static int reply_dump(sd_bus_message *message, char *dump) {
×
1445
        return sd_bus_reply_method_return(message, "s", dump);
×
1446
}
1447

1448
static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1449
        return dump_impl(message, userdata, error, NULL, reply_dump);
×
1450
}
1451

1452
static int reply_dump_by_fd(sd_bus_message *message, char *dump) {
10✔
1453
        _cleanup_close_ int fd = -EBADF;
10✔
1454

1455
        fd = memfd_new_and_seal_string("dump", dump);
10✔
1456
        if (fd < 0)
10✔
1457
                return fd;
1458

1459
        return sd_bus_reply_method_return(message, "h", fd);
10✔
1460
}
1461

1462
static int method_dump_by_fd(sd_bus_message *message, void *userdata, sd_bus_error *error) {
4✔
1463
        return dump_impl(message, userdata, error, NULL, reply_dump_by_fd);
4✔
1464
}
1465

1466
static int dump_units_matching_patterns(
10✔
1467
                sd_bus_message *message,
1468
                void *userdata,
1469
                sd_bus_error *error,
1470
                int (*reply)(sd_bus_message *, char *)) {
1471
        _cleanup_strv_free_ char **patterns = NULL;
10✔
1472
        int r;
10✔
1473

1474
        r = sd_bus_message_read_strv(message, &patterns);
10✔
1475
        if (r < 0)
10✔
1476
                return r;
1477

1478
        return dump_impl(message, userdata, error, patterns, reply);
10✔
1479
}
1480

1481
static int method_dump_units_matching_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1482
        return dump_units_matching_patterns(message, userdata, error, reply_dump);
×
1483
}
1484

1485
static int method_dump_units_matching_patterns_by_fd(sd_bus_message *message, void *userdata, sd_bus_error *error) {
10✔
1486
        return dump_units_matching_patterns(message, userdata, error, reply_dump_by_fd);
10✔
1487
}
1488

1489
static int method_refuse_snapshot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1490
        return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for snapshots has been removed.");
×
1491
}
1492

1493
static void log_caller(sd_bus_message *message, Manager *manager, const char *method) {
66✔
1494
        _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
66✔
1495
        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
×
1496

1497
        assert(message);
66✔
1498
        assert(manager);
66✔
1499
        assert(method);
66✔
1500

1501
        if (sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID|SD_BUS_CREDS_PIDFD|SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_COMM, &creds) < 0)
66✔
1502
                return;
1503

1504
        /* We need at least the PID, otherwise there's nothing to log, the rest is optional. */
1505
        if (bus_creds_get_pidref(creds, &pidref) < 0)
66✔
1506
                return;
1507

1508
        const char *comm = NULL;
66✔
1509
        Unit *caller;
66✔
1510

1511
        (void) sd_bus_creds_get_comm(creds, &comm);
66✔
1512
        caller = manager_get_unit_by_pidref(manager, &pidref);
66✔
1513

1514
        log_notice("%s requested from client PID " PID_FMT "%s%s%s%s%s%s...",
66✔
1515
                   method, pidref.pid,
1516
                   comm ? " ('" : "", strempty(comm), comm ? "')" : "",
1517
                   caller ? " (unit " : "", caller ? caller->id : "", caller ? ")" : "");
1518
}
1519

1520
static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
27✔
1521
        Manager *m = ASSERT_PTR(userdata);
27✔
1522
        int r;
27✔
1523

1524
        assert(message);
27✔
1525

1526
        r = mac_selinux_access_check(message, "reload", error);
27✔
1527
        if (r < 0)
27✔
1528
                return r;
1529

1530
        r = bus_verify_reload_daemon_async(m, message, error);
27✔
1531
        if (r < 0)
27✔
1532
                return r;
1533
        if (r == 0)
27✔
1534
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1535

1536
        /* Write a log message noting the unit or process who requested the Reload() */
1537
        log_caller(message, m, "Reload");
27✔
1538

1539
        /* Check the rate limit after the authorization succeeds, to avoid denial-of-service issues. */
1540
        if (!ratelimit_below(&m->reload_reexec_ratelimit)) {
27✔
1541
                log_warning("Reloading request rejected due to rate limit.");
1✔
1542
                return sd_bus_error_setf(error,
1✔
1543
                                         SD_BUS_ERROR_LIMITS_EXCEEDED,
1544
                                         "Reload() request rejected due to rate limit.");
1545
        }
1546

1547
        /* Instead of sending the reply back right away, we just
1548
         * remember that we need to and then send it after the reload
1549
         * is finished. That way the caller knows when the reload
1550
         * finished. */
1551

1552
        assert(!m->pending_reload_message);
26✔
1553
        r = sd_bus_message_new_method_return(message, &m->pending_reload_message);
26✔
1554
        if (r < 0)
26✔
1555
                return r;
1556

1557
        m->objective = MANAGER_RELOAD;
26✔
1558

1559
        return 1;
26✔
1560
}
1561

1562
static int method_reexecute(sd_bus_message *message, void *userdata, sd_bus_error *error) {
39✔
1563
        Manager *m = ASSERT_PTR(userdata);
39✔
1564
        int r;
39✔
1565

1566
        assert(message);
39✔
1567

1568
        r = mac_selinux_access_check(message, "reload", error);
39✔
1569
        if (r < 0)
39✔
1570
                return r;
1571

1572
        r = bus_verify_reload_daemon_async(m, message, error);
39✔
1573
        if (r < 0)
39✔
1574
                return r;
1575
        if (r == 0)
39✔
1576
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1577

1578
        /* Write a log message noting the unit or process who requested the Reexecute() */
1579
        log_caller(message, m, "Reexecution");
39✔
1580

1581
        /* Check the rate limit after the authorization succeeds, to avoid denial-of-service issues. */
1582
        if (!ratelimit_below(&m->reload_reexec_ratelimit)) {
39✔
1583
                log_warning("Reexecution request rejected due to rate limit.");
1✔
1584
                return sd_bus_error_setf(error,
1✔
1585
                                         SD_BUS_ERROR_LIMITS_EXCEEDED,
1586
                                         "Reexecute() request rejected due to rate limit.");
1587
        }
1588

1589
        /* We don't send a reply back here, the client should
1590
         * just wait for us disconnecting. */
1591

1592
        m->objective = MANAGER_REEXECUTE;
38✔
1593
        return 1;
38✔
1594
}
1595

1596
static int method_exit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1597
        Manager *m = ASSERT_PTR(userdata);
×
1598
        int r;
×
1599

1600
        assert(message);
×
1601

1602
        r = mac_selinux_access_check(message, "halt", error);
×
1603
        if (r < 0)
×
1604
                return r;
1605

1606
        log_caller(message, m, "Exit");
×
1607

1608
        /* Exit() (in contrast to SetExitCode()) is actually allowed even if
1609
         * we are running on the host. It will fall back on reboot() in
1610
         * systemd-shutdown if it cannot do the exit() because it isn't a
1611
         * container. */
1612

1613
        m->objective = MANAGER_EXIT;
×
1614

1615
        return sd_bus_reply_method_return(message, NULL);
×
1616
}
1617

1618
static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1619
        Manager *m = ASSERT_PTR(userdata);
×
1620
        int r;
×
1621

1622
        assert(message);
×
1623

1624
        if (!MANAGER_IS_SYSTEM(m))
×
1625
                return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
×
1626
                                        "Reboot is only supported by system manager.");
1627

1628
        r = mac_selinux_access_check(message, "reboot", error);
×
1629
        if (r < 0)
×
1630
                return r;
1631

1632
        log_caller(message, m, "Reboot");
×
1633

1634
        m->objective = MANAGER_REBOOT;
×
1635

1636
        return sd_bus_reply_method_return(message, NULL);
×
1637
}
1638

1639
static int method_soft_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1640
        Manager *m = ASSERT_PTR(userdata);
×
1641
        _cleanup_free_ char *rt = NULL;
×
1642
        const char *root;
×
1643
        int r;
×
1644

1645
        assert(message);
×
1646

1647
        if (!MANAGER_IS_SYSTEM(m))
×
1648
                return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
×
1649
                                        "Soft reboot is only supported by system manager.");
1650

1651
        r = mac_selinux_access_check(message, "reboot", error);
×
1652
        if (r < 0)
×
1653
                return r;
1654

1655
        r = sd_bus_message_read(message, "s", &root);
×
1656
        if (r < 0)
×
1657
                return r;
1658

1659
        if (!isempty(root)) {
×
1660
                if (!path_is_valid(root))
×
1661
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1662
                                                 "New root directory '%s' must be a valid path.", root);
1663
                if (!path_is_absolute(root))
×
1664
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1665
                                                 "New root directory path '%s' is not absolute.", root);
1666

1667
                r = path_simplify_alloc(root, &rt);
×
1668
                if (r < 0)
×
1669
                        return r;
1670
        }
1671

1672
        log_caller(message, m, "Soft reboot");
×
1673

1674
        free_and_replace(m->switch_root, rt);
×
1675
        m->objective = MANAGER_SOFT_REBOOT;
×
1676

1677
        return sd_bus_reply_method_return(message, NULL);
×
1678
}
1679

1680
static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1681
        Manager *m = ASSERT_PTR(userdata);
×
1682
        int r;
×
1683

1684
        assert(message);
×
1685

1686
        if (!MANAGER_IS_SYSTEM(m))
×
1687
                return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
×
1688
                                        "Powering off is only supported by system manager.");
1689

1690
        r = mac_selinux_access_check(message, "halt", error);
×
1691
        if (r < 0)
×
1692
                return r;
1693

1694
        log_caller(message, m, "Poweroff");
×
1695

1696
        m->objective = MANAGER_POWEROFF;
×
1697

1698
        return sd_bus_reply_method_return(message, NULL);
×
1699
}
1700

1701
static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1702
        Manager *m = ASSERT_PTR(userdata);
×
1703
        int r;
×
1704

1705
        assert(message);
×
1706

1707
        if (!MANAGER_IS_SYSTEM(m))
×
1708
                return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
×
1709
                                        "Halt is only supported by system manager.");
1710

1711
        r = mac_selinux_access_check(message, "halt", error);
×
1712
        if (r < 0)
×
1713
                return r;
1714

1715
        log_caller(message, m, "Halt");
×
1716

1717
        m->objective = MANAGER_HALT;
×
1718

1719
        return sd_bus_reply_method_return(message, NULL);
×
1720
}
1721

1722
static int method_kexec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1723
        Manager *m = ASSERT_PTR(userdata);
×
1724
        int r;
×
1725

1726
        assert(message);
×
1727

1728
        if (!MANAGER_IS_SYSTEM(m))
×
1729
                return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
×
1730
                                        "KExec is only supported by system manager.");
1731

1732
        r = mac_selinux_access_check(message, "reboot", error);
×
1733
        if (r < 0)
×
1734
                return r;
1735

1736
        log_caller(message, m, "Kexec");
×
1737

1738
        m->objective = MANAGER_KEXEC;
×
1739

1740
        return sd_bus_reply_method_return(message, NULL);
×
1741
}
1742

1743
static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_error *error) {
9✔
1744
        Manager *m = ASSERT_PTR(userdata);
9✔
1745
        _cleanup_free_ char *ri = NULL, *rt = NULL;
9✔
1746
        const char *root, *init;
9✔
1747
        int r;
9✔
1748

1749
        assert(message);
9✔
1750

1751
        if (!MANAGER_IS_SYSTEM(m))
9✔
1752
                return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
×
1753
                                        "Root switching is only supported by system manager.");
1754

1755
        r = mac_selinux_access_check(message, "reboot", error);
9✔
1756
        if (r < 0)
9✔
1757
                return r;
1758

1759
        r = sd_bus_message_read(message, "ss", &root, &init);
9✔
1760
        if (r < 0)
9✔
1761
                return r;
1762

1763
        if (isempty(root))
9✔
1764
                /* If path is not specified, default to "/sysroot" which is what we generally expect initrds
1765
                 * to use */
1766
                root = "/sysroot";
×
1767
        else {
1768
                if (!path_is_valid(root))
9✔
1769
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
×
1770
                                                "New root directory must be a valid path.");
1771

1772
                if (!path_is_absolute(root))
9✔
1773
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1774
                                                 "New root path '%s' is not absolute.", root);
1775

1776
                r = path_is_root(root);
9✔
1777
                if (r < 0)
9✔
1778
                        return sd_bus_error_set_errnof(error, r,
×
1779
                                                       "Failed to check if new root directory '%s' is the same as old root: %m",
1780
                                                       root);
1781
                if (r > 0)
9✔
1782
                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
×
1783
                                                "New root directory cannot be the old root directory.");
1784
        }
1785

1786
        /* Safety check */
1787
        if (!in_initrd())
9✔
1788
                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
×
1789
                                        "Not in initrd, refusing switch-root operation.");
1790

1791
        r = path_is_os_tree(root);
9✔
1792
        if (r < 0)
9✔
1793
                return sd_bus_error_set_errnof(error, r,
×
1794
                                               "Failed to determine whether root path '%s' contains an OS tree: %m",
1795
                                               root);
1796
        if (r == 0)
9✔
1797
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1798
                                         "Specified switch root path '%s' does not seem to be an OS tree. os-release file is missing.",
1799
                                         root);
1800

1801
        if (!isempty(init)) {
9✔
1802
                if (!path_is_valid(init))
×
1803
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1804
                                                 "Path to init binary '%s' is not a valid path.", init);
1805

1806
                if (!path_is_absolute(init))
×
1807
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1808
                                                 "Path to init binary '%s' not absolute.", init);
1809

1810
                r = chase_and_access(init, root, CHASE_PREFIX_ROOT, X_OK, NULL);
×
1811
                if (r == -EACCES)
×
1812
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1813
                                                 "Init binary %s is not executable.", init);
1814
                if (r < 0)
×
1815
                        return sd_bus_error_set_errnof(error, r,
×
1816
                                                       "Could not resolve init executable %s: %m", init);
1817
        }
1818

1819
        r = path_simplify_alloc(root, &rt);
9✔
1820
        if (r < 0)
9✔
1821
                return r;
1822

1823
        if (!isempty(init)) {
9✔
1824
                r = path_simplify_alloc(init, &ri);
×
1825
                if (r < 0)
×
1826
                        return r;
1827
        }
1828

1829
        free_and_replace(m->switch_root, rt);
9✔
1830
        free_and_replace(m->switch_root_init, ri);
9✔
1831

1832
        m->objective = MANAGER_SWITCH_ROOT;
9✔
1833

1834
        return sd_bus_reply_method_return(message, NULL);
9✔
1835
}
1836

1837
static int method_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
173✔
1838
        _cleanup_strv_free_ char **plus = NULL;
173✔
1839
        Manager *m = ASSERT_PTR(userdata);
173✔
1840
        int r;
173✔
1841

1842
        assert(message);
173✔
1843

1844
        r = mac_selinux_access_check(message, "reload", error);
173✔
1845
        if (r < 0)
173✔
1846
                return r;
1847

1848
        r = sd_bus_message_read_strv(message, &plus);
173✔
1849
        if (r < 0)
173✔
1850
                return r;
1851
        if (!strv_env_is_valid(plus))
173✔
1852
                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
×
1853

1854
        r = bus_verify_set_environment_async(m, message, error);
173✔
1855
        if (r < 0)
173✔
1856
                return r;
1857
        if (r == 0)
173✔
1858
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1859

1860
        r = manager_client_environment_modify(m, NULL, plus);
173✔
1861
        if (r < 0)
173✔
1862
                return r;
1863

1864
        return sd_bus_reply_method_return(message, NULL);
173✔
1865
}
1866

1867
static int method_unset_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1✔
1868
        _cleanup_strv_free_ char **minus = NULL;
1✔
1869
        Manager *m = ASSERT_PTR(userdata);
1✔
1870
        int r;
1✔
1871

1872
        assert(message);
1✔
1873

1874
        r = mac_selinux_access_check(message, "reload", error);
1✔
1875
        if (r < 0)
1✔
1876
                return r;
1877

1878
        r = sd_bus_message_read_strv(message, &minus);
1✔
1879
        if (r < 0)
1✔
1880
                return r;
1881

1882
        if (!strv_env_name_or_assignment_is_valid(minus))
1✔
1883
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1884
                                         "Invalid environment variable names or assignments");
1885

1886
        r = bus_verify_set_environment_async(m, message, error);
1✔
1887
        if (r < 0)
1✔
1888
                return r;
1889
        if (r == 0)
1✔
1890
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1891

1892
        r = manager_client_environment_modify(m, minus, NULL);
1✔
1893
        if (r < 0)
1✔
1894
                return r;
1895

1896
        return sd_bus_reply_method_return(message, NULL);
1✔
1897
}
1898

1899
static int method_unset_and_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1900
        _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
×
1901
        Manager *m = ASSERT_PTR(userdata);
×
1902
        int r;
×
1903

1904
        assert(message);
×
1905

1906
        r = mac_selinux_access_check(message, "reload", error);
×
1907
        if (r < 0)
×
1908
                return r;
1909

1910
        r = sd_bus_message_read_strv(message, &minus);
×
1911
        if (r < 0)
×
1912
                return r;
1913

1914
        r = sd_bus_message_read_strv(message, &plus);
×
1915
        if (r < 0)
×
1916
                return r;
1917

1918
        if (!strv_env_name_or_assignment_is_valid(minus))
×
1919
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1920
                                         "Invalid environment variable names or assignments");
1921
        if (!strv_env_is_valid(plus))
×
1922
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1923
                                         "Invalid environment assignments");
1924

1925
        r = bus_verify_set_environment_async(m, message, error);
×
1926
        if (r < 0)
×
1927
                return r;
1928
        if (r == 0)
×
1929
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1930

1931
        r = manager_client_environment_modify(m, minus, plus);
×
1932
        if (r < 0)
×
1933
                return r;
1934

1935
        return sd_bus_reply_method_return(message, NULL);
×
1936
}
1937

1938
static int method_set_exit_code(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1939
        Manager *m = ASSERT_PTR(userdata);
×
1940
        uint8_t code;
×
1941
        int r;
×
1942

1943
        assert(message);
×
1944

1945
        r = mac_selinux_access_check(message, "exit", error);
×
1946
        if (r < 0)
×
1947
                return r;
×
1948

1949
        r = sd_bus_message_read_basic(message, 'y', &code);
×
1950
        if (r < 0)
×
1951
                return r;
1952

1953
        m->return_value = code;
×
1954

1955
        return sd_bus_reply_method_return(message, NULL);
×
1956
}
1957

1958
static int method_lookup_dynamic_user_by_name(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1959
        Manager *m = ASSERT_PTR(userdata);
×
1960
        const char *name;
×
1961
        uid_t uid;
×
1962
        int r;
×
1963

1964
        assert(message);
×
1965

1966
        r = sd_bus_message_read_basic(message, 's', &name);
×
1967
        if (r < 0)
×
1968
                return r;
×
1969

1970
        if (!MANAGER_IS_SYSTEM(m))
×
1971
                return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
×
1972
                                         "Dynamic users are only supported in the system instance.");
1973
        if (!valid_user_group_name(name, VALID_USER_RELAX))
×
1974
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
1975
                                         "User name invalid: %s", name);
1976

1977
        r = dynamic_user_lookup_name(m, name, &uid);
×
1978
        if (r == -ESRCH)
×
1979
                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DYNAMIC_USER,
×
1980
                                         "Dynamic user %s does not exist.", name);
1981
        if (r < 0)
×
1982
                return r;
1983

1984
        return sd_bus_reply_method_return(message, "u", (uint32_t) uid);
×
1985
}
1986

1987
static int method_lookup_dynamic_user_by_uid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
1988
        _cleanup_free_ char *name = NULL;
×
1989
        Manager *m = ASSERT_PTR(userdata);
×
1990
        uid_t uid;
×
1991
        int r;
×
1992

1993
        assert(message);
×
1994

1995
        assert_cc(sizeof(uid_t) == sizeof(uint32_t));
×
1996
        r = sd_bus_message_read_basic(message, 'u', &uid);
×
1997
        if (r < 0)
×
1998
                return r;
1999

2000
        if (!MANAGER_IS_SYSTEM(m))
×
2001
                return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
×
2002
                                         "Dynamic users are only supported in the system instance.");
2003
        if (!uid_is_valid(uid))
×
2004
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
2005
                                         "User ID invalid: " UID_FMT, uid);
2006

2007
        r = dynamic_user_lookup_uid(m, uid, &name);
×
2008
        if (r == -ESRCH)
×
2009
                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DYNAMIC_USER,
×
2010
                                         "Dynamic user ID " UID_FMT " does not exist.", uid);
2011
        if (r < 0)
×
2012
                return r;
2013

2014
        return sd_bus_reply_method_return(message, "s", name);
×
2015
}
2016

2017
static int method_get_dynamic_users(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2018
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
×
2019
        Manager *m = ASSERT_PTR(userdata);
×
2020
        DynamicUser *d;
×
2021
        int r;
×
2022

2023
        assert(message);
×
2024

2025
        assert_cc(sizeof(uid_t) == sizeof(uint32_t));
×
2026

2027
        if (!MANAGER_IS_SYSTEM(m))
×
2028
                return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
×
2029
                                         "Dynamic users are only supported in the system instance.");
2030

2031
        r = sd_bus_message_new_method_return(message, &reply);
×
2032
        if (r < 0)
×
2033
                return r;
2034

2035
        r = sd_bus_message_open_container(reply, 'a', "(us)");
×
2036
        if (r < 0)
×
2037
                return r;
2038

2039
        HASHMAP_FOREACH(d, m->dynamic_users) {
×
2040
                uid_t uid;
×
2041

2042
                r = dynamic_user_current(d, &uid);
×
2043
                if (r == -EAGAIN) /* not realized yet? */
×
2044
                        continue;
×
2045
                if (r < 0)
×
2046
                        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED,
×
2047
                                                 "Failed to look up a dynamic user.");
2048

2049
                r = sd_bus_message_append(reply, "(us)", uid, d->name);
×
2050
                if (r < 0)
×
2051
                        return r;
2052
        }
2053

2054
        r = sd_bus_message_close_container(reply);
×
2055
        if (r < 0)
×
2056
                return r;
2057

2058
        return sd_bus_send(NULL, reply, NULL);
×
2059
}
2060

2061
static int method_enqueue_marked_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2062
        Manager *m = ASSERT_PTR(userdata);
×
2063
        int r;
×
2064

2065
        assert(message);
×
2066

2067
        r = mac_selinux_access_check(message, "start", error);
×
2068
        if (r < 0)
×
2069
                return r;
×
2070

2071
        r = bus_verify_manage_units_async(m, message, error);
×
2072
        if (r < 0)
×
2073
                return r;
2074
        if (r == 0)
×
2075
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2076

2077
        log_info("Queuing reload/restart jobs for marked units%s", glyph(GLYPH_ELLIPSIS));
×
2078

2079
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
×
2080
        r = sd_bus_message_new_method_return(message, &reply);
×
2081
        if (r < 0)
×
2082
                return r;
2083

2084
        r = sd_bus_message_open_container(reply, 'a', "o");
×
2085
        if (r < 0)
×
2086
                return r;
2087

2088
        Unit *u;
×
2089
        char *k;
×
2090
        int ret = 0;
×
2091
        HASHMAP_FOREACH_KEY(u, k, m->units) {
×
2092
                /* ignore aliases */
2093
                if (u->id != k)
×
2094
                        continue;
×
2095

2096
                BusUnitQueueFlags flags;
×
2097
                if (BIT_SET(u->markers, UNIT_MARKER_NEEDS_RESTART))
×
2098
                        flags = 0;
2099
                else if (BIT_SET(u->markers, UNIT_MARKER_NEEDS_RELOAD))
×
2100
                        flags = BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE;
2101
                else
2102
                        continue;
×
2103

2104
                r = mac_selinux_unit_access_check(u, message, "start", error);
×
2105
                if (r >= 0)
×
2106
                        r = bus_unit_queue_job_one(message, u,
×
2107
                                                   JOB_TRY_RESTART, JOB_FAIL, flags,
2108
                                                   reply, error);
2109
                if (ERRNO_IS_NEG_RESOURCE(r))
×
2110
                        return r;
×
2111
                if (r < 0) {
×
2112
                        if (ret >= 0)
×
2113
                                ret = r;
×
2114
                        sd_bus_error_free(error);
×
2115
                }
2116
        }
2117

2118
        if (ret < 0)
×
2119
                return sd_bus_error_set_errnof(error, ret,
×
2120
                                               "Failed to enqueue some jobs, see logs for details: %m");
2121

2122
        r = sd_bus_message_close_container(reply);
×
2123
        if (r < 0)
×
2124
                return r;
2125

2126
        return sd_bus_send(NULL, reply, NULL);
×
2127
}
2128

2129
static int list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) {
×
2130
        Manager *m = ASSERT_PTR(userdata);
×
2131
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
×
2132
        _cleanup_hashmap_free_ Hashmap *h = NULL;
×
2133
        int r;
×
2134

2135
        assert(message);
×
2136

2137
        /* Anyone can call this method */
2138

2139
        r = mac_selinux_access_check(message, "status", error);
×
2140
        if (r < 0)
×
2141
                return r;
2142

2143
        r = sd_bus_message_new_method_return(message, &reply);
×
2144
        if (r < 0)
×
2145
                return r;
2146

2147
        r = unit_file_get_list(m->runtime_scope, /* root_dir = */ NULL, states, patterns, &h);
×
2148
        if (r < 0)
×
2149
                return r;
2150

2151
        r = sd_bus_message_open_container(reply, 'a', "(ss)");
×
2152
        if (r < 0)
×
2153
                return r;
2154

2155
        UnitFileList *item;
×
2156
        HASHMAP_FOREACH(item, h) {
×
2157
                r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
×
2158
                if (r < 0)
×
2159
                        return r;
×
2160
        }
2161

2162
        r = sd_bus_message_close_container(reply);
×
2163
        if (r < 0)
×
2164
                return r;
2165

2166
        return sd_bus_send(NULL, reply, NULL);
×
2167
}
2168

2169
static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2170
        return list_unit_files_by_patterns(message, userdata, error, NULL, NULL);
×
2171
}
2172

2173
static int method_list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2174
        _cleanup_strv_free_ char **states = NULL;
×
2175
        _cleanup_strv_free_ char **patterns = NULL;
×
2176
        int r;
×
2177

2178
        r = sd_bus_message_read_strv(message, &states);
×
2179
        if (r < 0)
×
2180
                return r;
2181

2182
        r = sd_bus_message_read_strv(message, &patterns);
×
2183
        if (r < 0)
×
2184
                return r;
2185

2186
        return list_unit_files_by_patterns(message, userdata, error, states, patterns);
×
2187
}
2188

2189
static int method_get_unit_file_state(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1✔
2190
        Manager *m = ASSERT_PTR(userdata);
1✔
2191
        const char *name;
1✔
2192
        UnitFileState state;
1✔
2193
        int r;
1✔
2194

2195
        assert(message);
1✔
2196

2197
        /* Anyone can call this method */
2198

2199
        r = mac_selinux_access_check(message, "status", error);
1✔
2200
        if (r < 0)
1✔
2201
                return r;
1✔
2202

2203
        r = sd_bus_message_read(message, "s", &name);
1✔
2204
        if (r < 0)
1✔
2205
                return r;
2206

2207
        r = unit_file_get_state(m->runtime_scope, NULL, name, &state);
1✔
2208
        if (r < 0)
1✔
2209
                return r;
2210

2211
        return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1✔
2212
}
2213

2214
static int method_get_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2215
        _cleanup_free_ char *default_target = NULL;
×
2216
        Manager *m = ASSERT_PTR(userdata);
×
2217
        int r;
×
2218

2219
        assert(message);
×
2220

2221
        /* Anyone can call this method */
2222

2223
        r = mac_selinux_access_check(message, "status", error);
×
2224
        if (r < 0)
×
2225
                return r;
2226

2227
        r = unit_file_get_default(m->runtime_scope, NULL, &default_target);
×
2228
        if (r == -ERFKILL)
×
2229
                sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked.");
×
2230
        if (r < 0)
×
2231
                return r;
2232

2233
        return sd_bus_reply_method_return(message, "s", default_target);
×
2234
}
2235

2236
static int send_unit_files_changed(sd_bus *bus, void *userdata) {
×
2237
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
×
2238
        int r;
×
2239

2240
        assert(bus);
×
2241

2242
        r = sd_bus_message_new_signal(bus, &message,
×
2243
                                      "/org/freedesktop/systemd1",
2244
                                      "org.freedesktop.systemd1.Manager",
2245
                                      "UnitFilesChanged");
2246
        if (r < 0)
×
2247
                return r;
2248

2249
        return sd_bus_send(bus, message, NULL);
×
2250
}
2251

2252
static void manager_unit_files_changed(Manager *m, const InstallChange *changes, size_t n_changes) {
×
2253
        int r;
×
2254

2255
        assert(m);
×
2256
        assert(changes || n_changes == 0);
×
2257

2258
        if (!install_changes_have_modification(changes, n_changes))
×
2259
                return;
2260

2261
        /* See comments for this variable in manager.h */
2262
        m->unit_file_state_outdated = true;
×
2263

2264
        r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
×
2265
        if (r < 0)
×
2266
                log_debug_errno(r, "Failed to send UnitFilesChanged signal, ignoring: %m");
×
2267
}
2268

2269
static int install_error(
×
2270
                sd_bus_error *error,
2271
                int c,
2272
                InstallChange *changes,
2273
                size_t n_changes) {
2274

2275
        int r;
×
2276

2277
        /* Create an error reply, using the error information from changes[] if possible, and fall back to
2278
         * generating an error from error code c. The error message only describes the first error. */
2279

2280
        assert(changes || n_changes == 0);
×
2281

2282
        CLEANUP_ARRAY(changes, n_changes, install_changes_free);
×
2283

2284
        FOREACH_ARRAY(i, changes, n_changes) {
×
2285
                _cleanup_free_ char *err_message = NULL;
×
2286
                const char *bus_error;
×
2287

2288
                if (i->type >= 0)
×
2289
                        continue;
×
2290

2291
                r = install_change_dump_error(i, &err_message, &bus_error);
×
2292
                if (r == -ENOMEM)
×
2293
                        return r;
2294
                if (r < 0)
×
2295
                        return sd_bus_error_set_errnof(error, r, "File %s: %m", i->path);
×
2296

2297
                return sd_bus_error_set(error, bus_error, err_message);
×
2298
        }
2299

2300
        return c < 0 ? c : -EINVAL;
×
2301
}
2302

2303
static int reply_install_changes_and_free(
×
2304
                Manager *m,
2305
                sd_bus_message *message,
2306
                int carries_install_info,
2307
                InstallChange *changes,
2308
                size_t n_changes,
2309
                sd_bus_error *error) {
2310

2311
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
×
2312
        bool bad = false, good = false;
×
2313
        int r;
×
2314

2315
        CLEANUP_ARRAY(changes, n_changes, install_changes_free);
×
2316

2317
        r = sd_bus_message_new_method_return(message, &reply);
×
2318
        if (r < 0)
×
2319
                return r;
2320

2321
        if (carries_install_info >= 0) {
×
2322
                r = sd_bus_message_append(reply, "b", carries_install_info);
×
2323
                if (r < 0)
×
2324
                        return r;
2325
        }
2326

2327
        r = sd_bus_message_open_container(reply, 'a', "(sss)");
×
2328
        if (r < 0)
×
2329
                return r;
2330

2331
        FOREACH_ARRAY(i, changes, n_changes) {
×
2332
                if (i->type < 0) {
×
2333
                        bad = true;
×
2334
                        continue;
×
2335
                }
2336

2337
                r = sd_bus_message_append(
×
2338
                                reply, "(sss)",
2339
                                install_change_type_to_string(i->type),
2340
                                i->path,
2341
                                i->source);
2342
                if (r < 0)
×
2343
                        return r;
2344

2345
                good = true;
2346
        }
2347

2348
        /* If there was a failed change, and no successful change, then return the first failure as proper
2349
         * method call error. */
2350
        if (bad && !good)
×
2351
                return install_error(error, 0, TAKE_PTR(changes), n_changes);
×
2352

2353
        r = sd_bus_message_close_container(reply);
×
2354
        if (r < 0)
×
2355
                return r;
2356

2357
        return sd_bus_send(NULL, reply, NULL);
×
2358
}
2359

2360
static int method_enable_unit_files_generic(
×
2361
                sd_bus_message *message,
2362
                Manager *m,
2363
                int (*call)(RuntimeScope scope, UnitFileFlags flags, const char *root_dir, char * const *files, InstallChange **changes, size_t *n_changes),
2364
                bool carries_install_info,
2365
                sd_bus_error *error) {
2366

2367
        _cleanup_strv_free_ char **l = NULL;
×
2368
        InstallChange *changes = NULL;
×
2369
        size_t n_changes = 0;
×
2370
        UnitFileFlags flags;
×
2371
        int r;
×
2372

2373
        assert(message);
×
2374
        assert(m);
×
2375

2376
        r = sd_bus_message_read_strv(message, &l);
×
2377
        if (r < 0)
×
2378
                return r;
2379

2380
        if (sd_bus_message_is_method_call(message, NULL, "EnableUnitFilesWithFlags")) {
×
2381
                uint64_t raw_flags;
×
2382

2383
                r = sd_bus_message_read(message, "t", &raw_flags);
×
2384
                if (r < 0)
×
2385
                        return r;
×
2386
                if ((raw_flags & ~_UNIT_FILE_FLAGS_MASK_PUBLIC) != 0)
×
2387
                        return -EINVAL;
2388
                flags = raw_flags;
×
2389
        } else {
2390
                int runtime, force;
×
2391

2392
                r = sd_bus_message_read(message, "bb", &runtime, &force);
×
2393
                if (r < 0)
×
2394
                        return r;
×
2395
                flags = unit_file_bools_to_flags(runtime, force);
×
2396
        }
2397

2398
        r = bus_verify_manage_unit_files_async(m, message, error);
×
2399
        if (r < 0)
×
2400
                return r;
2401
        if (r == 0)
×
2402
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2403

2404
        r = call(m->runtime_scope, flags, NULL, l, &changes, &n_changes);
×
2405
        manager_unit_files_changed(m, changes, n_changes);
×
2406
        if (r < 0)
×
2407
                return install_error(error, r, changes, n_changes);
×
2408

2409
        return reply_install_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes, error);
×
2410
}
2411

2412
static int method_enable_unit_files_with_flags(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2413
        return method_enable_unit_files_generic(message, userdata, unit_file_enable, /* carries_install_info = */ true, error);
×
2414
}
2415

2416
static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2417
        return method_enable_unit_files_generic(message, userdata, unit_file_enable, /* carries_install_info = */ true, error);
×
2418
}
2419

2420
static int method_reenable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2421
        return method_enable_unit_files_generic(message, userdata, unit_file_reenable, /* carries_install_info = */ true, error);
×
2422
}
2423

2424
static int method_link_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2425
        return method_enable_unit_files_generic(message, userdata, unit_file_link, /* carries_install_info = */ false, error);
×
2426
}
2427

2428
static int unit_file_preset_without_mode(RuntimeScope scope, UnitFileFlags flags, const char *root_dir, char * const *files, InstallChange **changes, size_t *n_changes) {
×
2429
        return unit_file_preset(scope, flags, root_dir, files, UNIT_FILE_PRESET_FULL, changes, n_changes);
×
2430
}
2431

2432
static int method_preset_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2433
        return method_enable_unit_files_generic(message, userdata, unit_file_preset_without_mode, /* carries_install_info = */ true, error);
×
2434
}
2435

2436
static int method_mask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2437
        return method_enable_unit_files_generic(message, userdata, unit_file_mask, /* carries_install_info = */ false, error);
×
2438
}
2439

2440
static int method_preset_unit_files_with_mode(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2441

2442
        _cleanup_strv_free_ char **l = NULL;
×
2443
        InstallChange *changes = NULL;
×
2444
        size_t n_changes = 0;
×
2445
        Manager *m = ASSERT_PTR(userdata);
×
2446
        UnitFilePresetMode preset_mode;
×
2447
        int runtime, force, r;
×
2448
        UnitFileFlags flags;
×
2449
        const char *mode;
×
2450

2451
        assert(message);
×
2452

2453
        r = sd_bus_message_read_strv(message, &l);
×
2454
        if (r < 0)
×
2455
                return r;
2456

2457
        r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
×
2458
        if (r < 0)
×
2459
                return r;
2460

2461
        flags = unit_file_bools_to_flags(runtime, force);
×
2462

2463
        if (isempty(mode))
×
2464
                preset_mode = UNIT_FILE_PRESET_FULL;
2465
        else {
2466
                preset_mode = unit_file_preset_mode_from_string(mode);
×
2467
                if (preset_mode < 0)
×
2468
                        return -EINVAL;
2469
        }
2470

2471
        r = bus_verify_manage_unit_files_async(m, message, error);
×
2472
        if (r < 0)
×
2473
                return r;
2474
        if (r == 0)
×
2475
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2476

2477
        r = unit_file_preset(m->runtime_scope, flags, NULL, l, preset_mode, &changes, &n_changes);
×
2478
        manager_unit_files_changed(m, changes, n_changes);
×
2479
        if (r < 0)
×
2480
                return install_error(error, r, changes, n_changes);
×
2481

2482
        return reply_install_changes_and_free(m, message, r, changes, n_changes, error);
×
2483
}
2484

2485
static int method_disable_unit_files_generic(
×
2486
                sd_bus_message *message,
2487
                Manager *m,
2488
                int (*call)(RuntimeScope scope, UnitFileFlags flags, const char *root_dir, char * const *files, InstallChange **changes, size_t *n_changes),
2489
                bool carries_install_info,
2490
                sd_bus_error *error) {
2491

2492
        _cleanup_strv_free_ char **l = NULL;
×
2493
        InstallChange *changes = NULL;
×
2494
        UnitFileFlags flags;
×
2495
        size_t n_changes = 0;
×
2496
        int r;
×
2497

2498
        assert(message);
×
2499
        assert(m);
×
2500

2501
        r = sd_bus_message_read_strv(message, &l);
×
2502
        if (r < 0)
×
2503
                return r;
2504

2505
        if (sd_bus_message_is_method_call(message, NULL, "DisableUnitFilesWithFlags") ||
×
2506
            sd_bus_message_is_method_call(message, NULL, "DisableUnitFilesWithFlagsAndInstallInfo")) {
×
2507
                uint64_t raw_flags;
×
2508

2509
                r = sd_bus_message_read(message, "t", &raw_flags);
×
2510
                if (r < 0)
×
2511
                        return r;
×
2512
                if ((raw_flags & ~_UNIT_FILE_FLAGS_MASK_PUBLIC) != 0 ||
×
2513
                                FLAGS_SET(raw_flags, UNIT_FILE_FORCE))
×
2514
                        return -EINVAL;
2515
                flags = raw_flags;
×
2516
        } else {
2517
                int runtime;
×
2518

2519
                r = sd_bus_message_read(message, "b", &runtime);
×
2520
                if (r < 0)
×
2521
                        return r;
×
2522
                flags = unit_file_bools_to_flags(runtime, false);
×
2523
        }
2524

2525
        r = bus_verify_manage_unit_files_async(m, message, error);
×
2526
        if (r < 0)
×
2527
                return r;
2528
        if (r == 0)
×
2529
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2530

2531
        r = call(m->runtime_scope, flags, NULL, l, &changes, &n_changes);
×
2532
        manager_unit_files_changed(m, changes, n_changes);
×
2533
        if (r < 0)
×
2534
                return install_error(error, r, changes, n_changes);
×
2535

2536
        return reply_install_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes, error);
×
2537
}
2538

2539
static int method_disable_unit_files_with_flags(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2540
        return method_disable_unit_files_generic(message, userdata, unit_file_disable, /* carries_install_info = */ false, error);
×
2541
}
2542

2543
static int method_disable_unit_files_with_flags_and_install_info(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2544
        return method_disable_unit_files_generic(message, userdata, unit_file_disable, /* carries_install_info = */ true, error);
×
2545
}
2546

2547
static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2548
        return method_disable_unit_files_generic(message, userdata, unit_file_disable, /* carries_install_info = */ false, error);
×
2549
}
2550

2551
static int method_unmask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2552
        return method_disable_unit_files_generic(message, userdata, unit_file_unmask, /* carries_install_info = */ false, error);
×
2553
}
2554

2555
static int method_revert_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2556
        _cleanup_strv_free_ char **l = NULL;
×
2557
        InstallChange *changes = NULL;
×
2558
        size_t n_changes = 0;
×
2559
        Manager *m = ASSERT_PTR(userdata);
×
2560
        int r;
×
2561

2562
        assert(message);
×
2563

2564
        r = sd_bus_message_read_strv(message, &l);
×
2565
        if (r < 0)
×
2566
                return r;
2567

2568
        r = bus_verify_manage_unit_files_async(m, message, error);
×
2569
        if (r < 0)
×
2570
                return r;
2571
        if (r == 0)
×
2572
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2573

2574
        r = unit_file_revert(m->runtime_scope, NULL, l, &changes, &n_changes);
×
2575
        manager_unit_files_changed(m, changes, n_changes);
×
2576
        if (r < 0)
×
2577
                return install_error(error, r, changes, n_changes);
×
2578

2579
        return reply_install_changes_and_free(m, message, -1, changes, n_changes, error);
×
2580
}
2581

2582
static int method_set_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2583
        InstallChange *changes = NULL;
×
2584
        size_t n_changes = 0;
×
2585
        Manager *m = ASSERT_PTR(userdata);
×
2586
        const char *name;
×
2587
        int force, r;
×
2588

2589
        assert(message);
×
2590

2591
        r = mac_selinux_access_check(message, "enable", error);
×
2592
        if (r < 0)
×
2593
                return r;
×
2594

2595
        r = sd_bus_message_read(message, "sb", &name, &force);
×
2596
        if (r < 0)
×
2597
                return r;
2598

2599
        r = bus_verify_manage_unit_files_async(m, message, error);
×
2600
        if (r < 0)
×
2601
                return r;
2602
        if (r == 0)
×
2603
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2604

2605
        r = unit_file_set_default(m->runtime_scope, force ? UNIT_FILE_FORCE : 0, NULL, name, &changes, &n_changes);
×
2606
        manager_unit_files_changed(m, changes, n_changes);
×
2607
        if (r < 0)
×
2608
                return install_error(error, r, changes, n_changes);
×
2609

2610
        return reply_install_changes_and_free(m, message, -1, changes, n_changes, error);
×
2611
}
2612

2613
static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2614
        InstallChange *changes = NULL;
×
2615
        size_t n_changes = 0;
×
2616
        Manager *m = ASSERT_PTR(userdata);
×
2617
        UnitFilePresetMode preset_mode;
×
2618
        const char *mode;
×
2619
        UnitFileFlags flags;
×
2620
        int force, runtime, r;
×
2621

2622
        assert(message);
×
2623

2624
        r = mac_selinux_access_check(message, "enable", error);
×
2625
        if (r < 0)
×
2626
                return r;
×
2627

2628
        r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
×
2629
        if (r < 0)
×
2630
                return r;
2631

2632
        flags = unit_file_bools_to_flags(runtime, force);
×
2633

2634
        if (isempty(mode))
×
2635
                preset_mode = UNIT_FILE_PRESET_FULL;
2636
        else {
2637
                preset_mode = unit_file_preset_mode_from_string(mode);
×
2638
                if (preset_mode < 0)
×
2639
                        return -EINVAL;
2640
        }
2641

2642
        r = bus_verify_manage_unit_files_async(m, message, error);
×
2643
        if (r < 0)
×
2644
                return r;
2645
        if (r == 0)
×
2646
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2647

2648
        r = unit_file_preset_all(m->runtime_scope, flags, NULL, preset_mode, &changes, &n_changes);
×
2649
        manager_unit_files_changed(m, changes, n_changes);
×
2650
        if (r < 0)
×
2651
                return install_error(error, r, changes, n_changes);
×
2652

2653
        return reply_install_changes_and_free(m, message, -1, changes, n_changes, error);
×
2654
}
2655

2656
static int method_add_dependency_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2657
        _cleanup_strv_free_ char **l = NULL;
×
2658
        Manager *m = ASSERT_PTR(userdata);
×
2659
        InstallChange *changes = NULL;
×
2660
        size_t n_changes = 0;
×
2661
        int runtime, force, r;
×
2662
        char *target, *type;
×
2663
        UnitDependency dep;
×
2664
        UnitFileFlags flags;
×
2665

2666
        assert(message);
×
2667

2668
        r = bus_verify_manage_unit_files_async(m, message, error);
×
2669
        if (r < 0)
×
2670
                return r;
2671
        if (r == 0)
×
2672
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2673

2674
        r = sd_bus_message_read_strv(message, &l);
×
2675
        if (r < 0)
×
2676
                return r;
2677

2678
        r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
×
2679
        if (r < 0)
×
2680
                return r;
2681

2682
        flags = unit_file_bools_to_flags(runtime, force);
×
2683

2684
        dep = unit_dependency_from_string(type);
×
2685
        if (dep < 0 || !IN_SET(dep, UNIT_WANTS, UNIT_REQUIRES))
×
2686
                return -EINVAL;
2687

2688
        r = unit_file_add_dependency(m->runtime_scope, flags, NULL, l, target, dep, &changes, &n_changes);
×
2689
        manager_unit_files_changed(m, changes, n_changes);
×
2690
        if (r < 0)
×
2691
                return install_error(error, r, changes, n_changes);
×
2692

2693
        return reply_install_changes_and_free(m, message, -1, changes, n_changes, error);
×
2694
}
2695

2696
static int method_get_unit_file_links(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2697
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
×
2698
        Manager *m = ASSERT_PTR(userdata);
×
2699
        InstallChange *changes = NULL;
×
2700
        size_t n_changes = 0, i;
×
2701
        const char *name;
×
2702
        int runtime, r;
×
2703

2704
        CLEANUP_ARRAY(changes, n_changes, install_changes_free);
×
2705

2706
        r = sd_bus_message_read(message, "sb", &name, &runtime);
×
2707
        if (r < 0)
×
2708
                return r;
2709

2710
        r = sd_bus_message_new_method_return(message, &reply);
×
2711
        if (r < 0)
×
2712
                return r;
2713

2714
        r = sd_bus_message_open_container(reply, SD_BUS_TYPE_ARRAY, "s");
×
2715
        if (r < 0)
×
2716
                return r;
2717

2718
        r = unit_file_disable(m->runtime_scope,
×
2719
                              UNIT_FILE_DRY_RUN | (runtime ? UNIT_FILE_RUNTIME : 0),
×
2720
                              NULL, STRV_MAKE(name), &changes, &n_changes);
×
2721
        if (r < 0)
×
2722
                return log_error_errno(r, "Failed to get file links for %s: %m", name);
×
2723

2724
        for (i = 0; i < n_changes; i++)
×
2725
                if (changes[i].type == INSTALL_CHANGE_UNLINK) {
×
2726
                        r = sd_bus_message_append(reply, "s", changes[i].path);
×
2727
                        if (r < 0)
×
2728
                                return r;
2729
                }
2730

2731
        r = sd_bus_message_close_container(reply);
×
2732
        if (r < 0)
×
2733
                return r;
2734

2735
        return sd_bus_send(NULL, reply, NULL);
×
2736
}
2737

2738
static int method_get_job_waiting(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2739
        Manager *m = ASSERT_PTR(userdata);
×
2740
        uint32_t id;
×
2741
        Job *j;
×
2742
        int r;
×
2743

2744
        assert(message);
×
2745

2746
        r = sd_bus_message_read(message, "u", &id);
×
2747
        if (r < 0)
×
2748
                return r;
×
2749

2750
        j = manager_get_job(m, id);
×
2751
        if (!j)
×
2752
                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
×
2753

2754
        return bus_job_method_get_waiting_jobs(message, j, error);
×
2755
}
2756

2757
static int method_abandon_scope(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2✔
2758
        Manager *m = ASSERT_PTR(userdata);
2✔
2759
        const char *name;
2✔
2760
        Unit *u;
2✔
2761
        int r;
2✔
2762

2763
        assert(message);
2✔
2764

2765
        r = sd_bus_message_read(message, "s", &name);
2✔
2766
        if (r < 0)
2✔
2767
                return r;
2✔
2768

2769
        r = bus_get_unit_by_name(m, message, name, &u, error);
2✔
2770
        if (r < 0)
2✔
2771
                return r;
2772

2773
        if (u->type != UNIT_SCOPE)
2✔
2774
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
2775
                                         "Unit '%s' is not a scope unit, refusing.", name);
2776

2777
        return bus_scope_method_abandon(message, u, error);
2✔
2778
}
2779

2780
static int method_set_show_status(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2781
        Manager *m = ASSERT_PTR(userdata);
×
2782
        ShowStatus mode = _SHOW_STATUS_INVALID;
×
2783
        const char *t;
×
2784
        int r;
×
2785

2786
        assert(message);
×
2787

2788
        r = mac_selinux_access_check(message, "reload", error);
×
2789
        if (r < 0)
×
2790
                return r;
×
2791

2792
        r = bus_verify_set_environment_async(m, message, error);
×
2793
        if (r < 0)
×
2794
                return r;
2795
        if (r == 0)
×
2796
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2797

2798
        r = sd_bus_message_read(message, "s", &t);
×
2799
        if (r < 0)
×
2800
                return r;
2801

2802
        if (!isempty(t)) {
×
2803
                mode = show_status_from_string(t);
×
2804
                if (mode < 0)
×
2805
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
2806
                                                 "Invalid show status '%s'", t);
2807
        }
2808

2809
        manager_override_show_status(m, mode, "bus");
×
2810

2811
        return sd_bus_reply_method_return(message, NULL);
×
2812
}
2813

2814
static int method_dump_unit_descriptor_store(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2815
        return method_generic_unit_operation(message, userdata, error, bus_service_method_dump_file_descriptor_store, 0);
×
2816
}
2817

2818
static int method_start_aux_scope(sd_bus_message *message, void *userdata, sd_bus_error *error) {
×
2819
        return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "StartAuxiliaryScope() method has been removed.");
×
2820
}
2821

2822
const sd_bus_vtable bus_manager_vtable[] = {
2823
        SD_BUS_VTABLE_START(0),
2824

2825
        SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2826
        SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2827
        SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2828
        SD_BUS_PROPERTY("ConfidentialVirtualization", "s", property_get_confidential_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2829
        SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2830
        SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2831
        BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_FIRMWARE]), SD_BUS_VTABLE_PROPERTY_CONST),
2832
        BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_LOADER]), SD_BUS_VTABLE_PROPERTY_CONST),
2833
        BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_KERNEL]), SD_BUS_VTABLE_PROPERTY_CONST),
2834
        BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD]), SD_BUS_VTABLE_PROPERTY_CONST),
2835
        BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_USERSPACE]), SD_BUS_VTABLE_PROPERTY_CONST),
2836
        BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2837
        BUS_PROPERTY_DUAL_TIMESTAMP("ShutdownStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_SHUTDOWN_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2838
        BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_SECURITY_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2839
        BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_SECURITY_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2840
        BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2841
        BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2842
        BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2843
        BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2844
        BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD]), SD_BUS_VTABLE_PROPERTY_CONST),
2845
        BUS_PROPERTY_DUAL_TIMESTAMP("InitRDSecurityStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_SECURITY_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2846
        BUS_PROPERTY_DUAL_TIMESTAMP("InitRDSecurityFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2847
        BUS_PROPERTY_DUAL_TIMESTAMP("InitRDGeneratorsStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_GENERATORS_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2848
        BUS_PROPERTY_DUAL_TIMESTAMP("InitRDGeneratorsFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_GENERATORS_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2849
        BUS_PROPERTY_DUAL_TIMESTAMP("InitRDUnitsLoadStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2850
        BUS_PROPERTY_DUAL_TIMESTAMP("InitRDUnitsLoadFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2851
        SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", bus_property_get_log_level, property_set_log_level, 0, 0),
2852
        SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", bus_property_get_log_target, property_set_log_target, 0, 0),
2853
        SD_BUS_PROPERTY("NNames", "u", property_get_hashmap_size, offsetof(Manager, units), 0),
2854
        SD_BUS_PROPERTY("NFailedUnits", "u", property_get_set_size, offsetof(Manager, failed_units), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2855
        SD_BUS_PROPERTY("NJobs", "u", property_get_hashmap_size, offsetof(Manager, jobs), 0),
2856
        SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
2857
        SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
2858
        SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
2859
        SD_BUS_PROPERTY("Environment", "as", property_get_environment, 0, 0),
2860
        SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
2861
        SD_BUS_PROPERTY("ShowStatus", "b", property_get_show_status, 0, 0),
2862
        SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.search_path), SD_BUS_VTABLE_PROPERTY_CONST),
2863
        SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, defaults.std_output), SD_BUS_VTABLE_PROPERTY_CONST),
2864
        SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, defaults.std_error), SD_BUS_VTABLE_PROPERTY_CONST),
2865
        SD_BUS_PROPERTY("WatchdogDevice", "s", property_get_watchdog_device, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2866
        SD_BUS_PROPERTY("WatchdogLastPingTimestamp", "t", property_get_watchdog_last_ping_realtime, 0, 0),
2867
        SD_BUS_PROPERTY("WatchdogLastPingTimestampMonotonic", "t", property_get_watchdog_last_ping_monotonic, 0, 0),
2868
        SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", property_get_runtime_watchdog, property_set_runtime_watchdog, 0, 0),
2869
        SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogPreUSec", "t", property_get_pretimeout_watchdog, property_set_pretimeout_watchdog, 0, 0),
2870
        SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogPreGovernor", "s", property_get_pretimeout_watchdog_governor, property_set_pretimeout_watchdog_governor, 0, 0),
2871
        SD_BUS_WRITABLE_PROPERTY("RebootWatchdogUSec", "t", property_get_reboot_watchdog, property_set_reboot_watchdog, 0, 0),
2872
        /* The following item is an obsolete alias */
2873
        SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", property_get_reboot_watchdog, property_set_reboot_watchdog, 0, SD_BUS_VTABLE_HIDDEN),
2874
        SD_BUS_WRITABLE_PROPERTY("KExecWatchdogUSec", "t", property_get_kexec_watchdog, property_set_kexec_watchdog, 0, 0),
2875
        SD_BUS_WRITABLE_PROPERTY("ServiceWatchdogs", "b", bus_property_get_bool, bus_property_set_bool, offsetof(Manager, service_watchdogs), 0),
2876
        SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
2877
        SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
2878
        SD_BUS_PROPERTY("ExitCode", "y", NULL, offsetof(Manager, return_value), 0),
2879
        SD_BUS_PROPERTY("DefaultTimerAccuracyUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.timer_accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2880
        SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2881
        SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2882
        SD_BUS_PROPERTY("DefaultTimeoutAbortUSec", "t", property_get_default_timeout_abort_usec, 0, 0),
2883
        SD_BUS_PROPERTY("DefaultDeviceTimeoutUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.device_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2884
        SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2885
        SD_BUS_PROPERTY("DefaultStartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
2886
        /* The following two items are obsolete alias */
2887
        SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, defaults.start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
2888
        SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, defaults.start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
2889
        SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, defaults.start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
2890
        SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, defaults.cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
2891
        SD_BUS_PROPERTY("DefaultIOAccounting", "b", bus_property_get_bool, offsetof(Manager, defaults.io_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
2892
        SD_BUS_PROPERTY("DefaultIPAccounting", "b", bus_property_get_bool, offsetof(Manager, defaults.ip_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
2893
        SD_BUS_PROPERTY("DefaultMemoryAccounting", "b", bus_property_get_bool, offsetof(Manager, defaults.memory_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
2894
        SD_BUS_PROPERTY("DefaultTasksAccounting", "b", bus_property_get_bool, offsetof(Manager, defaults.tasks_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
2895
        SD_BUS_PROPERTY("DefaultLimitCPU", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
2896
        SD_BUS_PROPERTY("DefaultLimitCPUSoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
2897
        SD_BUS_PROPERTY("DefaultLimitFSIZE", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
2898
        SD_BUS_PROPERTY("DefaultLimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
2899
        SD_BUS_PROPERTY("DefaultLimitDATA", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
2900
        SD_BUS_PROPERTY("DefaultLimitDATASoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
2901
        SD_BUS_PROPERTY("DefaultLimitSTACK", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
2902
        SD_BUS_PROPERTY("DefaultLimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
2903
        SD_BUS_PROPERTY("DefaultLimitCORE", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
2904
        SD_BUS_PROPERTY("DefaultLimitCORESoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
2905
        SD_BUS_PROPERTY("DefaultLimitRSS", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
2906
        SD_BUS_PROPERTY("DefaultLimitRSSSoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
2907
        SD_BUS_PROPERTY("DefaultLimitNOFILE", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
2908
        SD_BUS_PROPERTY("DefaultLimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
2909
        SD_BUS_PROPERTY("DefaultLimitAS", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
2910
        SD_BUS_PROPERTY("DefaultLimitASSoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
2911
        SD_BUS_PROPERTY("DefaultLimitNPROC", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
2912
        SD_BUS_PROPERTY("DefaultLimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
2913
        SD_BUS_PROPERTY("DefaultLimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
2914
        SD_BUS_PROPERTY("DefaultLimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
2915
        SD_BUS_PROPERTY("DefaultLimitLOCKS", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
2916
        SD_BUS_PROPERTY("DefaultLimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
2917
        SD_BUS_PROPERTY("DefaultLimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
2918
        SD_BUS_PROPERTY("DefaultLimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
2919
        SD_BUS_PROPERTY("DefaultLimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
2920
        SD_BUS_PROPERTY("DefaultLimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
2921
        SD_BUS_PROPERTY("DefaultLimitNICE", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
2922
        SD_BUS_PROPERTY("DefaultLimitNICESoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
2923
        SD_BUS_PROPERTY("DefaultLimitRTPRIO", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
2924
        SD_BUS_PROPERTY("DefaultLimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
2925
        SD_BUS_PROPERTY("DefaultLimitRTTIME", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
2926
        SD_BUS_PROPERTY("DefaultLimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
2927
        SD_BUS_PROPERTY("DefaultTasksMax", "t", bus_property_get_tasks_max, offsetof(Manager, defaults.tasks_max), 0),
2928
        SD_BUS_PROPERTY("DefaultMemoryPressureThresholdUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.memory_pressure_threshold_usec), 0),
2929
        SD_BUS_PROPERTY("DefaultMemoryPressureWatch", "s", bus_property_get_cgroup_pressure_watch, offsetof(Manager, defaults.memory_pressure_watch), 0),
2930
        SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2931
        SD_BUS_PROPERTY("DefaultOOMPolicy", "s", bus_property_get_oom_policy, offsetof(Manager, defaults.oom_policy), SD_BUS_VTABLE_PROPERTY_CONST),
2932
        SD_BUS_PROPERTY("DefaultOOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2933
        SD_BUS_PROPERTY("CtrlAltDelBurstAction", "s", bus_property_get_emergency_action, offsetof(Manager, cad_burst_action), SD_BUS_VTABLE_PROPERTY_CONST),
2934
        SD_BUS_PROPERTY("SoftRebootsCount", "u", bus_property_get_unsigned, offsetof(Manager, soft_reboots_count), SD_BUS_VTABLE_PROPERTY_CONST),
2935
        /* deprecated cgroup v1 property */
2936
        SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool_false, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_DEPRECATED|SD_BUS_VTABLE_HIDDEN),
2937

2938
        SD_BUS_METHOD_WITH_ARGS("GetUnit",
2939
                                SD_BUS_ARGS("s", name),
2940
                                SD_BUS_RESULT("o", unit),
2941
                                method_get_unit,
2942
                                SD_BUS_VTABLE_UNPRIVILEGED),
2943
        SD_BUS_METHOD_WITH_ARGS("GetUnitByPID",
2944
                                SD_BUS_ARGS("u", pid),
2945
                                SD_BUS_RESULT("o", unit),
2946
                                method_get_unit_by_pid,
2947
                                SD_BUS_VTABLE_UNPRIVILEGED),
2948
        SD_BUS_METHOD_WITH_ARGS("GetUnitByInvocationID",
2949
                                SD_BUS_ARGS("ay", invocation_id),
2950
                                SD_BUS_RESULT("o", unit),
2951
                                method_get_unit_by_invocation_id,
2952
                                SD_BUS_VTABLE_UNPRIVILEGED),
2953
        SD_BUS_METHOD_WITH_ARGS("GetUnitByControlGroup",
2954
                                SD_BUS_ARGS("s", cgroup),
2955
                                SD_BUS_RESULT("o", unit),
2956
                                method_get_unit_by_control_group,
2957
                                SD_BUS_VTABLE_UNPRIVILEGED),
2958
        SD_BUS_METHOD_WITH_ARGS("GetUnitByPIDFD",
2959
                                SD_BUS_ARGS("h", pidfd),
2960
                                SD_BUS_RESULT("o", unit, "s", unit_id, "ay", invocation_id),
2961
                                method_get_unit_by_pidfd,
2962
                                SD_BUS_VTABLE_UNPRIVILEGED),
2963
        SD_BUS_METHOD_WITH_ARGS("LoadUnit",
2964
                                SD_BUS_ARGS("s", name),
2965
                                SD_BUS_RESULT("o", unit),
2966
                                method_load_unit,
2967
                                SD_BUS_VTABLE_UNPRIVILEGED),
2968
        SD_BUS_METHOD_WITH_ARGS("StartUnit",
2969
                                SD_BUS_ARGS("s", name, "s", mode),
2970
                                SD_BUS_RESULT("o", job),
2971
                                method_start_unit,
2972
                                SD_BUS_VTABLE_UNPRIVILEGED),
2973
        SD_BUS_METHOD_WITH_ARGS("StartUnitWithFlags",
2974
                                SD_BUS_ARGS("s", name, "s", mode, "t", flags),
2975
                                SD_BUS_RESULT("o", job),
2976
                                method_start_unit,
2977
                                SD_BUS_VTABLE_UNPRIVILEGED),
2978
        SD_BUS_METHOD_WITH_ARGS("StartUnitReplace",
2979
                                SD_BUS_ARGS("s", old_unit, "s", new_unit, "s", mode),
2980
                                SD_BUS_RESULT("o", job),
2981
                                method_start_unit_replace,
2982
                                SD_BUS_VTABLE_UNPRIVILEGED),
2983
        SD_BUS_METHOD_WITH_ARGS("StopUnit",
2984
                                SD_BUS_ARGS("s", name, "s", mode),
2985
                                SD_BUS_RESULT("o", job),
2986
                                method_stop_unit,
2987
                                SD_BUS_VTABLE_UNPRIVILEGED),
2988
        SD_BUS_METHOD_WITH_ARGS("ReloadUnit",
2989
                                SD_BUS_ARGS("s", name, "s", mode),
2990
                                SD_BUS_RESULT("o", job),
2991
                                method_reload_unit,
2992
                                SD_BUS_VTABLE_UNPRIVILEGED),
2993
        SD_BUS_METHOD_WITH_ARGS("RestartUnit",
2994
                                SD_BUS_ARGS("s", name, "s", mode),
2995
                                SD_BUS_RESULT("o", job),
2996
                                method_restart_unit,
2997
                                SD_BUS_VTABLE_UNPRIVILEGED),
2998
        SD_BUS_METHOD_WITH_ARGS("TryRestartUnit",
2999
                                SD_BUS_ARGS("s", name, "s", mode),
3000
                                SD_BUS_RESULT("o", job),
3001
                                method_try_restart_unit,
3002
                                SD_BUS_VTABLE_UNPRIVILEGED),
3003
        SD_BUS_METHOD_WITH_ARGS("ReloadOrRestartUnit",
3004
                                SD_BUS_ARGS("s", name, "s", mode),
3005
                                SD_BUS_RESULT("o", job),
3006
                                method_reload_or_restart_unit,
3007
                                SD_BUS_VTABLE_UNPRIVILEGED),
3008
        SD_BUS_METHOD_WITH_ARGS("ReloadOrTryRestartUnit",
3009
                                SD_BUS_ARGS("s", name, "s", mode),
3010
                                SD_BUS_RESULT("o", job),
3011
                                method_reload_or_try_restart_unit,
3012
                                SD_BUS_VTABLE_UNPRIVILEGED),
3013
        SD_BUS_METHOD_WITH_ARGS("EnqueueUnitJob",
3014
                                SD_BUS_ARGS("s", name, "s", job_type, "s", job_mode),
3015
                                SD_BUS_RESULT("u", job_id, "o", job_path, "s", unit_id, "o", unit_path, "s", job_type, "a(uosos)", affected_jobs),
3016
                                method_enqueue_unit_job,
3017
                                SD_BUS_VTABLE_UNPRIVILEGED),
3018
        SD_BUS_METHOD_WITH_ARGS("KillUnit",
3019
                                SD_BUS_ARGS("s", name, "s", whom, "i", signal),
3020
                                SD_BUS_NO_RESULT,
3021
                                method_kill_unit,
3022
                                SD_BUS_VTABLE_UNPRIVILEGED),
3023
        SD_BUS_METHOD_WITH_ARGS("QueueSignalUnit",
3024
                                SD_BUS_ARGS("s", name, "s", whom, "i", signal, "i", value),
3025
                                SD_BUS_NO_RESULT,
3026
                                method_kill_unit,
3027
                                SD_BUS_VTABLE_UNPRIVILEGED),
3028
        SD_BUS_METHOD_WITH_ARGS("CleanUnit",
3029
                                SD_BUS_ARGS("s", name, "as", mask),
3030
                                SD_BUS_NO_RESULT,
3031
                                method_clean_unit,
3032
                                SD_BUS_VTABLE_UNPRIVILEGED),
3033
        SD_BUS_METHOD_WITH_ARGS("FreezeUnit",
3034
                                SD_BUS_ARGS("s", name),
3035
                                SD_BUS_NO_RESULT,
3036
                                method_freeze_unit,
3037
                                SD_BUS_VTABLE_UNPRIVILEGED),
3038
        SD_BUS_METHOD_WITH_ARGS("ThawUnit",
3039
                                SD_BUS_ARGS("s", name),
3040
                                SD_BUS_NO_RESULT,
3041
                                method_thaw_unit,
3042
                                SD_BUS_VTABLE_UNPRIVILEGED),
3043
        SD_BUS_METHOD_WITH_ARGS("ResetFailedUnit",
3044
                                SD_BUS_ARGS("s", name),
3045
                                SD_BUS_NO_RESULT,
3046
                                method_reset_failed_unit,
3047
                                SD_BUS_VTABLE_UNPRIVILEGED),
3048
        SD_BUS_METHOD_WITH_ARGS("SetUnitProperties",
3049
                                SD_BUS_ARGS("s", name, "b", runtime, "a(sv)", properties),
3050
                                SD_BUS_NO_RESULT,
3051
                                method_set_unit_properties,
3052
                                SD_BUS_VTABLE_UNPRIVILEGED),
3053
        SD_BUS_METHOD_WITH_ARGS("BindMountUnit",
3054
                                SD_BUS_ARGS("s", name, "s", source, "s", destination, "b", read_only, "b", mkdir),
3055
                                SD_BUS_NO_RESULT,
3056
                                method_bind_mount_unit,
3057
                                SD_BUS_VTABLE_UNPRIVILEGED),
3058
        SD_BUS_METHOD_WITH_ARGS("MountImageUnit",
3059
                                SD_BUS_ARGS("s", name, "s", source, "s", destination, "b", read_only, "b", mkdir, "a(ss)", options),
3060
                                SD_BUS_NO_RESULT,
3061
                                method_mount_image_unit,
3062
                                SD_BUS_VTABLE_UNPRIVILEGED),
3063
        SD_BUS_METHOD_WITH_ARGS("RefUnit",
3064
                                SD_BUS_ARGS("s", name),
3065
                                SD_BUS_NO_RESULT,
3066
                                method_ref_unit,
3067
                                SD_BUS_VTABLE_UNPRIVILEGED),
3068
        SD_BUS_METHOD_WITH_ARGS("UnrefUnit",
3069
                                SD_BUS_ARGS("s", name),
3070
                                SD_BUS_NO_RESULT,
3071
                                method_unref_unit,
3072
                                SD_BUS_VTABLE_UNPRIVILEGED),
3073
        SD_BUS_METHOD_WITH_ARGS("StartTransientUnit",
3074
                                SD_BUS_ARGS("s", name, "s", mode, "a(sv)", properties, "a(sa(sv))", aux),
3075
                                SD_BUS_RESULT("o", job),
3076
                                method_start_transient_unit,
3077
                                SD_BUS_VTABLE_UNPRIVILEGED),
3078
        SD_BUS_METHOD_WITH_ARGS("GetUnitProcesses",
3079
                                SD_BUS_ARGS("s", name),
3080
                                SD_BUS_RESULT("a(sus)", processes),
3081
                                method_get_unit_processes,
3082
                                SD_BUS_VTABLE_UNPRIVILEGED),
3083
        SD_BUS_METHOD_WITH_ARGS("AttachProcessesToUnit",
3084
                                SD_BUS_ARGS("s", unit_name, "s", subcgroup, "au", pids),
3085
                                SD_BUS_NO_RESULT,
3086
                                method_attach_processes_to_unit,
3087
                                SD_BUS_VTABLE_UNPRIVILEGED),
3088
        SD_BUS_METHOD_WITH_ARGS("RemoveSubgroupFromUnit",
3089
                                SD_BUS_ARGS("s", unit_name, "s", subcgroup, "t", flags),
3090
                                SD_BUS_NO_RESULT,
3091
                                method_remove_subgroup_from_unit,
3092
                                SD_BUS_VTABLE_UNPRIVILEGED),
3093
        SD_BUS_METHOD_WITH_ARGS("AbandonScope",
3094
                                SD_BUS_ARGS("s", name),
3095
                                SD_BUS_NO_RESULT,
3096
                                method_abandon_scope,
3097
                                SD_BUS_VTABLE_UNPRIVILEGED),
3098
        SD_BUS_METHOD_WITH_ARGS("GetJob",
3099
                                SD_BUS_ARGS("u", id),
3100
                                SD_BUS_RESULT("o", job),
3101
                                method_get_job,
3102
                                SD_BUS_VTABLE_UNPRIVILEGED),
3103
        SD_BUS_METHOD_WITH_ARGS("GetJobAfter",
3104
                                SD_BUS_ARGS("u", id),
3105
                                SD_BUS_RESULT("a(usssoo)", jobs),
3106
                                method_get_job_waiting,
3107
                                SD_BUS_VTABLE_UNPRIVILEGED),
3108
        SD_BUS_METHOD_WITH_ARGS("GetJobBefore",
3109
                                SD_BUS_ARGS("u", id),
3110
                                SD_BUS_RESULT("a(usssoo)", jobs),
3111
                                method_get_job_waiting,
3112
                                SD_BUS_VTABLE_UNPRIVILEGED),
3113
        SD_BUS_METHOD_WITH_ARGS("CancelJob",
3114
                                SD_BUS_ARGS("u", id),
3115
                                SD_BUS_NO_RESULT,
3116
                                method_cancel_job,
3117
                                SD_BUS_VTABLE_UNPRIVILEGED),
3118
        SD_BUS_METHOD("ClearJobs",
3119
                      NULL,
3120
                      NULL,
3121
                      method_clear_jobs,
3122
                      SD_BUS_VTABLE_UNPRIVILEGED),
3123
        SD_BUS_METHOD("ResetFailed",
3124
                      NULL,
3125
                      NULL,
3126
                      method_reset_failed,
3127
                      SD_BUS_VTABLE_UNPRIVILEGED),
3128
        SD_BUS_METHOD_WITH_ARGS("SetShowStatus",
3129
                                SD_BUS_ARGS("s", mode),
3130
                                SD_BUS_NO_RESULT,
3131
                                method_set_show_status,
3132
                                SD_BUS_VTABLE_UNPRIVILEGED),
3133
        SD_BUS_METHOD_WITH_ARGS("ListUnits",
3134
                                SD_BUS_NO_ARGS,
3135
                                SD_BUS_RESULT("a(ssssssouso)", units),
3136
                                method_list_units,
3137
                                SD_BUS_VTABLE_UNPRIVILEGED),
3138
        SD_BUS_METHOD_WITH_ARGS("ListUnitsFiltered",
3139
                                SD_BUS_ARGS("as", states),
3140
                                SD_BUS_RESULT("a(ssssssouso)", units),
3141
                                method_list_units_filtered,
3142
                                SD_BUS_VTABLE_UNPRIVILEGED),
3143
        SD_BUS_METHOD_WITH_ARGS("ListUnitsByPatterns",
3144
                                SD_BUS_ARGS("as", states, "as", patterns),
3145
                                SD_BUS_RESULT("a(ssssssouso)", units),
3146
                                method_list_units_by_patterns,
3147
                                SD_BUS_VTABLE_UNPRIVILEGED),
3148
        SD_BUS_METHOD_WITH_ARGS("ListUnitsByNames",
3149
                                SD_BUS_ARGS("as", names),
3150
                                SD_BUS_RESULT("a(ssssssouso)", units),
3151
                                method_list_units_by_names,
3152
                                SD_BUS_VTABLE_UNPRIVILEGED),
3153
        SD_BUS_METHOD_WITH_ARGS("ListJobs",
3154
                                SD_BUS_NO_ARGS,
3155
                                SD_BUS_RESULT("a(usssoo)", jobs),
3156
                                method_list_jobs,
3157
                                SD_BUS_VTABLE_UNPRIVILEGED),
3158
        SD_BUS_METHOD("Subscribe",
3159
                      NULL,
3160
                      NULL,
3161
                      method_subscribe,
3162
                      SD_BUS_VTABLE_UNPRIVILEGED),
3163
        SD_BUS_METHOD("Unsubscribe",
3164
                      NULL,
3165
                      NULL,
3166
                      method_unsubscribe,
3167
                      SD_BUS_VTABLE_UNPRIVILEGED),
3168
        SD_BUS_METHOD_WITH_ARGS("Dump",
3169
                                SD_BUS_NO_ARGS,
3170
                                SD_BUS_RESULT("s", output),
3171
                                method_dump,
3172
                                SD_BUS_VTABLE_UNPRIVILEGED),
3173
        SD_BUS_METHOD_WITH_ARGS("DumpUnitsMatchingPatterns",
3174
                                SD_BUS_ARGS("as", patterns),
3175
                                SD_BUS_RESULT("s", output),
3176
                                method_dump_units_matching_patterns,
3177
                                SD_BUS_VTABLE_UNPRIVILEGED),
3178
        SD_BUS_METHOD_WITH_ARGS("DumpByFileDescriptor",
3179
                                SD_BUS_NO_ARGS,
3180
                                SD_BUS_RESULT("h", fd),
3181
                                method_dump_by_fd,
3182
                                SD_BUS_VTABLE_UNPRIVILEGED),
3183
        SD_BUS_METHOD_WITH_ARGS("DumpUnitsMatchingPatternsByFileDescriptor",
3184
                                SD_BUS_ARGS("as", patterns),
3185
                                SD_BUS_RESULT("h", fd),
3186
                                method_dump_units_matching_patterns_by_fd,
3187
                                SD_BUS_VTABLE_UNPRIVILEGED),
3188
        SD_BUS_METHOD_WITH_ARGS("CreateSnapshot",
3189
                                SD_BUS_ARGS("s", name, "b", cleanup),
3190
                                SD_BUS_RESULT("o", unit),
3191
                                method_refuse_snapshot,
3192
                                SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_HIDDEN),
3193
        SD_BUS_METHOD_WITH_ARGS("RemoveSnapshot",
3194
                                SD_BUS_ARGS("s", name),
3195
                                SD_BUS_NO_RESULT,
3196
                                method_refuse_snapshot,
3197
                                SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_HIDDEN),
3198
        SD_BUS_METHOD("Reload",
3199
                      NULL,
3200
                      NULL,
3201
                      method_reload,
3202
                      SD_BUS_VTABLE_UNPRIVILEGED),
3203
        SD_BUS_METHOD("Reexecute",
3204
                      NULL,
3205
                      NULL,
3206
                      method_reexecute,
3207
                      SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_METHOD_NO_REPLY),
3208
        SD_BUS_METHOD("Exit",
3209
                      NULL,
3210
                      NULL,
3211
                      method_exit,
3212
                      0),
3213
        SD_BUS_METHOD("Reboot",
3214
                      NULL,
3215
                      NULL,
3216
                      method_reboot,
3217
                      SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
3218
        SD_BUS_METHOD_WITH_ARGS("SoftReboot",
3219
                                SD_BUS_ARGS("s", new_root),
3220
                                SD_BUS_NO_RESULT,
3221
                                method_soft_reboot,
3222
                                SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
3223
        SD_BUS_METHOD("PowerOff",
3224
                      NULL,
3225
                      NULL,
3226
                      method_poweroff,
3227
                      SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
3228
        SD_BUS_METHOD("Halt",
3229
                      NULL,
3230
                      NULL,
3231
                      method_halt,
3232
                      SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
3233
        SD_BUS_METHOD("KExec",
3234
                      NULL,
3235
                      NULL,
3236
                      method_kexec,
3237
                      SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
3238
        SD_BUS_METHOD_WITH_ARGS("SwitchRoot",
3239
                                SD_BUS_ARGS("s", new_root, "s", init),
3240
                                SD_BUS_NO_RESULT,
3241
                                method_switch_root,
3242
                                SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
3243
        SD_BUS_METHOD_WITH_ARGS("SetEnvironment",
3244
                                SD_BUS_ARGS("as", assignments),
3245
                                SD_BUS_NO_RESULT,
3246
                                method_set_environment,
3247
                                SD_BUS_VTABLE_UNPRIVILEGED),
3248
        SD_BUS_METHOD_WITH_ARGS("UnsetEnvironment",
3249
                                SD_BUS_ARGS("as", names),
3250
                                SD_BUS_NO_RESULT,
3251
                                method_unset_environment,
3252
                                SD_BUS_VTABLE_UNPRIVILEGED),
3253
        SD_BUS_METHOD_WITH_ARGS("UnsetAndSetEnvironment",
3254
                                SD_BUS_ARGS("as", names, "as", assignments),
3255
                                SD_BUS_NO_RESULT,
3256
                                method_unset_and_set_environment,
3257
                                SD_BUS_VTABLE_UNPRIVILEGED),
3258
        SD_BUS_METHOD_WITH_ARGS("EnqueueMarkedJobs",
3259
                                SD_BUS_NO_ARGS,
3260
                                SD_BUS_RESULT("ao", jobs),
3261
                                method_enqueue_marked_jobs,
3262
                                SD_BUS_VTABLE_UNPRIVILEGED),
3263
        SD_BUS_METHOD_WITH_ARGS("ListUnitFiles",
3264
                                SD_BUS_NO_ARGS,
3265
                                SD_BUS_RESULT("a(ss)", unit_files),
3266
                                method_list_unit_files,
3267
                                SD_BUS_VTABLE_UNPRIVILEGED),
3268
        SD_BUS_METHOD_WITH_ARGS("ListUnitFilesByPatterns",
3269
                                SD_BUS_ARGS("as", states, "as", patterns),
3270
                                SD_BUS_RESULT("a(ss)", unit_files),
3271
                                method_list_unit_files_by_patterns,
3272
                                SD_BUS_VTABLE_UNPRIVILEGED),
3273
        SD_BUS_METHOD_WITH_ARGS("GetUnitFileState",
3274
                                SD_BUS_ARGS("s", file),
3275
                                SD_BUS_RESULT("s", state),
3276
                                method_get_unit_file_state,
3277
                                SD_BUS_VTABLE_UNPRIVILEGED),
3278
        SD_BUS_METHOD_WITH_ARGS("EnableUnitFiles",
3279
                                SD_BUS_ARGS("as", files, "b", runtime, "b", force),
3280
                                SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes),
3281
                                method_enable_unit_files,
3282
                                SD_BUS_VTABLE_UNPRIVILEGED),
3283
        SD_BUS_METHOD_WITH_ARGS("DisableUnitFiles",
3284
                                SD_BUS_ARGS("as", files, "b", runtime),
3285
                                SD_BUS_RESULT("a(sss)", changes),
3286
                                method_disable_unit_files,
3287
                                SD_BUS_VTABLE_UNPRIVILEGED),
3288
        SD_BUS_METHOD_WITH_ARGS("EnableUnitFilesWithFlags",
3289
                                SD_BUS_ARGS("as", files, "t", flags),
3290
                                SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes),
3291
                                method_enable_unit_files_with_flags,
3292
                                SD_BUS_VTABLE_UNPRIVILEGED),
3293
        SD_BUS_METHOD_WITH_ARGS("DisableUnitFilesWithFlags",
3294
                                SD_BUS_ARGS("as", files, "t", flags),
3295
                                SD_BUS_RESULT("a(sss)", changes),
3296
                                method_disable_unit_files_with_flags,
3297
                                SD_BUS_VTABLE_UNPRIVILEGED),
3298
        SD_BUS_METHOD_WITH_ARGS("DisableUnitFilesWithFlagsAndInstallInfo",
3299
                                SD_BUS_ARGS("as", files, "t", flags),
3300
                                SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes),
3301
                                method_disable_unit_files_with_flags_and_install_info,
3302
                                SD_BUS_VTABLE_UNPRIVILEGED),
3303
        SD_BUS_METHOD_WITH_ARGS("ReenableUnitFiles",
3304
                                SD_BUS_ARGS("as", files, "b", runtime, "b", force),
3305
                                SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes),
3306
                                method_reenable_unit_files,
3307
                                SD_BUS_VTABLE_UNPRIVILEGED),
3308
        SD_BUS_METHOD_WITH_ARGS("LinkUnitFiles",
3309
                                SD_BUS_ARGS("as", files, "b", runtime, "b", force),
3310
                                SD_BUS_RESULT("a(sss)", changes),
3311
                                method_link_unit_files,
3312
                                SD_BUS_VTABLE_UNPRIVILEGED),
3313
        SD_BUS_METHOD_WITH_ARGS("PresetUnitFiles",
3314
                                SD_BUS_ARGS("as", files, "b", runtime, "b", force),
3315
                                SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes),
3316
                                method_preset_unit_files,
3317
                                SD_BUS_VTABLE_UNPRIVILEGED),
3318
        SD_BUS_METHOD_WITH_ARGS("PresetUnitFilesWithMode",
3319
                                SD_BUS_ARGS("as", files, "s", mode, "b", runtime, "b", force),
3320
                                SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes),
3321
                                method_preset_unit_files_with_mode,
3322
                                SD_BUS_VTABLE_UNPRIVILEGED),
3323
        SD_BUS_METHOD_WITH_ARGS("MaskUnitFiles",
3324
                                SD_BUS_ARGS("as", files, "b", runtime, "b", force),
3325
                                SD_BUS_RESULT("a(sss)", changes),
3326
                                method_mask_unit_files,
3327
                                SD_BUS_VTABLE_UNPRIVILEGED),
3328
        SD_BUS_METHOD_WITH_ARGS("UnmaskUnitFiles",
3329
                                SD_BUS_ARGS("as", files, "b", runtime),
3330
                                SD_BUS_RESULT("a(sss)", changes),
3331
                                method_unmask_unit_files,
3332
                                SD_BUS_VTABLE_UNPRIVILEGED),
3333
        SD_BUS_METHOD_WITH_ARGS("RevertUnitFiles",
3334
                                SD_BUS_ARGS("as", files),
3335
                                SD_BUS_RESULT("a(sss)", changes),
3336
                                method_revert_unit_files,
3337
                                SD_BUS_VTABLE_UNPRIVILEGED),
3338
        SD_BUS_METHOD_WITH_ARGS("SetDefaultTarget",
3339
                                SD_BUS_ARGS("s", name, "b", force),
3340
                                SD_BUS_RESULT("a(sss)", changes),
3341
                                method_set_default_target,
3342
                                SD_BUS_VTABLE_UNPRIVILEGED),
3343
        SD_BUS_METHOD_WITH_ARGS("GetDefaultTarget",
3344
                                SD_BUS_NO_ARGS,
3345
                                SD_BUS_RESULT("s", name),
3346
                                method_get_default_target,
3347
                                SD_BUS_VTABLE_UNPRIVILEGED),
3348
        SD_BUS_METHOD_WITH_ARGS("PresetAllUnitFiles",
3349
                                SD_BUS_ARGS("s", mode, "b", runtime, "b", force),
3350
                                SD_BUS_RESULT("a(sss)", changes),
3351
                                method_preset_all_unit_files,
3352
                                SD_BUS_VTABLE_UNPRIVILEGED),
3353
        SD_BUS_METHOD_WITH_ARGS("AddDependencyUnitFiles",
3354
                                SD_BUS_ARGS("as", files, "s", target, "s", type, "b", runtime, "b", force),
3355
                                SD_BUS_RESULT("a(sss)", changes),
3356
                                method_add_dependency_unit_files,
3357
                                SD_BUS_VTABLE_UNPRIVILEGED),
3358
        SD_BUS_METHOD_WITH_ARGS("GetUnitFileLinks",
3359
                                SD_BUS_ARGS("s", name, "b", runtime),
3360
                                SD_BUS_RESULT("as", links),
3361
                                method_get_unit_file_links,
3362
                                SD_BUS_VTABLE_UNPRIVILEGED),
3363
        SD_BUS_METHOD_WITH_ARGS("SetExitCode",
3364
                                SD_BUS_ARGS("y", number),
3365
                                SD_BUS_NO_RESULT,
3366
                                method_set_exit_code,
3367
                                SD_BUS_VTABLE_UNPRIVILEGED),
3368
        SD_BUS_METHOD_WITH_ARGS("LookupDynamicUserByName",
3369
                                SD_BUS_ARGS("s", name),
3370
                                SD_BUS_RESULT("u", uid),
3371
                                method_lookup_dynamic_user_by_name,
3372
                                SD_BUS_VTABLE_UNPRIVILEGED),
3373
        SD_BUS_METHOD_WITH_ARGS("LookupDynamicUserByUID",
3374
                                SD_BUS_ARGS("u", uid),
3375
                                SD_BUS_RESULT("s", name),
3376
                                method_lookup_dynamic_user_by_uid,
3377
                                SD_BUS_VTABLE_UNPRIVILEGED),
3378
        SD_BUS_METHOD_WITH_ARGS("GetDynamicUsers",
3379
                                SD_BUS_NO_ARGS,
3380
                                SD_BUS_RESULT("a(us)", users),
3381
                                method_get_dynamic_users,
3382
                                SD_BUS_VTABLE_UNPRIVILEGED),
3383
        SD_BUS_METHOD_WITH_ARGS("DumpUnitFileDescriptorStore",
3384
                                SD_BUS_ARGS("s", name),
3385
                                SD_BUS_RESULT("a(suuutuusu)", entries),
3386
                                method_dump_unit_descriptor_store,
3387
                                SD_BUS_VTABLE_UNPRIVILEGED),
3388
        SD_BUS_METHOD_WITH_ARGS("StartAuxiliaryScope",
3389
                                SD_BUS_ARGS("s", name, "ah", pidfds, "t", flags, "a(sv)", properties),
3390
                                SD_BUS_RESULT("o", job),
3391
                                method_start_aux_scope,
3392
                                SD_BUS_VTABLE_DEPRECATED|SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_HIDDEN),
3393

3394
        SD_BUS_SIGNAL_WITH_ARGS("UnitNew",
3395
                                SD_BUS_ARGS("s", id, "o", unit),
3396
                                0),
3397
        SD_BUS_SIGNAL_WITH_ARGS("UnitRemoved",
3398
                                SD_BUS_ARGS("s", id, "o", unit),
3399
                                0),
3400
        SD_BUS_SIGNAL_WITH_ARGS("JobNew",
3401
                                SD_BUS_ARGS("u", id, "o", job, "s", unit),
3402
                                0),
3403
        SD_BUS_SIGNAL_WITH_ARGS("JobRemoved",
3404
                                SD_BUS_ARGS("u", id, "o", job, "s", unit, "s", result),
3405
                                0),
3406
        SD_BUS_SIGNAL_WITH_ARGS("StartupFinished",
3407
                                SD_BUS_ARGS("t", firmware, "t", loader, "t", kernel, "t", initrd, "t", userspace, "t", total),
3408
                                0),
3409
        SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
3410
        SD_BUS_SIGNAL_WITH_ARGS("Reloading",
3411
                                SD_BUS_ARGS("b", active),
3412
                                0),
3413

3414
        SD_BUS_VTABLE_END
3415
};
3416

3417
const sd_bus_vtable bus_manager_log_control_vtable[] = {
3418
        SD_BUS_VTABLE_START(0),
3419

3420
        /* We define a private version of this interface here, since we want slightly different
3421
         * implementations for the setters. We'll still use the generic getters however, and we share the
3422
         * setters with the implementations for the Manager interface above (which pre-dates the generic
3423
         * service API interface). */
3424

3425
        SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", bus_property_get_log_level, property_set_log_level, 0, 0),
3426
        SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", bus_property_get_log_target, property_set_log_target, 0, 0),
3427
        SD_BUS_PROPERTY("SyslogIdentifier", "s", bus_property_get_syslog_identifier, 0, 0),
3428

3429
        SD_BUS_VTABLE_END,
3430
};
3431

3432
static int send_finished(sd_bus *bus, void *userdata) {
×
3433
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
×
3434
        usec_t *times = ASSERT_PTR(userdata);
×
3435
        int r;
×
3436

3437
        assert(bus);
×
3438

3439
        r = sd_bus_message_new_signal(bus,
×
3440
                                      &message,
3441
                                      "/org/freedesktop/systemd1",
3442
                                      "org.freedesktop.systemd1.Manager",
3443
                                      "StartupFinished");
3444
        if (r < 0)
×
3445
                return r;
3446

3447
        r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
×
3448
        if (r < 0)
×
3449
                return r;
3450

3451
        return sd_bus_send(bus, message, NULL);
×
3452
}
3453

3454
void bus_manager_send_finished(
172✔
3455
                Manager *m,
3456
                usec_t firmware_usec,
3457
                usec_t loader_usec,
3458
                usec_t kernel_usec,
3459
                usec_t initrd_usec,
3460
                usec_t userspace_usec,
3461
                usec_t total_usec) {
3462

3463
        int r;
172✔
3464

3465
        assert(m);
172✔
3466

3467
        r = bus_foreach_bus(
344✔
3468
                        m,
3469
                        NULL,
3470
                        send_finished,
3471
                        (usec_t[6]) {
172✔
3472
                                firmware_usec,
3473
                                loader_usec,
3474
                                kernel_usec,
3475
                                initrd_usec,
3476
                                userspace_usec,
3477
                                total_usec
3478
                        });
3479
        if (r < 0)
172✔
3480
                log_debug_errno(r, "Failed to send finished signal: %m");
×
3481
}
172✔
3482

3483
static int send_reloading(sd_bus *bus, void *userdata) {
222✔
3484
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
222✔
3485
        int r;
222✔
3486

3487
        assert(bus);
222✔
3488

3489
        r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
222✔
3490
        if (r < 0)
222✔
3491
                return r;
3492

3493
        r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
222✔
3494
        if (r < 0)
222✔
3495
                return r;
3496

3497
        return sd_bus_send(bus, message, NULL);
222✔
3498
}
3499

3500
void bus_manager_send_reloading(Manager *m, bool active) {
130✔
3501
        int r;
130✔
3502

3503
        assert(m);
130✔
3504

3505
        r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
130✔
3506
        if (r < 0)
130✔
3507
                log_debug_errno(r, "Failed to send reloading signal: %m");
9✔
3508
}
130✔
3509

3510
static int send_changed_signal(sd_bus *bus, void *userdata) {
220✔
3511
        assert(bus);
220✔
3512

3513
        return sd_bus_emit_properties_changed_strv(bus,
220✔
3514
                                                   "/org/freedesktop/systemd1",
3515
                                                   "org.freedesktop.systemd1.Manager",
3516
                                                   NULL);
3517
}
3518

3519
void bus_manager_send_change_signal(Manager *m) {
500✔
3520
        int r;
500✔
3521

3522
        assert(m);
500✔
3523

3524
        r = bus_foreach_bus(m, NULL, send_changed_signal, NULL);
500✔
3525
        if (r < 0)
500✔
3526
                log_debug_errno(r, "Failed to send manager change signal: %m");
×
3527
}
500✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc