summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2015-04-19 12:58:44 +0200
committerAndy Wingo <wingo@pobox.com>2015-04-19 12:58:44 +0200
commit9ad77dd132a43bcb42ec391d0f7acee8935bde6c (patch)
tree69e8bf0854e20635cf3ed72b0334bbcbb48c401f /src/core
parentf48dd74a8d39b6074f820f904953f5cece03b9b0 (diff)
Remove src/core
Diffstat (limited to 'src/core')
-rw-r--r--src/core/.gitignore2
l---------src/core/Makefile1
-rw-r--r--src/core/audit-fd.c73
-rw-r--r--src/core/audit-fd.h25
-rw-r--r--src/core/automount.c878
-rw-r--r--src/core/automount.h69
-rw-r--r--src/core/bus-endpoint.c134
-rw-r--r--src/core/bus-endpoint.h44
-rw-r--r--src/core/bus-policy.c174
-rw-r--r--src/core/bus-policy.h66
-rw-r--r--src/core/busname.c1066
-rw-r--r--src/core/busname.h84
-rw-r--r--src/core/cgroup.c1136
-rw-r--r--src/core/cgroup.h134
-rw-r--r--src/core/dbus-automount.c34
-rw-r--r--src/core/dbus-automount.h25
-rw-r--r--src/core/dbus-busname.c38
-rw-r--r--src/core/dbus-busname.h25
-rw-r--r--src/core/dbus-cgroup.c680
-rw-r--r--src/core/dbus-cgroup.h29
-rw-r--r--src/core/dbus-device.c30
-rw-r--r--src/core/dbus-device.h26
-rw-r--r--src/core/dbus-execute.c1006
-rw-r--r--src/core/dbus-execute.h46
-rw-r--r--src/core/dbus-job.c193
-rw-r--r--src/core/dbus-job.h32
-rw-r--r--src/core/dbus-kill.c123
-rw-r--r--src/core/dbus-kill.h30
-rw-r--r--src/core/dbus-manager.c2157
-rw-r--r--src/core/dbus-manager.h30
-rw-r--r--src/core/dbus-mount.c212
-rw-r--r--src/core/dbus-mount.h30
-rw-r--r--src/core/dbus-path.c87
-rw-r--r--src/core/dbus-path.h26
-rw-r--r--src/core/dbus-scope.c231
-rw-r--r--src/core/dbus-scope.h32
-rw-r--r--src/core/dbus-service.c266
-rw-r--r--src/core/dbus-service.h30
-rw-r--r--src/core/dbus-slice.c54
-rw-r--r--src/core/dbus-slice.h30
-rw-r--r--src/core/dbus-snapshot.c56
-rw-r--r--src/core/dbus-snapshot.h28
-rw-r--r--src/core/dbus-socket.c159
-rw-r--r--src/core/dbus-socket.h30
-rw-r--r--src/core/dbus-swap.c116
-rw-r--r--src/core/dbus-swap.h31
-rw-r--r--src/core/dbus-target.c28
-rw-r--r--src/core/dbus-target.h25
-rw-r--r--src/core/dbus-timer.c326
-rw-r--r--src/core/dbus-timer.h29
-rw-r--r--src/core/dbus-unit.c1109
-rw-r--r--src/core/dbus-unit.h39
-rw-r--r--src/core/dbus.c1214
-rw-r--r--src/core/dbus.h43
-rw-r--r--src/core/device.c813
-rw-r--r--src/core/device.h63
-rw-r--r--src/core/execute.c2912
-rw-r--r--src/core/execute.h267
-rw-r--r--src/core/failure-action.c139
-rw-r--r--src/core/failure-action.h43
-rw-r--r--src/core/hostname-setup.c88
-rw-r--r--src/core/hostname-setup.h24
-rw-r--r--src/core/ima-setup.c74
-rw-r--r--src/core/ima-setup.h26
-rw-r--r--src/core/job.c1238
-rw-r--r--src/core/job.h237
-rw-r--r--src/core/kill.c66
-rw-r--r--src/core/kill.h64
-rw-r--r--src/core/killall.c225
-rw-r--r--src/core/killall.h24
-rw-r--r--src/core/kmod-setup.c126
-rw-r--r--src/core/kmod-setup.h24
-rw-r--r--src/core/load-dropin.c82
-rw-r--r--src/core/load-dropin.h36
-rw-r--r--src/core/load-fragment-gperf.gperf.m4360
-rw-r--r--src/core/load-fragment.c3771
-rw-r--r--src/core/load-fragment.h116
-rw-r--r--src/core/locale-setup.c125
-rw-r--r--src/core/locale-setup.h24
-rw-r--r--src/core/loopback-setup.c91
-rw-r--r--src/core/loopback-setup.h24
-rw-r--r--src/core/machine-id-setup.c361
-rw-r--r--src/core/machine-id-setup.h25
-rw-r--r--src/core/macros.systemd.in109
-rw-r--r--src/core/main.c2036
-rw-r--r--src/core/manager.c3155
-rw-r--r--src/core/manager.h368
-rw-r--r--src/core/mount-setup.c399
-rw-r--r--src/core/mount-setup.h32
-rw-r--r--src/core/mount.c1947
-rw-r--r--src/core/mount.h132
-rw-r--r--src/core/namespace.c702
-rw-r--r--src/core/namespace.h65
-rw-r--r--src/core/org.freedesktop.systemd1.conf212
-rw-r--r--src/core/org.freedesktop.systemd1.policy.in.in70
-rw-r--r--src/core/org.freedesktop.systemd1.service11
-rw-r--r--src/core/path.c789
-rw-r--r--src/core/path.h106
-rw-r--r--src/core/scope.c561
-rw-r--r--src/core/scope.h71
-rw-r--r--src/core/selinux-access.c279
-rw-r--r--src/core/selinux-access.h50
-rw-r--r--src/core/selinux-setup.c123
-rw-r--r--src/core/selinux-setup.h26
-rw-r--r--src/core/service.c3212
-rw-r--r--src/core/service.h242
-rw-r--r--src/core/show-status.c42
-rw-r--r--src/core/show-status.h34
-rw-r--r--src/core/shutdown.c412
-rw-r--r--src/core/slice.c305
-rw-r--r--src/core/slice.h45
-rw-r--r--src/core/smack-setup.c167
-rw-r--r--src/core/smack-setup.h26
-rw-r--r--src/core/snapshot.c312
-rw-r--r--src/core/snapshot.h48
-rw-r--r--src/core/socket.c2740
-rw-r--r--src/core/socket.h194
-rw-r--r--src/core/swap.c1522
-rw-r--r--src/core/swap.h130
-rw-r--r--src/core/system.conf57
-rw-r--r--src/core/systemd.pc.in35
-rw-r--r--src/core/target.c236
-rw-r--r--src/core/target.h43
-rw-r--r--src/core/timer.c785
-rw-r--r--src/core/timer.h101
-rw-r--r--src/core/transaction.c1145
-rw-r--r--src/core/transaction.h54
-rw-r--r--src/core/umount.c594
-rw-r--r--src/core/umount.h30
-rw-r--r--src/core/unit-printf.c446
-rw-r--r--src/core/unit-printf.h28
-rw-r--r--src/core/unit.c3679
-rw-r--r--src/core/unit.h625
-rw-r--r--src/core/user.conf44
134 files changed, 0 insertions, 52665 deletions
diff --git a/src/core/.gitignore b/src/core/.gitignore
deleted file mode 100644
index f293bbdc9..000000000
--- a/src/core/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/macros.systemd
-/systemd.pc
diff --git a/src/core/Makefile b/src/core/Makefile
deleted file mode 120000
index d0b0e8e00..000000000
--- a/src/core/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile \ No newline at end of file
diff --git a/src/core/audit-fd.c b/src/core/audit-fd.c
deleted file mode 100644
index 5a18e263a..000000000
--- a/src/core/audit-fd.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-
-#include <errno.h>
-#include "audit-fd.h"
-
-#ifdef HAVE_AUDIT
-
-#include <stdbool.h>
-#include <libaudit.h>
-
-#include "log.h"
-#include "util.h"
-
-static bool initialized = false;
-static int audit_fd;
-
-int get_audit_fd(void) {
-
- if (!initialized) {
- audit_fd = audit_open();
-
- if (audit_fd < 0) {
- if (errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
- log_error_errno(errno, "Failed to connect to audit log: %m");
-
- audit_fd = errno ? -errno : -EINVAL;
- }
-
- initialized = true;
- }
-
- return audit_fd;
-}
-
-void close_audit_fd(void) {
-
- if (initialized && audit_fd >= 0)
- safe_close(audit_fd);
-
- initialized = true;
- audit_fd = -ECONNRESET;
-}
-
-#else
-
-int get_audit_fd(void) {
- return -EAFNOSUPPORT;
-}
-
-void close_audit_fd(void) {
-}
-
-#endif
diff --git a/src/core/audit-fd.h b/src/core/audit-fd.h
deleted file mode 100644
index 8b58289dc..000000000
--- a/src/core/audit-fd.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-int get_audit_fd(void);
-void close_audit_fd(void);
diff --git a/src/core/automount.c b/src/core/automount.c
deleted file mode 100644
index cec90cbb3..000000000
--- a/src/core/automount.c
+++ /dev/null
@@ -1,878 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <limits.h>
-#include <sys/mount.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/epoll.h>
-#include <sys/stat.h>
-#include <linux/auto_fs4.h>
-#include <linux/auto_dev-ioctl.h>
-
-#include "unit.h"
-#include "automount.h"
-#include "mount.h"
-#include "unit-name.h"
-#include "special.h"
-#include "label.h"
-#include "mkdir.h"
-#include "path-util.h"
-#include "dbus-automount.h"
-#include "bus-util.h"
-#include "bus-error.h"
-
-static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
- [AUTOMOUNT_DEAD] = UNIT_INACTIVE,
- [AUTOMOUNT_WAITING] = UNIT_ACTIVE,
- [AUTOMOUNT_RUNNING] = UNIT_ACTIVE,
- [AUTOMOUNT_FAILED] = UNIT_FAILED
-};
-
-static int open_dev_autofs(Manager *m);
-static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata);
-
-static void automount_init(Unit *u) {
- Automount *a = AUTOMOUNT(u);
-
- assert(u);
- assert(u->load_state == UNIT_STUB);
-
- a->pipe_fd = -1;
- a->directory_mode = 0755;
- UNIT(a)->ignore_on_isolate = true;
-}
-
-static void repeat_unmount(const char *path) {
- assert(path);
-
- for (;;) {
- /* If there are multiple mounts on a mount point, this
- * removes them all */
-
- if (umount2(path, MNT_DETACH) >= 0)
- continue;
-
- if (errno != EINVAL)
- log_error_errno(errno, "Failed to unmount: %m");
-
- break;
- }
-}
-
-static void unmount_autofs(Automount *a) {
- assert(a);
-
- if (a->pipe_fd < 0)
- return;
-
- automount_send_ready(a, -EHOSTDOWN);
-
- a->pipe_event_source = sd_event_source_unref(a->pipe_event_source);
- a->pipe_fd = safe_close(a->pipe_fd);
-
- /* If we reload/reexecute things we keep the mount point
- * around */
- if (a->where &&
- (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
- UNIT(a)->manager->exit_code != MANAGER_REEXECUTE))
- repeat_unmount(a->where);
-}
-
-static void automount_done(Unit *u) {
- Automount *a = AUTOMOUNT(u);
-
- assert(a);
-
- unmount_autofs(a);
-
- free(a->where);
- a->where = NULL;
-
- set_free(a->tokens);
- a->tokens = NULL;
-}
-
-static int automount_add_mount_links(Automount *a) {
- _cleanup_free_ char *parent = NULL;
- int r;
-
- assert(a);
-
- r = path_get_parent(a->where, &parent);
- if (r < 0)
- return r;
-
- return unit_require_mounts_for(UNIT(a), parent);
-}
-
-static int automount_add_default_dependencies(Automount *a) {
- int r;
-
- assert(a);
-
- if (UNIT(a)->manager->running_as != SYSTEMD_SYSTEM)
- return 0;
-
- r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-static int automount_verify(Automount *a) {
- bool b;
- _cleanup_free_ char *e = NULL;
- assert(a);
-
- if (UNIT(a)->load_state != UNIT_LOADED)
- return 0;
-
- if (path_equal(a->where, "/")) {
- log_unit_error(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
- return -EINVAL;
- }
-
- e = unit_name_from_path(a->where, ".automount");
- if (!e)
- return -ENOMEM;
-
- b = unit_has_name(UNIT(a), e);
-
- if (!b) {
- log_unit_error(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int automount_load(Unit *u) {
- Automount *a = AUTOMOUNT(u);
- int r;
-
- assert(u);
- assert(u->load_state == UNIT_STUB);
-
- /* Load a .automount file */
- r = unit_load_fragment_and_dropin_optional(u);
- if (r < 0)
- return r;
-
- if (u->load_state == UNIT_LOADED) {
- Unit *x;
-
- if (!a->where) {
- a->where = unit_name_to_path(u->id);
- if (!a->where)
- return -ENOMEM;
- }
-
- path_kill_slashes(a->where);
-
- r = unit_load_related_unit(u, ".mount", &x);
- if (r < 0)
- return r;
-
- r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
- if (r < 0)
- return r;
-
- r = automount_add_mount_links(a);
- if (r < 0)
- return r;
-
- if (UNIT(a)->default_dependencies) {
- r = automount_add_default_dependencies(a);
- if (r < 0)
- return r;
- }
- }
-
- return automount_verify(a);
-}
-
-static void automount_set_state(Automount *a, AutomountState state) {
- AutomountState old_state;
- assert(a);
-
- old_state = a->state;
- a->state = state;
-
- if (state != AUTOMOUNT_WAITING &&
- state != AUTOMOUNT_RUNNING)
- unmount_autofs(a);
-
- if (state != old_state)
- log_unit_debug(UNIT(a)->id,
- "%s changed %s -> %s",
- UNIT(a)->id,
- automount_state_to_string(old_state),
- automount_state_to_string(state));
-
- unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
-}
-
-static int automount_coldplug(Unit *u, Hashmap *deferred_work) {
- Automount *a = AUTOMOUNT(u);
- int r;
-
- assert(a);
- assert(a->state == AUTOMOUNT_DEAD);
-
- if (a->deserialized_state != a->state) {
-
- r = open_dev_autofs(u->manager);
- if (r < 0)
- return r;
-
- if (a->deserialized_state == AUTOMOUNT_WAITING ||
- a->deserialized_state == AUTOMOUNT_RUNNING) {
-
- assert(a->pipe_fd >= 0);
-
- r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
- if (r < 0)
- return r;
- }
-
- automount_set_state(a, a->deserialized_state);
- }
-
- return 0;
-}
-
-static void automount_dump(Unit *u, FILE *f, const char *prefix) {
- Automount *a = AUTOMOUNT(u);
-
- assert(a);
-
- fprintf(f,
- "%sAutomount State: %s\n"
- "%sResult: %s\n"
- "%sWhere: %s\n"
- "%sDirectoryMode: %04o\n",
- prefix, automount_state_to_string(a->state),
- prefix, automount_result_to_string(a->result),
- prefix, a->where,
- prefix, a->directory_mode);
-}
-
-static void automount_enter_dead(Automount *a, AutomountResult f) {
- assert(a);
-
- if (f != AUTOMOUNT_SUCCESS)
- a->result = f;
-
- automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
-}
-
-static int open_dev_autofs(Manager *m) {
- struct autofs_dev_ioctl param;
-
- assert(m);
-
- if (m->dev_autofs_fd >= 0)
- return m->dev_autofs_fd;
-
- label_fix("/dev/autofs", false, false);
-
- m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
- if (m->dev_autofs_fd < 0)
- return log_error_errno(errno, "Failed to open /dev/autofs: %m");
-
- init_autofs_dev_ioctl(&param);
- if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, &param) < 0) {
- m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
- return -errno;
- }
-
- log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
-
- return m->dev_autofs_fd;
-}
-
-static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
- struct autofs_dev_ioctl *param;
- size_t l;
-
- assert(dev_autofs_fd >= 0);
- assert(where);
-
- l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
- param = alloca(l);
-
- init_autofs_dev_ioctl(param);
- param->size = l;
- param->ioctlfd = -1;
- param->openmount.devid = devid;
- strcpy(param->path, where);
-
- if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0)
- return -errno;
-
- if (param->ioctlfd < 0)
- return -EIO;
-
- fd_cloexec(param->ioctlfd, true);
- return param->ioctlfd;
-}
-
-static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
- uint32_t major, minor;
- struct autofs_dev_ioctl param;
-
- assert(dev_autofs_fd >= 0);
- assert(ioctl_fd >= 0);
-
- init_autofs_dev_ioctl(&param);
- param.ioctlfd = ioctl_fd;
-
- if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, &param) < 0)
- return -errno;
-
- major = param.protover.version;
-
- init_autofs_dev_ioctl(&param);
- param.ioctlfd = ioctl_fd;
-
- if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, &param) < 0)
- return -errno;
-
- minor = param.protosubver.sub_version;
-
- log_debug("Autofs protocol version %i.%i", major, minor);
- return 0;
-}
-
-static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
- struct autofs_dev_ioctl param;
-
- assert(dev_autofs_fd >= 0);
- assert(ioctl_fd >= 0);
-
- init_autofs_dev_ioctl(&param);
- param.ioctlfd = ioctl_fd;
- param.timeout.timeout = sec;
-
- if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, &param) < 0)
- return -errno;
-
- return 0;
-}
-
-static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
- struct autofs_dev_ioctl param;
-
- assert(dev_autofs_fd >= 0);
- assert(ioctl_fd >= 0);
-
- init_autofs_dev_ioctl(&param);
- param.ioctlfd = ioctl_fd;
-
- if (status) {
- param.fail.token = token;
- param.fail.status = status;
- } else
- param.ready.token = token;
-
- if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, &param) < 0)
- return -errno;
-
- return 0;
-}
-
-int automount_send_ready(Automount *a, int status) {
- _cleanup_close_ int ioctl_fd = -1;
- unsigned token;
- int r;
-
- assert(a);
- assert(status <= 0);
-
- if (set_isempty(a->tokens))
- return 0;
-
- ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
- if (ioctl_fd < 0)
- return ioctl_fd;
-
- if (status)
- log_unit_debug_errno(UNIT(a)->id, status, "Sending failure: %m");
- else
- log_unit_debug(UNIT(a)->id, "Sending success.");
-
- r = 0;
-
- /* Autofs thankfully does not hand out 0 as a token */
- while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
- int k;
-
- /* Autofs fun fact II:
- *
- * if you pass a positive status code here, the kernel will
- * freeze! Yay! */
-
- k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
- ioctl_fd,
- token,
- status);
- if (k < 0)
- r = k;
- }
-
- return r;
-}
-
-static void automount_enter_waiting(Automount *a) {
- _cleanup_close_ int ioctl_fd = -1;
- int p[2] = { -1, -1 };
- char name[sizeof("systemd-")-1 + DECIMAL_STR_MAX(pid_t) + 1];
- char options[sizeof("fd=,pgrp=,minproto=5,maxproto=5,direct")-1
- + DECIMAL_STR_MAX(int) + DECIMAL_STR_MAX(gid_t) + 1];
- bool mounted = false;
- int r, dev_autofs_fd;
- struct stat st;
-
- assert(a);
- assert(a->pipe_fd < 0);
- assert(a->where);
-
- if (a->tokens)
- set_clear(a->tokens);
-
- dev_autofs_fd = open_dev_autofs(UNIT(a)->manager);
- if (dev_autofs_fd < 0) {
- r = dev_autofs_fd;
- goto fail;
- }
-
- /* We knowingly ignore the results of this call */
- mkdir_p_label(a->where, 0555);
-
- warn_if_dir_nonempty(a->meta.id, a->where);
-
- if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
- r = -errno;
- goto fail;
- }
-
- xsprintf(options, "fd=%i,pgrp="PID_FMT",minproto=5,maxproto=5,direct", p[1], getpgrp());
- xsprintf(name, "systemd-"PID_FMT, getpid());
- if (mount(name, a->where, "autofs", 0, options) < 0) {
- r = -errno;
- goto fail;
- }
-
- mounted = true;
-
- p[1] = safe_close(p[1]);
-
- if (stat(a->where, &st) < 0) {
- r = -errno;
- goto fail;
- }
-
- ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev);
- if (ioctl_fd < 0) {
- r = ioctl_fd;
- goto fail;
- }
-
- r = autofs_protocol(dev_autofs_fd, ioctl_fd);
- if (r < 0)
- goto fail;
-
- r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300);
- if (r < 0)
- goto fail;
-
- /* Autofs fun fact:
- *
- * Unless we close the ioctl fd here, for some weird reason
- * the direct mount will not receive events from the
- * kernel. */
-
- r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
- if (r < 0)
- goto fail;
-
- a->pipe_fd = p[0];
- a->dev_id = st.st_dev;
-
- automount_set_state(a, AUTOMOUNT_WAITING);
-
- return;
-
-fail:
- safe_close_pair(p);
-
- if (mounted)
- repeat_unmount(a->where);
-
- log_unit_error(UNIT(a)->id,
- "Failed to initialize automounter: %s", strerror(-r));
- automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
-}
-
-static void automount_enter_runnning(Automount *a) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- struct stat st;
- int r;
-
- assert(a);
-
- /* We don't take mount requests anymore if we are supposed to
- * shut down anyway */
- if (unit_stop_pending(UNIT(a))) {
- log_unit_debug(UNIT(a)->id,
- "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
- automount_send_ready(a, -EHOSTDOWN);
- return;
- }
-
- mkdir_p_label(a->where, a->directory_mode);
-
- /* Before we do anything, let's see if somebody is playing games with us? */
- if (lstat(a->where, &st) < 0) {
- log_unit_warning(UNIT(a)->id,
- "%s failed to stat automount point: %m", UNIT(a)->id);
- goto fail;
- }
-
- if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
- log_unit_info(UNIT(a)->id,
- "%s's automount point already active?", UNIT(a)->id);
- else {
- r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
- JOB_REPLACE, true, &error, NULL);
- if (r < 0) {
- log_unit_warning(UNIT(a)->id,
- "%s failed to queue mount startup job: %s",
- UNIT(a)->id, bus_error_message(&error, r));
- goto fail;
- }
- }
-
- automount_set_state(a, AUTOMOUNT_RUNNING);
- return;
-
-fail:
- automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
-}
-
-static int automount_start(Unit *u) {
- Automount *a = AUTOMOUNT(u);
-
- assert(a);
- assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
-
- if (path_is_mount_point(a->where, false)) {
- log_unit_error(u->id,
- "Path %s is already a mount point, refusing start for %s",
- a->where, u->id);
- return -EEXIST;
- }
-
- if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
- return -ENOENT;
-
- a->result = AUTOMOUNT_SUCCESS;
- automount_enter_waiting(a);
- return 1;
-}
-
-static int automount_stop(Unit *u) {
- Automount *a = AUTOMOUNT(u);
-
- assert(a);
- assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
-
- automount_enter_dead(a, AUTOMOUNT_SUCCESS);
- return 1;
-}
-
-static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
- Automount *a = AUTOMOUNT(u);
- void *p;
- Iterator i;
-
- assert(a);
- assert(f);
- assert(fds);
-
- unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
- unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
- unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
-
- SET_FOREACH(p, a->tokens, i)
- unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
-
- if (a->pipe_fd >= 0) {
- int copy;
-
- copy = fdset_put_dup(fds, a->pipe_fd);
- if (copy < 0)
- return copy;
-
- unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
- }
-
- return 0;
-}
-
-static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
- Automount *a = AUTOMOUNT(u);
- int r;
-
- assert(a);
- assert(fds);
-
- if (streq(key, "state")) {
- AutomountState state;
-
- state = automount_state_from_string(value);
- if (state < 0)
- log_unit_debug(u->id, "Failed to parse state value %s", value);
- else
- a->deserialized_state = state;
- } else if (streq(key, "result")) {
- AutomountResult f;
-
- f = automount_result_from_string(value);
- if (f < 0)
- log_unit_debug(u->id, "Failed to parse result value %s", value);
- else if (f != AUTOMOUNT_SUCCESS)
- a->result = f;
-
- } else if (streq(key, "dev-id")) {
- unsigned d;
-
- if (safe_atou(value, &d) < 0)
- log_unit_debug(u->id, "Failed to parse dev-id value %s", value);
- else
- a->dev_id = (unsigned) d;
- } else if (streq(key, "token")) {
- unsigned token;
-
- if (safe_atou(value, &token) < 0)
- log_unit_debug(u->id, "Failed to parse token value %s", value);
- else {
- if (!a->tokens)
- if (!(a->tokens = set_new(NULL)))
- return -ENOMEM;
-
- r = set_put(a->tokens, UINT_TO_PTR(token));
- if (r < 0)
- return r;
- }
- } else if (streq(key, "pipe-fd")) {
- int fd;
-
- if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
- log_unit_debug(u->id, "Failed to parse pipe-fd value %s", value);
- else {
- safe_close(a->pipe_fd);
- a->pipe_fd = fdset_remove(fds, fd);
- }
- } else
- log_unit_debug(u->id, "Unknown serialization key '%s'", key);
-
- return 0;
-}
-
-static UnitActiveState automount_active_state(Unit *u) {
- assert(u);
-
- return state_translation_table[AUTOMOUNT(u)->state];
-}
-
-static const char *automount_sub_state_to_string(Unit *u) {
- assert(u);
-
- return automount_state_to_string(AUTOMOUNT(u)->state);
-}
-
-static bool automount_check_gc(Unit *u) {
- assert(u);
-
- if (!UNIT_TRIGGER(u))
- return false;
-
- return UNIT_VTABLE(UNIT_TRIGGER(u))->check_gc(UNIT_TRIGGER(u));
-}
-
-static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) {
- union autofs_v5_packet_union packet;
- Automount *a = AUTOMOUNT(userdata);
- int r;
-
- assert(a);
- assert(fd == a->pipe_fd);
-
- if (events != EPOLLIN) {
- log_unit_error(UNIT(a)->id, "Got invalid poll event on pipe.");
- goto fail;
- }
-
- r = loop_read_exact(a->pipe_fd, &packet, sizeof(packet), true);
- if (r < 0) {
- log_unit_error_errno(UNIT(a)->id, r, "Invalid read from pipe: %m");
- goto fail;
- }
-
- switch (packet.hdr.type) {
-
- case autofs_ptype_missing_direct:
-
- if (packet.v5_packet.pid > 0) {
- _cleanup_free_ char *p = NULL;
-
- get_process_comm(packet.v5_packet.pid, &p);
- log_unit_info(UNIT(a)->id,
- "Got automount request for %s, triggered by %"PRIu32" (%s)",
- a->where, packet.v5_packet.pid, strna(p));
- } else
- log_unit_debug(UNIT(a)->id, "Got direct mount request on %s", a->where);
-
- r = set_ensure_allocated(&a->tokens, NULL);
- if (r < 0) {
- log_unit_error(UNIT(a)->id, "Failed to allocate token set.");
- goto fail;
- }
-
- r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
- if (r < 0) {
- log_unit_error_errno(UNIT(a)->id, r, "Failed to remember token: %m");
- goto fail;
- }
-
- automount_enter_runnning(a);
- break;
-
- default:
- log_unit_error(UNIT(a)->id, "Received unknown automount request %i", packet.hdr.type);
- break;
- }
-
- return 0;
-
-fail:
- automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
- return 0;
-}
-
-static void automount_shutdown(Manager *m) {
- assert(m);
-
- m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
-}
-
-static void automount_reset_failed(Unit *u) {
- Automount *a = AUTOMOUNT(u);
-
- assert(a);
-
- if (a->state == AUTOMOUNT_FAILED)
- automount_set_state(a, AUTOMOUNT_DEAD);
-
- a->result = AUTOMOUNT_SUCCESS;
-}
-
-static bool automount_supported(Manager *m) {
- static int supported = -1;
-
- assert(m);
-
- if (supported < 0)
- supported = access("/dev/autofs", F_OK) >= 0;
-
- return supported;
-}
-
-static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
- [AUTOMOUNT_DEAD] = "dead",
- [AUTOMOUNT_WAITING] = "waiting",
- [AUTOMOUNT_RUNNING] = "running",
- [AUTOMOUNT_FAILED] = "failed"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
-
-static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
- [AUTOMOUNT_SUCCESS] = "success",
- [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
-
-const UnitVTable automount_vtable = {
- .object_size = sizeof(Automount),
-
- .sections =
- "Unit\0"
- "Automount\0"
- "Install\0",
-
- .no_alias = true,
- .no_instances = true,
-
- .init = automount_init,
- .load = automount_load,
- .done = automount_done,
-
- .coldplug = automount_coldplug,
-
- .dump = automount_dump,
-
- .start = automount_start,
- .stop = automount_stop,
-
- .serialize = automount_serialize,
- .deserialize_item = automount_deserialize_item,
-
- .active_state = automount_active_state,
- .sub_state_to_string = automount_sub_state_to_string,
-
- .check_gc = automount_check_gc,
-
- .reset_failed = automount_reset_failed,
-
- .bus_interface = "org.freedesktop.systemd1.Automount",
- .bus_vtable = bus_automount_vtable,
-
- .shutdown = automount_shutdown,
- .supported = automount_supported,
-
- .status_message_formats = {
- .finished_start_job = {
- [JOB_DONE] = "Set up automount %s.",
- [JOB_FAILED] = "Failed to set up automount %s.",
- [JOB_DEPENDENCY] = "Dependency failed for %s.",
- },
- .finished_stop_job = {
- [JOB_DONE] = "Unset automount %s.",
- [JOB_FAILED] = "Failed to unset automount %s.",
- },
- },
-};
diff --git a/src/core/automount.h b/src/core/automount.h
deleted file mode 100644
index 60f552238..000000000
--- a/src/core/automount.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-typedef struct Automount Automount;
-
-#include "unit.h"
-
-typedef enum AutomountState {
- AUTOMOUNT_DEAD,
- AUTOMOUNT_WAITING,
- AUTOMOUNT_RUNNING,
- AUTOMOUNT_FAILED,
- _AUTOMOUNT_STATE_MAX,
- _AUTOMOUNT_STATE_INVALID = -1
-} AutomountState;
-
-typedef enum AutomountResult {
- AUTOMOUNT_SUCCESS,
- AUTOMOUNT_FAILURE_RESOURCES,
- _AUTOMOUNT_RESULT_MAX,
- _AUTOMOUNT_RESULT_INVALID = -1
-} AutomountResult;
-
-struct Automount {
- Unit meta;
-
- AutomountState state, deserialized_state;
-
- char *where;
-
- int pipe_fd;
- sd_event_source *pipe_event_source;
- mode_t directory_mode;
- dev_t dev_id;
-
- Set *tokens;
-
- AutomountResult result;
-};
-
-extern const UnitVTable automount_vtable;
-
-int automount_send_ready(Automount *a, int status);
-
-const char* automount_state_to_string(AutomountState i) _const_;
-AutomountState automount_state_from_string(const char *s) _pure_;
-
-const char* automount_result_to_string(AutomountResult i) _const_;
-AutomountResult automount_result_from_string(const char *s) _pure_;
diff --git a/src/core/bus-endpoint.c b/src/core/bus-endpoint.c
deleted file mode 100644
index 0c4b3e7c8..000000000
--- a/src/core/bus-endpoint.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Daniel Mack
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-
-#include "kdbus.h"
-#include "bus-kernel.h"
-#include "bus-policy.h"
-#include "bus-endpoint.h"
-
-int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) {
-
- struct kdbus_cmd *update;
- struct kdbus_item *n;
- BusEndpointPolicy *po;
- Iterator i;
- size_t size;
- int r;
-
- size = ALIGN8(offsetof(struct kdbus_cmd, items));
-
- HASHMAP_FOREACH(po, ep->policy_hash, i) {
- size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1);
- size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
- }
-
- update = alloca0_align(size, 8);
- update->size = size;
-
- n = update->items;
-
- HASHMAP_FOREACH(po, ep->policy_hash, i) {
- n->type = KDBUS_ITEM_NAME;
- n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1;
- strcpy(n->str, po->name);
- n = KDBUS_ITEM_NEXT(n);
-
- n->type = KDBUS_ITEM_POLICY_ACCESS;
- n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
-
- n->policy_access.type = KDBUS_POLICY_ACCESS_USER;
- n->policy_access.access = bus_kernel_translate_access(po->access);
- n->policy_access.id = uid;
-
- n = KDBUS_ITEM_NEXT(n);
- }
-
- r = ioctl(fd, KDBUS_CMD_ENDPOINT_UPDATE, update);
- if (r < 0)
- return -errno;
-
- return 0;
-}
-
-int bus_endpoint_new(BusEndpoint **ep) {
- assert(ep);
-
- *ep = new0(BusEndpoint, 1);
- if (!*ep)
- return -ENOMEM;
-
- return 0;
-}
-
-int bus_endpoint_add_policy(BusEndpoint *ep, const char *name, BusPolicyAccess access) {
- _cleanup_free_ BusEndpointPolicy *po = NULL;
- _cleanup_free_ char *key = NULL;
- int r;
-
- assert(ep);
- assert(name);
- assert(access > _BUS_POLICY_ACCESS_INVALID && access < _BUS_POLICY_ACCESS_MAX);
-
- /* check if we already have this name in the policy list. If we do, see if the new access level
- * is higher than the exising one, and upgrade the entry in that case. Otherwise, do nothing.
- */
-
- if (ep->policy_hash) {
- po = hashmap_get(ep->policy_hash, name);
- if (po) {
- if (po->access < access)
- po->access = access;
-
- return 0;
- }
- } else {
- ep->policy_hash = hashmap_new(&string_hash_ops);
- if (!ep->policy_hash)
- return -ENOMEM;
- }
-
- po = new0(BusEndpointPolicy, 1);
- if (!po)
- return -ENOMEM;
-
- key = strdup(name);
- if (!key)
- return -ENOMEM;
-
- po->name = key;
- po->access = access;
-
- r = hashmap_put(ep->policy_hash, key, po);
- if (r < 0)
- return r;
-
- po = NULL;
- key = NULL;
- return 0;
-}
-
-void bus_endpoint_free(BusEndpoint *endpoint) {
- if (!endpoint)
- return;
-
- hashmap_free_free_free(endpoint->policy_hash);
- free(endpoint);
-}
diff --git a/src/core/bus-endpoint.h b/src/core/bus-endpoint.h
deleted file mode 100644
index 4a31f4c4b..000000000
--- a/src/core/bus-endpoint.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Daniel Mack
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-typedef struct BusEndpoint BusEndpoint;
-typedef struct BusEndpointPolicy BusEndpointPolicy;
-
-#include "hashmap.h"
-#include "bus-policy.h"
-
-struct BusEndpointPolicy {
- char *name;
- BusPolicyAccess access;
-};
-
-struct BusEndpoint {
- Hashmap *policy_hash;
-};
-
-int bus_endpoint_new(BusEndpoint **ep);
-void bus_endpoint_free(BusEndpoint *endpoint);
-
-int bus_endpoint_add_policy(BusEndpoint *ep, const char *name, BusPolicyAccess access);
-
-int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep);
diff --git a/src/core/bus-policy.c b/src/core/bus-policy.c
deleted file mode 100644
index 064eee1c8..000000000
--- a/src/core/bus-policy.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Daniel Mack
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-
-#include "kdbus.h"
-#include "util.h"
-#include "bus-kernel.h"
-#include "bus-policy.h"
-
-int bus_kernel_translate_access(BusPolicyAccess access) {
- assert(access >= 0);
- assert(access < _BUS_POLICY_ACCESS_MAX);
-
- switch (access) {
-
- case BUS_POLICY_ACCESS_SEE:
- return KDBUS_POLICY_SEE;
-
- case BUS_POLICY_ACCESS_TALK:
- return KDBUS_POLICY_TALK;
-
- case BUS_POLICY_ACCESS_OWN:
- return KDBUS_POLICY_OWN;
-
- default:
- assert_not_reached("Unknown policy access");
- }
-}
-
-int bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbus_item *item) {
- int r;
-
- assert(policy);
- assert(item);
-
- switch (policy->type) {
-
- case BUSNAME_POLICY_TYPE_USER: {
- const char *user = policy->name;
- uid_t uid;
-
- r = get_user_creds(&user, &uid, NULL, NULL, NULL);
- if (r < 0)
- return r;
-
- item->policy_access.type = KDBUS_POLICY_ACCESS_USER;
- item->policy_access.id = uid;
- break;
- }
-
- case BUSNAME_POLICY_TYPE_GROUP: {
- const char *group = policy->name;
- gid_t gid;
-
- r = get_group_creds(&group, &gid);
- if (r < 0)
- return r;
-
- item->policy_access.type = KDBUS_POLICY_ACCESS_GROUP;
- item->policy_access.id = gid;
- break;
- }
-
- default:
- assert_not_reached("Unknown policy type");
- }
-
- item->policy_access.access = bus_kernel_translate_access(policy->access);
-
- return 0;
-}
-
-int bus_kernel_make_starter(
- int fd,
- const char *name,
- bool activating,
- bool accept_fd,
- BusNamePolicy *policy,
- BusPolicyAccess world_policy) {
-
- struct kdbus_cmd_free cmd_free = { .size = sizeof(cmd_free) };
- struct kdbus_cmd_hello *hello;
- struct kdbus_item *n;
- size_t policy_cnt = 0;
- BusNamePolicy *po;
- size_t size;
- int r;
-
- assert(fd >= 0);
- assert(name);
-
- LIST_FOREACH(policy, po, policy)
- policy_cnt++;
-
- if (world_policy >= 0)
- policy_cnt++;
-
- size = offsetof(struct kdbus_cmd_hello, items) +
- ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) +
- policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
-
- hello = alloca0_align(size, 8);
-
- n = hello->items;
- strcpy(n->str, name);
- n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
- n->type = KDBUS_ITEM_NAME;
- n = KDBUS_ITEM_NEXT(n);
-
- LIST_FOREACH(policy, po, policy) {
- n->type = KDBUS_ITEM_POLICY_ACCESS;
- n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
-
- r = bus_kernel_translate_policy(po, n);
- if (r < 0)
- return r;
-
- n = KDBUS_ITEM_NEXT(n);
- }
-
- if (world_policy >= 0) {
- n->type = KDBUS_ITEM_POLICY_ACCESS;
- n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
- n->policy_access.type = KDBUS_POLICY_ACCESS_WORLD;
- n->policy_access.access = bus_kernel_translate_access(world_policy);
- }
-
- hello->size = size;
- hello->flags =
- (activating ? KDBUS_HELLO_ACTIVATOR : KDBUS_HELLO_POLICY_HOLDER) |
- (accept_fd ? KDBUS_HELLO_ACCEPT_FD : 0);
- hello->pool_size = KDBUS_POOL_SIZE;
- hello->attach_flags_send = _KDBUS_ATTACH_ANY;
- hello->attach_flags_recv = _KDBUS_ATTACH_ANY;
-
- if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0)
- return -errno;
-
- /* not interested in any output values */
- cmd_free.offset = hello->offset;
- (void) ioctl(fd, KDBUS_CMD_FREE, &cmd_free);
-
- /* The higher 32bit of the bus_flags fields are considered
- * 'incompatible flags'. Refuse them all for now. */
- if (hello->bus_flags > 0xFFFFFFFFULL)
- return -EOPNOTSUPP;
-
- return fd;
-}
-
-static const char* const bus_policy_access_table[_BUS_POLICY_ACCESS_MAX] = {
- [BUS_POLICY_ACCESS_SEE] = "see",
- [BUS_POLICY_ACCESS_TALK] = "talk",
- [BUS_POLICY_ACCESS_OWN] = "own",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(bus_policy_access, BusPolicyAccess);
diff --git a/src/core/bus-policy.h b/src/core/bus-policy.h
deleted file mode 100644
index 3b04f5457..000000000
--- a/src/core/bus-policy.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Daniel Mack
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "list.h"
-#include "macro.h"
-#include "kdbus.h"
-
-typedef struct BusNamePolicy BusNamePolicy;
-
-typedef enum BusPolicyAccess {
- BUS_POLICY_ACCESS_SEE,
- BUS_POLICY_ACCESS_TALK,
- BUS_POLICY_ACCESS_OWN,
- _BUS_POLICY_ACCESS_MAX,
- _BUS_POLICY_ACCESS_INVALID = -1
-} BusPolicyAccess;
-
-typedef enum BusNamePolicyType {
- BUSNAME_POLICY_TYPE_USER,
- BUSNAME_POLICY_TYPE_GROUP,
- _BUSNAME_POLICY_TYPE_MAX,
- _BUSNAME_POLICY_TYPE_INVALID = -1
-} BusNamePolicyType;
-
-struct BusNamePolicy {
- BusNamePolicyType type;
- BusPolicyAccess access;
-
- char *name;
-
- LIST_FIELDS(BusNamePolicy, policy);
-};
-
-int bus_kernel_translate_access(BusPolicyAccess access);
-int bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbus_item *item);
-
-const char* bus_policy_access_to_string(BusPolicyAccess i) _const_;
-BusPolicyAccess bus_policy_access_from_string(const char *s) _pure_;
-
-int bus_kernel_make_starter(
- int fd,
- const char *name,
- bool activating,
- bool accept_fd,
- BusNamePolicy *policy,
- BusPolicyAccess world_policy);
diff --git a/src/core/busname.c b/src/core/busname.c
deleted file mode 100644
index 43d7607a3..000000000
--- a/src/core/busname.c
+++ /dev/null
@@ -1,1066 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/mman.h>
-
-#include "special.h"
-#include "bus-kernel.h"
-#include "bus-internal.h"
-#include "bus-util.h"
-#include "service.h"
-#include "kdbus.h"
-#include "bus-policy.h"
-#include "dbus-busname.h"
-#include "busname.h"
-
-static const UnitActiveState state_translation_table[_BUSNAME_STATE_MAX] = {
- [BUSNAME_DEAD] = UNIT_INACTIVE,
- [BUSNAME_MAKING] = UNIT_ACTIVATING,
- [BUSNAME_REGISTERED] = UNIT_ACTIVE,
- [BUSNAME_LISTENING] = UNIT_ACTIVE,
- [BUSNAME_RUNNING] = UNIT_ACTIVE,
- [BUSNAME_SIGTERM] = UNIT_DEACTIVATING,
- [BUSNAME_SIGKILL] = UNIT_DEACTIVATING,
- [BUSNAME_FAILED] = UNIT_FAILED
-};
-
-static int busname_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
-static int busname_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
-
-static void busname_init(Unit *u) {
- BusName *n = BUSNAME(u);
-
- assert(u);
- assert(u->load_state == UNIT_STUB);
-
- n->starter_fd = -1;
- n->accept_fd = true;
- n->activating = true;
-
- n->timeout_usec = u->manager->default_timeout_start_usec;
-}
-
-static void busname_unwatch_control_pid(BusName *n) {
- assert(n);
-
- if (n->control_pid <= 0)
- return;
-
- unit_unwatch_pid(UNIT(n), n->control_pid);
- n->control_pid = 0;
-}
-
-static void busname_free_policy(BusName *n) {
- BusNamePolicy *p;
-
- assert(n);
-
- while ((p = n->policy)) {
- LIST_REMOVE(policy, n->policy, p);
-
- free(p->name);
- free(p);
- }
-}
-
-static void busname_close_fd(BusName *n) {
- assert(n);
-
- n->starter_event_source = sd_event_source_unref(n->starter_event_source);
- n->starter_fd = safe_close(n->starter_fd);
-}
-
-static void busname_done(Unit *u) {
- BusName *n = BUSNAME(u);
-
- assert(n);
-
- free(n->name);
- n->name = NULL;
-
- busname_free_policy(n);
- busname_unwatch_control_pid(n);
- busname_close_fd(n);
-
- unit_ref_unset(&n->service);
-
- n->timer_event_source = sd_event_source_unref(n->timer_event_source);
-}
-
-static int busname_arm_timer(BusName *n) {
- int r;
-
- assert(n);
-
- if (n->timeout_usec <= 0) {
- n->timer_event_source = sd_event_source_unref(n->timer_event_source);
- return 0;
- }
-
- if (n->timer_event_source) {
- r = sd_event_source_set_time(n->timer_event_source, now(CLOCK_MONOTONIC) + n->timeout_usec);
- if (r < 0)
- return r;
-
- return sd_event_source_set_enabled(n->timer_event_source, SD_EVENT_ONESHOT);
- }
-
- return sd_event_add_time(
- UNIT(n)->manager->event,
- &n->timer_event_source,
- CLOCK_MONOTONIC,
- now(CLOCK_MONOTONIC) + n->timeout_usec, 0,
- busname_dispatch_timer, n);
-}
-
-static int busname_add_default_default_dependencies(BusName *n) {
- int r;
-
- assert(n);
-
- r = unit_add_dependency_by_name(UNIT(n), UNIT_BEFORE, SPECIAL_BUSNAMES_TARGET, NULL, true);
- if (r < 0)
- return r;
-
- if (UNIT(n)->manager->running_as == SYSTEMD_SYSTEM) {
- r = unit_add_two_dependencies_by_name(UNIT(n), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
- if (r < 0)
- return r;
- }
-
- return unit_add_two_dependencies_by_name(UNIT(n), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
-}
-
-static int busname_add_extras(BusName *n) {
- Unit *u = UNIT(n);
- int r;
-
- assert(n);
-
- if (!n->name) {
- n->name = unit_name_to_prefix(u->id);
- if (!n->name)
- return -ENOMEM;
- }
-
- if (!u->description) {
- r = unit_set_description(u, n->name);
- if (r < 0)
- return r;
- }
-
- if (n->activating) {
- if (!UNIT_DEREF(n->service)) {
- Unit *x;
-
- r = unit_load_related_unit(u, ".service", &x);
- if (r < 0)
- return r;
-
- unit_ref_set(&n->service, x);
- }
-
- r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(n->service), true);
- if (r < 0)
- return r;
- }
-
- if (u->default_dependencies) {
- r = busname_add_default_default_dependencies(n);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-static int busname_verify(BusName *n) {
- char *e;
-
- assert(n);
-
- if (UNIT(n)->load_state != UNIT_LOADED)
- return 0;
-
- if (!service_name_is_valid(n->name)) {
- log_unit_error(UNIT(n)->id, "%s's Name= setting is not a valid service name Refusing.", UNIT(n)->id);
- return -EINVAL;
- }
-
- e = strjoina(n->name, ".busname");
- if (!unit_has_name(UNIT(n), e)) {
- log_unit_error(UNIT(n)->id, "%s's Name= setting doesn't match unit name. Refusing.", UNIT(n)->id);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int busname_load(Unit *u) {
- BusName *n = BUSNAME(u);
- int r;
-
- assert(u);
- assert(u->load_state == UNIT_STUB);
-
- r = unit_load_fragment_and_dropin(u);
- if (r < 0)
- return r;
-
- if (u->load_state == UNIT_LOADED) {
- /* This is a new unit? Then let's add in some extras */
- r = busname_add_extras(n);
- if (r < 0)
- return r;
- }
-
- return busname_verify(n);
-}
-
-static void busname_dump(Unit *u, FILE *f, const char *prefix) {
- BusName *n = BUSNAME(u);
-
- assert(n);
- assert(f);
-
- fprintf(f,
- "%sBus Name State: %s\n"
- "%sResult: %s\n"
- "%sName: %s\n"
- "%sActivating: %s\n"
- "%sAccept FD: %s\n",
- prefix, busname_state_to_string(n->state),
- prefix, busname_result_to_string(n->result),
- prefix, n->name,
- prefix, yes_no(n->activating),
- prefix, yes_no(n->accept_fd));
-
- if (n->control_pid > 0)
- fprintf(f,
- "%sControl PID: "PID_FMT"\n",
- prefix, n->control_pid);
-}
-
-static void busname_unwatch_fd(BusName *n) {
- int r;
-
- assert(n);
-
- if (!n->starter_event_source)
- return;
-
- r = sd_event_source_set_enabled(n->starter_event_source, SD_EVENT_OFF);
- if (r < 0)
- log_unit_debug(UNIT(n)->id, "Failed to disable event source.");
-}
-
-static int busname_watch_fd(BusName *n) {
- int r;
-
- assert(n);
-
- if (n->starter_fd < 0)
- return 0;
-
- if (n->starter_event_source)
- r = sd_event_source_set_enabled(n->starter_event_source, SD_EVENT_ON);
- else
- r = sd_event_add_io(UNIT(n)->manager->event, &n->starter_event_source, n->starter_fd, EPOLLIN, busname_dispatch_io, n);
- if (r < 0) {
- log_unit_warning_errno(UNIT(n)->id, r, "Failed to watch starter fd: %m");
- busname_unwatch_fd(n);
- return r;
- }
-
- return 0;
-}
-
-static int busname_open_fd(BusName *n) {
- _cleanup_free_ char *path = NULL;
- const char *mode;
-
- assert(n);
-
- if (n->starter_fd >= 0)
- return 0;
-
- mode = UNIT(n)->manager->running_as == SYSTEMD_SYSTEM ? "system" : "user";
- n->starter_fd = bus_kernel_open_bus_fd(mode, &path);
- if (n->starter_fd < 0)
- return log_unit_warning_errno(UNIT(n)->id, n->starter_fd, "Failed to open %s: %m", path ?: "kdbus");
-
- return 0;
-}
-
-static void busname_set_state(BusName *n, BusNameState state) {
- BusNameState old_state;
- assert(n);
-
- old_state = n->state;
- n->state = state;
-
- if (!IN_SET(state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) {
- n->timer_event_source = sd_event_source_unref(n->timer_event_source);
- busname_unwatch_control_pid(n);
- }
-
- if (state != BUSNAME_LISTENING)
- busname_unwatch_fd(n);
-
- if (!IN_SET(state, BUSNAME_LISTENING, BUSNAME_MAKING, BUSNAME_REGISTERED, BUSNAME_RUNNING))
- busname_close_fd(n);
-
- if (state != old_state)
- log_unit_debug(UNIT(n)->id, "%s changed %s -> %s",
- UNIT(n)->id, busname_state_to_string(old_state), busname_state_to_string(state));
-
- unit_notify(UNIT(n), state_translation_table[old_state], state_translation_table[state], true);
-}
-
-static int busname_coldplug(Unit *u, Hashmap *deferred_work) {
- BusName *n = BUSNAME(u);
- int r;
-
- assert(n);
- assert(n->state == BUSNAME_DEAD);
-
- if (n->deserialized_state == n->state)
- return 0;
-
- if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) {
-
- if (n->control_pid <= 0)
- return -EBADMSG;
-
- r = unit_watch_pid(UNIT(n), n->control_pid);
- if (r < 0)
- return r;
-
- r = busname_arm_timer(n);
- if (r < 0)
- return r;
- }
-
- if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_LISTENING, BUSNAME_REGISTERED, BUSNAME_RUNNING)) {
- r = busname_open_fd(n);
- if (r < 0)
- return r;
- }
-
- if (n->deserialized_state == BUSNAME_LISTENING) {
- r = busname_watch_fd(n);
- if (r < 0)
- return r;
- }
-
- busname_set_state(n, n->deserialized_state);
- return 0;
-}
-
-static int busname_make_starter(BusName *n, pid_t *_pid) {
- pid_t pid;
- int r;
-
- r = busname_arm_timer(n);
- if (r < 0)
- goto fail;
-
- /* We have to resolve the user/group names out-of-process,
- * hence let's fork here. It's messy, but well, what can we
- * do? */
-
- pid = fork();
- if (pid < 0)
- return -errno;
-
- if (pid == 0) {
- int ret;
-
- default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1);
- ignore_signals(SIGPIPE, -1);
- log_forget_fds();
-
- r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, n->policy, n->policy_world);
- if (r < 0) {
- ret = EXIT_MAKE_STARTER;
- goto fail_child;
- }
-
- _exit(0);
-
- fail_child:
- log_open();
- log_error_errno(r, "Failed to create starter connection at step %s: %m", exit_status_to_string(ret, EXIT_STATUS_SYSTEMD));
-
- _exit(ret);
- }
-
- r = unit_watch_pid(UNIT(n), pid);
- if (r < 0)
- goto fail;
-
- *_pid = pid;
- return 0;
-
-fail:
- n->timer_event_source = sd_event_source_unref(n->timer_event_source);
- return r;
-}
-
-static void busname_enter_dead(BusName *n, BusNameResult f) {
- assert(n);
-
- if (f != BUSNAME_SUCCESS)
- n->result = f;
-
- busname_set_state(n, n->result != BUSNAME_SUCCESS ? BUSNAME_FAILED : BUSNAME_DEAD);
-}
-
-static void busname_enter_signal(BusName *n, BusNameState state, BusNameResult f) {
- KillContext kill_context = {};
- int r;
-
- assert(n);
-
- if (f != BUSNAME_SUCCESS)
- n->result = f;
-
- kill_context_init(&kill_context);
-
- r = unit_kill_context(UNIT(n),
- &kill_context,
- state != BUSNAME_SIGTERM ? KILL_KILL : KILL_TERMINATE,
- -1,
- n->control_pid,
- false);
- if (r < 0) {
- log_unit_warning_errno(UNIT(n)->id, r, "%s failed to kill control process: %m", UNIT(n)->id);
- goto fail;
- }
-
- if (r > 0) {
- r = busname_arm_timer(n);
- if (r < 0) {
- log_unit_warning_errno(UNIT(n)->id, r, "%s failed to arm timer: %m", UNIT(n)->id);
- goto fail;
- }
-
- busname_set_state(n, state);
- } else if (state == BUSNAME_SIGTERM)
- busname_enter_signal(n, BUSNAME_SIGKILL, BUSNAME_SUCCESS);
- else
- busname_enter_dead(n, BUSNAME_SUCCESS);
-
- return;
-
-fail:
- busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
-}
-
-static void busname_enter_listening(BusName *n) {
- int r;
-
- assert(n);
-
- if (n->activating) {
- r = busname_watch_fd(n);
- if (r < 0) {
- log_unit_warning_errno(UNIT(n)->id, r, "%s failed to watch names: %m", UNIT(n)->id);
- goto fail;
- }
-
- busname_set_state(n, BUSNAME_LISTENING);
- } else
- busname_set_state(n, BUSNAME_REGISTERED);
-
- return;
-
-fail:
- busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_FAILURE_RESOURCES);
-}
-
-static void busname_enter_making(BusName *n) {
- int r;
-
- assert(n);
-
- r = busname_open_fd(n);
- if (r < 0)
- goto fail;
-
- if (n->policy) {
- /* If there is a policy, we need to resolve user/group
- * names, which we can't do from PID1, hence let's
- * fork. */
- busname_unwatch_control_pid(n);
-
- r = busname_make_starter(n, &n->control_pid);
- if (r < 0) {
- log_unit_warning_errno(UNIT(n)->id, r, "%s failed to fork 'making' task: %m", UNIT(n)->id);
- goto fail;
- }
-
- busname_set_state(n, BUSNAME_MAKING);
- } else {
- /* If there is no policy, we can do everything
- * directly from PID 1, hence do so. */
-
- r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, NULL, n->policy_world);
- if (r < 0) {
- log_unit_warning_errno(UNIT(n)->id, r, "%s failed to make starter: %m", UNIT(n)->id);
- goto fail;
- }
-
- busname_enter_listening(n);
- }
-
- return;
-
-fail:
- busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
-}
-
-static void busname_enter_running(BusName *n) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- bool pending = false;
- Unit *other;
- Iterator i;
- int r;
-
- assert(n);
-
- if (!n->activating)
- return;
-
- /* We don't take conenctions anymore if we are supposed to
- * shut down anyway */
-
- if (unit_stop_pending(UNIT(n))) {
- log_unit_debug(UNIT(n)->id, "Suppressing activation request on %s since unit stop is scheduled.", UNIT(n)->id);
-
- /* Flush all queued activation reqeuest by closing and reopening the connection */
- bus_kernel_drop_one(n->starter_fd);
-
- busname_enter_listening(n);
- return;
- }
-
- /* If there's already a start pending don't bother to do
- * anything */
- SET_FOREACH(other, UNIT(n)->dependencies[UNIT_TRIGGERS], i)
- if (unit_active_or_pending(other)) {
- pending = true;
- break;
- }
-
- if (!pending) {
- r = manager_add_job(UNIT(n)->manager, JOB_START, UNIT_DEREF(n->service), JOB_REPLACE, true, &error, NULL);
- if (r < 0)
- goto fail;
- }
-
- busname_set_state(n, BUSNAME_RUNNING);
- return;
-
-fail:
- log_unit_warning(UNIT(n)->id, "%s failed to queue service startup job: %s", UNIT(n)->id, bus_error_message(&error, r));
- busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
-}
-
-static int busname_start(Unit *u) {
- BusName *n = BUSNAME(u);
-
- assert(n);
-
- /* We cannot fulfill this request right now, try again later
- * please! */
- if (IN_SET(n->state, BUSNAME_SIGTERM, BUSNAME_SIGKILL))
- return -EAGAIN;
-
- /* Already on it! */
- if (n->state == BUSNAME_MAKING)
- return 0;
-
- if (n->activating && UNIT_ISSET(n->service)) {
- Service *service;
-
- service = SERVICE(UNIT_DEREF(n->service));
-
- if (UNIT(service)->load_state != UNIT_LOADED) {
- log_unit_error(u->id, "Bus service %s not loaded, refusing.", UNIT(service)->id);
- return -ENOENT;
- }
- }
-
- assert(IN_SET(n->state, BUSNAME_DEAD, BUSNAME_FAILED));
-
- n->result = BUSNAME_SUCCESS;
- busname_enter_making(n);
-
- return 1;
-}
-
-static int busname_stop(Unit *u) {
- BusName *n = BUSNAME(u);
-
- assert(n);
-
- /* Already on it */
- if (IN_SET(n->state, BUSNAME_SIGTERM, BUSNAME_SIGKILL))
- return 0;
-
- /* If there's already something running, we go directly into
- * kill mode. */
-
- if (n->state == BUSNAME_MAKING) {
- busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_SUCCESS);
- return -EAGAIN;
- }
-
- assert(IN_SET(n->state, BUSNAME_REGISTERED, BUSNAME_LISTENING, BUSNAME_RUNNING));
-
- busname_enter_dead(n, BUSNAME_SUCCESS);
- return 1;
-}
-
-static int busname_serialize(Unit *u, FILE *f, FDSet *fds) {
- BusName *n = BUSNAME(u);
-
- assert(n);
- assert(f);
- assert(fds);
-
- unit_serialize_item(u, f, "state", busname_state_to_string(n->state));
- unit_serialize_item(u, f, "result", busname_result_to_string(n->result));
-
- if (n->control_pid > 0)
- unit_serialize_item_format(u, f, "control-pid", PID_FMT, n->control_pid);
-
- if (n->starter_fd >= 0) {
- int copy;
-
- copy = fdset_put_dup(fds, n->starter_fd);
- if (copy < 0)
- return copy;
-
- unit_serialize_item_format(u, f, "starter-fd", "%i", copy);
- }
-
- return 0;
-}
-
-static int busname_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
- BusName *n = BUSNAME(u);
-
- assert(n);
- assert(key);
- assert(value);
-
- if (streq(key, "state")) {
- BusNameState state;
-
- state = busname_state_from_string(value);
- if (state < 0)
- log_unit_debug(u->id, "Failed to parse state value %s", value);
- else
- n->deserialized_state = state;
-
- } else if (streq(key, "result")) {
- BusNameResult f;
-
- f = busname_result_from_string(value);
- if (f < 0)
- log_unit_debug(u->id, "Failed to parse result value %s", value);
- else if (f != BUSNAME_SUCCESS)
- n->result = f;
-
- } else if (streq(key, "control-pid")) {
- pid_t pid;
-
- if (parse_pid(value, &pid) < 0)
- log_unit_debug(u->id, "Failed to parse control-pid value %s", value);
- else
- n->control_pid = pid;
- } else if (streq(key, "starter-fd")) {
- int fd;
-
- if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
- log_unit_debug(u->id, "Failed to parse starter fd value %s", value);
- else {
- safe_close(n->starter_fd);
- n->starter_fd = fdset_remove(fds, fd);
- }
- } else
- log_unit_debug(u->id, "Unknown serialization key '%s'", key);
-
- return 0;
-}
-
-_pure_ static UnitActiveState busname_active_state(Unit *u) {
- assert(u);
-
- return state_translation_table[BUSNAME(u)->state];
-}
-
-_pure_ static const char *busname_sub_state_to_string(Unit *u) {
- assert(u);
-
- return busname_state_to_string(BUSNAME(u)->state);
-}
-
-static int busname_peek_message(BusName *n) {
- struct kdbus_cmd_recv cmd_recv = {
- .size = sizeof(cmd_recv),
- .flags = KDBUS_RECV_PEEK,
- };
- struct kdbus_cmd_free cmd_free = {
- .size = sizeof(cmd_free),
- };
- const char *comm = NULL;
- struct kdbus_item *d;
- struct kdbus_msg *k;
- size_t start, ps, sz, delta;
- void *p = NULL;
- pid_t pid = 0;
- int r;
-
- /* Generate a friendly debug log message about which process
- * caused triggering of this bus name. This simply peeks the
- * metadata of the first queued message and logs it. */
-
- assert(n);
-
- /* Let's shortcut things a bit, if debug logging is turned off
- * anyway. */
-
- if (log_get_max_level() < LOG_DEBUG)
- return 0;
-
- r = ioctl(n->starter_fd, KDBUS_CMD_RECV, &cmd_recv);
- if (r < 0) {
- if (errno == EINTR || errno == EAGAIN)
- return 0;
-
- log_unit_error(UNIT(n)->id, "%s: Failed to query activation message: %m", UNIT(n)->id);
- return -errno;
- }
-
- /* We map as late as possible, and unmap imemdiately after
- * use. On 32bit address space is scarce and we want to be
- * able to handle a lot of activator connections at the same
- * time, and hence shouldn't keep the mmap()s around for
- * longer than necessary. */
-
- ps = page_size();
- start = (cmd_recv.msg.offset / ps) * ps;
- delta = cmd_recv.msg.offset - start;
- sz = PAGE_ALIGN(delta + cmd_recv.msg.msg_size);
-
- p = mmap(NULL, sz, PROT_READ, MAP_SHARED, n->starter_fd, start);
- if (p == MAP_FAILED) {
- log_unit_error(UNIT(n)->id, "%s: Failed to map activation message: %m", UNIT(n)->id);
- r = -errno;
- goto finish;
- }
-
- k = (struct kdbus_msg *) ((uint8_t *) p + delta);
- KDBUS_ITEM_FOREACH(d, k, items) {
- switch (d->type) {
-
- case KDBUS_ITEM_PIDS:
- pid = d->pids.pid;
- break;
-
- case KDBUS_ITEM_PID_COMM:
- comm = d->str;
- break;
- }
- }
-
- if (pid > 0)
- log_unit_debug(UNIT(n)->id, "%s: Activation triggered by process " PID_FMT " (%s)", UNIT(n)->id, pid, strna(comm));
-
- r = 0;
-
-finish:
- if (p)
- (void) munmap(p, sz);
-
- cmd_free.offset = cmd_recv.msg.offset;
- if (ioctl(n->starter_fd, KDBUS_CMD_FREE, &cmd_free) < 0)
- log_unit_warning(UNIT(n)->id, "Failed to free peeked message, ignoring: %m");
-
- return r;
-}
-
-static int busname_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
- BusName *n = userdata;
-
- assert(n);
- assert(fd >= 0);
-
- if (n->state != BUSNAME_LISTENING)
- return 0;
-
- log_unit_debug(UNIT(n)->id, "Activation request on %s", UNIT(n)->id);
-
- if (revents != EPOLLIN) {
- log_unit_error(UNIT(n)->id, "%s: Got unexpected poll event (0x%x) on starter fd.",
- UNIT(n)->id, revents);
- goto fail;
- }
-
- busname_peek_message(n);
- busname_enter_running(n);
- return 0;
-fail:
-
- busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
- return 0;
-}
-
-static void busname_sigchld_event(Unit *u, pid_t pid, int code, int status) {
- BusName *n = BUSNAME(u);
- BusNameResult f;
-
- assert(n);
- assert(pid >= 0);
-
- if (pid != n->control_pid)
- return;
-
- n->control_pid = 0;
-
- if (is_clean_exit(code, status, NULL))
- f = BUSNAME_SUCCESS;
- else if (code == CLD_EXITED)
- f = BUSNAME_FAILURE_EXIT_CODE;
- else if (code == CLD_KILLED)
- f = BUSNAME_FAILURE_SIGNAL;
- else if (code == CLD_DUMPED)
- f = BUSNAME_FAILURE_CORE_DUMP;
- else
- assert_not_reached("Unknown sigchld code");
-
- log_unit_full(u->id,
- f == BUSNAME_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
- "%s control process exited, code=%s status=%i",
- u->id, sigchld_code_to_string(code), status);
-
- if (f != BUSNAME_SUCCESS)
- n->result = f;
-
- switch (n->state) {
-
- case BUSNAME_MAKING:
- if (f == BUSNAME_SUCCESS)
- busname_enter_listening(n);
- else
- busname_enter_signal(n, BUSNAME_SIGTERM, f);
- break;
-
- case BUSNAME_SIGTERM:
- case BUSNAME_SIGKILL:
- busname_enter_dead(n, f);
- break;
-
- default:
- assert_not_reached("Uh, control process died at wrong time.");
- }
-
- /* Notify clients about changed exit status */
- unit_add_to_dbus_queue(u);
-}
-
-static int busname_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
- BusName *n = BUSNAME(userdata);
-
- assert(n);
- assert(n->timer_event_source == source);
-
- switch (n->state) {
-
- case BUSNAME_MAKING:
- log_unit_warning(UNIT(n)->id, "%s making timed out. Terminating.", UNIT(n)->id);
- busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_FAILURE_TIMEOUT);
- break;
-
- case BUSNAME_SIGTERM:
- log_unit_warning(UNIT(n)->id, "%s stopping timed out. Killing.", UNIT(n)->id);
- busname_enter_signal(n, BUSNAME_SIGKILL, BUSNAME_FAILURE_TIMEOUT);
- break;
-
- case BUSNAME_SIGKILL:
- log_unit_warning(UNIT(n)->id, "%s still around after SIGKILL. Ignoring.", UNIT(n)->id);
- busname_enter_dead(n, BUSNAME_FAILURE_TIMEOUT);
- break;
-
- default:
- assert_not_reached("Timeout at wrong time.");
- }
-
- return 0;
-}
-
-static void busname_reset_failed(Unit *u) {
- BusName *n = BUSNAME(u);
-
- assert(n);
-
- if (n->state == BUSNAME_FAILED)
- busname_set_state(n, BUSNAME_DEAD);
-
- n->result = BUSNAME_SUCCESS;
-}
-
-static void busname_trigger_notify(Unit *u, Unit *other) {
- BusName *n = BUSNAME(u);
- Service *s;
-
- assert(n);
- assert(other);
-
- if (!IN_SET(n->state, BUSNAME_RUNNING, BUSNAME_LISTENING))
- return;
-
- if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE)
- return;
-
- s = SERVICE(other);
-
- if (s->state == SERVICE_FAILED && s->result == SERVICE_FAILURE_START_LIMIT)
- busname_enter_dead(n, BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT);
- else if (IN_SET(s->state,
- SERVICE_DEAD, SERVICE_FAILED,
- SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
- SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
- SERVICE_AUTO_RESTART))
- busname_enter_listening(n);
-}
-
-static int busname_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
- return unit_kill_common(u, who, signo, -1, BUSNAME(u)->control_pid, error);
-}
-
-static int busname_get_timeout(Unit *u, uint64_t *timeout) {
- BusName *n = BUSNAME(u);
- int r;
-
- if (!n->timer_event_source)
- return 0;
-
- r = sd_event_source_get_time(n->timer_event_source, timeout);
- if (r < 0)
- return r;
-
- return 1;
-}
-
-static bool busname_supported(Manager *m) {
- static int supported = -1;
- assert(m);
-
- if (supported < 0)
- supported = access("/sys/fs/kdbus", F_OK) >= 0;
-
- return supported;
-}
-
-static const char* const busname_state_table[_BUSNAME_STATE_MAX] = {
- [BUSNAME_DEAD] = "dead",
- [BUSNAME_MAKING] = "making",
- [BUSNAME_REGISTERED] = "registered",
- [BUSNAME_LISTENING] = "listening",
- [BUSNAME_RUNNING] = "running",
- [BUSNAME_SIGTERM] = "sigterm",
- [BUSNAME_SIGKILL] = "sigkill",
- [BUSNAME_FAILED] = "failed",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(busname_state, BusNameState);
-
-static const char* const busname_result_table[_BUSNAME_RESULT_MAX] = {
- [BUSNAME_SUCCESS] = "success",
- [BUSNAME_FAILURE_RESOURCES] = "resources",
- [BUSNAME_FAILURE_TIMEOUT] = "timeout",
- [BUSNAME_FAILURE_EXIT_CODE] = "exit-code",
- [BUSNAME_FAILURE_SIGNAL] = "signal",
- [BUSNAME_FAILURE_CORE_DUMP] = "core-dump",
- [BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(busname_result, BusNameResult);
-
-const UnitVTable busname_vtable = {
- .object_size = sizeof(BusName),
-
- .sections =
- "Unit\0"
- "BusName\0"
- "Install\0",
- .private_section = "BusName",
-
- .init = busname_init,
- .done = busname_done,
- .load = busname_load,
-
- .coldplug = busname_coldplug,
-
- .dump = busname_dump,
-
- .start = busname_start,
- .stop = busname_stop,
-
- .kill = busname_kill,
-
- .get_timeout = busname_get_timeout,
-
- .serialize = busname_serialize,
- .deserialize_item = busname_deserialize_item,
-
- .active_state = busname_active_state,
- .sub_state_to_string = busname_sub_state_to_string,
-
- .sigchld_event = busname_sigchld_event,
-
- .trigger_notify = busname_trigger_notify,
-
- .reset_failed = busname_reset_failed,
-
- .supported = busname_supported,
-
- .bus_interface = "org.freedesktop.systemd1.BusName",
- .bus_vtable = bus_busname_vtable,
-
- .status_message_formats = {
- .finished_start_job = {
- [JOB_DONE] = "Listening on %s.",
- [JOB_FAILED] = "Failed to listen on %s.",
- [JOB_DEPENDENCY] = "Dependency failed for %s.",
- [JOB_TIMEOUT] = "Timed out starting %s.",
- },
- .finished_stop_job = {
- [JOB_DONE] = "Closed %s.",
- [JOB_FAILED] = "Failed stopping %s.",
- [JOB_TIMEOUT] = "Timed out stopping %s.",
- },
- },
-};
diff --git a/src/core/busname.h b/src/core/busname.h
deleted file mode 100644
index 69528a2ae..000000000
--- a/src/core/busname.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-typedef struct BusName BusName;
-typedef struct BusNamePolicy BusNamePolicy;
-
-
-typedef enum BusNameState {
- BUSNAME_DEAD,
- BUSNAME_MAKING,
- BUSNAME_REGISTERED,
- BUSNAME_LISTENING,
- BUSNAME_RUNNING,
- BUSNAME_SIGTERM,
- BUSNAME_SIGKILL,
- BUSNAME_FAILED,
- _BUSNAME_STATE_MAX,
- _BUSNAME_STATE_INVALID = -1
-} BusNameState;
-
-typedef enum BusNameResult {
- BUSNAME_SUCCESS,
- BUSNAME_FAILURE_RESOURCES,
- BUSNAME_FAILURE_TIMEOUT,
- BUSNAME_FAILURE_EXIT_CODE,
- BUSNAME_FAILURE_SIGNAL,
- BUSNAME_FAILURE_CORE_DUMP,
- BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT,
- _BUSNAME_RESULT_MAX,
- _BUSNAME_RESULT_INVALID = -1
-} BusNameResult;
-
-struct BusName {
- Unit meta;
-
- char *name;
- int starter_fd;
-
- bool activating;
- bool accept_fd;
-
- UnitRef service;
-
- BusNameState state, deserialized_state;
- BusNameResult result;
-
- usec_t timeout_usec;
-
- sd_event_source *starter_event_source;
- sd_event_source *timer_event_source;
-
- pid_t control_pid;
-
- LIST_HEAD(BusNamePolicy, policy);
- BusPolicyAccess policy_world;
-};
-
-extern const UnitVTable busname_vtable;
-
-const char* busname_state_to_string(BusNameState i) _const_;
-BusNameState busname_state_from_string(const char *s) _pure_;
-
-const char* busname_result_to_string(BusNameResult i) _const_;
-BusNameResult busname_result_from_string(const char *s) _pure_;
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
deleted file mode 100644
index b28137789..000000000
--- a/src/core/cgroup.c
+++ /dev/null
@@ -1,1136 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <fcntl.h>
-#include <fnmatch.h>
-
-#include "path-util.h"
-#include "special.h"
-#include "cgroup-util.h"
-#include "cgroup.h"
-
-#define CGROUP_CPU_QUOTA_PERIOD_USEC ((usec_t) 100 * USEC_PER_MSEC)
-
-void cgroup_context_init(CGroupContext *c) {
- assert(c);
-
- /* Initialize everything to the kernel defaults, assuming the
- * structure is preinitialized to 0 */
-
- c->cpu_shares = (unsigned long) -1;
- c->startup_cpu_shares = (unsigned long) -1;
- c->memory_limit = (uint64_t) -1;
- c->blockio_weight = (unsigned long) -1;
- c->startup_blockio_weight = (unsigned long) -1;
-
- c->cpu_quota_per_sec_usec = USEC_INFINITY;
-}
-
-void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a) {
- assert(c);
- assert(a);
-
- LIST_REMOVE(device_allow, c->device_allow, a);
- free(a->path);
- free(a);
-}
-
-void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w) {
- assert(c);
- assert(w);
-
- LIST_REMOVE(device_weights, c->blockio_device_weights, w);
- free(w->path);
- free(w);
-}
-
-void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b) {
- assert(c);
- assert(b);
-
- LIST_REMOVE(device_bandwidths, c->blockio_device_bandwidths, b);
- free(b->path);
- free(b);
-}
-
-void cgroup_context_done(CGroupContext *c) {
- assert(c);
-
- while (c->blockio_device_weights)
- cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights);
-
- while (c->blockio_device_bandwidths)
- cgroup_context_free_blockio_device_bandwidth(c, c->blockio_device_bandwidths);
-
- while (c->device_allow)
- cgroup_context_free_device_allow(c, c->device_allow);
-}
-
-void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
- CGroupBlockIODeviceBandwidth *b;
- CGroupBlockIODeviceWeight *w;
- CGroupDeviceAllow *a;
- char u[FORMAT_TIMESPAN_MAX];
-
- assert(c);
- assert(f);
-
- prefix = strempty(prefix);
-
- fprintf(f,
- "%sCPUAccounting=%s\n"
- "%sBlockIOAccounting=%s\n"
- "%sMemoryAccounting=%s\n"
- "%sCPUShares=%lu\n"
- "%sStartupCPUShares=%lu\n"
- "%sCPUQuotaPerSecSec=%s\n"
- "%sBlockIOWeight=%lu\n"
- "%sStartupBlockIOWeight=%lu\n"
- "%sMemoryLimit=%" PRIu64 "\n"
- "%sDevicePolicy=%s\n"
- "%sDelegate=%s\n",
- prefix, yes_no(c->cpu_accounting),
- prefix, yes_no(c->blockio_accounting),
- prefix, yes_no(c->memory_accounting),
- prefix, c->cpu_shares,
- prefix, c->startup_cpu_shares,
- prefix, format_timespan(u, sizeof(u), c->cpu_quota_per_sec_usec, 1),
- prefix, c->blockio_weight,
- prefix, c->startup_blockio_weight,
- prefix, c->memory_limit,
- prefix, cgroup_device_policy_to_string(c->device_policy),
- prefix, yes_no(c->delegate));
-
- LIST_FOREACH(device_allow, a, c->device_allow)
- fprintf(f,
- "%sDeviceAllow=%s %s%s%s\n",
- prefix,
- a->path,
- a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : "");
-
- LIST_FOREACH(device_weights, w, c->blockio_device_weights)
- fprintf(f,
- "%sBlockIODeviceWeight=%s %lu",
- prefix,
- w->path,
- w->weight);
-
- LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
- char buf[FORMAT_BYTES_MAX];
-
- fprintf(f,
- "%s%s=%s %s\n",
- prefix,
- b->read ? "BlockIOReadBandwidth" : "BlockIOWriteBandwidth",
- b->path,
- format_bytes(buf, sizeof(buf), b->bandwidth));
- }
-}
-
-static int lookup_blkio_device(const char *p, dev_t *dev) {
- struct stat st;
- int r;
-
- assert(p);
- assert(dev);
-
- r = stat(p, &st);
- if (r < 0)
- return log_warning_errno(errno, "Couldn't stat device %s: %m", p);
-
- if (S_ISBLK(st.st_mode))
- *dev = st.st_rdev;
- else if (major(st.st_dev) != 0) {
- /* If this is not a device node then find the block
- * device this file is stored on */
- *dev = st.st_dev;
-
- /* If this is a partition, try to get the originating
- * block device */
- block_get_whole_disk(*dev, dev);
- } else {
- log_warning("%s is not a block device and file system block device cannot be determined or is not local.", p);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static int whitelist_device(const char *path, const char *node, const char *acc) {
- char buf[2+DECIMAL_STR_MAX(dev_t)*2+2+4];
- struct stat st;
- int r;
-
- assert(path);
- assert(acc);
-
- if (stat(node, &st) < 0) {
- log_warning("Couldn't stat device %s", node);
- return -errno;
- }
-
- if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) {
- log_warning("%s is not a device.", node);
- return -ENODEV;
- }
-
- sprintf(buf,
- "%c %u:%u %s",
- S_ISCHR(st.st_mode) ? 'c' : 'b',
- major(st.st_rdev), minor(st.st_rdev),
- acc);
-
- r = cg_set_attribute("devices", path, "devices.allow", buf);
- if (r < 0)
- log_full_errno(IN_SET(r, -ENOENT, -EROFS, -EINVAL) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to set devices.allow on %s: %m", path);
-
- return r;
-}
-
-static int whitelist_major(const char *path, const char *name, char type, const char *acc) {
- _cleanup_fclose_ FILE *f = NULL;
- char line[LINE_MAX];
- bool good = false;
- int r;
-
- assert(path);
- assert(acc);
- assert(type == 'b' || type == 'c');
-
- f = fopen("/proc/devices", "re");
- if (!f)
- return log_warning_errno(errno, "Cannot open /proc/devices to resolve %s (%c): %m", name, type);
-
- FOREACH_LINE(line, f, goto fail) {
- char buf[2+DECIMAL_STR_MAX(unsigned)+3+4], *p, *w;
- unsigned maj;
-
- truncate_nl(line);
-
- if (type == 'c' && streq(line, "Character devices:")) {
- good = true;
- continue;
- }
-
- if (type == 'b' && streq(line, "Block devices:")) {
- good = true;
- continue;
- }
-
- if (isempty(line)) {
- good = false;
- continue;
- }
-
- if (!good)
- continue;
-
- p = strstrip(line);
-
- w = strpbrk(p, WHITESPACE);
- if (!w)
- continue;
- *w = 0;
-
- r = safe_atou(p, &maj);
- if (r < 0)
- continue;
- if (maj <= 0)
- continue;
-
- w++;
- w += strspn(w, WHITESPACE);
-
- if (fnmatch(name, w, 0) != 0)
- continue;
-
- sprintf(buf,
- "%c %u:* %s",
- type,
- maj,
- acc);
-
- r = cg_set_attribute("devices", path, "devices.allow", buf);
- if (r < 0)
- log_full_errno(IN_SET(r, -ENOENT, -EROFS, -EINVAL) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to set devices.allow on %s: %m", path);
- }
-
- return 0;
-
-fail:
- log_warning_errno(errno, "Failed to read /proc/devices: %m");
- return -errno;
-}
-
-void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const char *path, ManagerState state) {
- bool is_root;
- int r;
-
- assert(c);
- assert(path);
-
- if (mask == 0)
- return;
-
- /* Some cgroup attributes are not supported on the root cgroup,
- * hence silently ignore */
- is_root = isempty(path) || path_equal(path, "/");
- if (is_root)
- /* Make sure we don't try to display messages with an empty path. */
- path = "/";
-
- /* We generally ignore errors caused by read-only mounted
- * cgroup trees (assuming we are running in a container then),
- * and missing cgroups, i.e. EROFS and ENOENT. */
-
- if ((mask & CGROUP_CPU) && !is_root) {
- char buf[MAX(DECIMAL_STR_MAX(unsigned long), DECIMAL_STR_MAX(usec_t)) + 1];
-
- sprintf(buf, "%lu\n",
- IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) && c->startup_cpu_shares != (unsigned long) -1 ? c->startup_cpu_shares :
- c->cpu_shares != (unsigned long) -1 ? c->cpu_shares : 1024);
- r = cg_set_attribute("cpu", path, "cpu.shares", buf);
- if (r < 0)
- log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to set cpu.shares on %s: %m", path);
-
- sprintf(buf, USEC_FMT "\n", CGROUP_CPU_QUOTA_PERIOD_USEC);
- r = cg_set_attribute("cpu", path, "cpu.cfs_period_us", buf);
- if (r < 0)
- log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to set cpu.cfs_period_us on %s: %m", path);
-
- if (c->cpu_quota_per_sec_usec != USEC_INFINITY) {
- sprintf(buf, USEC_FMT "\n", c->cpu_quota_per_sec_usec * CGROUP_CPU_QUOTA_PERIOD_USEC / USEC_PER_SEC);
- r = cg_set_attribute("cpu", path, "cpu.cfs_quota_us", buf);
- } else
- r = cg_set_attribute("cpu", path, "cpu.cfs_quota_us", "-1");
- if (r < 0)
- log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to set cpu.cfs_quota_us on %s: %m", path);
- }
-
- if (mask & CGROUP_BLKIO) {
- char buf[MAX3(DECIMAL_STR_MAX(unsigned long)+1,
- DECIMAL_STR_MAX(dev_t)*2+2+DECIMAL_STR_MAX(unsigned long)*1,
- DECIMAL_STR_MAX(dev_t)*2+2+DECIMAL_STR_MAX(uint64_t)+1)];
- CGroupBlockIODeviceWeight *w;
- CGroupBlockIODeviceBandwidth *b;
-
- if (!is_root) {
- sprintf(buf, "%lu\n", IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) && c->startup_blockio_weight != (unsigned long) -1 ? c->startup_blockio_weight :
- c->blockio_weight != (unsigned long) -1 ? c->blockio_weight : 1000);
- r = cg_set_attribute("blkio", path, "blkio.weight", buf);
- if (r < 0)
- log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to set blkio.weight on %s: %m", path);
-
- /* FIXME: no way to reset this list */
- LIST_FOREACH(device_weights, w, c->blockio_device_weights) {
- dev_t dev;
-
- r = lookup_blkio_device(w->path, &dev);
- if (r < 0)
- continue;
-
- sprintf(buf, "%u:%u %lu", major(dev), minor(dev), w->weight);
- r = cg_set_attribute("blkio", path, "blkio.weight_device", buf);
- if (r < 0)
- log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to set blkio.weight_device on %s: %m", path);
- }
- }
-
- /* FIXME: no way to reset this list */
- LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
- const char *a;
- dev_t dev;
-
- r = lookup_blkio_device(b->path, &dev);
- if (r < 0)
- continue;
-
- a = b->read ? "blkio.throttle.read_bps_device" : "blkio.throttle.write_bps_device";
-
- sprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), b->bandwidth);
- r = cg_set_attribute("blkio", path, a, buf);
- if (r < 0)
- log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to set %s on %s: %m", a, path);
- }
- }
-
- if ((mask & CGROUP_MEMORY) && !is_root) {
- if (c->memory_limit != (uint64_t) -1) {
- char buf[DECIMAL_STR_MAX(uint64_t) + 1];
-
- sprintf(buf, "%" PRIu64 "\n", c->memory_limit);
- r = cg_set_attribute("memory", path, "memory.limit_in_bytes", buf);
- } else
- r = cg_set_attribute("memory", path, "memory.limit_in_bytes", "-1");
-
- if (r < 0)
- log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to set memory.limit_in_bytes on %s: %m", path);
- }
-
- if ((mask & CGROUP_DEVICE) && !is_root) {
- CGroupDeviceAllow *a;
-
- /* Changing the devices list of a populated cgroup
- * might result in EINVAL, hence ignore EINVAL
- * here. */
-
- if (c->device_allow || c->device_policy != CGROUP_AUTO)
- r = cg_set_attribute("devices", path, "devices.deny", "a");
- else
- r = cg_set_attribute("devices", path, "devices.allow", "a");
- if (r < 0)
- log_full_errno(IN_SET(r, -ENOENT, -EROFS, -EINVAL) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to reset devices.list on %s: %m", path);
-
- if (c->device_policy == CGROUP_CLOSED ||
- (c->device_policy == CGROUP_AUTO && c->device_allow)) {
- static const char auto_devices[] =
- "/dev/null\0" "rwm\0"
- "/dev/zero\0" "rwm\0"
- "/dev/full\0" "rwm\0"
- "/dev/random\0" "rwm\0"
- "/dev/urandom\0" "rwm\0"
- "/dev/tty\0" "rwm\0"
- "/dev/pts/ptmx\0" "rw\0"; /* /dev/pts/ptmx may not be duplicated, but accessed */
-
- const char *x, *y;
-
- NULSTR_FOREACH_PAIR(x, y, auto_devices)
- whitelist_device(path, x, y);
-
- whitelist_major(path, "pts", 'c', "rw");
- whitelist_major(path, "kdbus", 'c', "rw");
- whitelist_major(path, "kdbus/*", 'c', "rw");
- }
-
- LIST_FOREACH(device_allow, a, c->device_allow) {
- char acc[4];
- unsigned k = 0;
-
- if (a->r)
- acc[k++] = 'r';
- if (a->w)
- acc[k++] = 'w';
- if (a->m)
- acc[k++] = 'm';
-
- if (k == 0)
- continue;
-
- acc[k++] = 0;
-
- if (startswith(a->path, "/dev/"))
- whitelist_device(path, a->path, acc);
- else if (startswith(a->path, "block-"))
- whitelist_major(path, a->path + 6, 'b', acc);
- else if (startswith(a->path, "char-"))
- whitelist_major(path, a->path + 5, 'c', acc);
- else
- log_debug("Ignoring device %s while writing cgroup attribute.", a->path);
- }
- }
-}
-
-CGroupControllerMask cgroup_context_get_mask(CGroupContext *c) {
- CGroupControllerMask mask = 0;
-
- /* Figure out which controllers we need */
-
- if (c->cpu_accounting ||
- c->cpu_shares != (unsigned long) -1 ||
- c->startup_cpu_shares != (unsigned long) -1 ||
- c->cpu_quota_per_sec_usec != USEC_INFINITY)
- mask |= CGROUP_CPUACCT | CGROUP_CPU;
-
- if (c->blockio_accounting ||
- c->blockio_weight != (unsigned long) -1 ||
- c->startup_blockio_weight != (unsigned long) -1 ||
- c->blockio_device_weights ||
- c->blockio_device_bandwidths)
- mask |= CGROUP_BLKIO;
-
- if (c->memory_accounting ||
- c->memory_limit != (uint64_t) -1)
- mask |= CGROUP_MEMORY;
-
- if (c->device_allow ||
- c->device_policy != CGROUP_AUTO)
- mask |= CGROUP_DEVICE;
-
- return mask;
-}
-
-CGroupControllerMask unit_get_cgroup_mask(Unit *u) {
- CGroupContext *c;
-
- c = unit_get_cgroup_context(u);
- if (!c)
- return 0;
-
- /* If delegation is turned on, then turn on all cgroups,
- * unless the process we fork into it is known to drop
- * privileges anyway, and shouldn't get access to the
- * controllers anyway. */
-
- if (c->delegate) {
- ExecContext *e;
-
- e = unit_get_exec_context(u);
- if (!e || exec_context_maintains_privileges(e))
- return _CGROUP_CONTROLLER_MASK_ALL;
- }
-
- return cgroup_context_get_mask(c);
-}
-
-CGroupControllerMask unit_get_members_mask(Unit *u) {
- assert(u);
-
- if (u->cgroup_members_mask_valid)
- return u->cgroup_members_mask;
-
- u->cgroup_members_mask = 0;
-
- if (u->type == UNIT_SLICE) {
- Unit *member;
- Iterator i;
-
- SET_FOREACH(member, u->dependencies[UNIT_BEFORE], i) {
-
- if (member == u)
- continue;
-
- if (UNIT_DEREF(member->slice) != u)
- continue;
-
- u->cgroup_members_mask |=
- unit_get_cgroup_mask(member) |
- unit_get_members_mask(member);
- }
- }
-
- u->cgroup_members_mask_valid = true;
- return u->cgroup_members_mask;
-}
-
-CGroupControllerMask unit_get_siblings_mask(Unit *u) {
- assert(u);
-
- if (UNIT_ISSET(u->slice))
- return unit_get_members_mask(UNIT_DEREF(u->slice));
-
- return unit_get_cgroup_mask(u) | unit_get_members_mask(u);
-}
-
-CGroupControllerMask unit_get_target_mask(Unit *u) {
- CGroupControllerMask mask;
-
- mask = unit_get_cgroup_mask(u) | unit_get_members_mask(u) | unit_get_siblings_mask(u);
- mask &= u->manager->cgroup_supported;
-
- return mask;
-}
-
-/* Recurse from a unit up through its containing slices, propagating
- * mask bits upward. A unit is also member of itself. */
-void unit_update_cgroup_members_masks(Unit *u) {
- CGroupControllerMask m;
- bool more;
-
- assert(u);
-
- /* Calculate subtree mask */
- m = unit_get_cgroup_mask(u) | unit_get_members_mask(u);
-
- /* See if anything changed from the previous invocation. If
- * not, we're done. */
- if (u->cgroup_subtree_mask_valid && m == u->cgroup_subtree_mask)
- return;
-
- more =
- u->cgroup_subtree_mask_valid &&
- ((m & ~u->cgroup_subtree_mask) != 0) &&
- ((~m & u->cgroup_subtree_mask) == 0);
-
- u->cgroup_subtree_mask = m;
- u->cgroup_subtree_mask_valid = true;
-
- if (UNIT_ISSET(u->slice)) {
- Unit *s = UNIT_DEREF(u->slice);
-
- if (more)
- /* There's more set now than before. We
- * propagate the new mask to the parent's mask
- * (not caring if it actually was valid or
- * not). */
-
- s->cgroup_members_mask |= m;
-
- else
- /* There's less set now than before (or we
- * don't know), we need to recalculate
- * everything, so let's invalidate the
- * parent's members mask */
-
- s->cgroup_members_mask_valid = false;
-
- /* And now make sure that this change also hits our
- * grandparents */
- unit_update_cgroup_members_masks(s);
- }
-}
-
-static const char *migrate_callback(CGroupControllerMask mask, void *userdata) {
- Unit *u = userdata;
-
- assert(mask != 0);
- assert(u);
-
- while (u) {
- if (u->cgroup_path &&
- u->cgroup_realized &&
- (u->cgroup_realized_mask & mask) == mask)
- return u->cgroup_path;
-
- u = UNIT_DEREF(u->slice);
- }
-
- return NULL;
-}
-
-static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
- CGroupContext *c;
- int r;
-
- assert(u);
-
- c = unit_get_cgroup_context(u);
- if (!c)
- return 0;
-
- if (!u->cgroup_path) {
- _cleanup_free_ char *path = NULL;
-
- path = unit_default_cgroup_path(u);
- if (!path)
- return log_oom();
-
- r = hashmap_put(u->manager->cgroup_unit, path, u);
- if (r < 0) {
- log_error(r == -EEXIST ? "cgroup %s exists already: %s" : "hashmap_put failed for %s: %s", path, strerror(-r));
- return r;
- }
- if (r > 0) {
- u->cgroup_path = path;
- path = NULL;
- }
- }
-
- /* First, create our own group */
- r = cg_create_everywhere(u->manager->cgroup_supported, mask, u->cgroup_path);
- if (r < 0)
- return log_error_errno(r, "Failed to create cgroup %s: %m", u->cgroup_path);
-
- /* Keep track that this is now realized */
- u->cgroup_realized = true;
- u->cgroup_realized_mask = mask;
-
- if (u->type != UNIT_SLICE && !c->delegate) {
-
- /* Then, possibly move things over, but not if
- * subgroups may contain processes, which is the case
- * for slice and delegation units. */
- r = cg_migrate_everywhere(u->manager->cgroup_supported, u->cgroup_path, u->cgroup_path, migrate_callback, u);
- if (r < 0)
- log_warning_errno(r, "Failed to migrate cgroup from to %s: %m", u->cgroup_path);
- }
-
- return 0;
-}
-
-int unit_attach_pids_to_cgroup(Unit *u) {
- int r;
- assert(u);
-
- r = unit_realize_cgroup(u);
- if (r < 0)
- return r;
-
- r = cg_attach_many_everywhere(u->manager->cgroup_supported, u->cgroup_path, u->pids, migrate_callback, u);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-static bool unit_has_mask_realized(Unit *u, CGroupControllerMask mask) {
- assert(u);
-
- return u->cgroup_realized && u->cgroup_realized_mask == mask;
-}
-
-/* Check if necessary controllers and attributes for a unit are in place.
- *
- * If so, do nothing.
- * If not, create paths, move processes over, and set attributes.
- *
- * Returns 0 on success and < 0 on failure. */
-static int unit_realize_cgroup_now(Unit *u, ManagerState state) {
- CGroupControllerMask mask;
- int r;
-
- assert(u);
-
- if (u->in_cgroup_queue) {
- LIST_REMOVE(cgroup_queue, u->manager->cgroup_queue, u);
- u->in_cgroup_queue = false;
- }
-
- mask = unit_get_target_mask(u);
-
- if (unit_has_mask_realized(u, mask))
- return 0;
-
- /* First, realize parents */
- if (UNIT_ISSET(u->slice)) {
- r = unit_realize_cgroup_now(UNIT_DEREF(u->slice), state);
- if (r < 0)
- return r;
- }
-
- /* And then do the real work */
- r = unit_create_cgroups(u, mask);
- if (r < 0)
- return r;
-
- /* Finally, apply the necessary attributes. */
- cgroup_context_apply(unit_get_cgroup_context(u), mask, u->cgroup_path, state);
-
- return 0;
-}
-
-static void unit_add_to_cgroup_queue(Unit *u) {
-
- if (u->in_cgroup_queue)
- return;
-
- LIST_PREPEND(cgroup_queue, u->manager->cgroup_queue, u);
- u->in_cgroup_queue = true;
-}
-
-unsigned manager_dispatch_cgroup_queue(Manager *m) {
- ManagerState state;
- unsigned n = 0;
- Unit *i;
- int r;
-
- state = manager_state(m);
-
- while ((i = m->cgroup_queue)) {
- assert(i->in_cgroup_queue);
-
- r = unit_realize_cgroup_now(i, state);
- if (r < 0)
- log_warning_errno(r, "Failed to realize cgroups for queued unit %s: %m", i->id);
-
- n++;
- }
-
- return n;
-}
-
-static void unit_queue_siblings(Unit *u) {
- Unit *slice;
-
- /* This adds the siblings of the specified unit and the
- * siblings of all parent units to the cgroup queue. (But
- * neither the specified unit itself nor the parents.) */
-
- while ((slice = UNIT_DEREF(u->slice))) {
- Iterator i;
- Unit *m;
-
- SET_FOREACH(m, slice->dependencies[UNIT_BEFORE], i) {
- if (m == u)
- continue;
-
- /* Skip units that have a dependency on the slice
- * but aren't actually in it. */
- if (UNIT_DEREF(m->slice) != slice)
- continue;
-
- /* No point in doing cgroup application for units
- * without active processes. */
- if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(m)))
- continue;
-
- /* If the unit doesn't need any new controllers
- * and has current ones realized, it doesn't need
- * any changes. */
- if (unit_has_mask_realized(m, unit_get_target_mask(m)))
- continue;
-
- unit_add_to_cgroup_queue(m);
- }
-
- u = slice;
- }
-}
-
-int unit_realize_cgroup(Unit *u) {
- CGroupContext *c;
-
- assert(u);
-
- c = unit_get_cgroup_context(u);
- if (!c)
- return 0;
-
- /* So, here's the deal: when realizing the cgroups for this
- * unit, we need to first create all parents, but there's more
- * actually: for the weight-based controllers we also need to
- * make sure that all our siblings (i.e. units that are in the
- * same slice as we are) have cgroups, too. Otherwise, things
- * would become very uneven as each of their processes would
- * get as much resources as all our group together. This call
- * will synchronously create the parent cgroups, but will
- * defer work on the siblings to the next event loop
- * iteration. */
-
- /* Add all sibling slices to the cgroup queue. */
- unit_queue_siblings(u);
-
- /* And realize this one now (and apply the values) */
- return unit_realize_cgroup_now(u, manager_state(u->manager));
-}
-
-void unit_destroy_cgroup_if_empty(Unit *u) {
- int r;
-
- assert(u);
-
- if (!u->cgroup_path)
- return;
-
- r = cg_trim_everywhere(u->manager->cgroup_supported, u->cgroup_path, !unit_has_name(u, SPECIAL_ROOT_SLICE));
- if (r < 0) {
- log_debug_errno(r, "Failed to destroy cgroup %s: %m", u->cgroup_path);
- return;
- }
-
- hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
-
- free(u->cgroup_path);
- u->cgroup_path = NULL;
- u->cgroup_realized = false;
- u->cgroup_realized_mask = 0;
-}
-
-pid_t unit_search_main_pid(Unit *u) {
- _cleanup_fclose_ FILE *f = NULL;
- pid_t pid = 0, npid, mypid;
-
- assert(u);
-
- if (!u->cgroup_path)
- return 0;
-
- if (cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &f) < 0)
- return 0;
-
- mypid = getpid();
- while (cg_read_pid(f, &npid) > 0) {
- pid_t ppid;
-
- if (npid == pid)
- continue;
-
- /* Ignore processes that aren't our kids */
- if (get_parent_of_pid(npid, &ppid) >= 0 && ppid != mypid)
- continue;
-
- if (pid != 0) {
- /* Dang, there's more than one daemonized PID
- in this group, so we don't know what process
- is the main process. */
- pid = 0;
- break;
- }
-
- pid = npid;
- }
-
- return pid;
-}
-
-int manager_setup_cgroup(Manager *m) {
- _cleanup_free_ char *path = NULL;
- int r;
-
- assert(m);
-
- /* 1. Determine hierarchy */
- free(m->cgroup_root);
- m->cgroup_root = NULL;
-
- r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &m->cgroup_root);
- if (r < 0)
- return log_error_errno(r, "Cannot determine cgroup we are running in: %m");
-
- /* LEGACY: Already in /system.slice? If so, let's cut this
- * off. This is to support live upgrades from older systemd
- * versions where PID 1 was moved there. */
- if (m->running_as == SYSTEMD_SYSTEM) {
- char *e;
-
- e = endswith(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE);
- if (!e)
- e = endswith(m->cgroup_root, "/system");
- if (e)
- *e = 0;
- }
-
- /* And make sure to store away the root value without trailing
- * slash, even for the root dir, so that we can easily prepend
- * it everywhere. */
- if (streq(m->cgroup_root, "/"))
- m->cgroup_root[0] = 0;
-
- /* 2. Show data */
- r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, NULL, &path);
- if (r < 0)
- return log_error_errno(r, "Cannot find cgroup mount point: %m");
-
- log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path);
- if (!m->test_run) {
-
- /* 3. Install agent */
- if (m->running_as == SYSTEMD_SYSTEM) {
- r = -EINVAL;
- // cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH);
- if (r < 0)
- log_warning_errno(r, "Failed to install release agent, ignoring: %m");
- else if (r > 0)
- log_debug("Installed release agent.");
- else
- log_debug("Release agent already installed.");
- }
-
- /* 4. Make sure we are in the root cgroup */
- r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, 0);
- if (r < 0)
- return log_error_errno(r, "Failed to create root cgroup hierarchy: %m");
-
- /* 5. And pin it, so that it cannot be unmounted */
- safe_close(m->pin_cgroupfs_fd);
-
- m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK);
- if (m->pin_cgroupfs_fd < 0)
- return log_error_errno(errno, "Failed to open pin file: %m");
-
- /* 6. Always enable hierarchical support if it exists... */
- cg_set_attribute("memory", "/", "memory.use_hierarchy", "1");
- }
-
- /* 7. Figure out which controllers are supported */
- m->cgroup_supported = cg_mask_supported();
-
- return 0;
-}
-
-void manager_shutdown_cgroup(Manager *m, bool delete) {
- assert(m);
-
- /* We can't really delete the group, since we are in it. But
- * let's trim it. */
- if (delete && m->cgroup_root)
- cg_trim(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, false);
-
- m->pin_cgroupfs_fd = safe_close(m->pin_cgroupfs_fd);
-
- free(m->cgroup_root);
- m->cgroup_root = NULL;
-}
-
-Unit* manager_get_unit_by_cgroup(Manager *m, const char *cgroup) {
- char *p;
- Unit *u;
-
- assert(m);
- assert(cgroup);
-
- u = hashmap_get(m->cgroup_unit, cgroup);
- if (u)
- return u;
-
- p = strdupa(cgroup);
- for (;;) {
- char *e;
-
- e = strrchr(p, '/');
- if (e == p || !e)
- return NULL;
-
- *e = 0;
-
- u = hashmap_get(m->cgroup_unit, p);
- if (u)
- return u;
- }
-}
-
-Unit *manager_get_unit_by_pid(Manager *m, pid_t pid) {
- _cleanup_free_ char *cgroup = NULL;
- int r;
-
- assert(m);
-
- if (pid <= 1)
- return NULL;
-
- r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup);
- if (r < 0)
- return NULL;
-
- return manager_get_unit_by_cgroup(m, cgroup);
-}
-
-int manager_notify_cgroup_empty(Manager *m, const char *cgroup) {
- Unit *u;
- int r;
-
- assert(m);
- assert(cgroup);
-
- u = manager_get_unit_by_cgroup(m, cgroup);
- if (!u)
- return 0;
-
- r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true);
- if (r <= 0)
- return r;
-
- if (UNIT_VTABLE(u)->notify_cgroup_empty)
- UNIT_VTABLE(u)->notify_cgroup_empty(u);
-
- unit_add_to_gc_queue(u);
- return 0;
-}
-
-int unit_get_memory_current(Unit *u, uint64_t *ret) {
- _cleanup_free_ char *v = NULL;
- int r;
-
- assert(u);
- assert(ret);
-
- if (!u->cgroup_path)
- return -ENODATA;
-
- if ((u->cgroup_realized_mask & CGROUP_MEMORY) == 0)
- return -ENODATA;
-
- r = cg_get_attribute("memory", u->cgroup_path, "memory.usage_in_bytes", &v);
- if (r == -ENOENT)
- return -ENODATA;
- if (r < 0)
- return r;
-
- return safe_atou64(v, ret);
-}
-
-static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) {
- _cleanup_free_ char *v = NULL;
- uint64_t ns;
- int r;
-
- assert(u);
- assert(ret);
-
- if (!u->cgroup_path)
- return -ENODATA;
-
- if ((u->cgroup_realized_mask & CGROUP_CPUACCT) == 0)
- return -ENODATA;
-
- r = cg_get_attribute("cpuacct", u->cgroup_path, "cpuacct.usage", &v);
- if (r == -ENOENT)
- return -ENODATA;
- if (r < 0)
- return r;
-
- r = safe_atou64(v, &ns);
- if (r < 0)
- return r;
-
- *ret = ns;
- return 0;
-}
-
-int unit_get_cpu_usage(Unit *u, nsec_t *ret) {
- nsec_t ns;
- int r;
-
- r = unit_get_cpu_usage_raw(u, &ns);
- if (r < 0)
- return r;
-
- if (ns > u->cpuacct_usage_base)
- ns -= u->cpuacct_usage_base;
- else
- ns = 0;
-
- *ret = ns;
- return 0;
-}
-
-int unit_reset_cpu_usage(Unit *u) {
- nsec_t ns;
- int r;
-
- assert(u);
-
- r = unit_get_cpu_usage_raw(u, &ns);
- if (r < 0) {
- u->cpuacct_usage_base = 0;
- return r;
- }
-
- u->cpuacct_usage_base = ns;
- return 0;
-}
-
-static const char* const cgroup_device_policy_table[_CGROUP_DEVICE_POLICY_MAX] = {
- [CGROUP_AUTO] = "auto",
- [CGROUP_CLOSED] = "closed",
- [CGROUP_STRICT] = "strict",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(cgroup_device_policy, CGroupDevicePolicy);
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
deleted file mode 100644
index 869ddae8c..000000000
--- a/src/core/cgroup.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-#include "list.h"
-#include "time-util.h"
-
-typedef struct CGroupContext CGroupContext;
-typedef struct CGroupDeviceAllow CGroupDeviceAllow;
-typedef struct CGroupBlockIODeviceWeight CGroupBlockIODeviceWeight;
-typedef struct CGroupBlockIODeviceBandwidth CGroupBlockIODeviceBandwidth;
-
-typedef enum CGroupDevicePolicy {
-
- /* When devices listed, will allow those, plus built-in ones,
- if none are listed will allow everything. */
- CGROUP_AUTO,
-
- /* Everything forbidden, except built-in ones and listed ones. */
- CGROUP_CLOSED,
-
- /* Everythings forbidden, except for the listed devices */
- CGROUP_STRICT,
-
- _CGROUP_DEVICE_POLICY_MAX,
- _CGROUP_DEVICE_POLICY_INVALID = -1
-} CGroupDevicePolicy;
-
-struct CGroupDeviceAllow {
- LIST_FIELDS(CGroupDeviceAllow, device_allow);
- char *path;
- bool r:1;
- bool w:1;
- bool m:1;
-};
-
-struct CGroupBlockIODeviceWeight {
- LIST_FIELDS(CGroupBlockIODeviceWeight, device_weights);
- char *path;
- unsigned long weight;
-};
-
-struct CGroupBlockIODeviceBandwidth {
- LIST_FIELDS(CGroupBlockIODeviceBandwidth, device_bandwidths);
- char *path;
- uint64_t bandwidth;
- bool read;
-};
-
-struct CGroupContext {
- bool cpu_accounting;
- bool blockio_accounting;
- bool memory_accounting;
-
- unsigned long cpu_shares;
- unsigned long startup_cpu_shares;
- usec_t cpu_quota_per_sec_usec;
-
- unsigned long blockio_weight;
- unsigned long startup_blockio_weight;
- LIST_HEAD(CGroupBlockIODeviceWeight, blockio_device_weights);
- LIST_HEAD(CGroupBlockIODeviceBandwidth, blockio_device_bandwidths);
-
- uint64_t memory_limit;
-
- CGroupDevicePolicy device_policy;
- LIST_HEAD(CGroupDeviceAllow, device_allow);
-
- bool delegate;
-};
-
-#include "unit.h"
-#include "cgroup-util.h"
-
-void cgroup_context_init(CGroupContext *c);
-void cgroup_context_done(CGroupContext *c);
-void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix);
-void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const char *path, ManagerState state);
-
-CGroupControllerMask cgroup_context_get_mask(CGroupContext *c);
-
-void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a);
-void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w);
-void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b);
-
-CGroupControllerMask unit_get_cgroup_mask(Unit *u);
-CGroupControllerMask unit_get_siblings_mask(Unit *u);
-CGroupControllerMask unit_get_members_mask(Unit *u);
-CGroupControllerMask unit_get_target_mask(Unit *u);
-
-void unit_update_cgroup_members_masks(Unit *u);
-int unit_realize_cgroup(Unit *u);
-void unit_destroy_cgroup_if_empty(Unit *u);
-int unit_attach_pids_to_cgroup(Unit *u);
-
-int manager_setup_cgroup(Manager *m);
-void manager_shutdown_cgroup(Manager *m, bool delete);
-
-unsigned manager_dispatch_cgroup_queue(Manager *m);
-
-Unit *manager_get_unit_by_cgroup(Manager *m, const char *cgroup);
-Unit* manager_get_unit_by_pid(Manager *m, pid_t pid);
-
-pid_t unit_search_main_pid(Unit *u);
-
-int manager_notify_cgroup_empty(Manager *m, const char *group);
-
-int unit_get_memory_current(Unit *u, uint64_t *ret);
-int unit_get_cpu_usage(Unit *u, nsec_t *ret);
-int unit_reset_cpu_usage(Unit *u);
-
-const char* cgroup_device_policy_to_string(CGroupDevicePolicy i) _const_;
-CGroupDevicePolicy cgroup_device_policy_from_string(const char *s) _pure_;
diff --git a/src/core/dbus-automount.c b/src/core/dbus-automount.c
deleted file mode 100644
index 38acbd0c2..000000000
--- a/src/core/dbus-automount.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "automount.h"
-#include "dbus-automount.h"
-#include "bus-util.h"
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, automount_result, AutomountResult);
-
-const sd_bus_vtable bus_automount_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Where", "s", NULL, offsetof(Automount, where), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Automount, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Automount, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_VTABLE_END
-};
diff --git a/src/core/dbus-automount.h b/src/core/dbus-automount.h
deleted file mode 100644
index a2b124d75..000000000
--- a/src/core/dbus-automount.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-
-extern const sd_bus_vtable bus_automount_vtable[];
diff --git a/src/core/dbus-busname.c b/src/core/dbus-busname.c
deleted file mode 100644
index b1ceb05b1..000000000
--- a/src/core/dbus-busname.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "unit.h"
-#include "busname.h"
-#include "dbus-busname.h"
-#include "bus-util.h"
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, busname_result, BusNameResult);
-
-const sd_bus_vtable bus_busname_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Name", "s", NULL, offsetof(BusName, name), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TimeoutUSec", "t", bus_property_get_usec, offsetof(BusName, timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(BusName, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(BusName, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Activating", "b", bus_property_get_bool, offsetof(BusName, activating), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("AcceptFileDescriptors", "b", bus_property_get_bool, offsetof(BusName, accept_fd), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_VTABLE_END
-};
diff --git a/src/core/dbus-busname.h b/src/core/dbus-busname.h
deleted file mode 100644
index ea55b6c8c..000000000
--- a/src/core/dbus-busname.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-
-extern const sd_bus_vtable bus_busname_vtable[];
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
deleted file mode 100644
index 4a9df0601..000000000
--- a/src/core/dbus-cgroup.c
+++ /dev/null
@@ -1,680 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "bus-util.h"
-#include "path-util.h"
-#include "cgroup-util.h"
-#include "cgroup.h"
-#include "dbus-cgroup.h"
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy);
-
-static int property_get_blockio_device_weight(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- CGroupContext *c = userdata;
- CGroupBlockIODeviceWeight *w;
- int r;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- r = sd_bus_message_open_container(reply, 'a', "(st)");
- if (r < 0)
- return r;
-
- LIST_FOREACH(device_weights, w, c->blockio_device_weights) {
- r = sd_bus_message_append(reply, "(st)", w->path, w->weight);
- if (r < 0)
- return r;
- }
-
- return sd_bus_message_close_container(reply);
-}
-
-static int property_get_blockio_device_bandwidths(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- CGroupContext *c = userdata;
- CGroupBlockIODeviceBandwidth *b;
- int r;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- r = sd_bus_message_open_container(reply, 'a', "(st)");
- if (r < 0)
- return r;
-
- LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
-
- if (streq(property, "BlockIOReadBandwidth") != b->read)
- continue;
-
- r = sd_bus_message_append(reply, "(st)", b->path, b->bandwidth);
- if (r < 0)
- return r;
- }
-
- return sd_bus_message_close_container(reply);
-}
-
-static int property_get_device_allow(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- CGroupContext *c = userdata;
- CGroupDeviceAllow *a;
- int r;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- r = sd_bus_message_open_container(reply, 'a', "(ss)");
- if (r < 0)
- return r;
-
- LIST_FOREACH(device_allow, a, c->device_allow) {
- unsigned k = 0;
- char rwm[4];
-
- if (a->r)
- rwm[k++] = 'r';
- if (a->w)
- rwm[k++] = 'w';
- if (a->m)
- rwm[k++] = 'm';
-
- rwm[k] = 0;
-
- r = sd_bus_message_append(reply, "(ss)", a->path, rwm);
- if (r < 0)
- return r;
- }
-
- return sd_bus_message_close_container(reply);
-}
-
-static int property_get_ulong_as_u64(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- unsigned long *ul = userdata;
-
- assert(bus);
- assert(reply);
- assert(ul);
-
- return sd_bus_message_append(reply, "t", *ul == (unsigned long) -1 ? (uint64_t) -1 : (uint64_t) *ul);
-}
-
-const sd_bus_vtable bus_cgroup_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Delegate", "b", bus_property_get_bool, offsetof(CGroupContext, delegate), 0),
- SD_BUS_PROPERTY("CPUAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, cpu_accounting), 0),
- SD_BUS_PROPERTY("CPUShares", "t", property_get_ulong_as_u64, offsetof(CGroupContext, cpu_shares), 0),
- SD_BUS_PROPERTY("StartupCPUShares", "t", property_get_ulong_as_u64, offsetof(CGroupContext, startup_cpu_shares), 0),
- SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_per_sec_usec), 0),
- SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, blockio_accounting), 0),
- SD_BUS_PROPERTY("BlockIOWeight", "t", property_get_ulong_as_u64, offsetof(CGroupContext, blockio_weight), 0),
- SD_BUS_PROPERTY("StartupBlockIOWeight", "t", property_get_ulong_as_u64, offsetof(CGroupContext, startup_blockio_weight), 0),
- SD_BUS_PROPERTY("BlockIODeviceWeight", "a(st)", property_get_blockio_device_weight, 0, 0),
- SD_BUS_PROPERTY("BlockIOReadBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
- SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
- SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, memory_accounting), 0),
- SD_BUS_PROPERTY("MemoryLimit", "t", NULL, offsetof(CGroupContext, memory_limit), 0),
- SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy, offsetof(CGroupContext, device_policy), 0),
- SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow, 0, 0),
- SD_BUS_VTABLE_END
-};
-
-static int bus_cgroup_set_transient_property(
- Unit *u,
- CGroupContext *c,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- int r;
-
- assert(u);
- assert(c);
- assert(name);
- assert(message);
-
- if (streq(name, "Delegate")) {
- int b;
-
- r = sd_bus_message_read(message, "b", &b);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- c->delegate = b;
- unit_write_drop_in_private(u, mode, name, b ? "Delegate=yes" : "Delegate=no");
- }
-
- return 1;
- }
-
- return 0;
-}
-
-int bus_cgroup_set_property(
- Unit *u,
- CGroupContext *c,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- int r;
-
- assert(u);
- assert(c);
- assert(name);
- assert(message);
-
- if (streq(name, "CPUAccounting")) {
- int b;
-
- r = sd_bus_message_read(message, "b", &b);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- c->cpu_accounting = b;
- u->cgroup_realized_mask &= ~CGROUP_CPUACCT;
- unit_write_drop_in_private(u, mode, name, b ? "CPUAccounting=yes" : "CPUAccounting=no");
- }
-
- return 1;
-
- } else if (streq(name, "CPUShares")) {
- uint64_t u64;
- unsigned long ul;
-
- r = sd_bus_message_read(message, "t", &u64);
- if (r < 0)
- return r;
-
- if (u64 == (uint64_t) -1)
- ul = (unsigned long) -1;
- else {
- ul = (unsigned long) u64;
- if (ul <= 0 || (uint64_t) ul != u64)
- return sd_bus_error_set_errnof(error, EINVAL, "CPUShares value out of range");
- }
-
- if (mode != UNIT_CHECK) {
- c->cpu_shares = ul;
- u->cgroup_realized_mask &= ~CGROUP_CPU;
- unit_write_drop_in_private_format(u, mode, name, "CPUShares=%lu", ul);
- }
-
- return 1;
-
- } else if (streq(name, "StartupCPUShares")) {
- uint64_t u64;
- unsigned long ul;
-
- r = sd_bus_message_read(message, "t", &u64);
- if (r < 0)
- return r;
-
- if (u64 == (uint64_t) -1)
- ul = (unsigned long) -1;
- else {
- ul = (unsigned long) u64;
- if (ul <= 0 || (uint64_t) ul != u64)
- return sd_bus_error_set_errnof(error, EINVAL, "StartupCPUShares value out of range");
- }
-
- if (mode != UNIT_CHECK) {
- c->startup_cpu_shares = ul;
- u->cgroup_realized_mask &= ~CGROUP_CPU;
- unit_write_drop_in_private_format(u, mode, name, "StartupCPUShares=%lu", ul);
- }
-
- return 1;
-
- } else if (streq(name, "CPUQuotaPerSecUSec")) {
- uint64_t u64;
-
- r = sd_bus_message_read(message, "t", &u64);
- if (r < 0)
- return r;
-
- if (u64 <= 0)
- return sd_bus_error_set_errnof(error, EINVAL, "CPUQuotaPerSecUSec value out of range");
-
- if (mode != UNIT_CHECK) {
- c->cpu_quota_per_sec_usec = u64;
- u->cgroup_realized_mask &= ~CGROUP_CPU;
- unit_write_drop_in_private_format(u, mode, "CPUQuota", "CPUQuota=%0.f%%", (double) (c->cpu_quota_per_sec_usec / 10000));
- }
-
- return 1;
-
- } else if (streq(name, "BlockIOAccounting")) {
- int b;
-
- r = sd_bus_message_read(message, "b", &b);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- c->blockio_accounting = b;
- u->cgroup_realized_mask &= ~CGROUP_BLKIO;
- unit_write_drop_in_private(u, mode, name, b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no");
- }
-
- return 1;
-
- } else if (streq(name, "BlockIOWeight")) {
- uint64_t u64;
- unsigned long ul;
-
- r = sd_bus_message_read(message, "t", &u64);
- if (r < 0)
- return r;
-
- if (u64 == (uint64_t) -1)
- ul = (unsigned long) -1;
- else {
- ul = (unsigned long) u64;
- if (ul < 10 || ul > 1000)
- return sd_bus_error_set_errnof(error, EINVAL, "BlockIOWeight value out of range");
- }
-
- if (mode != UNIT_CHECK) {
- c->blockio_weight = ul;
- u->cgroup_realized_mask &= ~CGROUP_BLKIO;
- unit_write_drop_in_private_format(u, mode, name, "BlockIOWeight=%lu", ul);
- }
-
- return 1;
-
- } else if (streq(name, "StartupBlockIOWeight")) {
- uint64_t u64;
- unsigned long ul;
-
- r = sd_bus_message_read(message, "t", &u64);
- if (r < 0)
- return r;
-
- if (u64 == (uint64_t) -1)
- ul = (unsigned long) -1;
- else {
- ul = (unsigned long) u64;
- if (ul < 10 || ul > 1000)
- return sd_bus_error_set_errnof(error, EINVAL, "StartupBlockIOWeight value out of range");
- }
-
- if (mode != UNIT_CHECK) {
- c->startup_blockio_weight = ul;
- u->cgroup_realized_mask &= ~CGROUP_BLKIO;
- unit_write_drop_in_private_format(u, mode, name, "StartupBlockIOWeight=%lu", ul);
- }
-
- return 1;
-
- } else if (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth")) {
- const char *path;
- bool read = true;
- unsigned n = 0;
- uint64_t u64;
-
- if (streq(name, "BlockIOWriteBandwidth"))
- read = false;
-
- r = sd_bus_message_enter_container(message, 'a', "(st)");
- if (r < 0)
- return r;
-
- while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) {
-
- if (mode != UNIT_CHECK) {
- CGroupBlockIODeviceBandwidth *a = NULL, *b;
-
- LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
- if (path_equal(path, b->path) && read == b->read) {
- a = b;
- break;
- }
- }
-
- if (!a) {
- a = new0(CGroupBlockIODeviceBandwidth, 1);
- if (!a)
- return -ENOMEM;
-
- a->read = read;
- a->path = strdup(path);
- if (!a->path) {
- free(a);
- return -ENOMEM;
- }
-
- LIST_PREPEND(device_bandwidths, c->blockio_device_bandwidths, a);
- }
-
- a->bandwidth = u64;
- }
-
- n++;
- }
- if (r < 0)
- return r;
-
- r = sd_bus_message_exit_container(message);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- CGroupBlockIODeviceBandwidth *a, *next;
- _cleanup_free_ char *buf = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- size_t size = 0;
-
- if (n == 0) {
- LIST_FOREACH_SAFE(device_bandwidths, a, next, c->blockio_device_bandwidths)
- if (a->read == read)
- cgroup_context_free_blockio_device_bandwidth(c, a);
- }
-
- u->cgroup_realized_mask &= ~CGROUP_BLKIO;
-
- f = open_memstream(&buf, &size);
- if (!f)
- return -ENOMEM;
-
- if (read) {
- fputs("BlockIOReadBandwidth=\n", f);
- LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths)
- if (a->read)
- fprintf(f, "BlockIOReadBandwidth=%s %" PRIu64 "\n", a->path, a->bandwidth);
- } else {
- fputs("BlockIOWriteBandwidth=\n", f);
- LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths)
- if (!a->read)
- fprintf(f, "BlockIOWriteBandwidth=%s %" PRIu64 "\n", a->path, a->bandwidth);
- }
-
- fflush(f);
- unit_write_drop_in_private(u, mode, name, buf);
- }
-
- return 1;
-
- } else if (streq(name, "BlockIODeviceWeight")) {
- const char *path;
- uint64_t u64;
- unsigned n = 0;
-
- r = sd_bus_message_enter_container(message, 'a', "(st)");
- if (r < 0)
- return r;
-
- while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) {
- unsigned long ul = u64;
-
- if (ul < 10 || ul > 1000)
- return sd_bus_error_set_errnof(error, EINVAL, "BlockIODeviceWeight out of range");
-
- if (mode != UNIT_CHECK) {
- CGroupBlockIODeviceWeight *a = NULL, *b;
-
- LIST_FOREACH(device_weights, b, c->blockio_device_weights) {
- if (path_equal(b->path, path)) {
- a = b;
- break;
- }
- }
-
- if (!a) {
- a = new0(CGroupBlockIODeviceWeight, 1);
- if (!a)
- return -ENOMEM;
-
- a->path = strdup(path);
- if (!a->path) {
- free(a);
- return -ENOMEM;
- }
- LIST_PREPEND(device_weights,c->blockio_device_weights, a);
- }
-
- a->weight = ul;
- }
-
- n++;
- }
-
- r = sd_bus_message_exit_container(message);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- _cleanup_free_ char *buf = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- CGroupBlockIODeviceWeight *a;
- size_t size = 0;
-
- if (n == 0) {
- while (c->blockio_device_weights)
- cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights);
- }
-
- u->cgroup_realized_mask &= ~CGROUP_BLKIO;
-
- f = open_memstream(&buf, &size);
- if (!f)
- return -ENOMEM;
-
- fputs("BlockIODeviceWeight=\n", f);
- LIST_FOREACH(device_weights, a, c->blockio_device_weights)
- fprintf(f, "BlockIODeviceWeight=%s %lu\n", a->path, a->weight);
-
- fflush(f);
- unit_write_drop_in_private(u, mode, name, buf);
- }
-
- return 1;
-
- } else if (streq(name, "MemoryAccounting")) {
- int b;
-
- r = sd_bus_message_read(message, "b", &b);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- c->memory_accounting = b;
- u->cgroup_realized_mask &= ~CGROUP_MEMORY;
- unit_write_drop_in_private(u, mode, name, b ? "MemoryAccounting=yes" : "MemoryAccounting=no");
- }
-
- return 1;
-
- } else if (streq(name, "MemoryLimit")) {
- uint64_t limit;
-
- r = sd_bus_message_read(message, "t", &limit);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- c->memory_limit = limit;
- u->cgroup_realized_mask &= ~CGROUP_MEMORY;
- unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64, name, limit);
- }
-
- return 1;
-
- } else if (streq(name, "DevicePolicy")) {
- const char *policy;
- CGroupDevicePolicy p;
-
- r = sd_bus_message_read(message, "s", &policy);
- if (r < 0)
- return r;
-
- p = cgroup_device_policy_from_string(policy);
- if (p < 0)
- return -EINVAL;
-
- if (mode != UNIT_CHECK) {
- char *buf;
-
- c->device_policy = p;
- u->cgroup_realized_mask &= ~CGROUP_DEVICE;
-
- buf = strjoina("DevicePolicy=", policy);
- unit_write_drop_in_private(u, mode, name, buf);
- }
-
- return 1;
-
- } else if (streq(name, "DeviceAllow")) {
- const char *path, *rwm;
- unsigned n = 0;
-
- r = sd_bus_message_enter_container(message, 'a', "(ss)");
- if (r < 0)
- return r;
-
- while ((r = sd_bus_message_read(message, "(ss)", &path, &rwm)) > 0) {
-
- if ((!startswith(path, "/dev/") &&
- !startswith(path, "block-") &&
- !startswith(path, "char-")) ||
- strpbrk(path, WHITESPACE))
- return sd_bus_error_set_errnof(error, EINVAL, "DeviceAllow= requires device node");
-
- if (isempty(rwm))
- rwm = "rwm";
-
- if (!in_charset(rwm, "rwm"))
- return sd_bus_error_set_errnof(error, EINVAL, "DeviceAllow= requires combination of rwm flags");
-
- if (mode != UNIT_CHECK) {
- CGroupDeviceAllow *a = NULL, *b;
-
- LIST_FOREACH(device_allow, b, c->device_allow) {
- if (path_equal(b->path, path)) {
- a = b;
- break;
- }
- }
-
- if (!a) {
- a = new0(CGroupDeviceAllow, 1);
- if (!a)
- return -ENOMEM;
-
- a->path = strdup(path);
- if (!a->path) {
- free(a);
- return -ENOMEM;
- }
-
- LIST_PREPEND(device_allow, c->device_allow, a);
- }
-
- a->r = !!strchr(rwm, 'r');
- a->w = !!strchr(rwm, 'w');
- a->m = !!strchr(rwm, 'm');
- }
-
- n++;
- }
- if (r < 0)
- return r;
-
- r = sd_bus_message_exit_container(message);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- _cleanup_free_ char *buf = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- CGroupDeviceAllow *a;
- size_t size = 0;
-
- if (n == 0) {
- while (c->device_allow)
- cgroup_context_free_device_allow(c, c->device_allow);
- }
-
- u->cgroup_realized_mask &= ~CGROUP_DEVICE;
-
- f = open_memstream(&buf, &size);
- if (!f)
- return -ENOMEM;
-
- fputs("DeviceAllow=\n", f);
- LIST_FOREACH(device_allow, a, c->device_allow)
- fprintf(f, "DeviceAllow=%s %s%s%s\n", a->path, a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : "");
-
- fflush(f);
- unit_write_drop_in_private(u, mode, name, buf);
- }
-
- return 1;
-
- }
-
- if (u->transient && u->load_state == UNIT_STUB) {
- r = bus_cgroup_set_transient_property(u, c, name, message, mode, error);
- if (r != 0)
- return r;
-
- }
-
- return 0;
-}
diff --git a/src/core/dbus-cgroup.h b/src/core/dbus-cgroup.h
deleted file mode 100644
index c2a3910f3..000000000
--- a/src/core/dbus-cgroup.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "cgroup.h"
-
-extern const sd_bus_vtable bus_cgroup_vtable[];
-
-int bus_cgroup_set_property(Unit *u, CGroupContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
diff --git a/src/core/dbus-device.c b/src/core/dbus-device.c
deleted file mode 100644
index cb156fd37..000000000
--- a/src/core/dbus-device.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "unit.h"
-#include "device.h"
-#include "dbus-device.h"
-
-const sd_bus_vtable bus_device_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("SysFSPath", "s", NULL, offsetof(Device, sysfs), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_VTABLE_END
-};
diff --git a/src/core/dbus-device.h b/src/core/dbus-device.h
deleted file mode 100644
index 10e945e40..000000000
--- a/src/core/dbus-device.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "unit.h"
-
-extern const sd_bus_vtable bus_device_vtable[];
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
deleted file mode 100644
index a9f7971cd..000000000
--- a/src/core/dbus-execute.c
+++ /dev/null
@@ -1,1006 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/prctl.h>
-
-#ifdef HAVE_SECCOMP
-#include <seccomp.h>
-#endif
-
-#include "bus-util.h"
-#include "missing.h"
-#include "ioprio.h"
-#include "strv.h"
-#include "fileio.h"
-#include "execute.h"
-#include "capability.h"
-#include "env-util.h"
-#include "af-list.h"
-#include "namespace.h"
-#include "path-util.h"
-#include "dbus-execute.h"
-
-#ifdef HAVE_SECCOMP
-#include "seccomp-util.h"
-#endif
-
-BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_home, protect_home, ProtectHome);
-static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_system, protect_system, ProtectSystem);
-
-static int property_get_environment_files(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
- char **j;
- int r;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- r = sd_bus_message_open_container(reply, 'a', "(sb)");
- if (r < 0)
- return r;
-
- STRV_FOREACH(j, c->environment_files) {
- const char *fn = *j;
-
- r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
- if (r < 0)
- return r;
- }
-
- return sd_bus_message_close_container(reply);
-}
-
-static int property_get_rlimit(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- struct rlimit *rl;
- uint64_t u;
- rlim_t x;
-
- assert(bus);
- assert(reply);
- assert(userdata);
-
- rl = *(struct rlimit**) userdata;
- if (rl)
- x = rl->rlim_max;
- else {
- struct rlimit buf = {};
- int z;
-
- z = rlimit_from_string(property);
- assert(z >= 0);
-
- getrlimit(z, &buf);
- x = buf.rlim_max;
- }
-
- /* rlim_t might have different sizes, let's map
- * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on
- * all archs */
- u = x == RLIM_INFINITY ? (uint64_t) -1 : (uint64_t) x;
-
- return sd_bus_message_append(reply, "t", u);
-}
-
-static int property_get_oom_score_adjust(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
-
- ExecContext *c = userdata;
- int32_t n;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- if (c->oom_score_adjust_set)
- n = c->oom_score_adjust;
- else {
- _cleanup_free_ char *t = NULL;
-
- n = 0;
- if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
- safe_atoi(t, &n);
- }
-
- return sd_bus_message_append(reply, "i", n);
-}
-
-static int property_get_nice(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
-
- ExecContext *c = userdata;
- int32_t n;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- if (c->nice_set)
- n = c->nice;
- else {
- errno = 0;
- n = getpriority(PRIO_PROCESS, 0);
- if (errno != 0)
- n = 0;
- }
-
- return sd_bus_message_append(reply, "i", n);
-}
-
-static int property_get_ioprio(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
-
- ExecContext *c = userdata;
- int32_t n;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- if (c->ioprio_set)
- n = c->ioprio;
- else {
- n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
- if (n < 0)
- n = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
- }
-
- return sd_bus_message_append(reply, "i", n);
-}
-
-static int property_get_cpu_sched_policy(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
- int32_t n;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- if (c->cpu_sched_set)
- n = c->cpu_sched_policy;
- else {
- n = sched_getscheduler(0);
- if (n < 0)
- n = SCHED_OTHER;
- }
-
- return sd_bus_message_append(reply, "i", n);
-}
-
-static int property_get_cpu_sched_priority(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
- int32_t n;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- if (c->cpu_sched_set)
- n = c->cpu_sched_priority;
- else {
- struct sched_param p = {};
-
- if (sched_getparam(0, &p) >= 0)
- n = p.sched_priority;
- else
- n = 0;
- }
-
- return sd_bus_message_append(reply, "i", n);
-}
-
-static int property_get_cpu_affinity(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- if (c->cpuset)
- return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
- else
- return sd_bus_message_append_array(reply, 'y', NULL, 0);
-}
-
-static int property_get_timer_slack_nsec(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
- uint64_t u;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- if (c->timer_slack_nsec != NSEC_INFINITY)
- u = (uint64_t) c->timer_slack_nsec;
- else
- u = (uint64_t) prctl(PR_GET_TIMERSLACK);
-
- return sd_bus_message_append(reply, "t", u);
-}
-
-static int property_get_capability_bounding_set(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- /* We store this negated internally, to match the kernel, but
- * we expose it normalized. */
- return sd_bus_message_append(reply, "t", ~c->capability_bounding_set_drop);
-}
-
-static int property_get_capabilities(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
- _cleanup_cap_free_charp_ char *t = NULL;
- const char *s;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- if (c->capabilities)
- s = t = cap_to_text(c->capabilities, NULL);
- else
- s = "";
-
- if (!s)
- return -ENOMEM;
-
- return sd_bus_message_append(reply, "s", s);
-}
-
-static int property_get_syscall_filter(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
- _cleanup_strv_free_ char **l = NULL;
- int r;
-
-#ifdef HAVE_SECCOMP
- Iterator i;
- void *id;
-#endif
-
- assert(bus);
- assert(reply);
- assert(c);
-
- r = sd_bus_message_open_container(reply, 'r', "bas");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(reply, "b", c->syscall_whitelist);
- if (r < 0)
- return r;
-
-#ifdef HAVE_SECCOMP
- SET_FOREACH(id, c->syscall_filter, i) {
- char *name;
-
- name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
- if (!name)
- continue;
-
- r = strv_consume(&l, name);
- if (r < 0)
- return r;
- }
-#endif
-
- strv_sort(l);
-
- r = sd_bus_message_append_strv(reply, l);
- if (r < 0)
- return r;
-
- return sd_bus_message_close_container(reply);
-}
-
-static int property_get_syscall_archs(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
- _cleanup_strv_free_ char **l = NULL;
- int r;
-
-#ifdef HAVE_SECCOMP
- Iterator i;
- void *id;
-#endif
-
- assert(bus);
- assert(reply);
- assert(c);
-
-#ifdef HAVE_SECCOMP
- SET_FOREACH(id, c->syscall_archs, i) {
- const char *name;
-
- name = seccomp_arch_to_string(PTR_TO_UINT32(id) - 1);
- if (!name)
- continue;
-
- r = strv_extend(&l, name);
- if (r < 0)
- return -ENOMEM;
- }
-#endif
-
- strv_sort(l);
-
- r = sd_bus_message_append_strv(reply, l);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-static int property_get_syscall_errno(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- return sd_bus_message_append(reply, "i", (int32_t) c->syscall_errno);
-}
-
-static int property_get_selinux_context(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context);
-}
-
-static int property_get_apparmor_profile(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
-}
-
-static int property_get_smack_process_label(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- return sd_bus_message_append(reply, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
-}
-
-static int property_get_personality(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- return sd_bus_message_append(reply, "s", personality_to_string(c->personality));
-}
-
-static int property_get_address_families(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- ExecContext *c = userdata;
- _cleanup_strv_free_ char **l = NULL;
- Iterator i;
- void *af;
- int r;
-
- assert(bus);
- assert(reply);
- assert(c);
-
- r = sd_bus_message_open_container(reply, 'r', "bas");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(reply, "b", c->address_families_whitelist);
- if (r < 0)
- return r;
-
- SET_FOREACH(af, c->address_families, i) {
- const char *name;
-
- name = af_to_name(PTR_TO_INT(af));
- if (!name)
- continue;
-
- r = strv_extend(&l, name);
- if (r < 0)
- return -ENOMEM;
- }
-
- strv_sort(l);
-
- r = sd_bus_message_append_strv(reply, l);
- if (r < 0)
- return r;
-
- return sd_bus_message_close_container(reply);
-}
-
-const sd_bus_vtable bus_exec_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitCPU", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitFSIZE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitDATA", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitSTACK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitCORE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitRSS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitNOFILE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitAS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitNPROC", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitMEMLOCK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitLOCKS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitSIGPENDING", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitMSGQUEUE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitNICE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitRTPRIO", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LimitRTTIME", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("WorkingDirectory", "s", NULL, offsetof(ExecContext, working_directory), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ProtectHome", "s", bus_property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ProtectSystem", "s", bus_property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Personality", "s", property_get_personality, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, runtime_directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, runtime_directory), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_VTABLE_END
-};
-
-static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
- int r;
-
- assert(reply);
- assert(c);
-
- if (!c->path)
- return 0;
-
- r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(reply, "s", c->path);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append_strv(reply, c->argv);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(reply, "bttttuii",
- c->ignore,
- c->exec_status.start_timestamp.realtime,
- c->exec_status.start_timestamp.monotonic,
- c->exec_status.exit_timestamp.realtime,
- c->exec_status.exit_timestamp.monotonic,
- (uint32_t) c->exec_status.pid,
- (int32_t) c->exec_status.code,
- (int32_t) c->exec_status.status);
- if (r < 0)
- return r;
-
- return sd_bus_message_close_container(reply);
-}
-
-int bus_property_get_exec_command(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *ret_error) {
-
- ExecCommand *c = (ExecCommand*) userdata;
- int r;
-
- assert(bus);
- assert(reply);
-
- r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
- if (r < 0)
- return r;
-
- r = append_exec_command(reply, c);
- if (r < 0)
- return r;
-
- return sd_bus_message_close_container(reply);
-}
-
-int bus_property_get_exec_command_list(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *ret_error) {
-
- ExecCommand *c = *(ExecCommand**) userdata;
- int r;
-
- assert(bus);
- assert(reply);
-
- r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
- if (r < 0)
- return r;
-
- LIST_FOREACH(command, c, c) {
- r = append_exec_command(reply, c);
- if (r < 0)
- return r;
- }
-
- return sd_bus_message_close_container(reply);
-}
-
-int bus_exec_context_set_transient_property(
- Unit *u,
- ExecContext *c,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- int r;
-
- assert(u);
- assert(c);
- assert(name);
- assert(message);
-
- if (streq(name, "User")) {
- const char *uu;
-
- r = sd_bus_message_read(message, "s", &uu);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
-
- if (isempty(uu)) {
- free(c->user);
- c->user = NULL;
- } else {
- char *t;
-
- t = strdup(uu);
- if (!t)
- return -ENOMEM;
-
- free(c->user);
- c->user = t;
- }
-
- unit_write_drop_in_private_format(u, mode, name, "User=%s\n", uu);
- }
-
- return 1;
-
- } else if (streq(name, "Group")) {
- const char *gg;
-
- r = sd_bus_message_read(message, "s", &gg);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
-
- if (isempty(gg)) {
- free(c->group);
- c->group = NULL;
- } else {
- char *t;
-
- t = strdup(gg);
- if (!t)
- return -ENOMEM;
-
- free(c->group);
- c->group = t;
- }
-
- unit_write_drop_in_private_format(u, mode, name, "Group=%s\n", gg);
- }
-
- return 1;
-
- } else if (streq(name, "Nice")) {
- int n;
-
- r = sd_bus_message_read(message, "i", &n);
- if (r < 0)
- return r;
-
- if (n < PRIO_MIN || n >= PRIO_MAX)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
-
- if (mode != UNIT_CHECK) {
- c->nice = n;
- unit_write_drop_in_private_format(u, mode, name, "Nice=%i\n", n);
- }
-
- return 1;
-
- } else if (streq(name, "TTYPath")) {
- const char *tty;
-
- r = sd_bus_message_read(message, "s", &tty);
- if (r < 0)
- return r;
-
- if (!path_is_absolute(tty))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY device not absolute path");
-
- if (mode != UNIT_CHECK) {
- char *t;
-
- t = strdup(tty);
- if (!t)
- return -ENOMEM;
-
- free(c->tty_path);
- c->tty_path = t;
-
- unit_write_drop_in_private_format(u, mode, name, "TTYPath=%s\n", tty);
- }
-
- return 1;
-
- } else if (streq(name, "StandardInput")) {
- const char *s;
- ExecInput p;
-
- r = sd_bus_message_read(message, "s", &s);
- if (r < 0)
- return r;
-
- p = exec_input_from_string(s);
- if (p < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard input name");
-
- if (mode != UNIT_CHECK) {
- c->std_input = p;
-
- unit_write_drop_in_private_format(u, mode, name, "StandardInput=%s\n", exec_input_to_string(p));
- }
-
- return 1;
-
-
- } else if (streq(name, "StandardOutput")) {
- const char *s;
- ExecOutput p;
-
- r = sd_bus_message_read(message, "s", &s);
- if (r < 0)
- return r;
-
- p = exec_output_from_string(s);
- if (p < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard output name");
-
- if (mode != UNIT_CHECK) {
- c->std_output = p;
-
- unit_write_drop_in_private_format(u, mode, name, "StandardOutput=%s\n", exec_output_to_string(p));
- }
-
- return 1;
-
- } else if (streq(name, "StandardError")) {
- const char *s;
- ExecOutput p;
-
- r = sd_bus_message_read(message, "s", &s);
- if (r < 0)
- return r;
-
- p = exec_output_from_string(s);
- if (p < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard error name");
-
- if (mode != UNIT_CHECK) {
- c->std_error = p;
-
- unit_write_drop_in_private_format(u, mode, name, "StandardError=%s\n", exec_output_to_string(p));
- }
-
- return 1;
-
- } else if (streq(name, "Environment")) {
-
- _cleanup_strv_free_ char **l = NULL;
-
- r = sd_bus_message_read_strv(message, &l);
- if (r < 0)
- return r;
-
- if (!strv_env_is_valid(l))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
-
- if (mode != UNIT_CHECK) {
- _cleanup_free_ char *joined = NULL;
- char **e;
-
- e = strv_env_merge(2, c->environment, l);
- if (!e)
- return -ENOMEM;
-
- strv_free(c->environment);
- c->environment = e;
-
- joined = strv_join_quoted(c->environment);
- if (!joined)
- return -ENOMEM;
-
- unit_write_drop_in_private_format(u, mode, name, "Environment=%s\n", joined);
- }
-
- return 1;
-
- } else if (rlimit_from_string(name) >= 0) {
- uint64_t rl;
- rlim_t x;
-
- r = sd_bus_message_read(message, "t", &rl);
- if (r < 0)
- return r;
-
- if (rl == (uint64_t) -1)
- x = RLIM_INFINITY;
- else {
- x = (rlim_t) rl;
-
- if ((uint64_t) x != rl)
- return -ERANGE;
- }
-
- if (mode != UNIT_CHECK) {
- int z;
-
- z = rlimit_from_string(name);
-
- if (!c->rlimit[z]) {
- c->rlimit[z] = new(struct rlimit, 1);
- if (!c->rlimit[z])
- return -ENOMEM;
- }
-
- c->rlimit[z]->rlim_cur = c->rlimit[z]->rlim_max = x;
-
- if (x == RLIM_INFINITY)
- unit_write_drop_in_private_format(u, mode, name, "%s=infinity\n", name);
- else
- unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64 "\n", name, rl);
- }
-
- return 1;
- }
-
- return 0;
-}
diff --git a/src/core/dbus-execute.h b/src/core/dbus-execute.h
deleted file mode 100644
index e4c2d5ddf..000000000
--- a/src/core/dbus-execute.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "execute.h"
-
-#define BUS_EXEC_STATUS_VTABLE(prefix, offset, flags) \
- BUS_PROPERTY_DUAL_TIMESTAMP(prefix "StartTimestamp", (offset) + offsetof(ExecStatus, start_timestamp), flags), \
- BUS_PROPERTY_DUAL_TIMESTAMP(prefix "ExitTimestamp", (offset) + offsetof(ExecStatus, exit_timestamp), flags), \
- SD_BUS_PROPERTY(prefix "PID", "u", bus_property_get_pid, (offset) + offsetof(ExecStatus, pid), flags), \
- SD_BUS_PROPERTY(prefix "Code", "i", bus_property_get_int, (offset) + offsetof(ExecStatus, code), flags), \
- SD_BUS_PROPERTY(prefix "Status", "i", bus_property_get_int, (offset) + offsetof(ExecStatus, status), flags)
-
-#define BUS_EXEC_COMMAND_VTABLE(name, offset, flags) \
- SD_BUS_PROPERTY(name, "a(sasbttttuii)", bus_property_get_exec_command, offset, flags)
-
-#define BUS_EXEC_COMMAND_LIST_VTABLE(name, offset, flags) \
- SD_BUS_PROPERTY(name, "a(sasbttttuii)", bus_property_get_exec_command_list, offset, flags)
-
-extern const sd_bus_vtable bus_exec_vtable[];
-
-int bus_property_get_exec_output(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error);
-int bus_property_get_exec_command(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error);
-int bus_property_get_exec_command_list(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error);
-
-int bus_exec_context_set_transient_property(Unit *u, ExecContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c
deleted file mode 100644
index fa1d1f338..000000000
--- a/src/core/dbus-job.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "log.h"
-#include "sd-bus.h"
-#include "selinux-access.h"
-#include "job.h"
-#include "dbus-job.h"
-#include "dbus.h"
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, job_type, JobType);
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_state, job_state, JobState);
-
-static int property_get_unit(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- _cleanup_free_ char *p = NULL;
- Job *j = userdata;
-
- assert(bus);
- assert(reply);
- assert(j);
-
- p = unit_dbus_path(j->unit);
- if (!p)
- return -ENOMEM;
-
- return sd_bus_message_append(reply, "(so)", j->unit->id, p);
-}
-
-int bus_job_method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Job *j = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(j);
-
- r = mac_selinux_unit_access_check(j->unit, message, "stop", error);
- if (r < 0)
- return r;
-
- /* Access is granted to the job owner */
- if (!sd_bus_track_contains(j->clients, sd_bus_message_get_sender(message))) {
-
- /* And for everybody else consult PolicyKit */
- r = bus_verify_manage_units_async(j->unit->manager, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- }
-
- job_finish_and_invalidate(j, JOB_CANCELED, true);
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-const sd_bus_vtable bus_job_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_METHOD("Cancel", NULL, NULL, bus_job_method_cancel, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_PROPERTY("Id", "u", NULL, offsetof(Job, id), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Unit", "(so)", property_get_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("JobType", "s", property_get_type, offsetof(Job, type), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("State", "s", property_get_state, offsetof(Job, state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_VTABLE_END
-};
-
-static int send_new_signal(sd_bus *bus, void *userdata) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
- _cleanup_free_ char *p = NULL;
- Job *j = userdata;
- int r;
-
- assert(bus);
- assert(j);
-
- p = job_dbus_path(j);
- if (!p)
- return -ENOMEM;
-
- r = sd_bus_message_new_signal(
- bus,
- &m,
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "JobNew");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(m, "uos", j->id, p, j->unit->id);
- if (r < 0)
- return r;
-
- return sd_bus_send(bus, m, NULL);
-}
-
-static int send_changed_signal(sd_bus *bus, void *userdata) {
- _cleanup_free_ char *p = NULL;
- Job *j = userdata;
-
- assert(bus);
- assert(j);
-
- p = job_dbus_path(j);
- if (!p)
- return -ENOMEM;
-
- return sd_bus_emit_properties_changed(bus, p, "org.freedesktop.systemd1.Job", "State", NULL);
-}
-
-void bus_job_send_change_signal(Job *j) {
- int r;
-
- assert(j);
-
- if (j->in_dbus_queue) {
- LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
- j->in_dbus_queue = false;
- }
-
- r = bus_foreach_bus(j->manager, j->clients, j->sent_dbus_new_signal ? send_changed_signal : send_new_signal, j);
- if (r < 0)
- log_debug_errno(r, "Failed to send job change signal for %u: %m", j->id);
-
- j->sent_dbus_new_signal = true;
-}
-
-static int send_removed_signal(sd_bus *bus, void *userdata) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
- _cleanup_free_ char *p = NULL;
- Job *j = userdata;
- int r;
-
- assert(bus);
- assert(j);
-
- p = job_dbus_path(j);
- if (!p)
- return -ENOMEM;
-
- r = sd_bus_message_new_signal(
- bus,
- &m,
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "JobRemoved");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(m, "uoss", j->id, p, j->unit->id, job_result_to_string(j->result));
- if (r < 0)
- return r;
-
- return sd_bus_send(bus, m, NULL);
-}
-
-void bus_job_send_removed_signal(Job *j) {
- int r;
-
- assert(j);
-
- if (!j->sent_dbus_new_signal)
- bus_job_send_change_signal(j);
-
- r = bus_foreach_bus(j->manager, j->clients, send_removed_signal, j);
- if (r < 0)
- log_debug_errno(r, "Failed to send job remove signal for %u: %m", j->id);
-}
diff --git a/src/core/dbus-job.h b/src/core/dbus-job.h
deleted file mode 100644
index 6c2fc0789..000000000
--- a/src/core/dbus-job.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "job.h"
-
-extern const sd_bus_vtable bus_job_vtable[];
-
-int bus_job_method_cancel(sd_bus *bus, sd_bus_message *message, void *job, sd_bus_error *error);
-
-void bus_job_send_change_signal(Job *j);
-void bus_job_send_removed_signal(Job *j);
diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c
deleted file mode 100644
index fb29e147c..000000000
--- a/src/core/dbus-kill.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "kill.h"
-#include "dbus-kill.h"
-#include "bus-util.h"
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_kill_mode, kill_mode, KillMode);
-
-const sd_bus_vtable bus_kill_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("KillMode", "s", property_get_kill_mode, offsetof(KillContext, kill_mode), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("KillSignal", "i", bus_property_get_int, offsetof(KillContext, kill_signal), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SendSIGKILL", "b", bus_property_get_bool, offsetof(KillContext, send_sigkill), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SendSIGHUP", "b", bus_property_get_bool, offsetof(KillContext, send_sighup), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_VTABLE_END
-};
-
-int bus_kill_context_set_transient_property(
- Unit *u,
- KillContext *c,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- int r;
-
- assert(u);
- assert(c);
- assert(name);
- assert(message);
-
- if (streq(name, "KillMode")) {
- const char *m;
- KillMode k;
-
- r = sd_bus_message_read(message, "s", &m);
- if (r < 0)
- return r;
-
- k = kill_mode_from_string(m);
- if (k < 0)
- return -EINVAL;
-
- if (mode != UNIT_CHECK) {
- c->kill_mode = k;
-
- unit_write_drop_in_private_format(u, mode, name, "KillMode=%s\n", kill_mode_to_string(k));
- }
-
- return 1;
-
- } else if (streq(name, "KillSignal")) {
- int sig;
-
- r = sd_bus_message_read(message, "i", &sig);
- if (r < 0)
- return r;
-
- if (sig <= 0 || sig >= _NSIG)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal %i out of range", sig);
-
- if (mode != UNIT_CHECK) {
- c->kill_signal = sig;
-
- unit_write_drop_in_private_format(u, mode, name, "KillSignal=%s\n", signal_to_string(sig));
- }
-
- return 1;
-
- } else if (streq(name, "SendSIGHUP")) {
- int b;
-
- r = sd_bus_message_read(message, "b", &b);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- c->send_sighup = b;
-
- unit_write_drop_in_private_format(u, mode, name, "SendSIGHUP=%s\n", yes_no(b));
- }
-
- return 1;
-
- } else if (streq(name, "SendSIGKILL")) {
- int b;
-
- r = sd_bus_message_read(message, "b", &b);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- c->send_sigkill = b;
-
- unit_write_drop_in_private_format(u, mode, name, "SendSIGKILL=%s\n", yes_no(b));
- }
-
- return 1;
-
- }
-
- return 0;
-}
diff --git a/src/core/dbus-kill.h b/src/core/dbus-kill.h
deleted file mode 100644
index 7c15f3a90..000000000
--- a/src/core/dbus-kill.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "unit.h"
-#include "kill.h"
-
-extern const sd_bus_vtable bus_kill_vtable[];
-
-int bus_kill_context_set_transient_property(Unit *u, KillContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
deleted file mode 100644
index 1b26e5556..000000000
--- a/src/core/dbus-manager.c
+++ /dev/null
@@ -1,2157 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <unistd.h>
-
-#include "log.h"
-#include "strv.h"
-#include "build.h"
-#include "install.h"
-#include "selinux-access.h"
-#include "watchdog.h"
-#include "clock-util.h"
-#include "path-util.h"
-#include "virt.h"
-#include "architecture.h"
-#include "env-util.h"
-#include "dbus.h"
-#include "dbus-job.h"
-#include "dbus-manager.h"
-#include "dbus-unit.h"
-#include "dbus-snapshot.h"
-#include "dbus-execute.h"
-#include "bus-common-errors.h"
-
-static int property_get_version(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- assert(bus);
- assert(reply);
-
- return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
-}
-
-static int property_get_features(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- assert(bus);
- assert(reply);
-
- return sd_bus_message_append(reply, "s", SYSTEMD_FEATURES);
-}
-
-static int property_get_virtualization(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- const char *id = NULL;
-
- assert(bus);
- assert(reply);
-
- detect_virtualization(&id);
-
- return sd_bus_message_append(reply, "s", id);
-}
-
-static int property_get_architecture(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- assert(bus);
- assert(reply);
-
- return sd_bus_message_append(reply, "s", architecture_to_string(uname_architecture()));
-}
-
-static int property_get_tainted(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- char buf[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e = buf;
- _cleanup_free_ char *p = NULL;
- Manager *m = userdata;
-
- assert(bus);
- assert(reply);
- assert(m);
-
- if (m->taint_usr)
- e = stpcpy(e, "split-usr:");
-
- if (readlink_malloc("/etc/mtab", &p) < 0)
- e = stpcpy(e, "mtab-not-symlink:");
-
- if (access("/proc/cgroups", F_OK) < 0)
- e = stpcpy(e, "cgroups-missing:");
-
- if (clock_is_localtime() > 0)
- e = stpcpy(e, "local-hwclock:");
-
- /* remove the last ':' */
- if (e != buf)
- e[-1] = 0;
-
- return sd_bus_message_append(reply, "s", buf);
-}
-
-static int property_get_log_target(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- assert(bus);
- assert(reply);
-
- return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
-}
-
-static int property_set_log_target(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *value,
- void *userdata,
- sd_bus_error *error) {
-
- const char *t;
- int r;
-
- assert(bus);
- assert(value);
-
- r = sd_bus_message_read(value, "s", &t);
- if (r < 0)
- return r;
-
- return log_set_target_from_string(t);
-}
-
-static int property_get_log_level(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- _cleanup_free_ char *t = NULL;
- int r;
-
- assert(bus);
- assert(reply);
-
- r = log_level_to_string_alloc(log_get_max_level(), &t);
- if (r < 0)
- return r;
-
- return sd_bus_message_append(reply, "s", t);
-}
-
-static int property_set_log_level(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *value,
- void *userdata,
- sd_bus_error *error) {
-
- const char *t;
- int r;
-
- assert(bus);
- assert(value);
-
- r = sd_bus_message_read(value, "s", &t);
- if (r < 0)
- return r;
-
- return log_set_max_level_from_string(t);
-}
-
-static int property_get_n_names(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Manager *m = userdata;
-
- assert(bus);
- assert(reply);
- assert(m);
-
- return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
-}
-
-static int property_get_n_failed_units(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Manager *m = userdata;
-
- assert(bus);
- assert(reply);
- assert(m);
-
- return sd_bus_message_append(reply, "u", (uint32_t) set_size(m->failed_units));
-}
-
-static int property_get_n_jobs(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Manager *m = userdata;
-
- assert(bus);
- assert(reply);
- assert(m);
-
- return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
-}
-
-static int property_get_progress(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Manager *m = userdata;
- double d;
-
- assert(bus);
- assert(reply);
- assert(m);
-
- if (dual_timestamp_is_set(&m->finish_timestamp))
- d = 1.0;
- else
- d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
-
- return sd_bus_message_append(reply, "d", d);
-}
-
-static int property_get_system_state(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Manager *m = userdata;
-
- assert(bus);
- assert(reply);
- assert(m);
-
- return sd_bus_message_append(reply, "s", manager_state_to_string(manager_state(m)));
-}
-
-static int property_set_runtime_watchdog(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *value,
- void *userdata,
- sd_bus_error *error) {
-
- usec_t *t = userdata;
- int r;
-
- assert(bus);
- assert(value);
-
- assert_cc(sizeof(usec_t) == sizeof(uint64_t));
-
- r = sd_bus_message_read(value, "t", t);
- if (r < 0)
- return r;
-
- return watchdog_set_timeout(t);
-}
-
-static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_free_ char *path = NULL;
- Manager *m = userdata;
- const char *name;
- Unit *u;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- /* Anyone can call this method */
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- if (isempty(name)) {
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
- pid_t pid;
-
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_pid(creds, &pid);
- if (r < 0)
- return r;
-
- u = manager_get_unit_by_pid(m, pid);
- if (!u)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
- } else {
- u = manager_get_unit(m, name);
- if (!u)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
- }
-
- r = mac_selinux_unit_access_check(u, message, "status", error);
- if (r < 0)
- return r;
-
- path = unit_dbus_path(u);
- if (!path)
- return -ENOMEM;
-
- return sd_bus_reply_method_return(message, "o", path);
-}
-
-static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_free_ char *path = NULL;
- Manager *m = userdata;
- pid_t pid;
- Unit *u;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- assert_cc(sizeof(pid_t) == sizeof(uint32_t));
-
- /* Anyone can call this method */
-
- r = sd_bus_message_read(message, "u", &pid);
- if (r < 0)
- return r;
- if (pid < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PID " PID_FMT, pid);
-
- if (pid == 0) {
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
-
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_pid(creds, &pid);
- if (r < 0)
- return r;
- }
-
- u = manager_get_unit_by_pid(m, pid);
- if (!u)
- return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid);
-
- r = mac_selinux_unit_access_check(u, message, "status", error);
- if (r < 0)
- return r;
-
- path = unit_dbus_path(u);
- if (!path)
- return -ENOMEM;
-
- return sd_bus_reply_method_return(message, "o", path);
-}
-
-static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_free_ char *path = NULL;
- Manager *m = userdata;
- const char *name;
- Unit *u;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- /* Anyone can call this method */
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- if (isempty(name)) {
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
- pid_t pid;
-
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_pid(creds, &pid);
- if (r < 0)
- return r;
-
- u = manager_get_unit_by_pid(m, pid);
- if (!u)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
- } else {
- r = manager_load_unit(m, name, NULL, error, &u);
- if (r < 0)
- return r;
- }
-
- r = mac_selinux_unit_access_check(u, message, "status", error);
- if (r < 0)
- return r;
-
- path = unit_dbus_path(u);
- if (!path)
- return -ENOMEM;
-
- return sd_bus_reply_method_return(message, "o", path);
-}
-
-static int method_start_unit_generic(sd_bus *bus, sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
- const char *name;
- Unit *u;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- r = manager_load_unit(m, name, NULL, error, &u);
- if (r < 0)
- return r;
-
- return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
-}
-
-static int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
-}
-
-static int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
-}
-
-static int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
-}
-
-static int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
-}
-
-static int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
-}
-
-static int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
-}
-
-static int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
-}
-
-static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- const char *old_name;
- Unit *u;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &old_name);
- if (r < 0)
- return r;
-
- u = manager_get_unit(m, old_name);
- if (!u || !u->job || u->job->type != JOB_START)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
-
- return method_start_unit_generic(bus, message, m, JOB_START, false, error);
-}
-
-static int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- const char *name;
- Unit *u;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- u = manager_get_unit(m, name);
- if (!u)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
-
- return bus_unit_method_kill(bus, message, u, error);
-}
-
-static int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- const char *name;
- Unit *u;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- u = manager_get_unit(m, name);
- if (!u)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
-
- return bus_unit_method_reset_failed(bus, message, u, error);
-}
-
-static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- const char *name;
- Unit *u;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- u = manager_get_unit(m, name);
- if (!u)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
-
- return bus_unit_method_set_properties(bus, message, u, error);
-}
-
-static int transient_unit_from_message(
- Manager *m,
- sd_bus_message *message,
- const char *name,
- Unit **unit,
- sd_bus_error *error) {
-
- Unit *u;
- int r;
-
- assert(m);
- assert(message);
- assert(name);
-
- r = manager_load_unit(m, name, NULL, error, &u);
- if (r < 0)
- return r;
-
- if (u->load_state != UNIT_NOT_FOUND ||
- set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
- return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
-
- /* OK, the unit failed to load and is unreferenced, now let's
- * fill in the transient data instead */
- r = unit_make_transient(u);
- if (r < 0)
- return r;
-
- /* Set our properties */
- r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
- if (r < 0)
- return r;
-
- *unit = u;
-
- return 0;
-}
-
-static int transient_aux_units_from_message(
- Manager *m,
- sd_bus_message *message,
- sd_bus_error *error) {
-
- Unit *u;
- char *name = NULL;
- int r;
-
- assert(m);
- assert(message);
-
- r = sd_bus_message_enter_container(message, 'a', "(sa(sv))");
- if (r < 0)
- return r;
-
- while ((r = sd_bus_message_enter_container(message, 'r', "sa(sv)")) > 0) {
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- r = transient_unit_from_message(m, message, name, &u, error);
- if (r < 0 && r != -EEXIST)
- return r;
-
- if (r != -EEXIST) {
- r = unit_load(u);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_exit_container(message);
- if (r < 0)
- return r;
- }
- if (r < 0)
- return r;
-
- r = sd_bus_message_exit_container(message);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- const char *name, *smode;
- Manager *m = userdata;
- JobMode mode;
- UnitType t;
- Unit *u;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "start", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "ss", &name, &smode);
- if (r < 0)
- return r;
-
- t = unit_name_to_type(name);
- if (t < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
-
- if (!unit_vtable[t]->can_transient)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
-
- mode = job_mode_from_string(smode);
- if (mode < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
-
- r = bus_verify_manage_units_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- r = transient_unit_from_message(m, message, name, &u, error);
- if (r < 0)
- return r;
-
- r = transient_aux_units_from_message(m, message, error);
- if (r < 0)
- return r;
-
- /* And load this stub fully */
- r = unit_load(u);
- if (r < 0)
- return r;
-
- manager_dispatch_load_queue(m);
-
- /* Finally, start it */
- return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
-}
-
-static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_free_ char *path = NULL;
- Manager *m = userdata;
- uint32_t id;
- Job *j;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- /* Anyone can call this method */
-
- r = sd_bus_message_read(message, "u", &id);
- if (r < 0)
- return r;
-
- j = manager_get_job(m, id);
- if (!j)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
-
- r = mac_selinux_unit_access_check(j->unit, message, "status", error);
- if (r < 0)
- return r;
-
- path = job_dbus_path(j);
- if (!path)
- return -ENOMEM;
-
- return sd_bus_reply_method_return(message, "o", path);
-}
-
-static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- uint32_t id;
- Job *j;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "u", &id);
- if (r < 0)
- return r;
-
- j = manager_get_job(m, id);
- if (!j)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
-
- return bus_job_method_cancel(bus, message, j, error);
-}
-
-static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "reload", error);
- if (r < 0)
- return r;
-
- r = bus_verify_manage_units_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- manager_clear_jobs(m);
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "reload", error);
- if (r < 0)
- return r;
-
- r = bus_verify_manage_units_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- manager_reset_failed(m);
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- Manager *m = userdata;
- const char *k;
- Iterator i;
- Unit *u;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- /* Anyone can call this method */
-
- r = mac_selinux_access_check(message, "status", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
- if (r < 0)
- return r;
-
- HASHMAP_FOREACH_KEY(u, k, m->units, i) {
- _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
- Unit *following;
-
- if (k != u->id)
- continue;
-
- following = unit_following(u);
-
- if (!strv_isempty(states) &&
- !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
- !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
- !strv_contains(states, unit_sub_state_to_string(u)))
- continue;
-
- unit_path = unit_dbus_path(u);
- if (!unit_path)
- return -ENOMEM;
-
- if (u->job) {
- job_path = job_dbus_path(u->job);
- if (!job_path)
- return -ENOMEM;
- }
-
- r = sd_bus_message_append(
- reply, "(ssssssouso)",
- u->id,
- unit_description(u),
- unit_load_state_to_string(u->load_state),
- unit_active_state_to_string(unit_active_state(u)),
- unit_sub_state_to_string(u),
- following ? following->id : "",
- unit_path,
- u->job ? u->job->id : 0,
- u->job ? job_type_to_string(u->job->type) : "",
- job_path ? job_path : "/");
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return r;
-
- return sd_bus_send(bus, reply, NULL);
-}
-
-static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return list_units_filtered(bus, message, userdata, error, NULL);
-}
-
-static int method_list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_strv_free_ char **states = NULL;
- int r;
-
- r = sd_bus_message_read_strv(message, &states);
- if (r < 0)
- return r;
-
- return list_units_filtered(bus, message, userdata, error, states);
-}
-
-static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- Manager *m = userdata;
- Iterator i;
- Job *j;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- /* Anyone can call this method */
-
- r = mac_selinux_access_check(message, "status", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
- if (r < 0)
- return r;
-
- HASHMAP_FOREACH(j, m->jobs, i) {
- _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
-
- job_path = job_dbus_path(j);
- if (!job_path)
- return -ENOMEM;
-
- unit_path = unit_dbus_path(j->unit);
- if (!unit_path)
- return -ENOMEM;
-
- r = sd_bus_message_append(
- reply, "(usssoo)",
- j->id,
- j->unit->id,
- job_type_to_string(j->type),
- job_state_to_string(j->state),
- job_path,
- unit_path);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return r;
-
- return sd_bus_send(bus, reply, NULL);
-}
-
-static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- /* Anyone can call this method */
-
- r = mac_selinux_access_check(message, "status", error);
- if (r < 0)
- return r;
-
- if (bus == m->api_bus) {
-
- /* Note that direct bus connection subscribe by
- * default, we only track peers on the API bus here */
-
- if (!m->subscribed) {
- r = sd_bus_track_new(bus, &m->subscribed, NULL, NULL);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_track_add_sender(m->subscribed, message);
- if (r < 0)
- return r;
- if (r == 0)
- return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
- }
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- /* Anyone can call this method */
-
- r = mac_selinux_access_check(message, "status", error);
- if (r < 0)
- return r;
-
- if (bus == m->api_bus) {
- r = sd_bus_track_remove_sender(m->subscribed, message);
- if (r < 0)
- return r;
- if (r == 0)
- return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
- }
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_free_ char *dump = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- Manager *m = userdata;
- size_t size;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- /* Anyone can call this method */
-
- r = mac_selinux_access_check(message, "status", error);
- if (r < 0)
- return r;
-
- f = open_memstream(&dump, &size);
- if (!f)
- return -ENOMEM;
-
- manager_dump_units(m, f, NULL);
- manager_dump_jobs(m, f, NULL);
-
- fflush(f);
-
- if (ferror(f))
- return -ENOMEM;
-
- return sd_bus_reply_method_return(message, "s", dump);
-}
-
-static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_free_ char *path = NULL;
- Manager *m = userdata;
- const char *name;
- int cleanup;
- Snapshot *s = NULL;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "start", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "sb", &name, &cleanup);
- if (r < 0)
- return r;
-
- if (isempty(name))
- name = NULL;
-
- r = bus_verify_manage_units_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- r = snapshot_create(m, name, cleanup, error, &s);
- if (r < 0)
- return r;
-
- path = unit_dbus_path(UNIT(s));
- if (!path)
- return -ENOMEM;
-
- return sd_bus_reply_method_return(message, "o", path);
-}
-
-static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- const char *name;
- Unit *u;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- u = manager_get_unit(m, name);
- if (!u)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
-
- if (u->type != UNIT_SNAPSHOT)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
-
- return bus_snapshot_method_remove(bus, message, u, error);
-}
-
-static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "reload", error);
- if (r < 0)
- return r;
-
- r = bus_verify_reload_daemon_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- /* Instead of sending the reply back right away, we just
- * remember that we need to and then send it after the reload
- * is finished. That way the caller knows when the reload
- * finished. */
-
- assert(!m->queued_message);
- r = sd_bus_message_new_method_return(message, &m->queued_message);
- if (r < 0)
- return r;
-
- m->queued_message_bus = sd_bus_ref(bus);
- m->exit_code = MANAGER_RELOAD;
-
- return 1;
-}
-
-static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "reload", error);
- if (r < 0)
- return r;
-
- r = bus_verify_reload_daemon_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- /* We don't send a reply back here, the client should
- * just wait for us disconnecting. */
-
- m->exit_code = MANAGER_REEXECUTE;
- return 1;
-}
-
-static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "halt", error);
- if (r < 0)
- return r;
-
- if (m->running_as == SYSTEMD_SYSTEM)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
-
- m->exit_code = MANAGER_EXIT;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "reboot", error);
- if (r < 0)
- return r;
-
- if (m->running_as != SYSTEMD_SYSTEM)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
-
- m->exit_code = MANAGER_REBOOT;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "halt", error);
- if (r < 0)
- return r;
-
- if (m->running_as != SYSTEMD_SYSTEM)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
-
- m->exit_code = MANAGER_POWEROFF;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "halt", error);
- if (r < 0)
- return r;
-
- if (m->running_as != SYSTEMD_SYSTEM)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
-
- m->exit_code = MANAGER_HALT;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "reboot", error);
- if (r < 0)
- return r;
-
- if (m->running_as != SYSTEMD_SYSTEM)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
-
- m->exit_code = MANAGER_KEXEC;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- char *ri = NULL, *rt = NULL;
- const char *root, *init;
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "reboot", error);
- if (r < 0)
- return r;
-
- if (m->running_as != SYSTEMD_SYSTEM)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
-
- r = sd_bus_message_read(message, "ss", &root, &init);
- if (r < 0)
- return r;
-
- if (path_equal(root, "/") || !path_is_absolute(root))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
-
- /* Safety check */
- if (isempty(init)) {
- if (!path_is_os_tree(root))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. os-release file is missing.", root);
- } else {
- _cleanup_free_ char *p = NULL;
-
- if (!path_is_absolute(init))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
-
- p = strappend(root, init);
- if (!p)
- return -ENOMEM;
-
- if (access(p, X_OK) < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
- }
-
- rt = strdup(root);
- if (!rt)
- return -ENOMEM;
-
- if (!isempty(init)) {
- ri = strdup(init);
- if (!ri) {
- free(rt);
- return -ENOMEM;
- }
- }
-
- free(m->switch_root);
- m->switch_root = rt;
-
- free(m->switch_root_init);
- m->switch_root_init = ri;
-
- m->exit_code = MANAGER_SWITCH_ROOT;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_strv_free_ char **plus = NULL;
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "reload", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read_strv(message, &plus);
- if (r < 0)
- return r;
- if (!strv_env_is_valid(plus))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
-
- r = bus_verify_set_environment_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- r = manager_environment_add(m, NULL, plus);
- if (r < 0)
- return r;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_strv_free_ char **minus = NULL;
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "reload", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read_strv(message, &minus);
- if (r < 0)
- return r;
-
- if (!strv_env_name_or_assignment_is_valid(minus))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
-
- r = bus_verify_set_environment_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- r = manager_environment_add(m, minus, NULL);
- if (r < 0)
- return r;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "reload", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read_strv(message, &minus);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read_strv(message, &plus);
- if (r < 0)
- return r;
-
- if (!strv_env_name_or_assignment_is_valid(minus))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
- if (!strv_env_is_valid(plus))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
-
- r = bus_verify_set_environment_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- r = manager_environment_add(m, minus, plus);
- if (r < 0)
- return r;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- Manager *m = userdata;
- UnitFileList *item;
- Hashmap *h;
- Iterator i;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- /* Anyone can call this method */
-
- r = mac_selinux_access_check(message, "status", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- return r;
-
- h = hashmap_new(&string_hash_ops);
- if (!h)
- return -ENOMEM;
-
- r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
- if (r < 0)
- goto fail;
-
- r = sd_bus_message_open_container(reply, 'a', "(ss)");
- if (r < 0)
- goto fail;
-
- HASHMAP_FOREACH(item, h, i) {
-
- r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
- if (r < 0)
- goto fail;
- }
-
- unit_file_list_free(h);
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return r;
-
- return sd_bus_send(bus, reply, NULL);
-
-fail:
- unit_file_list_free(h);
- return r;
-}
-
-static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- const char *name;
- UnitFileState state;
- UnitFileScope scope;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- /* Anyone can call this method */
-
- r = mac_selinux_access_check(message, "status", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- state = unit_file_get_state(scope, NULL, name);
- if (state < 0)
- return state;
-
- return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
-}
-
-static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_free_ char *default_target = NULL;
- Manager *m = userdata;
- UnitFileScope scope;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- /* Anyone can call this method */
-
- r = mac_selinux_access_check(message, "status", error);
- if (r < 0)
- return r;
-
- scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = unit_file_get_default(scope, NULL, &default_target);
- if (r < 0)
- return r;
-
- return sd_bus_reply_method_return(message, "s", default_target);
-}
-
-static int send_unit_files_changed(sd_bus *bus, void *userdata) {
- _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
- int r;
-
- assert(bus);
-
- r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
- if (r < 0)
- return r;
-
- return sd_bus_send(bus, message, NULL);
-}
-
-static int reply_unit_file_changes_and_free(
- Manager *m,
- sd_bus *bus,
- sd_bus_message *message,
- int carries_install_info,
- UnitFileChange *changes,
- unsigned n_changes) {
-
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- unsigned i;
- int r;
-
- if (n_changes > 0) {
- r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
- if (r < 0)
- log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
- }
-
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- goto fail;
-
- if (carries_install_info >= 0) {
- r = sd_bus_message_append(reply, "b", carries_install_info);
- if (r < 0)
- goto fail;
- }
-
- r = sd_bus_message_open_container(reply, 'a', "(sss)");
- if (r < 0)
- goto fail;
-
- for (i = 0; i < n_changes; i++) {
- r = sd_bus_message_append(
- reply, "(sss)",
- unit_file_change_type_to_string(changes[i].type),
- changes[i].path,
- changes[i].source);
- if (r < 0)
- goto fail;
- }
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- goto fail;
-
- return sd_bus_send(bus, reply, NULL);
-
-fail:
- unit_file_changes_free(changes, n_changes);
- return r;
-}
-
-static int method_enable_unit_files_generic(
- sd_bus *bus,
- sd_bus_message *message,
- Manager *m,
- const char *verb,
- int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
- bool carries_install_info,
- sd_bus_error *error) {
-
- _cleanup_strv_free_ char **l = NULL;
- UnitFileChange *changes = NULL;
- unsigned n_changes = 0;
- UnitFileScope scope;
- int runtime, force, r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read_strv(message, &l);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "bb", &runtime, &force);
- if (r < 0)
- return r;
-
- r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
- if (r < 0)
- return r;
-
- r = bus_verify_manage_unit_files_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
- if (r < 0)
- return r;
-
- return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
-}
-
-static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
-}
-
-static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
-}
-
-static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
-}
-
-static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
- return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
-}
-
-static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset_without_mode, true, error);
-}
-
-static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
-}
-
-static int method_preset_unit_files_with_mode(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
-
- _cleanup_strv_free_ char **l = NULL;
- UnitFileChange *changes = NULL;
- unsigned n_changes = 0;
- Manager *m = userdata;
- UnitFilePresetMode mm;
- UnitFileScope scope;
- int runtime, force, r;
- const char *mode;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read_strv(message, &l);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
- if (r < 0)
- return r;
-
- if (isempty(mode))
- mm = UNIT_FILE_PRESET_FULL;
- else {
- mm = unit_file_preset_mode_from_string(mode);
- if (mm < 0)
- return -EINVAL;
- }
-
- r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
- if (r < 0)
- return r;
-
- r = bus_verify_manage_unit_files_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
- if (r < 0)
- return r;
-
- return reply_unit_file_changes_and_free(m, bus, message, r, changes, n_changes);
-}
-
-static int method_disable_unit_files_generic(
- sd_bus *bus,
- sd_bus_message *message,
- Manager *m, const
- char *verb,
- int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
- sd_bus_error *error) {
-
- _cleanup_strv_free_ char **l = NULL;
- UnitFileChange *changes = NULL;
- unsigned n_changes = 0;
- UnitFileScope scope;
- int r, runtime;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read_strv(message, &l);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "b", &runtime);
- if (r < 0)
- return r;
-
- r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
- if (r < 0)
- return r;
-
- scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = bus_verify_manage_unit_files_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- r = call(scope, runtime, NULL, l, &changes, &n_changes);
- if (r < 0)
- return r;
-
- return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
-}
-
-static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
-}
-
-static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
-}
-
-static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- UnitFileChange *changes = NULL;
- unsigned n_changes = 0;
- Manager *m = userdata;
- UnitFileScope scope;
- const char *name;
- int force, r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "enable", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "sb", &name, &force);
- if (r < 0)
- return r;
-
- r = bus_verify_manage_unit_files_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
- if (r < 0)
- return r;
-
- return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
-}
-
-static int method_preset_all_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- UnitFileChange *changes = NULL;
- unsigned n_changes = 0;
- Manager *m = userdata;
- UnitFilePresetMode mm;
- UnitFileScope scope;
- const char *mode;
- int force, runtime, r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = mac_selinux_access_check(message, "enable", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
- if (r < 0)
- return r;
-
- if (isempty(mode))
- mm = UNIT_FILE_PRESET_FULL;
- else {
- mm = unit_file_preset_mode_from_string(mode);
- if (mm < 0)
- return -EINVAL;
- }
-
- r = bus_verify_manage_unit_files_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
- if (r < 0)
- return r;
-
- return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
-}
-
-static int method_add_dependency_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_strv_free_ char **l = NULL;
- Manager *m = userdata;
- UnitFileChange *changes = NULL;
- unsigned n_changes = 0;
- UnitFileScope scope;
- int runtime, force, r;
- char *target;
- char *type;
- UnitDependency dep;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = bus_verify_manage_unit_files_async(m, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- r = sd_bus_message_read_strv(message, &l);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
- if (r < 0)
- return r;
-
- dep = unit_dependency_from_string(type);
- if (dep < 0)
- return -EINVAL;
-
- r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
- if (r < 0)
- return r;
-
- scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
- if (r < 0)
- return r;
-
- return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
-}
-
-const sd_bus_vtable bus_manager_vtable[] = {
- SD_BUS_VTABLE_START(0),
-
- SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
- SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
- SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
- SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
- SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
- SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
- SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
- SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
- SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
- SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
- SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
- SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
-
- SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
- SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
- SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
- SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
- SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
- SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
- SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
-
- SD_BUS_SIGNAL("UnitNew", "so", 0),
- SD_BUS_SIGNAL("UnitRemoved", "so", 0),
- SD_BUS_SIGNAL("JobNew", "uos", 0),
- SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
- SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
- SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
- SD_BUS_SIGNAL("Reloading", "b", 0),
-
- SD_BUS_VTABLE_END
-};
-
-static int send_finished(sd_bus *bus, void *userdata) {
- _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
- usec_t *times = userdata;
- int r;
-
- assert(bus);
- assert(times);
-
- r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
- if (r < 0)
- return r;
-
- return sd_bus_send(bus, message, NULL);
-}
-
-void bus_manager_send_finished(
- Manager *m,
- usec_t firmware_usec,
- usec_t loader_usec,
- usec_t kernel_usec,
- usec_t initrd_usec,
- usec_t userspace_usec,
- usec_t total_usec) {
-
- int r;
-
- assert(m);
-
- r = bus_foreach_bus(
- m,
- NULL,
- send_finished,
- (usec_t[6]) {
- firmware_usec,
- loader_usec,
- kernel_usec,
- initrd_usec,
- userspace_usec,
- total_usec
- });
- if (r < 0)
- log_debug_errno(r, "Failed to send finished signal: %m");
-}
-
-static int send_reloading(sd_bus *bus, void *userdata) {
- _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
- int r;
-
- assert(bus);
-
- r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
- if (r < 0)
- return r;
-
- return sd_bus_send(bus, message, NULL);
-}
-
-void bus_manager_send_reloading(Manager *m, bool active) {
- int r;
-
- assert(m);
-
- r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
- if (r < 0)
- log_debug_errno(r, "Failed to send reloading signal: %m");
-}
-
-static int send_changed_signal(sd_bus *bus, void *userdata) {
- assert(bus);
-
- return sd_bus_emit_properties_changed_strv(bus,
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- NULL);
-}
-
-void bus_manager_send_change_signal(Manager *m) {
- int r;
-
- assert(m);
-
- r = bus_foreach_bus(m, NULL, send_changed_signal, NULL);
- if (r < 0)
- log_debug_errno(r, "Failed to send manager change signal: %m");
-}
diff --git a/src/core/dbus-manager.h b/src/core/dbus-manager.h
deleted file mode 100644
index 5bdf6e17a..000000000
--- a/src/core/dbus-manager.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "manager.h"
-
-extern const sd_bus_vtable bus_manager_vtable[];
-
-void bus_manager_send_finished(Manager *m, usec_t firmware_usec, usec_t loader_usec, usec_t kernel_usec, usec_t initrd_usec, usec_t userspace_usec, usec_t total_usec);
-void bus_manager_send_reloading(Manager *m, bool active);
-void bus_manager_send_change_signal(Manager *m);
diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c
deleted file mode 100644
index 24813c6d2..000000000
--- a/src/core/dbus-mount.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "unit.h"
-#include "mount.h"
-#include "dbus-execute.h"
-#include "dbus-kill.h"
-#include "dbus-cgroup.h"
-#include "dbus-mount.h"
-#include "bus-util.h"
-
-static int property_get_what(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Mount *m = userdata;
- const char *d;
-
- assert(bus);
- assert(reply);
- assert(m);
-
- if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
- d = m->parameters_proc_self_mountinfo.what;
- else if (m->from_fragment && m->parameters_fragment.what)
- d = m->parameters_fragment.what;
- else
- d = "";
-
- return sd_bus_message_append(reply, "s", d);
-}
-
-static int property_get_options(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Mount *m = userdata;
- const char *d;
-
- assert(bus);
- assert(reply);
- assert(m);
-
- if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options)
- d = m->parameters_proc_self_mountinfo.options;
- else if (m->from_fragment && m->parameters_fragment.options)
- d = m->parameters_fragment.options;
- else
- d = "";
-
- return sd_bus_message_append(reply, "s", d);
-}
-
-static int property_get_type(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Mount *m = userdata;
- const char *d;
-
- assert(bus);
- assert(reply);
- assert(m);
-
- if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype)
- d = m->parameters_proc_self_mountinfo.fstype;
- else if (m->from_fragment && m->parameters_fragment.fstype)
- d = m->parameters_fragment.fstype;
- else
- d = "";
-
- return sd_bus_message_append(reply, "s", d);
-}
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, mount_result, MountResult);
-
-const sd_bus_vtable bus_mount_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Where", "s", NULL, offsetof(Mount, where), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("What", "s", property_get_what, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Options","s", property_get_options, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Type", "s", property_get_type, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("TimeoutUSec", "t", bus_property_get_usec, offsetof(Mount, timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Mount, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Mount, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SloppyOptions", "b", bus_property_get_bool, offsetof(Mount, sloppy_options), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Mount, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- BUS_EXEC_COMMAND_VTABLE("ExecMount", offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- BUS_EXEC_COMMAND_VTABLE("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- BUS_EXEC_COMMAND_VTABLE("ExecRemount", offsetof(Mount, exec_command[MOUNT_EXEC_REMOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- SD_BUS_VTABLE_END
-};
-
-static int bus_mount_set_transient_property(
- Mount *m,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- const char *new_property;
- char **property;
- char *p;
- int r;
-
- assert(m);
- assert(name);
- assert(message);
-
- if (streq(name, "What"))
- property = &m->parameters_fragment.what;
- else if (streq(name, "Options"))
- property = &m->parameters_fragment.options;
- else if (streq(name, "Type"))
- property = &m->parameters_fragment.fstype;
- else
- return 0;
-
- r = sd_bus_message_read(message, "s", &new_property);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- p = strdup(new_property);
- if (!p)
- return -ENOMEM;
-
- free(*property);
- *property = p;
- }
-
- return 1;
-}
-
-int bus_mount_set_property(
- Unit *u,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- Mount *m = MOUNT(u);
- int r;
-
- assert(m);
- assert(name);
- assert(message);
-
- r = bus_cgroup_set_property(u, &m->cgroup_context, name, message, mode, error);
- if (r != 0)
- return r;
-
- if (u->transient && u->load_state == UNIT_STUB) {
- /* This is a transient unit, let's load a little more */
-
- r = bus_mount_set_transient_property(m, name, message, mode, error);
- if (r != 0)
- return r;
-
- r = bus_exec_context_set_transient_property(u, &m->exec_context, name, message, mode, error);
- if (r != 0)
- return r;
-
- r = bus_kill_context_set_transient_property(u, &m->kill_context, name, message, mode, error);
- if (r != 0)
- return r;
- }
-
- return 0;
-}
-
-int bus_mount_commit_properties(Unit *u) {
- assert(u);
-
- unit_update_cgroup_members_masks(u);
- unit_realize_cgroup(u);
-
- return 0;
-}
diff --git a/src/core/dbus-mount.h b/src/core/dbus-mount.h
deleted file mode 100644
index f7004d252..000000000
--- a/src/core/dbus-mount.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "unit.h"
-
-extern const sd_bus_vtable bus_mount_vtable[];
-
-int bus_mount_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
-int bus_mount_commit_properties(Unit *u);
diff --git a/src/core/dbus-path.c b/src/core/dbus-path.c
deleted file mode 100644
index 683561999..000000000
--- a/src/core/dbus-path.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "unit.h"
-#include "path.h"
-#include "dbus-path.h"
-#include "bus-util.h"
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, path_result, PathResult);
-
-static int property_get_paths(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Path *p = userdata;
- PathSpec *k;
- int r;
-
- assert(bus);
- assert(reply);
- assert(p);
-
- r = sd_bus_message_open_container(reply, 'a', "(ss)");
- if (r < 0)
- return r;
-
- LIST_FOREACH(spec, k, p->specs) {
- r = sd_bus_message_append(reply, "(ss)", path_type_to_string(k->type), k->path);
- if (r < 0)
- return r;
- }
-
- return sd_bus_message_close_container(reply);
-}
-
-static int property_get_unit(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *p = userdata, *trigger;
-
- assert(bus);
- assert(reply);
- assert(p);
-
- trigger = UNIT_TRIGGER(p);
-
- return sd_bus_message_append(reply, "s", trigger ? trigger->id : "");
-}
-
-const sd_bus_vtable bus_path_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Unit", "s", property_get_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Paths", "a(ss)", property_get_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("MakeDirectory", "b", bus_property_get_bool, offsetof(Path, make_directory), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Path, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Path, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_VTABLE_END
-};
diff --git a/src/core/dbus-path.h b/src/core/dbus-path.h
deleted file mode 100644
index 389b0d7f9..000000000
--- a/src/core/dbus-path.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-
-
-extern const sd_bus_vtable bus_path_vtable[];
diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c
deleted file mode 100644
index 651c163be..000000000
--- a/src/core/dbus-scope.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "selinux-access.h"
-#include "unit.h"
-#include "scope.h"
-#include "dbus.h"
-#include "bus-util.h"
-#include "bus-internal.h"
-#include "bus-common-errors.h"
-#include "dbus-unit.h"
-#include "dbus-cgroup.h"
-#include "dbus-kill.h"
-#include "dbus-scope.h"
-
-static int bus_scope_abandon(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Scope *s = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(s);
-
- r = mac_selinux_unit_access_check(UNIT(s), message, "stop", error);
- if (r < 0)
- return r;
-
- r = bus_verify_manage_units_async(UNIT(s)->manager, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- r = scope_abandon(s);
- if (r == -ESTALE)
- return sd_bus_error_setf(error, BUS_ERROR_SCOPE_NOT_RUNNING, "Scope %s is not running, cannot abandon.", UNIT(s)->id);
- if (r < 0)
- return r;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, scope_result, ScopeResult);
-
-const sd_bus_vtable bus_scope_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Controller", "s", NULL, offsetof(Scope, controller), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Scope, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Scope, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_SIGNAL("RequestStop", NULL, 0),
- SD_BUS_METHOD("Abandon", NULL, NULL, bus_scope_abandon, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_VTABLE_END
-};
-
-static int bus_scope_set_transient_property(
- Scope *s,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- int r;
-
- assert(s);
- assert(name);
- assert(message);
-
- if (streq(name, "PIDs")) {
- unsigned n = 0;
- uint32_t pid;
-
- r = sd_bus_message_enter_container(message, 'a', "u");
- if (r < 0)
- return r;
-
- while ((r = sd_bus_message_read(message, "u", &pid)) > 0) {
-
- if (pid <= 1)
- return -EINVAL;
-
- if (mode != UNIT_CHECK) {
- r = unit_watch_pid(UNIT(s), pid);
- if (r < 0 && r != -EEXIST)
- return r;
- }
-
- n++;
- }
- if (r < 0)
- return r;
-
- r = sd_bus_message_exit_container(message);
- if (r < 0)
- return r;
-
- if (n <= 0)
- return -EINVAL;
-
- return 1;
-
- } else if (streq(name, "Controller")) {
- const char *controller;
- char *c;
-
- r = sd_bus_message_read(message, "s", &controller);
- if (r < 0)
- return r;
-
- if (!isempty(controller) && !service_name_is_valid(controller))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller);
-
- if (mode != UNIT_CHECK) {
- if (isempty(controller))
- c = NULL;
- else {
- c = strdup(controller);
- if (!c)
- return -ENOMEM;
- }
-
- free(s->controller);
- s->controller = c;
- }
-
- return 1;
-
- } else if (streq(name, "TimeoutStopUSec")) {
-
- if (mode != UNIT_CHECK) {
- r = sd_bus_message_read(message, "t", &s->timeout_stop_usec);
- if (r < 0)
- return r;
-
- unit_write_drop_in_format(UNIT(s), mode, name, "[Scope]\nTimeoutStopSec="USEC_FMT"us\n", s->timeout_stop_usec);
- } else {
- r = sd_bus_message_skip(message, "t");
- if (r < 0)
- return r;
- }
-
- return 1;
- }
-
- return 0;
-}
-
-int bus_scope_set_property(
- Unit *u,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- Scope *s = SCOPE(u);
- int r;
-
- assert(s);
- assert(name);
- assert(message);
-
- r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
- if (r != 0)
- return r;
-
- if (u->load_state == UNIT_STUB) {
- /* While we are created we still accept PIDs */
-
- r = bus_scope_set_transient_property(s, name, message, mode, error);
- if (r != 0)
- return r;
-
- r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
- if (r != 0)
- return r;
- }
-
- return 0;
-}
-
-int bus_scope_commit_properties(Unit *u) {
- assert(u);
-
- unit_update_cgroup_members_masks(u);
- unit_realize_cgroup(u);
-
- return 0;
-}
-
-int bus_scope_send_request_stop(Scope *s) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
- _cleanup_free_ char *p = NULL;
- int r;
-
- assert(s);
-
- if (!s->controller)
- return 0;
-
- p = unit_dbus_path(UNIT(s));
- if (!p)
- return -ENOMEM;
-
- r = sd_bus_message_new_signal(
- UNIT(s)->manager->api_bus,
- &m,
- p,
- "org.freedesktop.systemd1.Scope",
- "RequestStop");
- if (r < 0)
- return r;
-
- return sd_bus_send_to(UNIT(s)->manager->api_bus, m, /* s->controller */ NULL, NULL);
-}
diff --git a/src/core/dbus-scope.h b/src/core/dbus-scope.h
deleted file mode 100644
index 33beda47b..000000000
--- a/src/core/dbus-scope.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "unit.h"
-
-extern const sd_bus_vtable bus_scope_vtable[];
-
-int bus_scope_set_property(Unit *u, const char *name, sd_bus_message *i, UnitSetPropertiesMode mode, sd_bus_error *error);
-int bus_scope_commit_properties(Unit *u);
-
-int bus_scope_send_request_stop(Scope *s);
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
deleted file mode 100644
index e1f3d5649..000000000
--- a/src/core/dbus-service.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "strv.h"
-#include "path-util.h"
-#include "unit.h"
-#include "service.h"
-#include "dbus-execute.h"
-#include "dbus-kill.h"
-#include "dbus-cgroup.h"
-#include "dbus-service.h"
-#include "bus-util.h"
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, service_type, ServiceType);
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, service_result, ServiceResult);
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart, service_restart, ServiceRestart);
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_notify_access, notify_access, NotifyAccess);
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_failure_action, failure_action, FailureAction);
-
-const sd_bus_vtable bus_service_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Service, type), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Restart", "s", property_get_restart, offsetof(Service, restart), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("PIDFile", "s", NULL, offsetof(Service, pid_file), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("NotifyAccess", "s", property_get_notify_access, offsetof(Service, notify_access), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RestartUSec", "t", bus_property_get_usec, offsetof(Service, restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TimeoutStartUSec", "t", bus_property_get_usec, offsetof(Service, timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Service, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("WatchdogUSec", "t", bus_property_get_usec, offsetof(Service, watchdog_usec), SD_BUS_VTABLE_PROPERTY_CONST),
- BUS_PROPERTY_DUAL_TIMESTAMP("WatchdogTimestamp", offsetof(Service, watchdog_timestamp), 0),
- SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Service, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Service, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("StartLimitAction", "s", property_get_failure_action, offsetof(Service, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Service, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("FailureAction", "s", property_get_failure_action, offsetof(Service, failure_action), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool, offsetof(Service, permissions_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool, offsetof(Service, root_directory_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool, offsetof(Service, remain_after_exit), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("GuessMainPID", "b", bus_property_get_bool, offsetof(Service, guess_main_pid), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("MainPID", "u", bus_property_get_pid, offsetof(Service, main_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Service, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("BusName", "s", NULL, offsetof(Service, bus_name), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("FileDescriptorStoreMax", "u", NULL, offsetof(Service, n_fd_store_max), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("StatusText", "s", NULL, offsetof(Service, status_text), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("StatusErrno", "i", NULL, offsetof(Service, status_errno), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Service, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- BUS_EXEC_STATUS_VTABLE("ExecMain", offsetof(Service, main_exec_status), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- BUS_EXEC_COMMAND_LIST_VTABLE("ExecStart", offsetof(Service, exec_command[SERVICE_EXEC_START]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Service, exec_command[SERVICE_EXEC_START_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- BUS_EXEC_COMMAND_LIST_VTABLE("ExecReload", offsetof(Service, exec_command[SERVICE_EXEC_RELOAD]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- BUS_EXEC_COMMAND_LIST_VTABLE("ExecStop", offsetof(Service, exec_command[SERVICE_EXEC_STOP]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPost", offsetof(Service, exec_command[SERVICE_EXEC_STOP_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- SD_BUS_VTABLE_END
-};
-
-static int bus_service_set_transient_property(
- Service *s,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- int r;
-
- assert(s);
- assert(name);
- assert(message);
-
- if (streq(name, "RemainAfterExit")) {
- int b;
-
- r = sd_bus_message_read(message, "b", &b);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- s->remain_after_exit = b;
- unit_write_drop_in_private_format(UNIT(s), mode, name, "RemainAfterExit=%s\n", yes_no(b));
- }
-
- return 1;
-
- } else if (streq(name, "Type")) {
- const char *t;
- ServiceType k;
-
- r = sd_bus_message_read(message, "s", &t);
- if (r < 0)
- return r;
-
- k = service_type_from_string(t);
- if (k < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid service type %s", t);
-
- if (mode != UNIT_CHECK) {
- s->type = k;
- unit_write_drop_in_private_format(UNIT(s), mode, name, "Type=%s\n", service_type_to_string(s->type));
- }
-
- return 1;
-
- } else if (streq(name, "ExecStart")) {
- unsigned n = 0;
-
- r = sd_bus_message_enter_container(message, 'a', "(sasb)");
- if (r < 0)
- return r;
-
- while ((r = sd_bus_message_enter_container(message, 'r', "sasb")) > 0) {
- _cleanup_strv_free_ char **argv = NULL;
- const char *path;
- int b;
-
- r = sd_bus_message_read(message, "s", &path);
- if (r < 0)
- return r;
-
- if (!path_is_absolute(path))
- return sd_bus_error_set_errnof(error, EINVAL, "Path %s is not absolute.", path);
-
- r = sd_bus_message_read_strv(message, &argv);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "b", &b);
- if (r < 0)
- return r;
-
- r = sd_bus_message_exit_container(message);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- ExecCommand *c;
-
- c = new0(ExecCommand, 1);
- if (!c)
- return -ENOMEM;
-
- c->path = strdup(path);
- if (!c->path) {
- free(c);
- return -ENOMEM;
- }
-
- c->argv = argv;
- argv = NULL;
-
- c->ignore = b;
-
- path_kill_slashes(c->path);
- exec_command_append_list(&s->exec_command[SERVICE_EXEC_START], c);
- }
-
- n++;
- }
-
- if (r < 0)
- return r;
-
- r = sd_bus_message_exit_container(message);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- _cleanup_free_ char *buf = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- ExecCommand *c;
- size_t size = 0;
-
- if (n == 0)
- s->exec_command[SERVICE_EXEC_START] = exec_command_free_list(s->exec_command[SERVICE_EXEC_START]);
-
- f = open_memstream(&buf, &size);
- if (!f)
- return -ENOMEM;
-
- fputs("ExecStart=\n", f);
-
- LIST_FOREACH(command, c, s->exec_command[SERVICE_EXEC_START]) {
- _cleanup_free_ char *a;
-
- a = strv_join_quoted(c->argv);
- if (!a)
- return -ENOMEM;
-
- fprintf(f, "ExecStart=%s@%s %s\n",
- c->ignore ? "-" : "",
- c->path,
- a);
- }
-
- fflush(f);
- unit_write_drop_in_private(UNIT(s), mode, name, buf);
- }
-
- return 1;
- }
-
- return 0;
-}
-
-int bus_service_set_property(
- Unit *u,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- Service *s = SERVICE(u);
- int r;
-
- assert(s);
- assert(name);
- assert(message);
-
- r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
- if (r != 0)
- return r;
-
- if (u->transient && u->load_state == UNIT_STUB) {
- /* This is a transient unit, let's load a little more */
-
- r = bus_service_set_transient_property(s, name, message, mode, error);
- if (r != 0)
- return r;
-
- r = bus_exec_context_set_transient_property(u, &s->exec_context, name, message, mode, error);
- if (r != 0)
- return r;
-
- r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
- if (r != 0)
- return r;
- }
-
- return 0;
-}
-
-int bus_service_commit_properties(Unit *u) {
- assert(u);
-
- unit_update_cgroup_members_masks(u);
- unit_realize_cgroup(u);
-
- return 0;
-}
diff --git a/src/core/dbus-service.h b/src/core/dbus-service.h
deleted file mode 100644
index aab9f7aa2..000000000
--- a/src/core/dbus-service.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "unit.h"
-
-extern const sd_bus_vtable bus_service_vtable[];
-
-int bus_service_set_property(Unit *u, const char *name, sd_bus_message *i, UnitSetPropertiesMode mode, sd_bus_error *error);
-int bus_service_commit_properties(Unit *u);
diff --git a/src/core/dbus-slice.c b/src/core/dbus-slice.c
deleted file mode 100644
index 09e78d1f3..000000000
--- a/src/core/dbus-slice.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "unit.h"
-#include "slice.h"
-#include "dbus-cgroup.h"
-#include "dbus-slice.h"
-
-const sd_bus_vtable bus_slice_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_VTABLE_END
-};
-
-int bus_slice_set_property(
- Unit *u,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- Slice *s = SLICE(u);
-
- assert(name);
- assert(u);
-
- return bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
-}
-
-int bus_slice_commit_properties(Unit *u) {
- assert(u);
-
- unit_update_cgroup_members_masks(u);
- unit_realize_cgroup(u);
-
- return 0;
-}
diff --git a/src/core/dbus-slice.h b/src/core/dbus-slice.h
deleted file mode 100644
index eadc3b1a9..000000000
--- a/src/core/dbus-slice.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "unit.h"
-
-extern const sd_bus_vtable bus_slice_vtable[];
-
-int bus_slice_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
-int bus_slice_commit_properties(Unit *u);
diff --git a/src/core/dbus-snapshot.c b/src/core/dbus-snapshot.c
deleted file mode 100644
index 0be46c288..000000000
--- a/src/core/dbus-snapshot.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "selinux-access.h"
-#include "unit.h"
-#include "dbus.h"
-#include "snapshot.h"
-#include "dbus-snapshot.h"
-
-int bus_snapshot_method_remove(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Snapshot *s = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(s);
-
- r = mac_selinux_unit_access_check(UNIT(s), message, "stop", error);
- if (r < 0)
- return r;
-
- r = bus_verify_manage_units_async(UNIT(s)->manager, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- snapshot_remove(s);
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-const sd_bus_vtable bus_snapshot_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Cleanup", "b", bus_property_get_bool, offsetof(Snapshot, cleanup), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_METHOD("Remove", NULL, NULL, bus_snapshot_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_VTABLE_END
-};
diff --git a/src/core/dbus-snapshot.h b/src/core/dbus-snapshot.h
deleted file mode 100644
index d7551cbcd..000000000
--- a/src/core/dbus-snapshot.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-
-extern const sd_bus_vtable bus_snapshot_vtable[];
-
-int bus_snapshot_method_remove(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
deleted file mode 100644
index 02599a9e5..000000000
--- a/src/core/dbus-socket.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "unit.h"
-#include "socket.h"
-#include "dbus-execute.h"
-#include "dbus-cgroup.h"
-#include "dbus-socket.h"
-#include "bus-util.h"
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, socket_result, SocketResult);
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
-
-static int property_get_listen(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
-
- Socket *s = SOCKET(userdata);
- SocketPort *p;
- int r;
-
- assert(bus);
- assert(reply);
- assert(s);
-
- r = sd_bus_message_open_container(reply, 'a', "(ss)");
- if (r < 0)
- return r;
-
- LIST_FOREACH(port, p, s->ports) {
- _cleanup_free_ char *address = NULL;
- const char *a;
-
- switch (p->type) {
- case SOCKET_SOCKET: {
- r = socket_address_print(&p->address, &address);
- if (r)
- return r;
-
- a = address;
- break;
- }
-
- case SOCKET_SPECIAL:
- case SOCKET_MQUEUE:
- case SOCKET_FIFO:
- a = p->path;
- break;
-
- default:
- assert_not_reached("Unknown socket type");
- }
-
- r = sd_bus_message_append(reply, "(ss)", socket_port_type_to_string(p), a);
- if (r < 0)
- return r;
- }
-
- return sd_bus_message_close_container(reply);
-}
-
-const sd_bus_vtable bus_socket_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("BindIPv6Only", "s", property_get_bind_ipv6_only, offsetof(Socket, bind_ipv6_only), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Backlog", "u", bus_property_get_unsigned, offsetof(Socket, backlog), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TimeoutUSec", "t", bus_property_get_usec, offsetof(Socket, timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("BindToDevice", "s", NULL, offsetof(Socket, bind_to_device), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SocketUser", "s", NULL, offsetof(Socket, user), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SocketGroup", "s", NULL, offsetof(Socket, group), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SocketMode", "u", bus_property_get_mode, offsetof(Socket, socket_mode), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Socket, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Accept", "b", bus_property_get_bool, offsetof(Socket, accept), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("KeepAlive", "b", bus_property_get_bool, offsetof(Socket, keep_alive), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("KeepAliveTimeUSec", "t", bus_property_get_usec, offsetof(Socket, keep_alive_time), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("KeepAliveIntervalUSec", "t", bus_property_get_usec, offsetof(Socket, keep_alive_interval), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("KeepAliveProbes", "u", bus_property_get_unsigned, offsetof(Socket, keep_alive_cnt), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("DeferAcceptUSec" , "t", bus_property_get_usec, offsetof(Socket, defer_accept), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("NoDelay", "b", bus_property_get_bool, offsetof(Socket, no_delay), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Priority", "i", bus_property_get_int, offsetof(Socket, priority), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ReceiveBuffer", "t", bus_property_get_size, offsetof(Socket, receive_buffer), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SendBuffer", "t", bus_property_get_size, offsetof(Socket, send_buffer), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("IPTOS", "i", bus_property_get_int, offsetof(Socket, ip_tos), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("IPTTL", "i", bus_property_get_int, offsetof(Socket, ip_ttl), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("PipeSize", "t", bus_property_get_size, offsetof(Socket, pipe_size), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("FreeBind", "b", bus_property_get_bool, offsetof(Socket, free_bind), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Transparent", "b", bus_property_get_bool, offsetof(Socket, transparent), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Broadcast", "b", bus_property_get_bool, offsetof(Socket, broadcast), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("PassCredentials", "b", bus_property_get_bool, offsetof(Socket, pass_cred), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("PassSecurity", "b", bus_property_get_bool, offsetof(Socket, pass_sec), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RemoveOnStop", "b", bus_property_get_bool, offsetof(Socket, remove_on_stop), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Listen", "a(ss)", property_get_listen, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Symlinks", "as", NULL, offsetof(Socket, symlinks), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Mark", "i", bus_property_get_int, offsetof(Socket, mark), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("MaxConnections", "u", bus_property_get_unsigned, offsetof(Socket, max_connections), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("MessageQueueMaxMessages", "x", bus_property_get_long, offsetof(Socket, mq_maxmsg), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("MessageQueueMessageSize", "x", bus_property_get_long, offsetof(Socket, mq_msgsize), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ReusePort", "b", bus_property_get_bool, offsetof(Socket, reuse_port), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SmackLabel", "s", NULL, offsetof(Socket, smack), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SmackLabelIPIn", "s", NULL, offsetof(Socket, smack_ip_in), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SmackLabelIPOut", "s", NULL, offsetof(Socket, smack_ip_out), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Socket, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Socket, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("NConnections", "u", bus_property_get_unsigned, offsetof(Socket, n_connections), 0),
- SD_BUS_PROPERTY("NAccepted", "u", bus_property_get_unsigned, offsetof(Socket, n_accepted), 0),
- BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Socket, exec_command[SOCKET_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Socket, exec_command[SOCKET_EXEC_START_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPre", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPost", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- SD_BUS_VTABLE_END
-};
-
-int bus_socket_set_property(
- Unit *u,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- Socket *s = SOCKET(u);
-
- assert(s);
- assert(name);
- assert(message);
-
- return bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
-}
-
-int bus_socket_commit_properties(Unit *u) {
- assert(u);
-
- unit_update_cgroup_members_masks(u);
- unit_realize_cgroup(u);
-
- return 0;
-}
diff --git a/src/core/dbus-socket.h b/src/core/dbus-socket.h
deleted file mode 100644
index 17164d987..000000000
--- a/src/core/dbus-socket.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "unit.h"
-
-extern const sd_bus_vtable bus_socket_vtable[];
-
-int bus_socket_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
-int bus_socket_commit_properties(Unit *u);
diff --git a/src/core/dbus-swap.c b/src/core/dbus-swap.c
deleted file mode 100644
index 009337130..000000000
--- a/src/core/dbus-swap.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
- Copyright 2010 Maarten Lankhorst
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "unit.h"
-#include "swap.h"
-#include "dbus-execute.h"
-#include "dbus-cgroup.h"
-#include "dbus-swap.h"
-#include "bus-util.h"
-
-static int property_get_priority(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Swap *s = SWAP(userdata);
- int p;
-
- assert(bus);
- assert(reply);
- assert(s);
-
- if (s->from_proc_swaps)
- p = s->parameters_proc_swaps.priority;
- else if (s->from_fragment)
- p = s->parameters_fragment.priority;
- else
- p = -1;
-
- return sd_bus_message_append(reply, "i", p);
-}
-
-static int property_get_options(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Swap *s = SWAP(userdata);
- const char *options = NULL;
-
- assert(bus);
- assert(reply);
- assert(s);
-
- if (s->from_fragment)
- options = s->parameters_fragment.options;
-
- return sd_bus_message_append(reply, "s", options);
-}
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, swap_result, SwapResult);
-
-const sd_bus_vtable bus_swap_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("What", "s", NULL, offsetof(Swap, what), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Priority", "i", property_get_priority, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Options", "s", property_get_options, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("TimeoutUSec", "t", bus_property_get_usec, offsetof(Swap, timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Swap, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Swap, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- BUS_EXEC_COMMAND_VTABLE("ExecActivate", offsetof(Swap, exec_command[SWAP_EXEC_ACTIVATE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- BUS_EXEC_COMMAND_VTABLE("ExecDeactivate", offsetof(Swap, exec_command[SWAP_EXEC_DEACTIVATE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- SD_BUS_VTABLE_END
-};
-
-int bus_swap_set_property(
- Unit *u,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- Swap *s = SWAP(u);
-
- assert(s);
- assert(name);
- assert(message);
-
- return bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
-}
-
-int bus_swap_commit_properties(Unit *u) {
- assert(u);
-
- unit_update_cgroup_members_masks(u);
- unit_realize_cgroup(u);
-
- return 0;
-}
diff --git a/src/core/dbus-swap.h b/src/core/dbus-swap.h
deleted file mode 100644
index 9469f68ab..000000000
--- a/src/core/dbus-swap.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
- Copyright 2010 Maarten Lankhorst
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "unit.h"
-
-extern const sd_bus_vtable bus_swap_vtable[];
-
-int bus_swap_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
-int bus_swap_commit_properties(Unit *u);
diff --git a/src/core/dbus-target.c b/src/core/dbus-target.c
deleted file mode 100644
index 350f5c3ed..000000000
--- a/src/core/dbus-target.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "unit.h"
-#include "dbus-target.h"
-
-const sd_bus_vtable bus_target_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_VTABLE_END
-};
diff --git a/src/core/dbus-target.h b/src/core/dbus-target.h
deleted file mode 100644
index 4c4297bc9..000000000
--- a/src/core/dbus-target.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-
-extern const sd_bus_vtable bus_target_vtable[];
diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c
deleted file mode 100644
index 74a991435..000000000
--- a/src/core/dbus-timer.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "unit.h"
-#include "timer.h"
-#include "dbus-timer.h"
-#include "bus-util.h"
-#include "strv.h"
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, timer_result, TimerResult);
-
-static int property_get_monotonic_timers(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Timer *t = userdata;
- TimerValue *v;
- int r;
-
- assert(bus);
- assert(reply);
- assert(t);
-
- r = sd_bus_message_open_container(reply, 'a', "(stt)");
- if (r < 0)
- return r;
-
- LIST_FOREACH(value, v, t->values) {
- _cleanup_free_ char *buf = NULL;
- const char *s;
- size_t l;
-
- if (v->base == TIMER_CALENDAR)
- continue;
-
- s = timer_base_to_string(v->base);
- assert(endswith(s, "Sec"));
-
- /* s/Sec/USec/ */
- l = strlen(s);
- buf = new(char, l+2);
- if (!buf)
- return -ENOMEM;
-
- memcpy(buf, s, l-3);
- memcpy(buf+l-3, "USec", 5);
-
- r = sd_bus_message_append(reply, "(stt)", buf, v->value, v->next_elapse);
- if (r < 0)
- return r;
- }
-
- return sd_bus_message_close_container(reply);
-}
-
-static int property_get_calendar_timers(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Timer *t = userdata;
- TimerValue *v;
- int r;
-
- assert(bus);
- assert(reply);
- assert(t);
-
- r = sd_bus_message_open_container(reply, 'a', "(sst)");
- if (r < 0)
- return r;
-
- LIST_FOREACH(value, v, t->values) {
- _cleanup_free_ char *buf = NULL;
-
- if (v->base != TIMER_CALENDAR)
- continue;
-
- r = calendar_spec_to_string(v->calendar_spec, &buf);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(reply, "(sst)", timer_base_to_string(v->base), buf, v->next_elapse);
- if (r < 0)
- return r;
- }
-
- return sd_bus_message_close_container(reply);
-}
-
-static int property_get_unit(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata, *trigger;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- trigger = UNIT_TRIGGER(u);
-
- return sd_bus_message_append(reply, "s", trigger ? trigger->id : "");
-}
-
-static int property_get_next_elapse_monotonic(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Timer *t = userdata;
- usec_t x;
-
- assert(bus);
- assert(reply);
- assert(t);
-
- if (t->next_elapse_monotonic_or_boottime <= 0)
- x = 0;
- else if (t->wake_system) {
- usec_t a, b;
-
- a = now(CLOCK_MONOTONIC);
- b = now(CLOCK_BOOTTIME);
-
- if (t->next_elapse_monotonic_or_boottime + a > b)
- x = t->next_elapse_monotonic_or_boottime + a - b;
- else
- x = 0;
- } else
- x = t->next_elapse_monotonic_or_boottime;
-
- return sd_bus_message_append(reply, "t", x);
-}
-
-const sd_bus_vtable bus_timer_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Unit", "s", property_get_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TimersMonotonic", "a(stt)", property_get_monotonic_timers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- SD_BUS_PROPERTY("TimersCalendar", "a(sst)", property_get_calendar_timers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- SD_BUS_PROPERTY("NextElapseUSecRealtime", "t", bus_property_get_usec, offsetof(Timer, next_elapse_realtime), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("NextElapseUSecMonotonic", "t", property_get_next_elapse_monotonic, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- BUS_PROPERTY_DUAL_TIMESTAMP("LastTriggerUSec", offsetof(Timer, last_trigger), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Timer, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("AccuracyUSec", "t", bus_property_get_usec, offsetof(Timer, accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Persistent", "b", bus_property_get_bool, offsetof(Timer, persistent), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("WakeSystem", "b", bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_VTABLE_END
-};
-
-static int bus_timer_set_transient_property(
- Timer *t,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- int r;
-
- assert(t);
- assert(name);
- assert(message);
-
- if (STR_IN_SET(name,
- "OnActiveSec",
- "OnBootSec",
- "OnStartupSec",
- "OnUnitActiveSec",
- "OnUnitInactiveSec")) {
-
- TimerValue *v;
- TimerBase b = _TIMER_BASE_INVALID;
- usec_t u = 0;
-
- b = timer_base_from_string(name);
- if (b < 0)
- return -EINVAL;
-
- r = sd_bus_message_read(message, "t", &u);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- char time[FORMAT_TIMESPAN_MAX];
-
- unit_write_drop_in_private_format(UNIT(t), mode, name, "%s=%s\n", name, format_timespan(time, sizeof(time), u, USEC_PER_MSEC));
-
- v = new0(TimerValue, 1);
- if (!v)
- return -ENOMEM;
-
- v->base = b;
- v->value = u;
-
- LIST_PREPEND(value, t->values, v);
- }
-
- return 1;
-
- } else if (streq(name, "OnCalendar")) {
-
- TimerValue *v;
- CalendarSpec *c = NULL;
- const char *str;
-
- r = sd_bus_message_read(message, "s", &str);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- r = calendar_spec_from_string(str, &c);
- if (r < 0)
- return r;
-
- unit_write_drop_in_private_format(UNIT(t), mode, name, "%s=%s\n", name, str);
-
- v = new0(TimerValue, 1);
- if (!v) {
- if (c)
- calendar_spec_free(c);
- return -ENOMEM;
- }
-
- v->base = TIMER_CALENDAR;
- v->calendar_spec = c;
-
- LIST_PREPEND(value, t->values, v);
- }
-
- return 1;
-
- } else if (streq(name, "AccuracySec")) {
-
- usec_t u = 0;
-
- r = sd_bus_message_read(message, "t", &u);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- char time[FORMAT_TIMESPAN_MAX];
-
- t->accuracy_usec = u;
- unit_write_drop_in_private_format(UNIT(t), mode, name, "%s=%s\n", name, format_timespan(time, sizeof(time), u, USEC_PER_MSEC));
- }
-
- return 1;
-
- } else if (streq(name, "WakeSystem")) {
-
- int b;
-
- r = sd_bus_message_read(message, "b", &b);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- t->wake_system = b;
- unit_write_drop_in_private_format(UNIT(t), mode, name, "%s=%s\n", name, yes_no(t->wake_system));
- }
-
- return 1;
-
- }
-
- return 0;
-}
-
-int bus_timer_set_property(
- Unit *u,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- Timer *t = TIMER(u);
- int r;
-
- assert(t);
- assert(name);
- assert(message);
-
- if (u->transient && u->load_state == UNIT_STUB) {
- r = bus_timer_set_transient_property(t, name, message, mode, error);
- if (r != 0)
- return r;
- }
-
- return 0;
-}
diff --git a/src/core/dbus-timer.h b/src/core/dbus-timer.h
deleted file mode 100644
index 103172f05..000000000
--- a/src/core/dbus-timer.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "unit.h"
-
-extern const sd_bus_vtable bus_timer_vtable[];
-
-int bus_timer_set_property(Unit *u, const char *name, sd_bus_message *i, UnitSetPropertiesMode mode, sd_bus_error *error);
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
deleted file mode 100644
index af7dc2624..000000000
--- a/src/core/dbus-unit.c
+++ /dev/null
@@ -1,1109 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "log.h"
-#include "selinux-access.h"
-#include "cgroup-util.h"
-#include "strv.h"
-#include "bus-common-errors.h"
-#include "dbus.h"
-#include "dbus-unit.h"
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_job_mode, job_mode, JobMode);
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_failure_action, failure_action, FailureAction);
-
-static int property_get_names(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata;
- Iterator i;
- const char *t;
- int r;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- r = sd_bus_message_open_container(reply, 'a', "s");
- if (r < 0)
- return r;
-
- SET_FOREACH(t, u->names, i) {
- r = sd_bus_message_append(reply, "s", t);
- if (r < 0)
- return r;
- }
-
- return sd_bus_message_close_container(reply);
-}
-
-static int property_get_following(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata, *f;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- f = unit_following(u);
- return sd_bus_message_append(reply, "s", f ? f->id : "");
-}
-
-static int property_get_dependencies(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Set *s = *(Set**) userdata;
- Iterator j;
- Unit *u;
- int r;
-
- assert(bus);
- assert(reply);
-
- r = sd_bus_message_open_container(reply, 'a', "s");
- if (r < 0)
- return r;
-
- SET_FOREACH(u, s, j) {
- r = sd_bus_message_append(reply, "s", u->id);
- if (r < 0)
- return r;
- }
-
- return sd_bus_message_close_container(reply);
-}
-
-static int property_get_description(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- return sd_bus_message_append(reply, "s", unit_description(u));
-}
-
-static int property_get_active_state(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- return sd_bus_message_append(reply, "s", unit_active_state_to_string(unit_active_state(u)));
-}
-
-static int property_get_sub_state(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- return sd_bus_message_append(reply, "s", unit_sub_state_to_string(u));
-}
-
-static int property_get_unit_file_preset(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata;
- int r;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- r = unit_get_unit_file_preset(u);
-
- return sd_bus_message_append(reply, "s",
- r < 0 ? "":
- r > 0 ? "enabled" : "disabled");
-}
-
-static int property_get_unit_file_state(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- return sd_bus_message_append(reply, "s", unit_file_state_to_string(unit_get_unit_file_state(u)));
-}
-
-static int property_get_can_start(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- return sd_bus_message_append(reply, "b", unit_can_start(u) && !u->refuse_manual_start);
-}
-
-static int property_get_can_stop(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- /* On the lower levels we assume that every unit we can start
- * we can also stop */
-
- return sd_bus_message_append(reply, "b", unit_can_start(u) && !u->refuse_manual_stop);
-}
-
-static int property_get_can_reload(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- return sd_bus_message_append(reply, "b", unit_can_reload(u));
-}
-
-static int property_get_can_isolate(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- return sd_bus_message_append(reply, "b", unit_can_isolate(u) && !u->refuse_manual_start);
-}
-
-static int property_get_job(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- _cleanup_free_ char *p = NULL;
- Unit *u = userdata;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- if (!u->job)
- return sd_bus_message_append(reply, "(uo)", 0, "/");
-
- p = job_dbus_path(u->job);
- if (!p)
- return -ENOMEM;
-
- return sd_bus_message_append(reply, "(uo)", u->job->id, p);
-}
-
-static int property_get_need_daemon_reload(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- return sd_bus_message_append(reply, "b", unit_need_daemon_reload(u));
-}
-
-static int property_get_conditions(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- const char *(*to_string)(ConditionType type) = NULL;
- Condition **list = userdata, *c;
- int r;
-
- assert(bus);
- assert(reply);
- assert(list);
-
- to_string = streq(property, "Asserts") ? assert_type_to_string : condition_type_to_string;
-
- r = sd_bus_message_open_container(reply, 'a', "(sbbsi)");
- if (r < 0)
- return r;
-
- LIST_FOREACH(conditions, c, *list) {
- int tristate;
-
- tristate =
- c->result == CONDITION_UNTESTED ? 0 :
- c->result == CONDITION_SUCCEEDED ? 1 : -1;
-
- r = sd_bus_message_append(reply, "(sbbsi)",
- to_string(c->type),
- c->trigger, c->negate,
- c->parameter, tristate);
- if (r < 0)
- return r;
-
- }
-
- return sd_bus_message_close_container(reply);
-}
-
-static int property_get_load_error(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
- Unit *u = userdata;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- if (u->load_error != 0)
- sd_bus_error_set_errno(&e, u->load_error);
-
- return sd_bus_message_append(reply, "(ss)", e.name, e.message);
-}
-
-int bus_unit_method_start_generic(
- sd_bus *bus,
- sd_bus_message *message,
- Unit *u,
- JobType job_type,
- bool reload_if_possible,
- sd_bus_error *error) {
-
- const char *smode;
- JobMode mode;
- int r;
-
- assert(bus);
- assert(message);
- assert(u);
- assert(job_type >= 0 && job_type < _JOB_TYPE_MAX);
-
- r = mac_selinux_unit_access_check(u, message, job_type == JOB_STOP ? "stop" : "start", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "s", &smode);
- if (r < 0)
- return r;
-
- mode = job_mode_from_string(smode);
- if (mode < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s invalid", smode);
-
- r = bus_verify_manage_units_async(u->manager, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- return bus_unit_queue_job(bus, message, u, job_type, mode, reload_if_possible, error);
-}
-
-static int method_start(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return bus_unit_method_start_generic(bus, message, userdata, JOB_START, false, error);
-}
-
-static int method_stop(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return bus_unit_method_start_generic(bus, message, userdata, JOB_STOP, false, error);
-}
-
-static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return bus_unit_method_start_generic(bus, message, userdata, JOB_RELOAD, false, error);
-}
-
-static int method_restart(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return bus_unit_method_start_generic(bus, message, userdata, JOB_RESTART, false, error);
-}
-
-static int method_try_restart(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return bus_unit_method_start_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
-}
-
-static int method_reload_or_restart(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return bus_unit_method_start_generic(bus, message, userdata, JOB_RESTART, true, error);
-}
-
-static int method_reload_or_try_restart(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- return bus_unit_method_start_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
-}
-
-int bus_unit_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Unit *u = userdata;
- const char *swho;
- int32_t signo;
- KillWho who;
- int r;
-
- assert(bus);
- assert(message);
- assert(u);
-
- r = mac_selinux_unit_access_check(u, message, "stop", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "si", &swho, &signo);
- if (r < 0)
- return r;
-
- if (isempty(swho))
- who = KILL_ALL;
- else {
- who = kill_who_from_string(swho);
- if (who < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid who argument %s", swho);
- }
-
- if (signo <= 0 || signo >= _NSIG)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range.");
-
- r = bus_verify_manage_units_async_for_kill(u->manager, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- r = unit_kill(u, who, signo, error);
- if (r < 0)
- return r;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-int bus_unit_method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Unit *u = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(u);
-
- r = mac_selinux_unit_access_check(u, message, "reload", error);
- if (r < 0)
- return r;
-
- r = bus_verify_manage_units_async(u->manager, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- unit_reset_failed(u);
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-int bus_unit_method_set_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Unit *u = userdata;
- int runtime, r;
-
- assert(bus);
- assert(message);
- assert(u);
-
- r = mac_selinux_unit_access_check(u, message, "start", error);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(message, "b", &runtime);
- if (r < 0)
- return r;
-
- r = bus_verify_manage_units_async(u->manager, message, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-
- r = bus_unit_set_properties(u, message, runtime ? UNIT_RUNTIME : UNIT_PERSISTENT, true, error);
- if (r < 0)
- return r;
-
- return sd_bus_reply_method_return(message, NULL);
-}
-
-const sd_bus_vtable bus_unit_vtable[] = {
- SD_BUS_VTABLE_START(0),
-
- SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Unit, id), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Names", "as", property_get_names, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Following", "s", property_get_following, 0, 0),
- SD_BUS_PROPERTY("Requires", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRES]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RequiresOverridable", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Requisite", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUISITE]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RequisiteOverridable", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUISITE_OVERRIDABLE]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Wants", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_WANTS]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("BindsTo", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_BINDS_TO]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("PartOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_PART_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RequiredBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RequiredByOverridable", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("WantedBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_WANTED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("BoundBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_BOUND_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ConsistsOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_CONSISTS_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Conflicts", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_CONFLICTS]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ConflictedBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Before", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_BEFORE]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("After", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_AFTER]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("OnFailure", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_ON_FAILURE]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Triggers", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_TRIGGERS]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("TriggeredBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("PropagatesReloadTo", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ReloadPropagatedFrom", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_RELOAD_PROPAGATED_FROM]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("JoinsNamespaceOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_JOINS_NAMESPACE_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RequiresMountsFor", "as", NULL, offsetof(Unit, requires_mounts_for), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Documentation", "as", NULL, offsetof(Unit, documentation), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Description", "s", property_get_description, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("LoadState", "s", property_get_load_state, offsetof(Unit, load_state), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ActiveState", "s", property_get_active_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("SubState", "s", property_get_sub_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("FragmentPath", "s", NULL, offsetof(Unit, fragment_path), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Unit, source_path), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("DropInPaths", "as", NULL, offsetof(Unit, dropin_paths), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("UnitFileState", "s", property_get_unit_file_state, 0, 0),
- SD_BUS_PROPERTY("UnitFilePreset", "s", property_get_unit_file_preset, 0, 0),
- BUS_PROPERTY_DUAL_TIMESTAMP("InactiveExitTimestamp", offsetof(Unit, inactive_exit_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- BUS_PROPERTY_DUAL_TIMESTAMP("ActiveEnterTimestamp", offsetof(Unit, active_enter_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- BUS_PROPERTY_DUAL_TIMESTAMP("ActiveExitTimestamp", offsetof(Unit, active_exit_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- BUS_PROPERTY_DUAL_TIMESTAMP("InactiveEnterTimestamp", offsetof(Unit, inactive_enter_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("CanStart", "b", property_get_can_start, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("CanStop", "b", property_get_can_stop, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("CanReload", "b", property_get_can_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("CanIsolate", "b", property_get_can_isolate, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Job", "(uo)", property_get_job, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("StopWhenUnneeded", "b", bus_property_get_bool, offsetof(Unit, stop_when_unneeded), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RefuseManualStart", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_start), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RefuseManualStop", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_stop), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("AllowIsolate", "b", bus_property_get_bool, offsetof(Unit, allow_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("DefaultDependencies", "b", bus_property_get_bool, offsetof(Unit, default_dependencies), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("OnFailureJobMode", "s", property_get_job_mode, offsetof(Unit, on_failure_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("IgnoreOnIsolate", "b", bus_property_get_bool, offsetof(Unit, ignore_on_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("IgnoreOnSnapshot", "b", bus_property_get_bool, offsetof(Unit, ignore_on_snapshot), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("JobTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("JobTimeoutAction", "s", property_get_failure_action, offsetof(Unit, job_timeout_action), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("JobTimeoutRebootArgument", "s", NULL, offsetof(Unit, job_timeout_reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ConditionResult", "b", bus_property_get_bool, offsetof(Unit, condition_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("AssertResult", "b", bus_property_get_bool, offsetof(Unit, assert_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- BUS_PROPERTY_DUAL_TIMESTAMP("ConditionTimestamp", offsetof(Unit, condition_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- BUS_PROPERTY_DUAL_TIMESTAMP("AssertTimestamp", offsetof(Unit, assert_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Conditions", "a(sbbsi)", property_get_conditions, offsetof(Unit, conditions), 0),
- SD_BUS_PROPERTY("Asserts", "a(sbbsi)", property_get_conditions, offsetof(Unit, asserts), 0),
- SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST),
-
- SD_BUS_METHOD("Start", "s", "o", method_start, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Stop", "s", "o", method_stop, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Reload", "s", "o", method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Restart", "s", "o", method_restart, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("TryRestart", "s", "o", method_try_restart, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ReloadOrRestart", "s", "o", method_reload_or_restart, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ReloadOrTryRestart", "s", "o", method_reload_or_try_restart, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Kill", "si", NULL, bus_unit_method_kill, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ResetFailed", NULL, NULL, bus_unit_method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("SetProperties", "ba(sv)", NULL, bus_unit_method_set_properties, SD_BUS_VTABLE_UNPRIVILEGED),
-
- SD_BUS_VTABLE_END
-};
-
-static int property_get_slice(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- Unit *u = userdata;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- return sd_bus_message_append(reply, "s", unit_slice_name(u));
-}
-
-static int property_get_current_memory(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- uint64_t sz = (uint64_t) -1;
- Unit *u = userdata;
- int r;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- r = unit_get_memory_current(u, &sz);
- if (r < 0 && r != -ENODATA)
- log_unit_warning_errno(u->id, r, "Failed to get memory.usage_in_bytes attribute: %m");
-
- return sd_bus_message_append(reply, "t", sz);
-}
-
-static int property_get_cpu_usage(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- nsec_t ns = (nsec_t) -1;
- Unit *u = userdata;
- int r;
-
- assert(bus);
- assert(reply);
- assert(u);
-
- r = unit_get_cpu_usage(u, &ns);
- if (r < 0 && r != -ENODATA)
- log_unit_warning_errno(u->id, r, "Failed to get cpuacct.usage attribute: %m");
-
- return sd_bus_message_append(reply, "t", ns);
-}
-
-const sd_bus_vtable bus_unit_cgroup_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("Slice", "s", property_get_slice, 0, 0),
- SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Unit, cgroup_path), 0),
- SD_BUS_PROPERTY("MemoryCurrent", "t", property_get_current_memory, 0, 0),
- SD_BUS_PROPERTY("CPUUsageNSec", "t", property_get_cpu_usage, 0, 0),
- SD_BUS_VTABLE_END
-};
-
-static int send_new_signal(sd_bus *bus, void *userdata) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
- _cleanup_free_ char *p = NULL;
- Unit *u = userdata;
- int r;
-
- assert(bus);
- assert(u);
-
- p = unit_dbus_path(u);
- if (!u)
- return -ENOMEM;
-
- r = sd_bus_message_new_signal(
- bus,
- &m,
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "UnitNew");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(m, "so", u->id, p);
- if (r < 0)
- return r;
-
- return sd_bus_send(bus, m, NULL);
-}
-
-static int send_changed_signal(sd_bus *bus, void *userdata) {
- _cleanup_free_ char *p = NULL;
- Unit *u = userdata;
- int r;
-
- assert(bus);
- assert(u);
-
- p = unit_dbus_path(u);
- if (!p)
- return -ENOMEM;
-
- /* Send a properties changed signal. First for the specific
- * type, then for the generic unit. The clients may rely on
- * this order to get atomic behavior if needed. */
-
- r = sd_bus_emit_properties_changed_strv(
- bus, p,
- UNIT_VTABLE(u)->bus_interface,
- NULL);
- if (r < 0)
- return r;
-
- return sd_bus_emit_properties_changed_strv(
- bus, p,
- "org.freedesktop.systemd1.Unit",
- NULL);
-}
-
-void bus_unit_send_change_signal(Unit *u) {
- int r;
- assert(u);
-
- if (u->in_dbus_queue) {
- LIST_REMOVE(dbus_queue, u->manager->dbus_unit_queue, u);
- u->in_dbus_queue = false;
- }
-
- if (!u->id)
- return;
-
- r = bus_foreach_bus(u->manager, NULL, u->sent_dbus_new_signal ? send_changed_signal : send_new_signal, u);
- if (r < 0)
- log_debug_errno(r, "Failed to send unit change signal for %s: %m", u->id);
-
- u->sent_dbus_new_signal = true;
-}
-
-static int send_removed_signal(sd_bus *bus, void *userdata) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
- _cleanup_free_ char *p = NULL;
- Unit *u = userdata;
- int r;
-
- assert(bus);
- assert(u);
-
- p = unit_dbus_path(u);
- if (!u)
- return -ENOMEM;
-
- r = sd_bus_message_new_signal(
- bus,
- &m,
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "UnitRemoved");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(m, "so", u->id, p);
- if (r < 0)
- return r;
-
- return sd_bus_send(bus, m, NULL);
-}
-
-void bus_unit_send_removed_signal(Unit *u) {
- int r;
- assert(u);
-
- if (!u->sent_dbus_new_signal)
- bus_unit_send_change_signal(u);
-
- if (!u->id)
- return;
-
- r = bus_foreach_bus(u->manager, NULL, send_removed_signal, u);
- if (r < 0)
- log_debug_errno(r, "Failed to send unit remove signal for %s: %m", u->id);
-}
-
-int bus_unit_queue_job(
- sd_bus *bus,
- sd_bus_message *message,
- Unit *u,
- JobType type,
- JobMode mode,
- bool reload_if_possible,
- sd_bus_error *error) {
-
- _cleanup_free_ char *path = NULL;
- Job *j;
- int r;
-
- assert(bus);
- assert(message);
- assert(u);
- assert(type >= 0 && type < _JOB_TYPE_MAX);
- assert(mode >= 0 && mode < _JOB_MODE_MAX);
-
- if (reload_if_possible && unit_can_reload(u)) {
- if (type == JOB_RESTART)
- type = JOB_RELOAD_OR_START;
- else if (type == JOB_TRY_RESTART)
- type = JOB_RELOAD;
- }
-
- r = mac_selinux_unit_access_check(
- u, message,
- (type == JOB_START || type == JOB_RESTART || type == JOB_TRY_RESTART) ? "start" :
- type == JOB_STOP ? "stop" : "reload", error);
- if (r < 0)
- return r;
-
- if (type == JOB_STOP &&
- (u->load_state == UNIT_NOT_FOUND || u->load_state == UNIT_ERROR) &&
- unit_active_state(u) == UNIT_INACTIVE)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
-
- if ((type == JOB_START && u->refuse_manual_start) ||
- (type == JOB_STOP && u->refuse_manual_stop) ||
- ((type == JOB_RESTART || type == JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)))
- return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only.", u->id);
-
- r = manager_add_job(u->manager, type, u, mode, true, error, &j);
- if (r < 0)
- return r;
-
- if (bus == u->manager->api_bus) {
- if (!j->clients) {
- r = sd_bus_track_new(bus, &j->clients, NULL, NULL);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_track_add_sender(j->clients, message);
- if (r < 0)
- return r;
- }
-
- path = job_dbus_path(j);
- if (!path)
- return -ENOMEM;
-
- return sd_bus_reply_method_return(message, "o", path);
-}
-
-static int bus_unit_set_transient_property(
- Unit *u,
- const char *name,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- sd_bus_error *error) {
-
- int r;
-
- assert(u);
- assert(name);
- assert(message);
-
- if (streq(name, "Description")) {
- const char *d;
-
- r = sd_bus_message_read(message, "s", &d);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- r = unit_set_description(u, d);
- if (r < 0)
- return r;
-
- unit_write_drop_in_format(u, mode, name, "[Unit]\nDescription=%s\n", d);
- }
-
- return 1;
-
- } else if (streq(name, "DefaultDependencies")) {
- int b;
-
- r = sd_bus_message_read(message, "b", &b);
- if (r < 0)
- return r;
-
- if (mode != UNIT_CHECK) {
- u->default_dependencies = b;
- unit_write_drop_in_format(u, mode, name, "[Unit]\nDefaultDependencies=%s\n", yes_no(b));
- }
-
- return 1;
-
- } else if (streq(name, "Slice") && unit_get_cgroup_context(u)) {
- const char *s;
-
- r = sd_bus_message_read(message, "s", &s);
- if (r < 0)
- return r;
-
- if (!unit_name_is_valid(s, TEMPLATE_INVALID) || !endswith(s, ".slice"))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid slice name %s", s);
-
- if (isempty(s)) {
- if (mode != UNIT_CHECK) {
- unit_ref_unset(&u->slice);
- unit_remove_drop_in(u, mode, name);
- }
- } else {
- Unit *slice;
-
- r = manager_load_unit(u->manager, s, NULL, error, &slice);
- if (r < 0)
- return r;
-
- if (slice->type != UNIT_SLICE)
- return -EINVAL;
-
- if (mode != UNIT_CHECK) {
- unit_ref_set(&u->slice, slice);
- unit_write_drop_in_private_format(u, mode, name, "Slice=%s\n", s);
- }
- }
-
- return 1;
- } else if (STR_IN_SET(name,
- "Requires", "RequiresOverridable",
- "Requisite", "RequisiteOverridable",
- "Wants",
- "BindsTo",
- "Conflicts",
- "Before", "After",
- "OnFailure",
- "PropagatesReloadTo", "ReloadPropagatedFrom",
- "PartOf")) {
-
- UnitDependency d;
- const char *other;
-
- d = unit_dependency_from_string(name);
- if (d < 0)
- return -EINVAL;
-
- r = sd_bus_message_enter_container(message, 'a', "s");
- if (r < 0)
- return r;
-
- while ((r = sd_bus_message_read(message, "s", &other)) > 0) {
- if (!unit_name_is_valid(other, TEMPLATE_INVALID))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name %s", other);
-
- if (mode != UNIT_CHECK) {
- _cleanup_free_ char *label = NULL;
-
- r = unit_add_dependency_by_name(u, d, other, NULL, true);
- if (r < 0)
- return r;
-
- label = strjoin(name, "-", other, NULL);
- if (!label)
- return -ENOMEM;
-
- unit_write_drop_in_format(u, mode, label, "[Unit]\n%s=%s\n", name, other);
- }
-
- }
- if (r < 0)
- return r;
-
- r = sd_bus_message_exit_container(message);
- if (r < 0)
- return r;
-
- return 1;
- }
-
- return 0;
-}
-
-int bus_unit_set_properties(
- Unit *u,
- sd_bus_message *message,
- UnitSetPropertiesMode mode,
- bool commit,
- sd_bus_error *error) {
-
- bool for_real = false;
- unsigned n = 0;
- int r;
-
- assert(u);
- assert(message);
-
- /* We iterate through the array twice. First run we just check
- * if all passed data is valid, second run actually applies
- * it. This is to implement transaction-like behaviour without
- * actually providing full transactions. */
-
- r = sd_bus_message_enter_container(message, 'a', "(sv)");
- if (r < 0)
- return r;
-
- for (;;) {
- const char *name;
-
- r = sd_bus_message_enter_container(message, 'r', "sv");
- if (r < 0)
- return r;
- if (r == 0) {
- if (for_real || mode == UNIT_CHECK)
- break;
-
- /* Reached EOF. Let's try again, and this time for realz... */
- r = sd_bus_message_rewind(message, false);
- if (r < 0)
- return r;
-
- for_real = true;
- continue;
- }
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0)
- return r;
-
- if (!UNIT_VTABLE(u)->bus_set_property)
- return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Objects of this type do not support setting properties.");
-
- r = sd_bus_message_enter_container(message, 'v', NULL);
- if (r < 0)
- return r;
-
- r = UNIT_VTABLE(u)->bus_set_property(u, name, message, for_real ? mode : UNIT_CHECK, error);
- if (r == 0 && u->transient && u->load_state == UNIT_STUB)
- r = bus_unit_set_transient_property(u, name, message, for_real ? mode : UNIT_CHECK, error);
- if (r < 0)
- return r;
- if (r == 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Cannot set property %s, or unknown property.", name);
-
- r = sd_bus_message_exit_container(message);
- if (r < 0)
- return r;
-
- r = sd_bus_message_exit_container(message);
- if (r < 0)
- return r;
-
- n += for_real;
- }
-
- r = sd_bus_message_exit_container(message);
- if (r < 0)
- return r;
-
- if (commit && n > 0 && UNIT_VTABLE(u)->bus_commit_properties)
- UNIT_VTABLE(u)->bus_commit_properties(u);
-
- return n;
-}
diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h
deleted file mode 100644
index 57a5e1974..000000000
--- a/src/core/dbus-unit.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-#include "unit.h"
-
-extern const sd_bus_vtable bus_unit_vtable[];
-extern const sd_bus_vtable bus_unit_cgroup_vtable[];
-
-void bus_unit_send_change_signal(Unit *u);
-void bus_unit_send_removed_signal(Unit *u);
-
-int bus_unit_method_start_generic(sd_bus *bus, sd_bus_message *message, Unit *u, JobType job_type, bool reload_if_possible, sd_bus_error *error);
-int bus_unit_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_unit_method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
-
-int bus_unit_queue_job(sd_bus *bus, sd_bus_message *message, Unit *u, JobType type, JobMode mode, bool reload_if_possible, sd_bus_error *error);
-int bus_unit_set_properties(Unit *u, sd_bus_message *message, UnitSetPropertiesMode mode, bool commit, sd_bus_error *error);
-int bus_unit_method_set_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
diff --git a/src/core/dbus.c b/src/core/dbus.c
deleted file mode 100644
index ae259c37d..000000000
--- a/src/core/dbus.c
+++ /dev/null
@@ -1,1214 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/epoll.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "sd-bus.h"
-#include "log.h"
-#include "strv.h"
-#include "mkdir.h"
-#include "missing.h"
-#include "dbus-unit.h"
-#include "dbus-job.h"
-#include "dbus-manager.h"
-#include "dbus-execute.h"
-#include "dbus-kill.h"
-#include "dbus-cgroup.h"
-#include "special.h"
-#include "dbus.h"
-#include "bus-util.h"
-#include "bus-error.h"
-#include "bus-common-errors.h"
-#include "strxcpyx.h"
-#include "bus-internal.h"
-#include "selinux-access.h"
-
-#define CONNECTIONS_MAX 4096
-
-static void destroy_bus(Manager *m, sd_bus **bus);
-
-int bus_send_queued_message(Manager *m) {
- int r;
-
- assert(m);
-
- if (!m->queued_message)
- return 0;
-
- assert(m->queued_message_bus);
-
- /* If we cannot get rid of this message we won't dispatch any
- * D-Bus messages, so that we won't end up wanting to queue
- * another message. */
-
- r = sd_bus_send(m->queued_message_bus, m->queued_message, NULL);
- if (r < 0)
- log_warning_errno(r, "Failed to send queued message: %m");
-
- m->queued_message = sd_bus_message_unref(m->queued_message);
- m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
-
- return 0;
-}
-
-static int signal_agent_released(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- const char *cgroup;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &cgroup);
- if (r < 0) {
- bus_log_parse_error(r);
- return 0;
- }
-
- manager_notify_cgroup_empty(m, cgroup);
-
- /* only forward to system bus if running as system instance */
- if (m->running_as != SYSTEMD_SYSTEM || !m->system_bus)
- return 0;
-
- r = sd_bus_message_rewind(message, 1);
- if (r < 0)
- goto exit;
-
- r = sd_bus_send(m->system_bus, message, NULL);
-
-exit:
- if (r < 0)
- log_warning_errno(r, "Failed to forward Released message: %m");
- return 0;
-}
-
-static int signal_disconnected(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
-
- assert(bus);
- assert(message);
- assert(m);
-
- if (bus == m->api_bus)
- destroy_bus(m, &m->api_bus);
- if (bus == m->system_bus)
- destroy_bus(m, &m->system_bus);
- if (set_remove(m->private_buses, bus)) {
- log_debug("Got disconnect on private connection.");
- destroy_bus(m, &bus);
- }
-
- return 0;
-}
-
-static int signal_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- const char *name, *old_owner, *new_owner;
- Manager *m = userdata;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "sss", &name, &old_owner, &new_owner);
- if (r < 0) {
- bus_log_parse_error(r);
- return 0;
- }
-
- manager_dispatch_bus_name_owner_changed(
- m, name,
- isempty(old_owner) ? NULL : old_owner,
- isempty(new_owner) ? NULL : new_owner);
-
- return 0;
-}
-
-static int signal_activation_request(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- Manager *m = userdata;
- const char *name;
- Unit *u;
- int r;
-
- assert(bus);
- assert(message);
- assert(m);
-
- r = sd_bus_message_read(message, "s", &name);
- if (r < 0) {
- bus_log_parse_error(r);
- return 0;
- }
-
- if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) ||
- manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET)) {
- r = sd_bus_error_setf(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
- goto failed;
- }
-
- r = manager_load_unit(m, name, NULL, &error, &u);
- if (r < 0)
- goto failed;
-
- if (u->refuse_manual_start) {
- r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, %s may be requested by dependency only.", u->id);
- goto failed;
- }
-
- r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
- if (r < 0)
- goto failed;
-
- /* Successfully queued, that's it for us */
- return 0;
-
-failed:
- if (!sd_bus_error_is_set(&error))
- sd_bus_error_set_errno(&error, r);
-
- log_debug("D-Bus activation failed for %s: %s", name, bus_error_message(&error, r));
-
- r = sd_bus_message_new_signal(bus, &reply, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure");
- if (r < 0) {
- bus_log_create_error(r);
- return 0;
- }
-
- r = sd_bus_message_append(reply, "sss", name, error.name, error.message);
- if (r < 0) {
- bus_log_create_error(r);
- return 0;
- }
-
- r = sd_bus_send_to(bus, reply, "org.freedesktop.DBus", NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to respond with to bus activation request: %m");
-
- return 0;
-}
-
-#ifdef HAVE_SELINUX
-static int mac_selinux_filter(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
- const char *verb, *path;
- Unit *u = NULL;
- Job *j;
- int r;
-
- assert(bus);
- assert(message);
-
- /* Our own method calls are all protected individually with
- * selinux checks, but the built-in interfaces need to be
- * protected too. */
-
- if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set"))
- verb = "reload";
- else if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", NULL) ||
- sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", NULL) ||
- sd_bus_message_is_method_call(message, "org.freedesktop.DBus.ObjectManager", NULL) ||
- sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Peer", NULL))
- verb = "status";
- else
- return 0;
-
- path = sd_bus_message_get_path(message);
-
- if (object_path_startswith("/org/freedesktop/systemd1", path)) {
-
- r = mac_selinux_access_check(message, verb, error);
- if (r < 0)
- return r;
-
- return 0;
- }
-
- if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
- pid_t pid;
-
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return 0;
-
- r = sd_bus_creds_get_pid(creds, &pid);
- if (r < 0)
- return 0;
-
- u = manager_get_unit_by_pid(m, pid);
- } else {
- r = manager_get_job_from_dbus_path(m, path, &j);
- if (r >= 0)
- u = j->unit;
- else
- manager_load_unit_from_dbus_path(m, path, NULL, &u);
- }
-
- if (!u)
- return 0;
-
- r = mac_selinux_unit_access_check(u, message, verb, error);
- if (r < 0)
- return r;
-
- return 0;
-}
-#endif
-
-static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
- Manager *m = userdata;
- Job *j;
- int r;
-
- assert(bus);
- assert(path);
- assert(interface);
- assert(found);
- assert(m);
-
- r = manager_get_job_from_dbus_path(m, path, &j);
- if (r < 0)
- return 0;
-
- *found = j;
- return 1;
-}
-
-static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
- Unit *u;
- int r;
-
- assert(m);
- assert(bus);
- assert(path);
-
- if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
- sd_bus_message *message;
- pid_t pid;
-
- message = sd_bus_get_current_message(bus);
- if (!message)
- return 0;
-
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_pid(creds, &pid);
- if (r < 0)
- return r;
-
- u = manager_get_unit_by_pid(m, pid);
- } else {
- r = manager_load_unit_from_dbus_path(m, path, error, &u);
- if (r < 0)
- return 0;
- }
-
- if (!u)
- return 0;
-
- *unit = u;
- return 1;
-}
-
-static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
- Manager *m = userdata;
-
- assert(bus);
- assert(path);
- assert(interface);
- assert(found);
- assert(m);
-
- return find_unit(m, bus, path, (Unit**) found, error);
-}
-
-static int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
- Manager *m = userdata;
- Unit *u;
- int r;
-
- assert(bus);
- assert(path);
- assert(interface);
- assert(found);
- assert(m);
-
- r = find_unit(m, bus, path, &u, error);
- if (r <= 0)
- return r;
-
- if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
- return 0;
-
- *found = u;
- return 1;
-}
-
-static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
- Manager *m = userdata;
- Unit *u;
- int r;
-
- assert(bus);
- assert(path);
- assert(interface);
- assert(found);
- assert(m);
-
- r = find_unit(m, bus, path, &u, error);
- if (r <= 0)
- return r;
-
- if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
- return 0;
-
- if (!unit_get_cgroup_context(u))
- return 0;
-
- *found = u;
- return 1;
-}
-
-static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
- Manager *m = userdata;
- CGroupContext *c;
- Unit *u;
- int r;
-
- assert(bus);
- assert(path);
- assert(interface);
- assert(found);
- assert(m);
-
- r = find_unit(m, bus, path, &u, error);
- if (r <= 0)
- return r;
-
- if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
- return 0;
-
- c = unit_get_cgroup_context(u);
- if (!c)
- return 0;
-
- *found = c;
- return 1;
-}
-
-static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
- Manager *m = userdata;
- ExecContext *c;
- Unit *u;
- int r;
-
- assert(bus);
- assert(path);
- assert(interface);
- assert(found);
- assert(m);
-
- r = find_unit(m, bus, path, &u, error);
- if (r <= 0)
- return r;
-
- if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
- return 0;
-
- c = unit_get_exec_context(u);
- if (!c)
- return 0;
-
- *found = c;
- return 1;
-}
-
-static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
- Manager *m = userdata;
- KillContext *c;
- Unit *u;
- int r;
-
- assert(bus);
- assert(path);
- assert(interface);
- assert(found);
- assert(m);
-
- r = find_unit(m, bus, path, &u, error);
- if (r <= 0)
- return r;
-
- if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
- return 0;
-
- c = unit_get_kill_context(u);
- if (!c)
- return 0;
-
- *found = c;
- return 1;
-}
-
-static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
- _cleanup_free_ char **l = NULL;
- Manager *m = userdata;
- unsigned k = 0;
- Iterator i;
- Job *j;
-
- l = new0(char*, hashmap_size(m->jobs)+1);
- if (!l)
- return -ENOMEM;
-
- HASHMAP_FOREACH(j, m->jobs, i) {
- l[k] = job_dbus_path(j);
- if (!l[k])
- return -ENOMEM;
-
- k++;
- }
-
- assert(hashmap_size(m->jobs) == k);
-
- *nodes = l;
- l = NULL;
-
- return k;
-}
-
-static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
- _cleanup_free_ char **l = NULL;
- Manager *m = userdata;
- unsigned k = 0;
- Iterator i;
- Unit *u;
-
- l = new0(char*, hashmap_size(m->units)+1);
- if (!l)
- return -ENOMEM;
-
- HASHMAP_FOREACH(u, m->units, i) {
- l[k] = unit_dbus_path(u);
- if (!l[k])
- return -ENOMEM;
-
- k++;
- }
-
- *nodes = l;
- l = NULL;
-
- return k;
-}
-
-static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
- UnitType t;
- int r;
-
- assert(m);
- assert(bus);
-
-#ifdef HAVE_SELINUX
- r = sd_bus_add_filter(bus, NULL, mac_selinux_filter, m);
- if (r < 0)
- return log_error_errno(r, "Failed to add SELinux access filter: %m");
-#endif
-
- r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
- if (r < 0)
- return log_error_errno(r, "Failed to register Manager vtable: %m");
-
- r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
- if (r < 0)
- return log_error_errno(r, "Failed to register Job vtable: %m");
-
- r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
- if (r < 0)
- return log_error_errno(r, "Failed to add job enumerator: %m");
-
- r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
- if (r < 0)
- return log_error_errno(r, "Failed to register Unit vtable: %m");
-
- r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
- if (r < 0)
- return log_error_errno(r, "Failed to add job enumerator: %m");
-
- for (t = 0; t < _UNIT_TYPE_MAX; t++) {
- r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
- if (r < 0)
- return log_error_errno(r, "Failed to register type specific vtable for %s: %m", unit_vtable[t]->bus_interface);
-
- if (unit_vtable[t]->cgroup_context_offset > 0) {
- r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
- if (r < 0)
- return log_error_errno(r, "Failed to register control group unit vtable for %s: %m", unit_vtable[t]->bus_interface);
-
- r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
- if (r < 0)
- return log_error_errno(r, "Failed to register control group vtable for %s: %m", unit_vtable[t]->bus_interface);
- }
-
- if (unit_vtable[t]->exec_context_offset > 0) {
- r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
- if (r < 0)
- return log_error_errno(r, "Failed to register execute vtable for %s: %m", unit_vtable[t]->bus_interface);
- }
-
- if (unit_vtable[t]->kill_context_offset > 0) {
- r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
- if (r < 0)
- return log_error_errno(r, "Failed to register kill vtable for %s: %m", unit_vtable[t]->bus_interface);
- }
- }
-
- return 0;
-}
-
-static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
- int r;
-
- assert(m);
- assert(bus);
-
- r = sd_bus_add_match(
- bus,
- NULL,
- "sender='org.freedesktop.DBus.Local',"
- "type='signal',"
- "path='/org/freedesktop/DBus/Local',"
- "interface='org.freedesktop.DBus.Local',"
- "member='Disconnected'",
- signal_disconnected, m);
-
- if (r < 0)
- return log_error_errno(r, "Failed to register match for Disconnected message: %m");
-
- return 0;
-}
-
-static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
- _cleanup_bus_unref_ sd_bus *bus = NULL;
- _cleanup_close_ int nfd = -1;
- Manager *m = userdata;
- sd_id128_t id;
- int r;
-
- assert(s);
- assert(m);
-
- nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
- if (nfd < 0) {
- log_warning_errno(errno, "Failed to accept private connection, ignoring: %m");
- return 0;
- }
-
- if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
- log_warning("Too many concurrent connections, refusing");
- return 0;
- }
-
- r = set_ensure_allocated(&m->private_buses, NULL);
- if (r < 0) {
- log_oom();
- return 0;
- }
-
- r = sd_bus_new(&bus);
- if (r < 0) {
- log_warning_errno(r, "Failed to allocate new private connection bus: %m");
- return 0;
- }
-
- r = sd_bus_set_fd(bus, nfd, nfd);
- if (r < 0) {
- log_warning_errno(r, "Failed to set fd on new connection bus: %m");
- return 0;
- }
-
- nfd = -1;
-
- r = bus_check_peercred(bus);
- if (r < 0) {
- log_warning_errno(r, "Incoming private connection from unprivileged client, refusing: %m");
- return 0;
- }
-
- assert_se(sd_id128_randomize(&id) >= 0);
-
- r = sd_bus_set_server(bus, 1, id);
- if (r < 0) {
- log_warning_errno(r, "Failed to enable server support for new connection bus: %m");
- return 0;
- }
-
- r = sd_bus_start(bus);
- if (r < 0) {
- log_warning_errno(r, "Failed to start new connection bus: %m");
- return 0;
- }
-
- r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
- if (r < 0) {
- log_warning_errno(r, "Failed to attach new connection bus to event loop: %m");
- return 0;
- }
-
- if (m->running_as == SYSTEMD_SYSTEM) {
- /* When we run as system instance we get the Released
- * signal via a direct connection */
-
- r = sd_bus_add_match(
- bus,
- NULL,
- "type='signal',"
- "interface='org.freedesktop.systemd1.Agent',"
- "member='Released',"
- "path='/org/freedesktop/systemd1/agent'",
- signal_agent_released, m);
-
- if (r < 0) {
- log_warning_errno(r, "Failed to register Released match on new connection bus: %m");
- return 0;
- }
- }
-
- r = bus_setup_disconnected_match(m, bus);
- if (r < 0)
- return 0;
-
- r = bus_setup_api_vtables(m, bus);
- if (r < 0) {
- log_warning_errno(r, "Failed to set up API vtables on new connection bus: %m");
- return 0;
- }
-
- r = set_put(m->private_buses, bus);
- if (r < 0) {
- log_warning_errno(r, "Failed to add new conenction bus to set: %m");
- return 0;
- }
-
- bus = NULL;
-
- log_debug("Accepted new private connection.");
-
- return 0;
-}
-
-static int bus_list_names(Manager *m, sd_bus *bus) {
- _cleanup_strv_free_ char **names = NULL;
- char **i;
- int r;
-
- assert(m);
- assert(bus);
-
- r = sd_bus_list_names(bus, &names, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to get initial list of names: %m");
-
- /* This is a bit hacky, we say the owner of the name is the
- * name itself, because we don't want the extra traffic to
- * figure out the real owner. */
- STRV_FOREACH(i, names)
- manager_dispatch_bus_name_owner_changed(m, *i, NULL, *i);
-
- return 0;
-}
-
-static int bus_setup_api(Manager *m, sd_bus *bus) {
- int r;
-
- assert(m);
- assert(bus);
-
- /* Let's make sure we have enough credential bits so that we can make security and selinux decisions */
- r = sd_bus_negotiate_creds(bus, 1,
- SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|
- SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS|
- SD_BUS_CREDS_SELINUX_CONTEXT);
- if (r < 0)
- log_warning_errno(r, "Failed to enable credential passing, ignoring: %m");
-
- r = bus_setup_api_vtables(m, bus);
- if (r < 0)
- return r;
-
- r = sd_bus_add_match(
- bus,
- NULL,
- "type='signal',"
- "sender='org.freedesktop.DBus',"
- "path='/org/freedesktop/DBus',"
- "interface='org.freedesktop.DBus',"
- "member='NameOwnerChanged'",
- signal_name_owner_changed, m);
- if (r < 0)
- log_warning_errno(r, "Failed to subscribe to NameOwnerChanged signal: %m");
-
- r = sd_bus_add_match(
- bus,
- NULL,
- "type='signal',"
- "sender='org.freedesktop.DBus',"
- "path='/org/freedesktop/DBus',"
- "interface='org.freedesktop.systemd1.Activator',"
- "member='ActivationRequest'",
- signal_activation_request, m);
- if (r < 0)
- log_warning_errno(r, "Failed to subscribe to activation signal: %m");
-
- /* Allow replacing of our name, to ease implementation of
- * reexecution, where we keep the old connection open until
- * after the new connection is set up and the name installed
- * to allow clients to synchronously wait for reexecution to
- * finish */
- r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_ALLOW_REPLACEMENT);
- if (r < 0)
- return log_error_errno(r, "Failed to register name: %m");
-
- bus_list_names(m, bus);
-
- log_debug("Successfully connected to API bus.");
- return 0;
-}
-
-static int bus_init_api(Manager *m) {
- _cleanup_bus_unref_ sd_bus *bus = NULL;
- int r;
-
- if (m->api_bus)
- return 0;
-
- /* The API and system bus is the same if we are running in system mode */
- if (m->running_as == SYSTEMD_SYSTEM && m->system_bus)
- bus = sd_bus_ref(m->system_bus);
- else {
- if (m->running_as == SYSTEMD_SYSTEM)
- r = sd_bus_open_system(&bus);
- else
- r = sd_bus_open_user(&bus);
-
- if (r < 0) {
- log_debug("Failed to connect to API bus, retrying later...");
- return 0;
- }
-
- r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
- if (r < 0) {
- log_error_errno(r, "Failed to attach API bus to event loop: %m");
- return 0;
- }
-
- r = bus_setup_disconnected_match(m, bus);
- if (r < 0)
- return 0;
- }
-
- r = bus_setup_api(m, bus);
- if (r < 0) {
- log_error_errno(r, "Failed to set up API bus: %m");
- return 0;
- }
-
- m->api_bus = bus;
- bus = NULL;
-
- return 0;
-}
-
-static int bus_setup_system(Manager *m, sd_bus *bus) {
- int r;
-
- assert(m);
- assert(bus);
-
- /* On kdbus or if we are a user instance we get the Released message via the system bus */
- if (m->running_as == SYSTEMD_USER || m->kdbus_fd >= 0) {
- r = sd_bus_add_match(
- bus,
- NULL,
- "type='signal',"
- "interface='org.freedesktop.systemd1.Agent',"
- "member='Released',"
- "path='/org/freedesktop/systemd1/agent'",
- signal_agent_released, m);
- if (r < 0)
- log_warning_errno(r, "Failed to register Released match on system bus: %m");
- }
-
- log_debug("Successfully connected to system bus.");
- return 0;
-}
-
-static int bus_init_system(Manager *m) {
- _cleanup_bus_unref_ sd_bus *bus = NULL;
- int r;
-
- if (m->system_bus)
- return 0;
-
- /* The API and system bus is the same if we are running in system mode */
- if (m->running_as == SYSTEMD_SYSTEM && m->api_bus) {
- m->system_bus = sd_bus_ref(m->api_bus);
- return 0;
- }
-
- r = sd_bus_open_system(&bus);
- if (r < 0) {
- log_debug("Failed to connect to system bus, retrying later...");
- return 0;
- }
-
- r = bus_setup_disconnected_match(m, bus);
- if (r < 0)
- return 0;
-
- r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
- if (r < 0) {
- log_error_errno(r, "Failed to attach system bus to event loop: %m");
- return 0;
- }
-
- r = bus_setup_system(m, bus);
- if (r < 0) {
- log_error_errno(r, "Failed to set up system bus: %m");
- return 0;
- }
-
- m->system_bus = bus;
- bus = NULL;
-
- return 0;
-}
-
-static int bus_init_private(Manager *m) {
- _cleanup_close_ int fd = -1;
- union sockaddr_union sa = {
- .un.sun_family = AF_UNIX
- };
- sd_event_source *s;
- socklen_t salen;
- int r;
-
- assert(m);
-
- if (m->private_listen_fd >= 0)
- return 0;
-
- /* We don't need the private socket if we have kdbus */
- if (m->kdbus_fd >= 0)
- return 0;
-
- if (m->running_as == SYSTEMD_SYSTEM) {
-
- /* We want the private bus only when running as init */
- if (getpid() != 1)
- return 0;
-
- strcpy(sa.un.sun_path, "/run/systemd/private");
- salen = offsetof(union sockaddr_union, un.sun_path) + strlen("/run/systemd/private");
- } else {
- size_t left = sizeof(sa.un.sun_path);
- char *p = sa.un.sun_path;
- const char *e;
-
- e = secure_getenv("XDG_RUNTIME_DIR");
- if (!e) {
- log_error("Failed to determine XDG_RUNTIME_DIR");
- return -EHOSTDOWN;
- }
-
- left = strpcpy(&p, left, e);
- left = strpcpy(&p, left, "/systemd/private");
-
- salen = sizeof(sa.un) - left;
- }
-
- (void) mkdir_parents_label(sa.un.sun_path, 0755);
- (void) unlink(sa.un.sun_path);
-
- fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
- if (fd < 0)
- return log_error_errno(errno, "Failed to allocate private socket: %m");
-
- r = bind(fd, &sa.sa, salen);
- if (r < 0)
- return log_error_errno(errno, "Failed to bind private socket: %m");
-
- r = listen(fd, SOMAXCONN);
- if (r < 0)
- return log_error_errno(errno, "Failed to make private socket listening: %m");
-
- r = sd_event_add_io(m->event, &s, fd, EPOLLIN, bus_on_connection, m);
- if (r < 0)
- return log_error_errno(r, "Failed to allocate event source: %m");
-
- m->private_listen_fd = fd;
- m->private_listen_event_source = s;
- fd = -1;
-
- log_debug("Successfully created private D-Bus server.");
-
- return 0;
-}
-
-int bus_init(Manager *m, bool try_bus_connect) {
- int r;
-
- if (try_bus_connect) {
- r = bus_init_system(m);
- if (r < 0)
- return r;
-
- r = bus_init_api(m);
- if (r < 0)
- return r;
- }
-
- r = bus_init_private(m);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-static void destroy_bus(Manager *m, sd_bus **bus) {
- Iterator i;
- Job *j;
-
- assert(m);
- assert(bus);
-
- if (!*bus)
- return;
-
- /* Get rid of tracked clients on this bus */
- if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus)
- m->subscribed = sd_bus_track_unref(m->subscribed);
-
- HASHMAP_FOREACH(j, m->jobs, i)
- if (j->clients && sd_bus_track_get_bus(j->clients) == *bus)
- j->clients = sd_bus_track_unref(j->clients);
-
- /* Get rid of queued message on this bus */
- if (m->queued_message_bus == *bus) {
- m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
-
- if (m->queued_message)
- m->queued_message = sd_bus_message_unref(m->queued_message);
- }
-
- /* Possibly flush unwritten data, but only if we are
- * unprivileged, since we don't want to sync here */
- if (m->running_as != SYSTEMD_SYSTEM)
- sd_bus_flush(*bus);
-
- /* And destroy the object */
- sd_bus_close(*bus);
- *bus = sd_bus_unref(*bus);
-}
-
-void bus_done(Manager *m) {
- sd_bus *b;
-
- assert(m);
-
- if (m->api_bus)
- destroy_bus(m, &m->api_bus);
- if (m->system_bus)
- destroy_bus(m, &m->system_bus);
- while ((b = set_steal_first(m->private_buses)))
- destroy_bus(m, &b);
-
- set_free(m->private_buses);
- m->private_buses = NULL;
-
- m->subscribed = sd_bus_track_unref(m->subscribed);
- strv_free(m->deserialized_subscribed);
- m->deserialized_subscribed = NULL;
-
- if (m->private_listen_event_source)
- m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
-
- m->private_listen_fd = safe_close(m->private_listen_fd);
-
- bus_verify_polkit_async_registry_free(m->polkit_registry);
-}
-
-int bus_fdset_add_all(Manager *m, FDSet *fds) {
- Iterator i;
- sd_bus *b;
- int fd;
-
- assert(m);
- assert(fds);
-
- /* When we are about to reexecute we add all D-Bus fds to the
- * set to pass over to the newly executed systemd. They won't
- * be used there however, except thatt they are closed at the
- * very end of deserialization, those making it possible for
- * clients to synchronously wait for systemd to reexec by
- * simply waiting for disconnection */
-
- if (m->api_bus) {
- fd = sd_bus_get_fd(m->api_bus);
- if (fd >= 0) {
- fd = fdset_put_dup(fds, fd);
- if (fd < 0)
- return fd;
- }
- }
-
- SET_FOREACH(b, m->private_buses, i) {
- fd = sd_bus_get_fd(b);
- if (fd >= 0) {
- fd = fdset_put_dup(fds, fd);
- if (fd < 0)
- return fd;
- }
- }
-
- /* We don't offer any APIs on the system bus (well, unless it
- * is the same as the API bus) hence we don't bother with it
- * here */
-
- return 0;
-}
-
-int bus_foreach_bus(
- Manager *m,
- sd_bus_track *subscribed2,
- int (*send_message)(sd_bus *bus, void *userdata),
- void *userdata) {
-
- Iterator i;
- sd_bus *b;
- int r, ret = 0;
-
- /* Send to all direct busses, unconditionally */
- SET_FOREACH(b, m->private_buses, i) {
- r = send_message(b, userdata);
- if (r < 0)
- ret = r;
- }
-
- /* Send to API bus, but only if somebody is subscribed */
- if (sd_bus_track_count(m->subscribed) > 0 ||
- sd_bus_track_count(subscribed2) > 0) {
- r = send_message(m->api_bus, userdata);
- if (r < 0)
- ret = r;
- }
-
- return ret;
-}
-
-void bus_track_serialize(sd_bus_track *t, FILE *f) {
- const char *n;
-
- assert(f);
-
- for (n = sd_bus_track_first(t); n; n = sd_bus_track_next(t))
- fprintf(f, "subscribed=%s\n", n);
-}
-
-int bus_track_deserialize_item(char ***l, const char *line) {
- const char *e;
- int r;
-
- assert(l);
- assert(line);
-
- e = startswith(line, "subscribed=");
- if (!e)
- return 0;
-
- r = strv_extend(l, e);
- if (r < 0)
- return r;
-
- return 1;
-}
-
-int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l) {
- int r = 0;
-
- assert(m);
- assert(t);
- assert(l);
-
- if (!strv_isempty(*l) && m->api_bus) {
- char **i;
-
- if (!*t) {
- r = sd_bus_track_new(m->api_bus, t, NULL, NULL);
- if (r < 0)
- return r;
- }
-
- r = 0;
- STRV_FOREACH(i, *l) {
- int k;
-
- k = sd_bus_track_add_name(*t, *i);
- if (k < 0)
- r = k;
- }
- }
-
- strv_free(*l);
- *l = NULL;
-
- return r;
-}
-
-int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
- return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-units", false, UID_INVALID, &m->polkit_registry, error);
-}
-
-/* Same as bus_verify_manage_unit_async(), but checks for CAP_KILL instead of CAP_SYS_ADMIN */
-int bus_verify_manage_units_async_for_kill(Manager *m, sd_bus_message *call, sd_bus_error *error) {
- return bus_verify_polkit_async(call, CAP_KILL, "org.freedesktop.systemd1.manage-units", false, UID_INVALID, &m->polkit_registry, error);
-}
-
-int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
- return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-unit-files", false, UID_INVALID, &m->polkit_registry, error);
-}
-
-int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
- return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.reload-daemon", false, UID_INVALID, &m->polkit_registry, error);
-}
-
-int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
- return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.set-environment", false, UID_INVALID, &m->polkit_registry, error);
-}
diff --git a/src/core/dbus.h b/src/core/dbus.h
deleted file mode 100644
index 483272206..000000000
--- a/src/core/dbus.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "manager.h"
-
-int bus_send_queued_message(Manager *m);
-
-int bus_init(Manager *m, bool try_bus_connect);
-void bus_done(Manager *m);
-
-int bus_fdset_add_all(Manager *m, FDSet *fds);
-
-void bus_track_serialize(sd_bus_track *t, FILE *f);
-int bus_track_deserialize_item(char ***l, const char *line);
-int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l);
-
-int bus_foreach_bus(Manager *m, sd_bus_track *subscribed2, int (*send_message)(sd_bus *bus, void *userdata), void *userdata);
-
-int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
-int bus_verify_manage_units_async_for_kill(Manager *m, sd_bus_message *call, sd_bus_error *error);
-int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
-int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
-int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
diff --git a/src/core/device.c b/src/core/device.c
deleted file mode 100644
index b5d9d827e..000000000
--- a/src/core/device.c
+++ /dev/null
@@ -1,813 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <sys/epoll.h>
-#include <libudev.h>
-
-#include "log.h"
-#include "unit-name.h"
-#include "dbus-device.h"
-#include "path-util.h"
-#include "udev-util.h"
-#include "unit.h"
-#include "swap.h"
-#include "device.h"
-
-static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
- [DEVICE_DEAD] = UNIT_INACTIVE,
- [DEVICE_TENTATIVE] = UNIT_ACTIVATING,
- [DEVICE_PLUGGED] = UNIT_ACTIVE,
-};
-
-static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
-
-static void device_unset_sysfs(Device *d) {
- Hashmap *devices;
- Device *first;
-
- assert(d);
-
- if (!d->sysfs)
- return;
-
- /* Remove this unit from the chain of devices which share the
- * same sysfs path. */
- devices = UNIT(d)->manager->devices_by_sysfs;
- first = hashmap_get(devices, d->sysfs);
- LIST_REMOVE(same_sysfs, first, d);
-
- if (first)
- hashmap_remove_and_replace(devices, d->sysfs, first->sysfs, first);
- else
- hashmap_remove(devices, d->sysfs);
-
- free(d->sysfs);
- d->sysfs = NULL;
-}
-
-static int device_set_sysfs(Device *d, const char *sysfs) {
- Device *first;
- char *copy;
- int r;
-
- assert(d);
-
- if (streq_ptr(d->sysfs, sysfs))
- return 0;
-
- r = hashmap_ensure_allocated(&UNIT(d)->manager->devices_by_sysfs, &string_hash_ops);
- if (r < 0)
- return r;
-
- copy = strdup(sysfs);
- if (!copy)
- return -ENOMEM;
-
- device_unset_sysfs(d);
-
- first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, sysfs);
- LIST_PREPEND(same_sysfs, first, d);
-
- r = hashmap_replace(UNIT(d)->manager->devices_by_sysfs, copy, first);
- if (r < 0) {
- LIST_REMOVE(same_sysfs, first, d);
- free(copy);
- return r;
- }
-
- d->sysfs = copy;
-
- return 0;
-}
-
-static void device_init(Unit *u) {
- Device *d = DEVICE(u);
-
- assert(d);
- assert(UNIT(d)->load_state == UNIT_STUB);
-
- /* In contrast to all other unit types we timeout jobs waiting
- * for devices by default. This is because they otherwise wait
- * indefinitely for plugged in devices, something which cannot
- * happen for the other units since their operations time out
- * anyway. */
- u->job_timeout = u->manager->default_timeout_start_usec;
-
- u->ignore_on_isolate = true;
- u->ignore_on_snapshot = true;
-}
-
-static void device_done(Unit *u) {
- Device *d = DEVICE(u);
-
- assert(d);
-
- device_unset_sysfs(d);
-}
-
-static void device_set_state(Device *d, DeviceState state) {
- DeviceState old_state;
- assert(d);
-
- old_state = d->state;
- d->state = state;
-
- if (state != old_state)
- log_unit_debug(UNIT(d)->id,
- "%s changed %s -> %s", UNIT(d)->id,
- device_state_to_string(old_state),
- device_state_to_string(state));
-
- unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true);
-}
-
-static int device_coldplug(Unit *u, Hashmap *deferred_work) {
- Device *d = DEVICE(u);
-
- assert(d);
- assert(d->state == DEVICE_DEAD);
-
- if (d->found & DEVICE_FOUND_UDEV)
- /* If udev says the device is around, it's around */
- device_set_state(d, DEVICE_PLUGGED);
- else if (d->found != DEVICE_NOT_FOUND)
- /* If a device is found in /proc/self/mountinfo or
- * /proc/swaps, it's "tentatively" around. */
- device_set_state(d, DEVICE_TENTATIVE);
-
- return 0;
-}
-
-static void device_dump(Unit *u, FILE *f, const char *prefix) {
- Device *d = DEVICE(u);
-
- assert(d);
-
- fprintf(f,
- "%sDevice State: %s\n"
- "%sSysfs Path: %s\n",
- prefix, device_state_to_string(d->state),
- prefix, strna(d->sysfs));
-}
-
-_pure_ static UnitActiveState device_active_state(Unit *u) {
- assert(u);
-
- return state_translation_table[DEVICE(u)->state];
-}
-
-_pure_ static const char *device_sub_state_to_string(Unit *u) {
- assert(u);
-
- return device_state_to_string(DEVICE(u)->state);
-}
-
-static int device_update_description(Unit *u, struct udev_device *dev, const char *path) {
- const char *model;
- int r;
-
- assert(u);
- assert(dev);
- assert(path);
-
- model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE");
- if (!model)
- model = udev_device_get_property_value(dev, "ID_MODEL");
-
- if (model) {
- const char *label;
-
- /* Try to concatenate the device model string with a label, if there is one */
- label = udev_device_get_property_value(dev, "ID_FS_LABEL");
- if (!label)
- label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NAME");
- if (!label)
- label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER");
-
- if (label) {
- _cleanup_free_ char *j;
-
- j = strjoin(model, " ", label, NULL);
- if (j)
- r = unit_set_description(u, j);
- else
- r = -ENOMEM;
- } else
- r = unit_set_description(u, model);
- } else
- r = unit_set_description(u, path);
-
- if (r < 0)
- log_unit_error_errno(u->id, r, "Failed to set device description: %m");
-
- return r;
-}
-
-static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
- const char *wants;
- const char *word, *state;
- size_t l;
- int r;
- const char *property;
-
- assert(u);
- assert(dev);
-
- property = u->manager->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
- wants = udev_device_get_property_value(dev, property);
- if (!wants)
- return 0;
-
- FOREACH_WORD_QUOTED(word, l, wants, state) {
- _cleanup_free_ char *n = NULL;
- char e[l+1];
-
- memcpy(e, word, l);
- e[l] = 0;
-
- n = unit_name_mangle(e, MANGLE_NOGLOB);
- if (!n)
- return log_oom();
-
- r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true);
- if (r < 0)
- return log_unit_error_errno(u->id, r, "Failed to add wants dependency: %m");
- }
- if (!isempty(state))
- log_unit_warning(u->id, "Property %s on %s has trailing garbage, ignoring.", property, strna(udev_device_get_syspath(dev)));
-
- return 0;
-}
-
-static int device_setup_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
- _cleanup_free_ char *e = NULL;
- const char *sysfs;
- Unit *u = NULL;
- bool delete;
- int r;
-
- assert(m);
- assert(dev);
- assert(path);
-
- sysfs = udev_device_get_syspath(dev);
- if (!sysfs)
- return 0;
-
- e = unit_name_from_path(path, ".device");
- if (!e)
- return log_oom();
-
- u = manager_get_unit(m, e);
-
- if (u &&
- DEVICE(u)->sysfs &&
- !path_equal(DEVICE(u)->sysfs, sysfs)) {
- log_unit_error(u->id, "Device %s appeared twice with different sysfs paths %s and %s", e, DEVICE(u)->sysfs, sysfs);
- return -EEXIST;
- }
-
- if (!u) {
- delete = true;
-
- u = unit_new(m, sizeof(Device));
- if (!u)
- return log_oom();
-
- r = unit_add_name(u, e);
- if (r < 0)
- goto fail;
-
- unit_add_to_load_queue(u);
- } else
- delete = false;
-
- /* If this was created via some dependency and has not
- * actually been seen yet ->sysfs will not be
- * initialized. Hence initialize it if necessary. */
-
- r = device_set_sysfs(DEVICE(u), sysfs);
- if (r < 0)
- goto fail;
-
- (void) device_update_description(u, dev, path);
-
- /* The additional systemd udev properties we only interpret
- * for the main object */
- if (main)
- (void) device_add_udev_wants(u, dev);
-
- /* Note that this won't dispatch the load queue, the caller
- * has to do that if needed and appropriate */
-
- unit_add_to_dbus_queue(u);
- return 0;
-
-fail:
- log_unit_warning_errno(u->id, r, "Failed to set up device unit: %m");
-
- if (delete && u)
- unit_free(u);
-
- return r;
-}
-
-static int device_process_new(Manager *m, struct udev_device *dev) {
- const char *sysfs, *dn, *alias;
- struct udev_list_entry *item = NULL, *first = NULL;
- int r;
-
- assert(m);
-
- sysfs = udev_device_get_syspath(dev);
- if (!sysfs)
- return 0;
-
- /* Add the main unit named after the sysfs path */
- r = device_setup_unit(m, dev, sysfs, true);
- if (r < 0)
- return r;
-
- /* Add an additional unit for the device node */
- dn = udev_device_get_devnode(dev);
- if (dn)
- (void) device_setup_unit(m, dev, dn, false);
-
- /* Add additional units for all symlinks */
- first = udev_device_get_devlinks_list_entry(dev);
- udev_list_entry_foreach(item, first) {
- const char *p;
- struct stat st;
-
- /* Don't bother with the /dev/block links */
- p = udev_list_entry_get_name(item);
-
- if (path_startswith(p, "/dev/block/") ||
- path_startswith(p, "/dev/char/"))
- continue;
-
- /* Verify that the symlink in the FS actually belongs
- * to this device. This is useful to deal with
- * conflicting devices, e.g. when two disks want the
- * same /dev/disk/by-label/xxx link because they have
- * the same label. We want to make sure that the same
- * device that won the symlink wins in systemd, so we
- * check the device node major/minor */
- if (stat(p, &st) >= 0)
- if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
- st.st_rdev != udev_device_get_devnum(dev))
- continue;
-
- (void) device_setup_unit(m, dev, p, false);
- }
-
- /* Add additional units for all explicitly configured
- * aliases */
- alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
- if (alias) {
- const char *word, *state;
- size_t l;
-
- FOREACH_WORD_QUOTED(word, l, alias, state) {
- char e[l+1];
-
- memcpy(e, word, l);
- e[l] = 0;
-
- if (path_is_absolute(e))
- (void) device_setup_unit(m, dev, e, false);
- else
- log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, e);
- }
- if (!isempty(state))
- log_warning("SYSTEMD_ALIAS for %s has trailing garbage, ignoring.", sysfs);
- }
-
- return 0;
-}
-
-static void device_update_found_one(Device *d, bool add, DeviceFound found, bool now) {
- DeviceFound n;
-
- assert(d);
-
- n = add ? (d->found | found) : (d->found & ~found);
- if (n == d->found)
- return;
-
- d->found = n;
-
- if (now) {
- if (d->found & DEVICE_FOUND_UDEV)
- device_set_state(d, DEVICE_PLUGGED);
- else if (add && d->found != DEVICE_NOT_FOUND)
- device_set_state(d, DEVICE_TENTATIVE);
- else
- device_set_state(d, DEVICE_DEAD);
- }
-}
-
-static int device_update_found_by_sysfs(Manager *m, const char *sysfs, bool add, DeviceFound found, bool now) {
- Device *d, *l;
-
- assert(m);
- assert(sysfs);
-
- if (found == DEVICE_NOT_FOUND)
- return 0;
-
- l = hashmap_get(m->devices_by_sysfs, sysfs);
- LIST_FOREACH(same_sysfs, d, l)
- device_update_found_one(d, add, found, now);
-
- return 0;
-}
-
-static int device_update_found_by_name(Manager *m, const char *path, bool add, DeviceFound found, bool now) {
- _cleanup_free_ char *e = NULL;
- Unit *u;
-
- assert(m);
- assert(path);
-
- if (found == DEVICE_NOT_FOUND)
- return 0;
-
- e = unit_name_from_path(path, ".device");
- if (!e)
- return log_oom();
-
- u = manager_get_unit(m, e);
- if (!u)
- return 0;
-
- device_update_found_one(DEVICE(u), add, found, now);
- return 0;
-}
-
-static bool device_is_ready(struct udev_device *dev) {
- const char *ready;
-
- assert(dev);
-
- ready = udev_device_get_property_value(dev, "SYSTEMD_READY");
- if (!ready)
- return true;
-
- return parse_boolean(ready) != 0;
-}
-
-static Unit *device_following(Unit *u) {
- Device *d = DEVICE(u);
- Device *other, *first = NULL;
-
- assert(d);
-
- if (startswith(u->id, "sys-"))
- return NULL;
-
- /* Make everybody follow the unit that's named after the sysfs path */
- for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
- if (startswith(UNIT(other)->id, "sys-"))
- return UNIT(other);
-
- for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
- if (startswith(UNIT(other)->id, "sys-"))
- return UNIT(other);
-
- first = other;
- }
-
- return UNIT(first);
-}
-
-static int device_following_set(Unit *u, Set **_set) {
- Device *d = DEVICE(u), *other;
- Set *set;
- int r;
-
- assert(d);
- assert(_set);
-
- if (LIST_JUST_US(same_sysfs, d)) {
- *_set = NULL;
- return 0;
- }
-
- set = set_new(NULL);
- if (!set)
- return -ENOMEM;
-
- LIST_FOREACH_AFTER(same_sysfs, other, d) {
- r = set_put(set, other);
- if (r < 0)
- goto fail;
- }
-
- LIST_FOREACH_BEFORE(same_sysfs, other, d) {
- r = set_put(set, other);
- if (r < 0)
- goto fail;
- }
-
- *_set = set;
- return 1;
-
-fail:
- set_free(set);
- return r;
-}
-
-static void device_shutdown(Manager *m) {
- assert(m);
-
- m->udev_event_source = sd_event_source_unref(m->udev_event_source);
-
- if (m->udev_monitor) {
- udev_monitor_unref(m->udev_monitor);
- m->udev_monitor = NULL;
- }
-
- hashmap_free(m->devices_by_sysfs);
- m->devices_by_sysfs = NULL;
-}
-
-static int device_enumerate(Manager *m) {
- _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
- struct udev_list_entry *item = NULL, *first = NULL;
- int r;
-
- assert(m);
-
- if (!m->udev_monitor) {
- m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
- if (!m->udev_monitor) {
- r = -ENOMEM;
- goto fail;
- }
-
- /* This will fail if we are unprivileged, but that
- * should not matter much, as user instances won't run
- * during boot. */
- (void) udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
-
- r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd");
- if (r < 0)
- goto fail;
-
- r = udev_monitor_enable_receiving(m->udev_monitor);
- if (r < 0)
- goto fail;
-
- r = sd_event_add_io(m->event, &m->udev_event_source, udev_monitor_get_fd(m->udev_monitor), EPOLLIN, device_dispatch_io, m);
- if (r < 0)
- goto fail;
- }
-
- e = udev_enumerate_new(m->udev);
- if (!e) {
- r = -ENOMEM;
- goto fail;
- }
-
- r = udev_enumerate_add_match_tag(e, "systemd");
- if (r < 0)
- goto fail;
-
- r = udev_enumerate_add_match_is_initialized(e);
- if (r < 0)
- goto fail;
-
- r = udev_enumerate_scan_devices(e);
- if (r < 0)
- goto fail;
-
- first = udev_enumerate_get_list_entry(e);
- udev_list_entry_foreach(item, first) {
- _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
- const char *sysfs;
-
- sysfs = udev_list_entry_get_name(item);
-
- dev = udev_device_new_from_syspath(m->udev, sysfs);
- if (!dev) {
- log_oom();
- continue;
- }
-
- if (!device_is_ready(dev))
- continue;
-
- (void) device_process_new(m, dev);
-
- device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, false);
- }
-
- return 0;
-
-fail:
- log_error_errno(r, "Failed to enumerate devices: %m");
-
- device_shutdown(m);
- return r;
-}
-
-static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
- _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
- Manager *m = userdata;
- const char *action, *sysfs;
- int r;
-
- assert(m);
-
- if (revents != EPOLLIN) {
- static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
-
- if (!ratelimit_test(&limit))
- log_error_errno(errno, "Failed to get udev event: %m");
- if (!(revents & EPOLLIN))
- return 0;
- }
-
- /*
- * libudev might filter-out devices which pass the bloom
- * filter, so getting NULL here is not necessarily an error.
- */
- dev = udev_monitor_receive_device(m->udev_monitor);
- if (!dev)
- return 0;
-
- sysfs = udev_device_get_syspath(dev);
- if (!sysfs) {
- log_error("Failed to get udev sys path.");
- return 0;
- }
-
- action = udev_device_get_action(dev);
- if (!action) {
- log_error("Failed to get udev action string.");
- return 0;
- }
-
- if (streq(action, "remove")) {
- r = swap_process_device_remove(m, dev);
- if (r < 0)
- log_error_errno(r, "Failed to process swap device remove event: %m");
-
- /* If we get notified that a device was removed by
- * udev, then it's completely gone, hence unset all
- * found bits */
- device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV|DEVICE_FOUND_MOUNT|DEVICE_FOUND_SWAP, true);
-
- } else if (device_is_ready(dev)) {
-
- (void) device_process_new(m, dev);
-
- r = swap_process_device_new(m, dev);
- if (r < 0)
- log_error_errno(r, "Failed to process swap device new event: %m");
-
- manager_dispatch_load_queue(m);
-
- /* The device is found now, set the udev found bit */
- device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, true);
-
- } else {
- /* The device is nominally around, but not ready for
- * us. Hence unset the udev bit, but leave the rest
- * around. */
-
- device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV, true);
- }
-
- return 0;
-}
-
-static bool device_supported(Manager *m) {
- static int read_only = -1;
- assert(m);
-
- /* If /sys is read-only we don't support device units, and any
- * attempts to start one should fail immediately. */
-
- if (read_only < 0)
- read_only = path_is_read_only_fs("/sys");
-
- return read_only <= 0;
-}
-
-int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now) {
- _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
- struct stat st;
-
- assert(m);
- assert(node);
-
- /* This is called whenever we find a device referenced in
- * /proc/swaps or /proc/self/mounts. Such a device might be
- * mounted/enabled at a time where udev has not finished
- * probing it yet, and we thus haven't learned about it
- * yet. In this case we will set the device unit to
- * "tentative" state. */
-
- if (add) {
- if (!path_startswith(node, "/dev"))
- return 0;
-
- if (stat(node, &st) < 0) {
- if (errno == ENOENT)
- return 0;
-
- return log_error_errno(errno, "Failed to stat device node file %s: %m", node);
- }
-
- if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
- return 0;
-
- dev = udev_device_new_from_devnum(m->udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
- if (!dev) {
- if (errno == ENOENT)
- return 0;
-
- return log_oom();
- }
-
- /* If the device is known in the kernel and newly
- * appeared, then we'll create a device unit for it,
- * under the name referenced in /proc/swaps or
- * /proc/self/mountinfo. */
-
- (void) device_setup_unit(m, dev, node, false);
- }
-
- /* Update the device unit's state, should it exist */
- return device_update_found_by_name(m, node, add, found, now);
-}
-
-static const char* const device_state_table[_DEVICE_STATE_MAX] = {
- [DEVICE_DEAD] = "dead",
- [DEVICE_TENTATIVE] = "tentative",
- [DEVICE_PLUGGED] = "plugged",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
-
-const UnitVTable device_vtable = {
- .object_size = sizeof(Device),
- .sections =
- "Unit\0"
- "Device\0"
- "Install\0",
-
- .no_instances = true,
-
- .init = device_init,
- .done = device_done,
- .load = unit_load_fragment_and_dropin_optional,
-
- .coldplug = device_coldplug,
-
- .dump = device_dump,
-
- .active_state = device_active_state,
- .sub_state_to_string = device_sub_state_to_string,
-
- .bus_interface = "org.freedesktop.systemd1.Device",
- .bus_vtable = bus_device_vtable,
-
- .following = device_following,
- .following_set = device_following_set,
-
- .enumerate = device_enumerate,
- .shutdown = device_shutdown,
- .supported = device_supported,
-
- .status_message_formats = {
- .starting_stopping = {
- [0] = "Expecting device %s...",
- },
- .finished_start_job = {
- [JOB_DONE] = "Found device %s.",
- [JOB_TIMEOUT] = "Timed out waiting for device %s.",
- },
- },
-};
diff --git a/src/core/device.h b/src/core/device.h
deleted file mode 100644
index 9f46e0895..000000000
--- a/src/core/device.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-typedef struct Device Device;
-
-
-/* We simply watch devices, we cannot plug/unplug them. That
- * simplifies the state engine greatly */
-typedef enum DeviceState {
- DEVICE_DEAD,
- DEVICE_TENTATIVE, /* mounted or swapped, but not (yet) announced by udev */
- DEVICE_PLUGGED, /* announced by udev */
- _DEVICE_STATE_MAX,
- _DEVICE_STATE_INVALID = -1
-} DeviceState;
-
-typedef enum DeviceFound {
- DEVICE_NOT_FOUND = 0,
- DEVICE_FOUND_UDEV = 1,
- DEVICE_FOUND_MOUNT = 2,
- DEVICE_FOUND_SWAP = 4,
-} DeviceFound;
-
-struct Device {
- Unit meta;
-
- char *sysfs;
- DeviceFound found;
-
- /* In order to be able to distinguish dependencies on
- different device nodes we might end up creating multiple
- devices for the same sysfs path. We chain them up here. */
- LIST_FIELDS(struct Device, same_sysfs);
-
- DeviceState state;
-};
-
-extern const UnitVTable device_vtable;
-
-const char* device_state_to_string(DeviceState i) _const_;
-DeviceState device_state_from_string(const char *s) _pure_;
-
-int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now);
diff --git a/src/core/execute.c b/src/core/execute.c
deleted file mode 100644
index 027e3319e..000000000
--- a/src/core/execute.c
+++ /dev/null
@@ -1,2912 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/prctl.h>
-#include <sys/stat.h>
-#include <grp.h>
-#include <poll.h>
-#include <glob.h>
-#include <sys/personality.h>
-
-#ifdef HAVE_PAM
-#include <security/pam_appl.h>
-#endif
-
-#ifdef HAVE_SELINUX
-#include <selinux/selinux.h>
-#endif
-
-#ifdef HAVE_SECCOMP
-#include <seccomp.h>
-#endif
-
-#ifdef HAVE_APPARMOR
-#include <sys/apparmor.h>
-#endif
-
-#include "execute.h"
-#include "strv.h"
-#include "macro.h"
-#include "capability.h"
-#include "util.h"
-#include "log.h"
-#include "sd-messages.h"
-#include "ioprio.h"
-#include "securebits.h"
-#include "namespace.h"
-#include "exit-status.h"
-#include "missing.h"
-#include "def.h"
-#include "path-util.h"
-#include "env-util.h"
-#include "fileio.h"
-#include "unit.h"
-#include "async.h"
-#include "selinux-util.h"
-#include "errno-list.h"
-#include "af-list.h"
-#include "mkdir.h"
-#include "smack-util.h"
-#include "bus-endpoint.h"
-#include "cap-list.h"
-
-#ifdef HAVE_APPARMOR
-#include "apparmor-util.h"
-#endif
-
-#ifdef HAVE_SECCOMP
-#include "seccomp-util.h"
-#endif
-
-#define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
-#define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
-
-/* This assumes there is a 'tty' group */
-#define TTY_MODE 0620
-
-#define SNDBUF_SIZE (8*1024*1024)
-
-static int shift_fds(int fds[], unsigned n_fds) {
- int start, restart_from;
-
- if (n_fds <= 0)
- return 0;
-
- /* Modifies the fds array! (sorts it) */
-
- assert(fds);
-
- start = 0;
- for (;;) {
- int i;
-
- restart_from = -1;
-
- for (i = start; i < (int) n_fds; i++) {
- int nfd;
-
- /* Already at right index? */
- if (fds[i] == i+3)
- continue;
-
- if ((nfd = fcntl(fds[i], F_DUPFD, i+3)) < 0)
- return -errno;
-
- safe_close(fds[i]);
- fds[i] = nfd;
-
- /* Hmm, the fd we wanted isn't free? Then
- * let's remember that and try again from here */
- if (nfd != i+3 && restart_from < 0)
- restart_from = i;
- }
-
- if (restart_from < 0)
- break;
-
- start = restart_from;
- }
-
- return 0;
-}
-
-static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) {
- unsigned i;
- int r;
-
- if (n_fds <= 0)
- return 0;
-
- assert(fds);
-
- /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
-
- for (i = 0; i < n_fds; i++) {
-
- if ((r = fd_nonblock(fds[i], nonblock)) < 0)
- return r;
-
- /* We unconditionally drop FD_CLOEXEC from the fds,
- * since after all we want to pass these fds to our
- * children */
-
- if ((r = fd_cloexec(fds[i], false)) < 0)
- return r;
- }
-
- return 0;
-}
-
-_pure_ static const char *tty_path(const ExecContext *context) {
- assert(context);
-
- if (context->tty_path)
- return context->tty_path;
-
- return "/dev/console";
-}
-
-static void exec_context_tty_reset(const ExecContext *context) {
- assert(context);
-
- if (context->tty_vhangup)
- terminal_vhangup(tty_path(context));
-
- if (context->tty_reset)
- reset_terminal(tty_path(context));
-
- if (context->tty_vt_disallocate && context->tty_path)
- vt_disallocate(context->tty_path);
-}
-
-static bool is_terminal_output(ExecOutput o) {
- return
- o == EXEC_OUTPUT_TTY ||
- o == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
- o == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
- o == EXEC_OUTPUT_JOURNAL_AND_CONSOLE;
-}
-
-static int open_null_as(int flags, int nfd) {
- int fd, r;
-
- assert(nfd >= 0);
-
- fd = open("/dev/null", flags|O_NOCTTY);
- if (fd < 0)
- return -errno;
-
- if (fd != nfd) {
- r = dup2(fd, nfd) < 0 ? -errno : nfd;
- safe_close(fd);
- } else
- r = nfd;
-
- return r;
-}
-
-static int connect_journal_socket(int fd, uid_t uid, gid_t gid) {
- union sockaddr_union sa = {
- .un.sun_family = AF_UNIX,
- .un.sun_path = "/run/systemd/journal/stdout",
- };
- uid_t olduid = UID_INVALID;
- gid_t oldgid = GID_INVALID;
- int r;
-
- if (gid != GID_INVALID) {
- oldgid = getgid();
-
- r = setegid(gid);
- if (r < 0)
- return -errno;
- }
-
- if (uid != UID_INVALID) {
- olduid = getuid();
-
- r = seteuid(uid);
- if (r < 0) {
- r = -errno;
- goto restore_gid;
- }
- }
-
- r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
- if (r < 0)
- r = -errno;
-
- /* If we fail to restore the uid or gid, things will likely
- fail later on. This should only happen if an LSM interferes. */
-
- if (uid != UID_INVALID)
- (void) seteuid(olduid);
-
- restore_gid:
- if (gid != GID_INVALID)
- (void) setegid(oldgid);
-
- return r;
-}
-
-static int connect_logger_as(const ExecContext *context, ExecOutput output, const char *ident, const char *unit_id, int nfd, uid_t uid, gid_t gid) {
- int fd, r;
-
- assert(context);
- assert(output < _EXEC_OUTPUT_MAX);
- assert(ident);
- assert(nfd >= 0);
-
- fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (fd < 0)
- return -errno;
-
- r = connect_journal_socket(fd, uid, gid);
- if (r < 0)
- return r;
-
- if (shutdown(fd, SHUT_RD) < 0) {
- safe_close(fd);
- return -errno;
- }
-
- fd_inc_sndbuf(fd, SNDBUF_SIZE);
-
- dprintf(fd,
- "%s\n"
- "%s\n"
- "%i\n"
- "%i\n"
- "%i\n"
- "%i\n"
- "%i\n",
- context->syslog_identifier ? context->syslog_identifier : ident,
- unit_id,
- context->syslog_priority,
- !!context->syslog_level_prefix,
- output == EXEC_OUTPUT_SYSLOG || output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
- output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE,
- is_terminal_output(output));
-
- if (fd != nfd) {
- r = dup2(fd, nfd) < 0 ? -errno : nfd;
- safe_close(fd);
- } else
- r = nfd;
-
- return r;
-}
-static int open_terminal_as(const char *path, mode_t mode, int nfd) {
- int fd, r;
-
- assert(path);
- assert(nfd >= 0);
-
- if ((fd = open_terminal(path, mode | O_NOCTTY)) < 0)
- return fd;
-
- if (fd != nfd) {
- r = dup2(fd, nfd) < 0 ? -errno : nfd;
- safe_close(fd);
- } else
- r = nfd;
-
- return r;
-}
-
-static bool is_terminal_input(ExecInput i) {
- return
- i == EXEC_INPUT_TTY ||
- i == EXEC_INPUT_TTY_FORCE ||
- i == EXEC_INPUT_TTY_FAIL;
-}
-
-static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) {
-
- if (is_terminal_input(std_input) && !apply_tty_stdin)
- return EXEC_INPUT_NULL;
-
- if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0)
- return EXEC_INPUT_NULL;
-
- return std_input;
-}
-
-static int fixup_output(ExecOutput std_output, int socket_fd) {
-
- if (std_output == EXEC_OUTPUT_SOCKET && socket_fd < 0)
- return EXEC_OUTPUT_INHERIT;
-
- return std_output;
-}
-
-static int setup_input(const ExecContext *context, int socket_fd, bool apply_tty_stdin) {
- ExecInput i;
-
- assert(context);
-
- i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
-
- switch (i) {
-
- case EXEC_INPUT_NULL:
- return open_null_as(O_RDONLY, STDIN_FILENO);
-
- case EXEC_INPUT_TTY:
- case EXEC_INPUT_TTY_FORCE:
- case EXEC_INPUT_TTY_FAIL: {
- int fd, r;
-
- fd = acquire_terminal(tty_path(context),
- i == EXEC_INPUT_TTY_FAIL,
- i == EXEC_INPUT_TTY_FORCE,
- false,
- USEC_INFINITY);
- if (fd < 0)
- return fd;
-
- if (fd != STDIN_FILENO) {
- r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
- safe_close(fd);
- } else
- r = STDIN_FILENO;
-
- return r;
- }
-
- case EXEC_INPUT_SOCKET:
- return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
-
- default:
- assert_not_reached("Unknown input type");
- }
-}
-
-static int setup_output(const ExecContext *context, int fileno, int socket_fd, const char *ident, const char *unit_id, bool apply_tty_stdin, uid_t uid, gid_t gid) {
- ExecOutput o;
- ExecInput i;
- int r;
-
- assert(context);
- assert(ident);
-
- i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
- o = fixup_output(context->std_output, socket_fd);
-
- if (fileno == STDERR_FILENO) {
- ExecOutput e;
- e = fixup_output(context->std_error, socket_fd);
-
- /* This expects the input and output are already set up */
-
- /* Don't change the stderr file descriptor if we inherit all
- * the way and are not on a tty */
- if (e == EXEC_OUTPUT_INHERIT &&
- o == EXEC_OUTPUT_INHERIT &&
- i == EXEC_INPUT_NULL &&
- !is_terminal_input(context->std_input) &&
- getppid () != 1)
- return fileno;
-
- /* Duplicate from stdout if possible */
- if (e == o || e == EXEC_OUTPUT_INHERIT)
- return dup2(STDOUT_FILENO, fileno) < 0 ? -errno : fileno;
-
- o = e;
-
- } else if (o == EXEC_OUTPUT_INHERIT) {
- /* If input got downgraded, inherit the original value */
- if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input))
- return open_terminal_as(tty_path(context), O_WRONLY, fileno);
-
- /* If the input is connected to anything that's not a /dev/null, inherit that... */
- if (i != EXEC_INPUT_NULL)
- return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
-
- /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
- if (getppid() != 1)
- return fileno;
-
- /* We need to open /dev/null here anew, to get the right access mode. */
- return open_null_as(O_WRONLY, fileno);
- }
-
- switch (o) {
-
- case EXEC_OUTPUT_NULL:
- return open_null_as(O_WRONLY, fileno);
-
- case EXEC_OUTPUT_TTY:
- if (is_terminal_input(i))
- return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
-
- /* We don't reset the terminal if this is just about output */
- return open_terminal_as(tty_path(context), O_WRONLY, fileno);
-
- case EXEC_OUTPUT_SYSLOG:
- case EXEC_OUTPUT_SYSLOG_AND_CONSOLE:
- case EXEC_OUTPUT_KMSG:
- case EXEC_OUTPUT_KMSG_AND_CONSOLE:
- case EXEC_OUTPUT_JOURNAL:
- case EXEC_OUTPUT_JOURNAL_AND_CONSOLE:
- r = connect_logger_as(context, o, ident, unit_id, fileno, uid, gid);
- if (r < 0) {
- log_unit_struct(unit_id,
- LOG_ERR,
- LOG_MESSAGE("Failed to connect %s of %s to the journal socket: %s",
- fileno == STDOUT_FILENO ? "stdout" : "stderr",
- unit_id, strerror(-r)),
- LOG_ERRNO(-r),
- NULL);
- r = open_null_as(O_WRONLY, fileno);
- }
- return r;
-
- case EXEC_OUTPUT_SOCKET:
- assert(socket_fd >= 0);
- return dup2(socket_fd, fileno) < 0 ? -errno : fileno;
-
- default:
- assert_not_reached("Unknown error type");
- }
-}
-
-static int chown_terminal(int fd, uid_t uid) {
- struct stat st;
-
- assert(fd >= 0);
-
- /* This might fail. What matters are the results. */
- (void) fchown(fd, uid, -1);
- (void) fchmod(fd, TTY_MODE);
-
- if (fstat(fd, &st) < 0)
- return -errno;
-
- if (st.st_uid != uid || (st.st_mode & 0777) != TTY_MODE)
- return -EPERM;
-
- return 0;
-}
-
-static int setup_confirm_stdio(int *_saved_stdin,
- int *_saved_stdout) {
- int fd = -1, saved_stdin, saved_stdout = -1, r;
-
- assert(_saved_stdin);
- assert(_saved_stdout);
-
- saved_stdin = fcntl(STDIN_FILENO, F_DUPFD, 3);
- if (saved_stdin < 0)
- return -errno;
-
- saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD, 3);
- if (saved_stdout < 0) {
- r = errno;
- goto fail;
- }
-
- fd = acquire_terminal(
- "/dev/console",
- false,
- false,
- false,
- DEFAULT_CONFIRM_USEC);
- if (fd < 0) {
- r = fd;
- goto fail;
- }
-
- r = chown_terminal(fd, getuid());
- if (r < 0)
- goto fail;
-
- if (dup2(fd, STDIN_FILENO) < 0) {
- r = -errno;
- goto fail;
- }
-
- if (dup2(fd, STDOUT_FILENO) < 0) {
- r = -errno;
- goto fail;
- }
-
- if (fd >= 2)
- safe_close(fd);
-
- *_saved_stdin = saved_stdin;
- *_saved_stdout = saved_stdout;
-
- return 0;
-
-fail:
- safe_close(saved_stdout);
- safe_close(saved_stdin);
- safe_close(fd);
-
- return r;
-}
-
-_printf_(1, 2) static int write_confirm_message(const char *format, ...) {
- _cleanup_close_ int fd = -1;
- va_list ap;
-
- assert(format);
-
- fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return fd;
-
- va_start(ap, format);
- vdprintf(fd, format, ap);
- va_end(ap);
-
- return 0;
-}
-
-static int restore_confirm_stdio(int *saved_stdin,
- int *saved_stdout) {
-
- int r = 0;
-
- assert(saved_stdin);
- assert(saved_stdout);
-
- release_terminal();
-
- if (*saved_stdin >= 0)
- if (dup2(*saved_stdin, STDIN_FILENO) < 0)
- r = -errno;
-
- if (*saved_stdout >= 0)
- if (dup2(*saved_stdout, STDOUT_FILENO) < 0)
- r = -errno;
-
- safe_close(*saved_stdin);
- safe_close(*saved_stdout);
-
- return r;
-}
-
-static int ask_for_confirmation(char *response, char **argv) {
- int saved_stdout = -1, saved_stdin = -1, r;
- _cleanup_free_ char *line = NULL;
-
- r = setup_confirm_stdio(&saved_stdin, &saved_stdout);
- if (r < 0)
- return r;
-
- line = exec_command_line(argv);
- if (!line)
- return -ENOMEM;
-
- r = ask_char(response, "yns", "Execute %s? [Yes, No, Skip] ", line);
-
- restore_confirm_stdio(&saved_stdin, &saved_stdout);
-
- return r;
-}
-
-static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) {
- bool keep_groups = false;
- int r;
-
- assert(context);
-
- /* Lookup and set GID and supplementary group list. Here too
- * we avoid NSS lookups for gid=0. */
-
- if (context->group || username) {
-
- if (context->group) {
- const char *g = context->group;
-
- if ((r = get_group_creds(&g, &gid)) < 0)
- return r;
- }
-
- /* First step, initialize groups from /etc/groups */
- if (username && gid != 0) {
- if (initgroups(username, gid) < 0)
- return -errno;
-
- keep_groups = true;
- }
-
- /* Second step, set our gids */
- if (setresgid(gid, gid, gid) < 0)
- return -errno;
- }
-
- if (context->supplementary_groups) {
- int ngroups_max, k;
- gid_t *gids;
- char **i;
-
- /* Final step, initialize any manually set supplementary groups */
- assert_se((ngroups_max = (int) sysconf(_SC_NGROUPS_MAX)) > 0);
-
- if (!(gids = new(gid_t, ngroups_max)))
- return -ENOMEM;
-
- if (keep_groups) {
- if ((k = getgroups(ngroups_max, gids)) < 0) {
- free(gids);
- return -errno;
- }
- } else
- k = 0;
-
- STRV_FOREACH(i, context->supplementary_groups) {
- const char *g;
-
- if (k >= ngroups_max) {
- free(gids);
- return -E2BIG;
- }
-
- g = *i;
- r = get_group_creds(&g, gids+k);
- if (r < 0) {
- free(gids);
- return r;
- }
-
- k++;
- }
-
- if (setgroups(k, gids) < 0) {
- free(gids);
- return -errno;
- }
-
- free(gids);
- }
-
- return 0;
-}
-
-static int enforce_user(const ExecContext *context, uid_t uid) {
- assert(context);
-
- /* Sets (but doesn't lookup) the uid and make sure we keep the
- * capabilities while doing so. */
-
- if (context->capabilities) {
- _cleanup_cap_free_ cap_t d = NULL;
- static const cap_value_t bits[] = {
- CAP_SETUID, /* Necessary so that we can run setresuid() below */
- CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */
- };
-
- /* First step: If we need to keep capabilities but
- * drop privileges we need to make sure we keep our
- * caps, while we drop privileges. */
- if (uid != 0) {
- int sb = context->secure_bits | 1<<SECURE_KEEP_CAPS;
-
- if (prctl(PR_GET_SECUREBITS) != sb)
- if (prctl(PR_SET_SECUREBITS, sb) < 0)
- return -errno;
- }
-
- /* Second step: set the capabilities. This will reduce
- * the capabilities to the minimum we need. */
-
- d = cap_dup(context->capabilities);
- if (!d)
- return -errno;
-
- if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 ||
- cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0)
- return -errno;
-
- if (cap_set_proc(d) < 0)
- return -errno;
- }
-
- /* Third step: actually set the uids */
- if (setresuid(uid, uid, uid) < 0)
- return -errno;
-
- /* At this point we should have all necessary capabilities but
- are otherwise a normal user. However, the caps might got
- corrupted due to the setresuid() so we need clean them up
- later. This is done outside of this call. */
-
- return 0;
-}
-
-#ifdef HAVE_PAM
-
-static int null_conv(
- int num_msg,
- const struct pam_message **msg,
- struct pam_response **resp,
- void *appdata_ptr) {
-
- /* We don't support conversations */
-
- return PAM_CONV_ERR;
-}
-
-static int setup_pam(
- const char *name,
- const char *user,
- uid_t uid,
- const char *tty,
- char ***pam_env,
- int fds[], unsigned n_fds) {
-
- static const struct pam_conv conv = {
- .conv = null_conv,
- .appdata_ptr = NULL
- };
-
- pam_handle_t *handle = NULL;
- sigset_t ss, old_ss;
- int pam_code = PAM_SUCCESS;
- int err;
- char **e = NULL;
- bool close_session = false;
- pid_t pam_pid = 0, parent_pid;
- int flags = 0;
-
- assert(name);
- assert(user);
- assert(pam_env);
-
- /* We set up PAM in the parent process, then fork. The child
- * will then stay around until killed via PR_GET_PDEATHSIG or
- * systemd via the cgroup logic. It will then remove the PAM
- * session again. The parent process will exec() the actual
- * daemon. We do things this way to ensure that the main PID
- * of the daemon is the one we initially fork()ed. */
-
- if (log_get_max_level() < LOG_DEBUG)
- flags |= PAM_SILENT;
-
- pam_code = pam_start(name, user, &conv, &handle);
- if (pam_code != PAM_SUCCESS) {
- handle = NULL;
- goto fail;
- }
-
- if (tty) {
- pam_code = pam_set_item(handle, PAM_TTY, tty);
- if (pam_code != PAM_SUCCESS)
- goto fail;
- }
-
- pam_code = pam_acct_mgmt(handle, flags);
- if (pam_code != PAM_SUCCESS)
- goto fail;
-
- pam_code = pam_open_session(handle, flags);
- if (pam_code != PAM_SUCCESS)
- goto fail;
-
- close_session = true;
-
- e = pam_getenvlist(handle);
- if (!e) {
- pam_code = PAM_BUF_ERR;
- goto fail;
- }
-
- /* Block SIGTERM, so that we know that it won't get lost in
- * the child */
- if (sigemptyset(&ss) < 0 ||
- sigaddset(&ss, SIGTERM) < 0 ||
- sigprocmask(SIG_BLOCK, &ss, &old_ss) < 0)
- goto fail;
-
- parent_pid = getpid();
-
- pam_pid = fork();
- if (pam_pid < 0)
- goto fail;
-
- if (pam_pid == 0) {
- int sig;
- int r = EXIT_PAM;
-
- /* The child's job is to reset the PAM session on
- * termination */
-
- /* This string must fit in 10 chars (i.e. the length
- * of "/sbin/init"), to look pretty in /bin/ps */
- rename_process("(sd-pam)");
-
- /* Make sure we don't keep open the passed fds in this
- child. We assume that otherwise only those fds are
- open here that have been opened by PAM. */
- close_many(fds, n_fds);
-
- /* Drop privileges - we don't need any to pam_close_session
- * and this will make PR_SET_PDEATHSIG work in most cases.
- * If this fails, ignore the error - but expect sd-pam threads
- * to fail to exit normally */
- if (setresuid(uid, uid, uid) < 0)
- log_error_errno(r, "Error: Failed to setresuid() in sd-pam: %m");
-
- /* Wait until our parent died. This will only work if
- * the above setresuid() succeeds, otherwise the kernel
- * will not allow unprivileged parents kill their privileged
- * children this way. We rely on the control groups kill logic
- * to do the rest for us. */
- if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
- goto child_finish;
-
- /* Check if our parent process might already have
- * died? */
- if (getppid() == parent_pid) {
- for (;;) {
- if (sigwait(&ss, &sig) < 0) {
- if (errno == EINTR)
- continue;
-
- goto child_finish;
- }
-
- assert(sig == SIGTERM);
- break;
- }
- }
-
- /* If our parent died we'll end the session */
- if (getppid() != parent_pid) {
- pam_code = pam_close_session(handle, flags);
- if (pam_code != PAM_SUCCESS)
- goto child_finish;
- }
-
- r = 0;
-
- child_finish:
- pam_end(handle, pam_code | flags);
- _exit(r);
- }
-
- /* If the child was forked off successfully it will do all the
- * cleanups, so forget about the handle here. */
- handle = NULL;
-
- /* Unblock SIGTERM again in the parent */
- if (sigprocmask(SIG_SETMASK, &old_ss, NULL) < 0)
- goto fail;
-
- /* We close the log explicitly here, since the PAM modules
- * might have opened it, but we don't want this fd around. */
- closelog();
-
- *pam_env = e;
- e = NULL;
-
- return 0;
-
-fail:
- if (pam_code != PAM_SUCCESS) {
- log_error("PAM failed: %s", pam_strerror(handle, pam_code));
- err = -EPERM; /* PAM errors do not map to errno */
- } else {
- log_error_errno(errno, "PAM failed: %m");
- err = -errno;
- }
-
- if (handle) {
- if (close_session)
- pam_code = pam_close_session(handle, flags);
-
- pam_end(handle, pam_code | flags);
- }
-
- strv_free(e);
-
- closelog();
-
- if (pam_pid > 1) {
- kill(pam_pid, SIGTERM);
- kill(pam_pid, SIGCONT);
- }
-
- return err;
-}
-#endif
-
-static void rename_process_from_path(const char *path) {
- char process_name[11];
- const char *p;
- size_t l;
-
- /* This resulting string must fit in 10 chars (i.e. the length
- * of "/sbin/init") to look pretty in /bin/ps */
-
- p = basename(path);
- if (isempty(p)) {
- rename_process("(...)");
- return;
- }
-
- l = strlen(p);
- if (l > 8) {
- /* The end of the process name is usually more
- * interesting, since the first bit might just be
- * "systemd-" */
- p = p + l - 8;
- l = 8;
- }
-
- process_name[0] = '(';
- memcpy(process_name+1, p, l);
- process_name[1+l] = ')';
- process_name[1+l+1] = 0;
-
- rename_process(process_name);
-}
-
-#ifdef HAVE_SECCOMP
-
-static int apply_seccomp(const ExecContext *c) {
- uint32_t negative_action, action;
- scmp_filter_ctx *seccomp;
- Iterator i;
- void *id;
- int r;
-
- assert(c);
-
- negative_action = c->syscall_errno == 0 ? SCMP_ACT_KILL : SCMP_ACT_ERRNO(c->syscall_errno);
-
- seccomp = seccomp_init(c->syscall_whitelist ? negative_action : SCMP_ACT_ALLOW);
- if (!seccomp)
- return -ENOMEM;
-
- if (c->syscall_archs) {
-
- SET_FOREACH(id, c->syscall_archs, i) {
- r = seccomp_arch_add(seccomp, PTR_TO_UINT32(id) - 1);
- if (r == -EEXIST)
- continue;
- if (r < 0)
- goto finish;
- }
-
- } else {
- r = seccomp_add_secondary_archs(seccomp);
- if (r < 0)
- goto finish;
- }
-
- action = c->syscall_whitelist ? SCMP_ACT_ALLOW : negative_action;
- SET_FOREACH(id, c->syscall_filter, i) {
- r = seccomp_rule_add(seccomp, action, PTR_TO_INT(id) - 1, 0);
- if (r < 0)
- goto finish;
- }
-
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
- if (r < 0)
- goto finish;
-
- r = seccomp_load(seccomp);
-
-finish:
- seccomp_release(seccomp);
- return r;
-}
-
-static int apply_address_families(const ExecContext *c) {
- scmp_filter_ctx *seccomp;
- Iterator i;
- int r;
-
- assert(c);
-
- seccomp = seccomp_init(SCMP_ACT_ALLOW);
- if (!seccomp)
- return -ENOMEM;
-
- r = seccomp_add_secondary_archs(seccomp);
- if (r < 0)
- goto finish;
-
- if (c->address_families_whitelist) {
- int af, first = 0, last = 0;
- void *afp;
-
- /* If this is a whitelist, we first block the address
- * families that are out of range and then everything
- * that is not in the set. First, we find the lowest
- * and highest address family in the set. */
-
- SET_FOREACH(afp, c->address_families, i) {
- af = PTR_TO_INT(afp);
-
- if (af <= 0 || af >= af_max())
- continue;
-
- if (first == 0 || af < first)
- first = af;
-
- if (last == 0 || af > last)
- last = af;
- }
-
- assert((first == 0) == (last == 0));
-
- if (first == 0) {
-
- /* No entries in the valid range, block everything */
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPROTONOSUPPORT),
- SCMP_SYS(socket),
- 0);
- if (r < 0)
- goto finish;
-
- } else {
-
- /* Block everything below the first entry */
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPROTONOSUPPORT),
- SCMP_SYS(socket),
- 1,
- SCMP_A0(SCMP_CMP_LT, first));
- if (r < 0)
- goto finish;
-
- /* Block everything above the last entry */
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPROTONOSUPPORT),
- SCMP_SYS(socket),
- 1,
- SCMP_A0(SCMP_CMP_GT, last));
- if (r < 0)
- goto finish;
-
- /* Block everything between the first and last
- * entry */
- for (af = 1; af < af_max(); af++) {
-
- if (set_contains(c->address_families, INT_TO_PTR(af)))
- continue;
-
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPROTONOSUPPORT),
- SCMP_SYS(socket),
- 1,
- SCMP_A0(SCMP_CMP_EQ, af));
- if (r < 0)
- goto finish;
- }
- }
-
- } else {
- void *af;
-
- /* If this is a blacklist, then generate one rule for
- * each address family that are then combined in OR
- * checks. */
-
- SET_FOREACH(af, c->address_families, i) {
-
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPROTONOSUPPORT),
- SCMP_SYS(socket),
- 1,
- SCMP_A0(SCMP_CMP_EQ, PTR_TO_INT(af)));
- if (r < 0)
- goto finish;
- }
- }
-
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
- if (r < 0)
- goto finish;
-
- r = seccomp_load(seccomp);
-
-finish:
- seccomp_release(seccomp);
- return r;
-}
-
-#endif
-
-static void do_idle_pipe_dance(int idle_pipe[4]) {
- assert(idle_pipe);
-
-
- safe_close(idle_pipe[1]);
- safe_close(idle_pipe[2]);
-
- if (idle_pipe[0] >= 0) {
- int r;
-
- r = fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
-
- if (idle_pipe[3] >= 0 && r == 0 /* timeout */) {
- /* Signal systemd that we are bored and want to continue. */
- r = write(idle_pipe[3], "x", 1);
- if (r > 0)
- /* Wait for systemd to react to the signal above. */
- fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT2_USEC);
- }
-
- safe_close(idle_pipe[0]);
-
- }
-
- safe_close(idle_pipe[3]);
-}
-
-static int build_environment(
- const ExecContext *c,
- unsigned n_fds,
- usec_t watchdog_usec,
- const char *home,
- const char *username,
- const char *shell,
- char ***ret) {
-
- _cleanup_strv_free_ char **our_env = NULL;
- unsigned n_env = 0;
- char *x;
-
- assert(c);
- assert(ret);
-
- our_env = new0(char*, 10);
- if (!our_env)
- return -ENOMEM;
-
- if (n_fds > 0) {
- if (asprintf(&x, "LISTEN_PID="PID_FMT, getpid()) < 0)
- return -ENOMEM;
- our_env[n_env++] = x;
-
- if (asprintf(&x, "LISTEN_FDS=%u", n_fds) < 0)
- return -ENOMEM;
- our_env[n_env++] = x;
- }
-
- if (watchdog_usec > 0) {
- if (asprintf(&x, "WATCHDOG_PID="PID_FMT, getpid()) < 0)
- return -ENOMEM;
- our_env[n_env++] = x;
-
- if (asprintf(&x, "WATCHDOG_USEC="USEC_FMT, watchdog_usec) < 0)
- return -ENOMEM;
- our_env[n_env++] = x;
- }
-
- if (home) {
- x = strappend("HOME=", home);
- if (!x)
- return -ENOMEM;
- our_env[n_env++] = x;
- }
-
- if (username) {
- x = strappend("LOGNAME=", username);
- if (!x)
- return -ENOMEM;
- our_env[n_env++] = x;
-
- x = strappend("USER=", username);
- if (!x)
- return -ENOMEM;
- our_env[n_env++] = x;
- }
-
- if (shell) {
- x = strappend("SHELL=", shell);
- if (!x)
- return -ENOMEM;
- our_env[n_env++] = x;
- }
-
- if (is_terminal_input(c->std_input) ||
- c->std_output == EXEC_OUTPUT_TTY ||
- c->std_error == EXEC_OUTPUT_TTY ||
- c->tty_path) {
-
- x = strdup(default_term_for_tty(tty_path(c)));
- if (!x)
- return -ENOMEM;
- our_env[n_env++] = x;
- }
-
- our_env[n_env++] = NULL;
- assert(n_env <= 10);
-
- *ret = our_env;
- our_env = NULL;
-
- return 0;
-}
-
-static int exec_child(
- ExecCommand *command,
- const ExecContext *context,
- const ExecParameters *params,
- ExecRuntime *runtime,
- char **argv,
- int socket_fd,
- int *fds, unsigned n_fds,
- char **files_env,
- int *exit_status) {
-
- _cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
- _cleanup_free_ char *mac_selinux_context_net = NULL;
- const char *username = NULL, *home = NULL, *shell = NULL;
- unsigned n_dont_close = 0;
- int dont_close[n_fds + 4];
- uid_t uid = UID_INVALID;
- gid_t gid = GID_INVALID;
- int i, r;
-
- assert(command);
- assert(context);
- assert(params);
- assert(exit_status);
-
- rename_process_from_path(command->path);
-
- /* We reset exactly these signals, since they are the
- * only ones we set to SIG_IGN in the main daemon. All
- * others we leave untouched because we set them to
- * SIG_DFL or a valid handler initially, both of which
- * will be demoted to SIG_DFL. */
- default_signals(SIGNALS_CRASH_HANDLER,
- SIGNALS_IGNORE, -1);
-
- if (context->ignore_sigpipe)
- ignore_signals(SIGPIPE, -1);
-
- r = reset_signal_mask();
- if (r < 0) {
- *exit_status = EXIT_SIGNAL_MASK;
- return r;
- }
-
- if (params->idle_pipe)
- do_idle_pipe_dance(params->idle_pipe);
-
- /* Close sockets very early to make sure we don't
- * block init reexecution because it cannot bind its
- * sockets */
-
- log_forget_fds();
-
- if (socket_fd >= 0)
- dont_close[n_dont_close++] = socket_fd;
- if (n_fds > 0) {
- memcpy(dont_close + n_dont_close, fds, sizeof(int) * n_fds);
- n_dont_close += n_fds;
- }
- if (params->bus_endpoint_fd >= 0)
- dont_close[n_dont_close++] = params->bus_endpoint_fd;
- if (runtime) {
- if (runtime->netns_storage_socket[0] >= 0)
- dont_close[n_dont_close++] = runtime->netns_storage_socket[0];
- if (runtime->netns_storage_socket[1] >= 0)
- dont_close[n_dont_close++] = runtime->netns_storage_socket[1];
- }
-
- r = close_all_fds(dont_close, n_dont_close);
- if (r < 0) {
- *exit_status = EXIT_FDS;
- return r;
- }
-
- if (!context->same_pgrp)
- if (setsid() < 0) {
- *exit_status = EXIT_SETSID;
- return -errno;
- }
-
- exec_context_tty_reset(context);
-
- if (params->confirm_spawn) {
- char response;
-
- r = ask_for_confirmation(&response, argv);
- if (r == -ETIMEDOUT)
- write_confirm_message("Confirmation question timed out, assuming positive response.\n");
- else if (r < 0)
- write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r));
- else if (response == 's') {
- write_confirm_message("Skipping execution.\n");
- *exit_status = EXIT_CONFIRM;
- return -ECANCELED;
- } else if (response == 'n') {
- write_confirm_message("Failing execution.\n");
- *exit_status = 0;
- return 0;
- }
- }
-
- if (context->user) {
- username = context->user;
- r = get_user_creds(&username, &uid, &gid, &home, &shell);
- if (r < 0) {
- *exit_status = EXIT_USER;
- return r;
- }
- }
-
- /* If a socket is connected to STDIN/STDOUT/STDERR, we
- * must sure to drop O_NONBLOCK */
- if (socket_fd >= 0)
- fd_nonblock(socket_fd, false);
-
- r = setup_input(context, socket_fd, params->apply_tty_stdin);
- if (r < 0) {
- *exit_status = EXIT_STDIN;
- return r;
- }
-
- r = setup_output(context, STDOUT_FILENO, socket_fd, basename(command->path), params->unit_id, params->apply_tty_stdin, uid, gid);
- if (r < 0) {
- *exit_status = EXIT_STDOUT;
- return r;
- }
-
- r = setup_output(context, STDERR_FILENO, socket_fd, basename(command->path), params->unit_id, params->apply_tty_stdin, uid, gid);
- if (r < 0) {
- *exit_status = EXIT_STDERR;
- return r;
- }
-
- if (params->cgroup_path) {
- r = cg_attach_everywhere(params->cgroup_supported, params->cgroup_path, 0, NULL, NULL);
- if (r < 0) {
- *exit_status = EXIT_CGROUP;
- return r;
- }
- }
-
- if (context->oom_score_adjust_set) {
- char t[DECIMAL_STR_MAX(context->oom_score_adjust)];
-
- /* When we can't make this change due to EPERM, then
- * let's silently skip over it. User namespaces
- * prohibit write access to this file, and we
- * shouldn't trip up over that. */
-
- sprintf(t, "%i", context->oom_score_adjust);
- r = write_string_file("/proc/self/oom_score_adj", t);
- if (r == -EPERM || r == -EACCES) {
- log_open();
- log_unit_debug_errno(params->unit_id, r, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
- log_close();
- } else if (r < 0) {
- *exit_status = EXIT_OOM_ADJUST;
- return -errno;
- }
- }
-
- if (context->nice_set)
- if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) {
- *exit_status = EXIT_NICE;
- return -errno;
- }
-
- if (context->cpu_sched_set) {
- struct sched_param param = {
- .sched_priority = context->cpu_sched_priority,
- };
-
- r = sched_setscheduler(0,
- context->cpu_sched_policy |
- (context->cpu_sched_reset_on_fork ?
- SCHED_RESET_ON_FORK : 0),
- &param);
- if (r < 0) {
- *exit_status = EXIT_SETSCHEDULER;
- return -errno;
- }
- }
-
- if (context->cpuset)
- if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
- *exit_status = EXIT_CPUAFFINITY;
- return -errno;
- }
-
- if (context->ioprio_set)
- if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
- *exit_status = EXIT_IOPRIO;
- return -errno;
- }
-
- if (context->timer_slack_nsec != NSEC_INFINITY)
- if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
- *exit_status = EXIT_TIMERSLACK;
- return -errno;
- }
-
- if (context->personality != 0xffffffffUL)
- if (personality(context->personality) < 0) {
- *exit_status = EXIT_PERSONALITY;
- return -errno;
- }
-
- if (context->utmp_id)
- utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path);
-
- if (context->user && is_terminal_input(context->std_input)) {
- r = chown_terminal(STDIN_FILENO, uid);
- if (r < 0) {
- *exit_status = EXIT_STDIN;
- return r;
- }
- }
-
-#ifdef ENABLE_KDBUS
- if (params->bus_endpoint_fd >= 0 && context->bus_endpoint) {
- uid_t ep_uid = (uid == UID_INVALID) ? 0 : uid;
-
- r = bus_kernel_set_endpoint_policy(params->bus_endpoint_fd, ep_uid, context->bus_endpoint);
- if (r < 0) {
- *exit_status = EXIT_BUS_ENDPOINT;
- return r;
- }
- }
-#endif
-
- /* If delegation is enabled we'll pass ownership of the cgroup
- * (but only in systemd's own controller hierarchy!) to the
- * user of the new process. */
- if (params->cgroup_path && context->user && params->cgroup_delegate) {
- r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0644, uid, gid);
- if (r < 0) {
- *exit_status = EXIT_CGROUP;
- return r;
- }
-
-
- r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0755, uid, gid);
- if (r < 0) {
- *exit_status = EXIT_CGROUP;
- return r;
- }
- }
-
- if (!strv_isempty(context->runtime_directory) && params->runtime_prefix) {
- char **rt;
-
- STRV_FOREACH(rt, context->runtime_directory) {
- _cleanup_free_ char *p;
-
- p = strjoin(params->runtime_prefix, "/", *rt, NULL);
- if (!p) {
- *exit_status = EXIT_RUNTIME_DIRECTORY;
- return -ENOMEM;
- }
-
- r = mkdir_safe_label(p, context->runtime_directory_mode, uid, gid);
- if (r < 0) {
- *exit_status = EXIT_RUNTIME_DIRECTORY;
- return r;
- }
- }
- }
-
- if (params->apply_permissions) {
- r = enforce_groups(context, username, gid);
- if (r < 0) {
- *exit_status = EXIT_GROUP;
- return r;
- }
- }
-
- umask(context->umask);
-
-#ifdef HAVE_PAM
- if (params->apply_permissions && context->pam_name && username) {
- r = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
- if (r < 0) {
- *exit_status = EXIT_PAM;
- return r;
- }
- }
-#endif
-
- if (context->private_network && runtime && runtime->netns_storage_socket[0] >= 0) {
- r = setup_netns(runtime->netns_storage_socket);
- if (r < 0) {
- *exit_status = EXIT_NETWORK;
- return r;
- }
- }
-
- if (!strv_isempty(context->read_write_dirs) ||
- !strv_isempty(context->read_only_dirs) ||
- !strv_isempty(context->inaccessible_dirs) ||
- context->mount_flags != 0 ||
- (context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir)) ||
- params->bus_endpoint_path ||
- context->private_devices ||
- context->protect_system != PROTECT_SYSTEM_NO ||
- context->protect_home != PROTECT_HOME_NO) {
-
- char *tmp = NULL, *var = NULL;
-
- /* The runtime struct only contains the parent
- * of the private /tmp, which is
- * non-accessible to world users. Inside of it
- * there's a /tmp that is sticky, and that's
- * the one we want to use here. */
-
- if (context->private_tmp && runtime) {
- if (runtime->tmp_dir)
- tmp = strjoina(runtime->tmp_dir, "/tmp");
- if (runtime->var_tmp_dir)
- var = strjoina(runtime->var_tmp_dir, "/tmp");
- }
-
- r = setup_namespace(
- context->read_write_dirs,
- context->read_only_dirs,
- context->inaccessible_dirs,
- tmp,
- var,
- params->bus_endpoint_path,
- context->private_devices,
- context->protect_home,
- context->protect_system,
- context->mount_flags);
-
- /* If we couldn't set up the namespace this is
- * probably due to a missing capability. In this case,
- * silently proceeed. */
- if (r == -EPERM || r == -EACCES) {
- log_open();
- log_unit_debug_errno(params->unit_id, r, "Failed to set up namespace, assuming containerized execution, ignoring: %m");
- log_close();
- } else if (r < 0) {
- *exit_status = EXIT_NAMESPACE;
- return r;
- }
- }
-
- if (params->apply_chroot) {
- if (context->root_directory)
- if (chroot(context->root_directory) < 0) {
- *exit_status = EXIT_CHROOT;
- return -errno;
- }
-
- if (chdir(context->working_directory ?: "/") < 0 &&
- !context->working_directory_missing_ok) {
- *exit_status = EXIT_CHDIR;
- return -errno;
- }
- } else {
- _cleanup_free_ char *d = NULL;
-
- if (asprintf(&d, "%s/%s",
- context->root_directory ?: "",
- context->working_directory ?: "") < 0) {
- *exit_status = EXIT_MEMORY;
- return -ENOMEM;
- }
-
- if (chdir(d) < 0 &&
- !context->working_directory_missing_ok) {
- *exit_status = EXIT_CHDIR;
- return -errno;
- }
- }
-
-#ifdef HAVE_SELINUX
- if (params->apply_permissions && mac_selinux_use() && params->selinux_context_net && socket_fd >= 0) {
- r = mac_selinux_get_child_mls_label(socket_fd, command->path, context->selinux_context, &mac_selinux_context_net);
- if (r < 0) {
- *exit_status = EXIT_SELINUX_CONTEXT;
- return r;
- }
- }
-#endif
-
- /* We repeat the fd closing here, to make sure that
- * nothing is leaked from the PAM modules. Note that
- * we are more aggressive this time since socket_fd
- * and the netns fds we don't need anymore. The custom
- * endpoint fd was needed to upload the policy and can
- * now be closed as well. */
- r = close_all_fds(fds, n_fds);
- if (r >= 0)
- r = shift_fds(fds, n_fds);
- if (r >= 0)
- r = flags_fds(fds, n_fds, context->non_blocking);
- if (r < 0) {
- *exit_status = EXIT_FDS;
- return r;
- }
-
- if (params->apply_permissions) {
-
- for (i = 0; i < _RLIMIT_MAX; i++) {
- if (!context->rlimit[i])
- continue;
-
- if (setrlimit_closest(i, context->rlimit[i]) < 0) {
- *exit_status = EXIT_LIMITS;
- return -errno;
- }
- }
-
- if (context->capability_bounding_set_drop) {
- r = capability_bounding_set_drop(context->capability_bounding_set_drop, false);
- if (r < 0) {
- *exit_status = EXIT_CAPABILITIES;
- return r;
- }
- }
-
-#ifdef HAVE_SMACK
- if (context->smack_process_label) {
- r = mac_smack_apply_pid(0, context->smack_process_label);
- if (r < 0) {
- *exit_status = EXIT_SMACK_PROCESS_LABEL;
- return r;
- }
- }
-#endif
-
- if (context->user) {
- r = enforce_user(context, uid);
- if (r < 0) {
- *exit_status = EXIT_USER;
- return r;
- }
- }
-
- /* PR_GET_SECUREBITS is not privileged, while
- * PR_SET_SECUREBITS is. So to suppress
- * potential EPERMs we'll try not to call
- * PR_SET_SECUREBITS unless necessary. */
- if (prctl(PR_GET_SECUREBITS) != context->secure_bits)
- if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) {
- *exit_status = EXIT_SECUREBITS;
- return -errno;
- }
-
- if (context->capabilities)
- if (cap_set_proc(context->capabilities) < 0) {
- *exit_status = EXIT_CAPABILITIES;
- return -errno;
- }
-
- if (context->no_new_privileges)
- if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
- *exit_status = EXIT_NO_NEW_PRIVILEGES;
- return -errno;
- }
-
-#ifdef HAVE_SECCOMP
- if (context->address_families_whitelist ||
- !set_isempty(context->address_families)) {
- r = apply_address_families(context);
- if (r < 0) {
- *exit_status = EXIT_ADDRESS_FAMILIES;
- return r;
- }
- }
-
- if (context->syscall_whitelist ||
- !set_isempty(context->syscall_filter) ||
- !set_isempty(context->syscall_archs)) {
- r = apply_seccomp(context);
- if (r < 0) {
- *exit_status = EXIT_SECCOMP;
- return r;
- }
- }
-#endif
-
-#ifdef HAVE_SELINUX
- if (mac_selinux_use()) {
- char *exec_context = mac_selinux_context_net ?: context->selinux_context;
-
- if (exec_context) {
- r = setexeccon(exec_context);
- if (r < 0) {
- *exit_status = EXIT_SELINUX_CONTEXT;
- return r;
- }
- }
- }
-#endif
-
-#ifdef HAVE_APPARMOR
- if (context->apparmor_profile && mac_apparmor_use()) {
- r = aa_change_onexec(context->apparmor_profile);
- if (r < 0 && !context->apparmor_profile_ignore) {
- *exit_status = EXIT_APPARMOR_PROFILE;
- return -errno;
- }
- }
-#endif
- }
-
- r = build_environment(context, n_fds, params->watchdog_usec, home, username, shell, &our_env);
- if (r < 0) {
- *exit_status = EXIT_MEMORY;
- return r;
- }
-
- final_env = strv_env_merge(5,
- params->environment,
- our_env,
- context->environment,
- files_env,
- pam_env,
- NULL);
- if (!final_env) {
- *exit_status = EXIT_MEMORY;
- return -ENOMEM;
- }
-
- final_argv = replace_env_argv(argv, final_env);
- if (!final_argv) {
- *exit_status = EXIT_MEMORY;
- return -ENOMEM;
- }
-
- final_env = strv_env_clean(final_env);
-
- if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) {
- _cleanup_free_ char *line;
-
- line = exec_command_line(final_argv);
- if (line) {
- log_open();
- log_unit_struct(params->unit_id,
- LOG_DEBUG,
- "EXECUTABLE=%s", command->path,
- LOG_MESSAGE("Executing: %s", line),
- NULL);
- log_close();
- }
- }
- execve(command->path, final_argv, final_env);
- *exit_status = EXIT_EXEC;
- return -errno;
-}
-
-int exec_spawn(ExecCommand *command,
- const ExecContext *context,
- const ExecParameters *params,
- ExecRuntime *runtime,
- pid_t *ret) {
-
- _cleanup_strv_free_ char **files_env = NULL;
- int *fds = NULL; unsigned n_fds = 0;
- _cleanup_free_ char *line = NULL;
- int socket_fd, r;
- char **argv;
- pid_t pid;
-
- assert(command);
- assert(context);
- assert(ret);
- assert(params);
- assert(params->fds || params->n_fds <= 0);
-
- if (context->std_input == EXEC_INPUT_SOCKET ||
- context->std_output == EXEC_OUTPUT_SOCKET ||
- context->std_error == EXEC_OUTPUT_SOCKET) {
-
- if (params->n_fds != 1) {
- log_unit_error(params->unit_id, "Got more than one socket.");
- return -EINVAL;
- }
-
- socket_fd = params->fds[0];
- } else {
- socket_fd = -1;
- fds = params->fds;
- n_fds = params->n_fds;
- }
-
- r = exec_context_load_environment(context, params->unit_id, &files_env);
- if (r < 0)
- return log_unit_error_errno(params->unit_id, r, "Failed to load environment files: %m");
-
- argv = params->argv ?: command->argv;
- line = exec_command_line(argv);
- if (!line)
- return log_oom();
-
- log_unit_struct(params->unit_id,
- LOG_DEBUG,
- "EXECUTABLE=%s", command->path,
- LOG_MESSAGE("About to execute: %s", line),
- NULL);
- pid = fork();
- if (pid < 0)
- return log_unit_error_errno(params->unit_id, r, "Failed to fork: %m");
-
- if (pid == 0) {
- int exit_status;
-
- r = exec_child(command,
- context,
- params,
- runtime,
- argv,
- socket_fd,
- fds, n_fds,
- files_env,
- &exit_status);
- if (r < 0) {
- log_open();
- log_unit_struct(params->unit_id,
- LOG_ERR,
- LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED),
- "EXECUTABLE=%s", command->path,
- LOG_MESSAGE("Failed at step %s spawning %s: %s",
- exit_status_to_string(exit_status, EXIT_STATUS_SYSTEMD),
- command->path, strerror(-r)),
- LOG_ERRNO(r),
- NULL);
- }
-
- _exit(exit_status);
- }
-
- log_unit_debug(params->unit_id, "Forked %s as "PID_FMT, command->path, pid);
-
- /* We add the new process to the cgroup both in the child (so
- * that we can be sure that no user code is ever executed
- * outside of the cgroup) and in the parent (so that we can be
- * sure that when we kill the cgroup the process will be
- * killed too). */
- if (params->cgroup_path)
- cg_attach(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, pid);
-
- exec_status_start(&command->exec_status, pid);
-
- *ret = pid;
- return 0;
-}
-
-void exec_context_init(ExecContext *c) {
- assert(c);
-
- c->umask = 0022;
- c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0);
- c->cpu_sched_policy = SCHED_OTHER;
- c->syslog_priority = LOG_DAEMON|LOG_INFO;
- c->syslog_level_prefix = true;
- c->ignore_sigpipe = true;
- c->timer_slack_nsec = NSEC_INFINITY;
- c->personality = 0xffffffffUL;
- c->runtime_directory_mode = 0755;
-}
-
-void exec_context_done(ExecContext *c) {
- unsigned l;
-
- assert(c);
-
- strv_free(c->environment);
- c->environment = NULL;
-
- strv_free(c->environment_files);
- c->environment_files = NULL;
-
- for (l = 0; l < ELEMENTSOF(c->rlimit); l++) {
- free(c->rlimit[l]);
- c->rlimit[l] = NULL;
- }
-
- free(c->working_directory);
- c->working_directory = NULL;
- free(c->root_directory);
- c->root_directory = NULL;
-
- free(c->tty_path);
- c->tty_path = NULL;
-
- free(c->syslog_identifier);
- c->syslog_identifier = NULL;
-
- free(c->user);
- c->user = NULL;
-
- free(c->group);
- c->group = NULL;
-
- strv_free(c->supplementary_groups);
- c->supplementary_groups = NULL;
-
- free(c->pam_name);
- c->pam_name = NULL;
-
- if (c->capabilities) {
- cap_free(c->capabilities);
- c->capabilities = NULL;
- }
-
- strv_free(c->read_only_dirs);
- c->read_only_dirs = NULL;
-
- strv_free(c->read_write_dirs);
- c->read_write_dirs = NULL;
-
- strv_free(c->inaccessible_dirs);
- c->inaccessible_dirs = NULL;
-
- if (c->cpuset)
- CPU_FREE(c->cpuset);
-
- free(c->utmp_id);
- c->utmp_id = NULL;
-
- free(c->selinux_context);
- c->selinux_context = NULL;
-
- free(c->apparmor_profile);
- c->apparmor_profile = NULL;
-
- set_free(c->syscall_filter);
- c->syscall_filter = NULL;
-
- set_free(c->syscall_archs);
- c->syscall_archs = NULL;
-
- set_free(c->address_families);
- c->address_families = NULL;
-
- strv_free(c->runtime_directory);
- c->runtime_directory = NULL;
-
- bus_endpoint_free(c->bus_endpoint);
- c->bus_endpoint = NULL;
-}
-
-int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_prefix) {
- char **i;
-
- assert(c);
-
- if (!runtime_prefix)
- return 0;
-
- STRV_FOREACH(i, c->runtime_directory) {
- _cleanup_free_ char *p;
-
- p = strjoin(runtime_prefix, "/", *i, NULL);
- if (!p)
- return -ENOMEM;
-
- /* We execute this synchronously, since we need to be
- * sure this is gone when we start the service
- * next. */
- rm_rf(p, false, true, false);
- }
-
- return 0;
-}
-
-void exec_command_done(ExecCommand *c) {
- assert(c);
-
- free(c->path);
- c->path = NULL;
-
- strv_free(c->argv);
- c->argv = NULL;
-}
-
-void exec_command_done_array(ExecCommand *c, unsigned n) {
- unsigned i;
-
- for (i = 0; i < n; i++)
- exec_command_done(c+i);
-}
-
-ExecCommand* exec_command_free_list(ExecCommand *c) {
- ExecCommand *i;
-
- while ((i = c)) {
- LIST_REMOVE(command, c, i);
- exec_command_done(i);
- free(i);
- }
-
- return NULL;
-}
-
-void exec_command_free_array(ExecCommand **c, unsigned n) {
- unsigned i;
-
- for (i = 0; i < n; i++)
- c[i] = exec_command_free_list(c[i]);
-}
-
-typedef struct InvalidEnvInfo {
- const char *unit_id;
- const char *path;
-} InvalidEnvInfo;
-
-static void invalid_env(const char *p, void *userdata) {
- InvalidEnvInfo *info = userdata;
-
- log_unit_error(info->unit_id, "Ignoring invalid environment assignment '%s': %s", p, info->path);
-}
-
-int exec_context_load_environment(const ExecContext *c, const char *unit_id, char ***l) {
- char **i, **r = NULL;
-
- assert(c);
- assert(l);
-
- STRV_FOREACH(i, c->environment_files) {
- char *fn;
- int k;
- bool ignore = false;
- char **p;
- _cleanup_globfree_ glob_t pglob = {};
- int count, n;
-
- fn = *i;
-
- if (fn[0] == '-') {
- ignore = true;
- fn ++;
- }
-
- if (!path_is_absolute(fn)) {
- if (ignore)
- continue;
-
- strv_free(r);
- return -EINVAL;
- }
-
- /* Filename supports globbing, take all matching files */
- errno = 0;
- if (glob(fn, 0, NULL, &pglob) != 0) {
- if (ignore)
- continue;
-
- strv_free(r);
- return errno ? -errno : -EINVAL;
- }
- count = pglob.gl_pathc;
- if (count == 0) {
- if (ignore)
- continue;
-
- strv_free(r);
- return -EINVAL;
- }
- for (n = 0; n < count; n++) {
- k = load_env_file(NULL, pglob.gl_pathv[n], NULL, &p);
- if (k < 0) {
- if (ignore)
- continue;
-
- strv_free(r);
- return k;
- }
- /* Log invalid environment variables with filename */
- if (p) {
- InvalidEnvInfo info = {
- .unit_id = unit_id,
- .path = pglob.gl_pathv[n]
- };
-
- p = strv_env_clean_with_callback(p, invalid_env, &info);
- }
-
- if (r == NULL)
- r = p;
- else {
- char **m;
-
- m = strv_env_merge(2, r, p);
- strv_free(r);
- strv_free(p);
- if (!m)
- return -ENOMEM;
-
- r = m;
- }
- }
- }
-
- *l = r;
-
- return 0;
-}
-
-static bool tty_may_match_dev_console(const char *tty) {
- _cleanup_free_ char *active = NULL;
- char *console;
-
- if (startswith(tty, "/dev/"))
- tty += 5;
-
- /* trivial identity? */
- if (streq(tty, "console"))
- return true;
-
- console = resolve_dev_console(&active);
- /* if we could not resolve, assume it may */
- if (!console)
- return true;
-
- /* "tty0" means the active VC, so it may be the same sometimes */
- return streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty));
-}
-
-bool exec_context_may_touch_console(ExecContext *ec) {
- return (ec->tty_reset || ec->tty_vhangup || ec->tty_vt_disallocate ||
- is_terminal_input(ec->std_input) ||
- is_terminal_output(ec->std_output) ||
- is_terminal_output(ec->std_error)) &&
- tty_may_match_dev_console(tty_path(ec));
-}
-
-static void strv_fprintf(FILE *f, char **l) {
- char **g;
-
- assert(f);
-
- STRV_FOREACH(g, l)
- fprintf(f, " %s", *g);
-}
-
-void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
- char **e;
- unsigned i;
-
- assert(c);
- assert(f);
-
- prefix = strempty(prefix);
-
- fprintf(f,
- "%sUMask: %04o\n"
- "%sWorkingDirectory: %s\n"
- "%sRootDirectory: %s\n"
- "%sNonBlocking: %s\n"
- "%sPrivateTmp: %s\n"
- "%sPrivateNetwork: %s\n"
- "%sPrivateDevices: %s\n"
- "%sProtectHome: %s\n"
- "%sProtectSystem: %s\n"
- "%sIgnoreSIGPIPE: %s\n",
- prefix, c->umask,
- prefix, c->working_directory ? c->working_directory : "/",
- prefix, c->root_directory ? c->root_directory : "/",
- prefix, yes_no(c->non_blocking),
- prefix, yes_no(c->private_tmp),
- prefix, yes_no(c->private_network),
- prefix, yes_no(c->private_devices),
- prefix, protect_home_to_string(c->protect_home),
- prefix, protect_system_to_string(c->protect_system),
- prefix, yes_no(c->ignore_sigpipe));
-
- STRV_FOREACH(e, c->environment)
- fprintf(f, "%sEnvironment: %s\n", prefix, *e);
-
- STRV_FOREACH(e, c->environment_files)
- fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
-
- if (c->nice_set)
- fprintf(f,
- "%sNice: %i\n",
- prefix, c->nice);
-
- if (c->oom_score_adjust_set)
- fprintf(f,
- "%sOOMScoreAdjust: %i\n",
- prefix, c->oom_score_adjust);
-
- for (i = 0; i < RLIM_NLIMITS; i++)
- if (c->rlimit[i])
- fprintf(f, "%s%s: "RLIM_FMT"\n",
- prefix, rlimit_to_string(i), c->rlimit[i]->rlim_max);
-
- if (c->ioprio_set) {
- _cleanup_free_ char *class_str = NULL;
-
- ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str);
- fprintf(f,
- "%sIOSchedulingClass: %s\n"
- "%sIOPriority: %i\n",
- prefix, strna(class_str),
- prefix, (int) IOPRIO_PRIO_DATA(c->ioprio));
- }
-
- if (c->cpu_sched_set) {
- _cleanup_free_ char *policy_str = NULL;
-
- sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
- fprintf(f,
- "%sCPUSchedulingPolicy: %s\n"
- "%sCPUSchedulingPriority: %i\n"
- "%sCPUSchedulingResetOnFork: %s\n",
- prefix, strna(policy_str),
- prefix, c->cpu_sched_priority,
- prefix, yes_no(c->cpu_sched_reset_on_fork));
- }
-
- if (c->cpuset) {
- fprintf(f, "%sCPUAffinity:", prefix);
- for (i = 0; i < c->cpuset_ncpus; i++)
- if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
- fprintf(f, " %u", i);
- fputs("\n", f);
- }
-
- if (c->timer_slack_nsec != NSEC_INFINITY)
- fprintf(f, "%sTimerSlackNSec: "NSEC_FMT "\n", prefix, c->timer_slack_nsec);
-
- fprintf(f,
- "%sStandardInput: %s\n"
- "%sStandardOutput: %s\n"
- "%sStandardError: %s\n",
- prefix, exec_input_to_string(c->std_input),
- prefix, exec_output_to_string(c->std_output),
- prefix, exec_output_to_string(c->std_error));
-
- if (c->tty_path)
- fprintf(f,
- "%sTTYPath: %s\n"
- "%sTTYReset: %s\n"
- "%sTTYVHangup: %s\n"
- "%sTTYVTDisallocate: %s\n",
- prefix, c->tty_path,
- prefix, yes_no(c->tty_reset),
- prefix, yes_no(c->tty_vhangup),
- prefix, yes_no(c->tty_vt_disallocate));
-
- if (c->std_output == EXEC_OUTPUT_SYSLOG ||
- c->std_output == EXEC_OUTPUT_KMSG ||
- c->std_output == EXEC_OUTPUT_JOURNAL ||
- c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
- c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
- c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE ||
- c->std_error == EXEC_OUTPUT_SYSLOG ||
- c->std_error == EXEC_OUTPUT_KMSG ||
- c->std_error == EXEC_OUTPUT_JOURNAL ||
- c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
- c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
- c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) {
-
- _cleanup_free_ char *fac_str = NULL, *lvl_str = NULL;
-
- log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str);
- log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str);
-
- fprintf(f,
- "%sSyslogFacility: %s\n"
- "%sSyslogLevel: %s\n",
- prefix, strna(fac_str),
- prefix, strna(lvl_str));
- }
-
- if (c->capabilities) {
- _cleanup_cap_free_charp_ char *t;
-
- t = cap_to_text(c->capabilities, NULL);
- if (t)
- fprintf(f, "%sCapabilities: %s\n", prefix, t);
- }
-
- if (c->secure_bits)
- fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n",
- prefix,
- (c->secure_bits & 1<<SECURE_KEEP_CAPS) ? " keep-caps" : "",
- (c->secure_bits & 1<<SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "",
- (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "",
- (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "",
- (c->secure_bits & 1<<SECURE_NOROOT) ? " noroot" : "",
- (c->secure_bits & 1<<SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
-
- if (c->capability_bounding_set_drop) {
- unsigned long l;
- fprintf(f, "%sCapabilityBoundingSet:", prefix);
-
- for (l = 0; l <= cap_last_cap(); l++)
- if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l)))
- fprintf(f, " %s", strna(capability_to_name(l)));
-
- fputs("\n", f);
- }
-
- if (c->user)
- fprintf(f, "%sUser: %s\n", prefix, c->user);
- if (c->group)
- fprintf(f, "%sGroup: %s\n", prefix, c->group);
-
- if (strv_length(c->supplementary_groups) > 0) {
- fprintf(f, "%sSupplementaryGroups:", prefix);
- strv_fprintf(f, c->supplementary_groups);
- fputs("\n", f);
- }
-
- if (c->pam_name)
- fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
-
- if (strv_length(c->read_write_dirs) > 0) {
- fprintf(f, "%sReadWriteDirs:", prefix);
- strv_fprintf(f, c->read_write_dirs);
- fputs("\n", f);
- }
-
- if (strv_length(c->read_only_dirs) > 0) {
- fprintf(f, "%sReadOnlyDirs:", prefix);
- strv_fprintf(f, c->read_only_dirs);
- fputs("\n", f);
- }
-
- if (strv_length(c->inaccessible_dirs) > 0) {
- fprintf(f, "%sInaccessibleDirs:", prefix);
- strv_fprintf(f, c->inaccessible_dirs);
- fputs("\n", f);
- }
-
- if (c->utmp_id)
- fprintf(f,
- "%sUtmpIdentifier: %s\n",
- prefix, c->utmp_id);
-
- if (c->selinux_context)
- fprintf(f,
- "%sSELinuxContext: %s%s\n",
- prefix, c->selinux_context_ignore ? "-" : "", c->selinux_context);
-
- if (c->personality != 0xffffffffUL)
- fprintf(f,
- "%sPersonality: %s\n",
- prefix, strna(personality_to_string(c->personality)));
-
- if (c->syscall_filter) {
-#ifdef HAVE_SECCOMP
- Iterator j;
- void *id;
- bool first = true;
-#endif
-
- fprintf(f,
- "%sSystemCallFilter: ",
- prefix);
-
- if (!c->syscall_whitelist)
- fputc('~', f);
-
-#ifdef HAVE_SECCOMP
- SET_FOREACH(id, c->syscall_filter, j) {
- _cleanup_free_ char *name = NULL;
-
- if (first)
- first = false;
- else
- fputc(' ', f);
-
- name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
- fputs(strna(name), f);
- }
-#endif
-
- fputc('\n', f);
- }
-
- if (c->syscall_archs) {
-#ifdef HAVE_SECCOMP
- Iterator j;
- void *id;
-#endif
-
- fprintf(f,
- "%sSystemCallArchitectures:",
- prefix);
-
-#ifdef HAVE_SECCOMP
- SET_FOREACH(id, c->syscall_archs, j)
- fprintf(f, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id) - 1)));
-#endif
- fputc('\n', f);
- }
-
- if (c->syscall_errno != 0)
- fprintf(f,
- "%sSystemCallErrorNumber: %s\n",
- prefix, strna(errno_to_name(c->syscall_errno)));
-
- if (c->apparmor_profile)
- fprintf(f,
- "%sAppArmorProfile: %s%s\n",
- prefix, c->apparmor_profile_ignore ? "-" : "", c->apparmor_profile);
-}
-
-bool exec_context_maintains_privileges(ExecContext *c) {
- assert(c);
-
- /* Returns true if the process forked off would run run under
- * an unchanged UID or as root. */
-
- if (!c->user)
- return true;
-
- if (streq(c->user, "root") || streq(c->user, "0"))
- return true;
-
- return false;
-}
-
-void exec_status_start(ExecStatus *s, pid_t pid) {
- assert(s);
-
- zero(*s);
- s->pid = pid;
- dual_timestamp_get(&s->start_timestamp);
-}
-
-void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
- assert(s);
-
- if (s->pid && s->pid != pid)
- zero(*s);
-
- s->pid = pid;
- dual_timestamp_get(&s->exit_timestamp);
-
- s->code = code;
- s->status = status;
-
- if (context) {
- if (context->utmp_id)
- utmp_put_dead_process(context->utmp_id, pid, code, status);
-
- exec_context_tty_reset(context);
- }
-}
-
-void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
- char buf[FORMAT_TIMESTAMP_MAX];
-
- assert(s);
- assert(f);
-
- if (s->pid <= 0)
- return;
-
- prefix = strempty(prefix);
-
- fprintf(f,
- "%sPID: "PID_FMT"\n",
- prefix, s->pid);
-
- if (s->start_timestamp.realtime > 0)
- fprintf(f,
- "%sStart Timestamp: %s\n",
- prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime));
-
- if (s->exit_timestamp.realtime > 0)
- fprintf(f,
- "%sExit Timestamp: %s\n"
- "%sExit Code: %s\n"
- "%sExit Status: %i\n",
- prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime),
- prefix, sigchld_code_to_string(s->code),
- prefix, s->status);
-}
-
-char *exec_command_line(char **argv) {
- size_t k;
- char *n, *p, **a;
- bool first = true;
-
- assert(argv);
-
- k = 1;
- STRV_FOREACH(a, argv)
- k += strlen(*a)+3;
-
- if (!(n = new(char, k)))
- return NULL;
-
- p = n;
- STRV_FOREACH(a, argv) {
-
- if (!first)
- *(p++) = ' ';
- else
- first = false;
-
- if (strpbrk(*a, WHITESPACE)) {
- *(p++) = '\'';
- p = stpcpy(p, *a);
- *(p++) = '\'';
- } else
- p = stpcpy(p, *a);
-
- }
-
- *p = 0;
-
- /* FIXME: this doesn't really handle arguments that have
- * spaces and ticks in them */
-
- return n;
-}
-
-void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
- _cleanup_free_ char *cmd = NULL;
- const char *prefix2;
-
- assert(c);
- assert(f);
-
- prefix = strempty(prefix);
- prefix2 = strjoina(prefix, "\t");
-
- cmd = exec_command_line(c->argv);
- fprintf(f,
- "%sCommand Line: %s\n",
- prefix, cmd ? cmd : strerror(ENOMEM));
-
- exec_status_dump(&c->exec_status, f, prefix2);
-}
-
-void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
- assert(f);
-
- prefix = strempty(prefix);
-
- LIST_FOREACH(command, c, c)
- exec_command_dump(c, f, prefix);
-}
-
-void exec_command_append_list(ExecCommand **l, ExecCommand *e) {
- ExecCommand *end;
-
- assert(l);
- assert(e);
-
- if (*l) {
- /* It's kind of important, that we keep the order here */
- LIST_FIND_TAIL(command, *l, end);
- LIST_INSERT_AFTER(command, *l, end, e);
- } else
- *l = e;
-}
-
-int exec_command_set(ExecCommand *c, const char *path, ...) {
- va_list ap;
- char **l, *p;
-
- assert(c);
- assert(path);
-
- va_start(ap, path);
- l = strv_new_ap(path, ap);
- va_end(ap);
-
- if (!l)
- return -ENOMEM;
-
- p = strdup(path);
- if (!p) {
- strv_free(l);
- return -ENOMEM;
- }
-
- free(c->path);
- c->path = p;
-
- strv_free(c->argv);
- c->argv = l;
-
- return 0;
-}
-
-int exec_command_append(ExecCommand *c, const char *path, ...) {
- _cleanup_strv_free_ char **l = NULL;
- va_list ap;
- int r;
-
- assert(c);
- assert(path);
-
- va_start(ap, path);
- l = strv_new_ap(path, ap);
- va_end(ap);
-
- if (!l)
- return -ENOMEM;
-
- r = strv_extend_strv(&c->argv, l);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-
-static int exec_runtime_allocate(ExecRuntime **rt) {
-
- if (*rt)
- return 0;
-
- *rt = new0(ExecRuntime, 1);
- if (!*rt)
- return -ENOMEM;
-
- (*rt)->n_ref = 1;
- (*rt)->netns_storage_socket[0] = (*rt)->netns_storage_socket[1] = -1;
-
- return 0;
-}
-
-int exec_runtime_make(ExecRuntime **rt, ExecContext *c, const char *id) {
- int r;
-
- assert(rt);
- assert(c);
- assert(id);
-
- if (*rt)
- return 1;
-
- if (!c->private_network && !c->private_tmp)
- return 0;
-
- r = exec_runtime_allocate(rt);
- if (r < 0)
- return r;
-
- if (c->private_network && (*rt)->netns_storage_socket[0] < 0) {
- if (socketpair(AF_UNIX, SOCK_DGRAM, 0, (*rt)->netns_storage_socket) < 0)
- return -errno;
- }
-
- if (c->private_tmp && !(*rt)->tmp_dir) {
- r = setup_tmp_dirs(id, &(*rt)->tmp_dir, &(*rt)->var_tmp_dir);
- if (r < 0)
- return r;
- }
-
- return 1;
-}
-
-ExecRuntime *exec_runtime_ref(ExecRuntime *r) {
- assert(r);
- assert(r->n_ref > 0);
-
- r->n_ref++;
- return r;
-}
-
-ExecRuntime *exec_runtime_unref(ExecRuntime *r) {
-
- if (!r)
- return NULL;
-
- assert(r->n_ref > 0);
-
- r->n_ref--;
- if (r->n_ref <= 0) {
- free(r->tmp_dir);
- free(r->var_tmp_dir);
- safe_close_pair(r->netns_storage_socket);
- free(r);
- }
-
- return NULL;
-}
-
-int exec_runtime_serialize(ExecRuntime *rt, Unit *u, FILE *f, FDSet *fds) {
- assert(u);
- assert(f);
- assert(fds);
-
- if (!rt)
- return 0;
-
- if (rt->tmp_dir)
- unit_serialize_item(u, f, "tmp-dir", rt->tmp_dir);
-
- if (rt->var_tmp_dir)
- unit_serialize_item(u, f, "var-tmp-dir", rt->var_tmp_dir);
-
- if (rt->netns_storage_socket[0] >= 0) {
- int copy;
-
- copy = fdset_put_dup(fds, rt->netns_storage_socket[0]);
- if (copy < 0)
- return copy;
-
- unit_serialize_item_format(u, f, "netns-socket-0", "%i", copy);
- }
-
- if (rt->netns_storage_socket[1] >= 0) {
- int copy;
-
- copy = fdset_put_dup(fds, rt->netns_storage_socket[1]);
- if (copy < 0)
- return copy;
-
- unit_serialize_item_format(u, f, "netns-socket-1", "%i", copy);
- }
-
- return 0;
-}
-
-int exec_runtime_deserialize_item(ExecRuntime **rt, Unit *u, const char *key, const char *value, FDSet *fds) {
- int r;
-
- assert(rt);
- assert(key);
- assert(value);
-
- if (streq(key, "tmp-dir")) {
- char *copy;
-
- r = exec_runtime_allocate(rt);
- if (r < 0)
- return r;
-
- copy = strdup(value);
- if (!copy)
- return log_oom();
-
- free((*rt)->tmp_dir);
- (*rt)->tmp_dir = copy;
-
- } else if (streq(key, "var-tmp-dir")) {
- char *copy;
-
- r = exec_runtime_allocate(rt);
- if (r < 0)
- return r;
-
- copy = strdup(value);
- if (!copy)
- return log_oom();
-
- free((*rt)->var_tmp_dir);
- (*rt)->var_tmp_dir = copy;
-
- } else if (streq(key, "netns-socket-0")) {
- int fd;
-
- r = exec_runtime_allocate(rt);
- if (r < 0)
- return r;
-
- if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
- log_unit_debug(u->id, "Failed to parse netns socket value %s", value);
- else {
- safe_close((*rt)->netns_storage_socket[0]);
- (*rt)->netns_storage_socket[0] = fdset_remove(fds, fd);
- }
- } else if (streq(key, "netns-socket-1")) {
- int fd;
-
- r = exec_runtime_allocate(rt);
- if (r < 0)
- return r;
-
- if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
- log_unit_debug(u->id, "Failed to parse netns socket value %s", value);
- else {
- safe_close((*rt)->netns_storage_socket[1]);
- (*rt)->netns_storage_socket[1] = fdset_remove(fds, fd);
- }
- } else
- return 0;
-
- return 1;
-}
-
-static void *remove_tmpdir_thread(void *p) {
- _cleanup_free_ char *path = p;
-
- rm_rf_dangerous(path, false, true, false);
- return NULL;
-}
-
-void exec_runtime_destroy(ExecRuntime *rt) {
- int r;
-
- if (!rt)
- return;
-
- /* If there are multiple users of this, let's leave the stuff around */
- if (rt->n_ref > 1)
- return;
-
- if (rt->tmp_dir) {
- log_debug("Spawning thread to nuke %s", rt->tmp_dir);
-
- r = asynchronous_job(remove_tmpdir_thread, rt->tmp_dir);
- if (r < 0) {
- log_warning_errno(r, "Failed to nuke %s: %m", rt->tmp_dir);
- free(rt->tmp_dir);
- }
-
- rt->tmp_dir = NULL;
- }
-
- if (rt->var_tmp_dir) {
- log_debug("Spawning thread to nuke %s", rt->var_tmp_dir);
-
- r = asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir);
- if (r < 0) {
- log_warning_errno(r, "Failed to nuke %s: %m", rt->var_tmp_dir);
- free(rt->var_tmp_dir);
- }
-
- rt->var_tmp_dir = NULL;
- }
-
- safe_close_pair(rt->netns_storage_socket);
-}
-
-static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
- [EXEC_INPUT_NULL] = "null",
- [EXEC_INPUT_TTY] = "tty",
- [EXEC_INPUT_TTY_FORCE] = "tty-force",
- [EXEC_INPUT_TTY_FAIL] = "tty-fail",
- [EXEC_INPUT_SOCKET] = "socket"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
-
-static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
- [EXEC_OUTPUT_INHERIT] = "inherit",
- [EXEC_OUTPUT_NULL] = "null",
- [EXEC_OUTPUT_TTY] = "tty",
- [EXEC_OUTPUT_SYSLOG] = "syslog",
- [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console",
- [EXEC_OUTPUT_KMSG] = "kmsg",
- [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
- [EXEC_OUTPUT_JOURNAL] = "journal",
- [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
- [EXEC_OUTPUT_SOCKET] = "socket"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);
diff --git a/src/core/execute.h b/src/core/execute.h
deleted file mode 100644
index 1a43ac77b..000000000
--- a/src/core/execute.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-typedef struct ExecStatus ExecStatus;
-typedef struct ExecCommand ExecCommand;
-typedef struct ExecContext ExecContext;
-typedef struct ExecRuntime ExecRuntime;
-typedef struct ExecParameters ExecParameters;
-
-#include <sys/capability.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <sched.h>
-
-#include "list.h"
-#include "fdset.h"
-#include "missing.h"
-#include "namespace.h"
-#include "bus-endpoint.h"
-
-typedef enum ExecInput {
- EXEC_INPUT_NULL,
- EXEC_INPUT_TTY,
- EXEC_INPUT_TTY_FORCE,
- EXEC_INPUT_TTY_FAIL,
- EXEC_INPUT_SOCKET,
- _EXEC_INPUT_MAX,
- _EXEC_INPUT_INVALID = -1
-} ExecInput;
-
-typedef enum ExecOutput {
- EXEC_OUTPUT_INHERIT,
- EXEC_OUTPUT_NULL,
- EXEC_OUTPUT_TTY,
- EXEC_OUTPUT_SYSLOG,
- EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
- EXEC_OUTPUT_KMSG,
- EXEC_OUTPUT_KMSG_AND_CONSOLE,
- EXEC_OUTPUT_JOURNAL,
- EXEC_OUTPUT_JOURNAL_AND_CONSOLE,
- EXEC_OUTPUT_SOCKET,
- _EXEC_OUTPUT_MAX,
- _EXEC_OUTPUT_INVALID = -1
-} ExecOutput;
-
-struct ExecStatus {
- dual_timestamp start_timestamp;
- dual_timestamp exit_timestamp;
- pid_t pid;
- int code; /* as in siginfo_t::si_code */
- int status; /* as in sigingo_t::si_status */
-};
-
-struct ExecCommand {
- char *path;
- char **argv;
- ExecStatus exec_status;
- LIST_FIELDS(ExecCommand, command); /* useful for chaining commands */
- bool ignore;
-};
-
-struct ExecRuntime {
- int n_ref;
-
- char *tmp_dir;
- char *var_tmp_dir;
-
- int netns_storage_socket[2];
-};
-
-struct ExecContext {
- char **environment;
- char **environment_files;
-
- struct rlimit *rlimit[_RLIMIT_MAX];
- char *working_directory, *root_directory;
- bool working_directory_missing_ok;
-
- mode_t umask;
- int oom_score_adjust;
- int nice;
- int ioprio;
- int cpu_sched_policy;
- int cpu_sched_priority;
-
- cpu_set_t *cpuset;
- unsigned cpuset_ncpus;
-
- ExecInput std_input;
- ExecOutput std_output;
- ExecOutput std_error;
-
- nsec_t timer_slack_nsec;
-
- char *tty_path;
-
- bool tty_reset;
- bool tty_vhangup;
- bool tty_vt_disallocate;
-
- bool ignore_sigpipe;
-
- /* Since resolving these names might might involve socket
- * connections and we don't want to deadlock ourselves these
- * names are resolved on execution only and in the child
- * process. */
- char *user;
- char *group;
- char **supplementary_groups;
-
- char *pam_name;
-
- char *utmp_id;
-
- bool selinux_context_ignore;
- char *selinux_context;
-
- bool apparmor_profile_ignore;
- char *apparmor_profile;
-
- bool smack_process_label_ignore;
- char *smack_process_label;
-
- char **read_write_dirs, **read_only_dirs, **inaccessible_dirs;
- unsigned long mount_flags;
-
- uint64_t capability_bounding_set_drop;
-
- cap_t capabilities;
- int secure_bits;
-
- int syslog_priority;
- char *syslog_identifier;
- bool syslog_level_prefix;
-
- bool cpu_sched_reset_on_fork;
- bool non_blocking;
- bool private_tmp;
- bool private_network;
- bool private_devices;
- ProtectSystem protect_system;
- ProtectHome protect_home;
-
- bool no_new_privileges;
-
- /* This is not exposed to the user but available
- * internally. We need it to make sure that whenever we spawn
- * /bin/mount it is run in the same process group as us so
- * that the autofs logic detects that it belongs to us and we
- * don't enter a trigger loop. */
- bool same_pgrp;
-
- unsigned long personality;
-
- Set *syscall_filter;
- Set *syscall_archs;
- int syscall_errno;
- bool syscall_whitelist:1;
-
- Set *address_families;
- bool address_families_whitelist:1;
-
- char **runtime_directory;
- mode_t runtime_directory_mode;
-
- bool oom_score_adjust_set:1;
- bool nice_set:1;
- bool ioprio_set:1;
- bool cpu_sched_set:1;
- bool no_new_privileges_set:1;
-
- /* custom dbus enpoint */
- BusEndpoint *bus_endpoint;
-};
-
-#include "cgroup.h"
-#include "cgroup-util.h"
-
-struct ExecParameters {
- char **argv;
- int *fds; unsigned n_fds;
- char **environment;
- bool apply_permissions;
- bool apply_chroot;
- bool apply_tty_stdin;
- bool confirm_spawn;
- bool selinux_context_net;
- CGroupControllerMask cgroup_supported;
- const char *cgroup_path;
- bool cgroup_delegate;
- const char *runtime_prefix;
- const char *unit_id;
- usec_t watchdog_usec;
- int *idle_pipe;
- char *bus_endpoint_path;
- int bus_endpoint_fd;
-};
-
-int exec_spawn(ExecCommand *command,
- const ExecContext *context,
- const ExecParameters *exec_params,
- ExecRuntime *runtime,
- pid_t *ret);
-
-void exec_command_done(ExecCommand *c);
-void exec_command_done_array(ExecCommand *c, unsigned n);
-
-ExecCommand* exec_command_free_list(ExecCommand *c);
-void exec_command_free_array(ExecCommand **c, unsigned n);
-
-char *exec_command_line(char **argv);
-
-void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix);
-void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix);
-void exec_command_append_list(ExecCommand **l, ExecCommand *e);
-int exec_command_set(ExecCommand *c, const char *path, ...);
-int exec_command_append(ExecCommand *c, const char *path, ...);
-
-void exec_context_init(ExecContext *c);
-void exec_context_done(ExecContext *c);
-void exec_context_dump(ExecContext *c, FILE* f, const char *prefix);
-
-int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_root);
-
-int exec_context_load_environment(const ExecContext *c, const char *unit_id, char ***l);
-
-bool exec_context_may_touch_console(ExecContext *c);
-bool exec_context_maintains_privileges(ExecContext *c);
-
-void exec_status_start(ExecStatus *s, pid_t pid);
-void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status);
-void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix);
-
-int exec_runtime_make(ExecRuntime **rt, ExecContext *c, const char *id);
-ExecRuntime *exec_runtime_ref(ExecRuntime *r);
-ExecRuntime *exec_runtime_unref(ExecRuntime *r);
-
-int exec_runtime_serialize(ExecRuntime *rt, Unit *u, FILE *f, FDSet *fds);
-int exec_runtime_deserialize_item(ExecRuntime **rt, Unit *u, const char *key, const char *value, FDSet *fds);
-
-void exec_runtime_destroy(ExecRuntime *rt);
-
-const char* exec_output_to_string(ExecOutput i) _const_;
-ExecOutput exec_output_from_string(const char *s) _pure_;
-
-const char* exec_input_to_string(ExecInput i) _const_;
-ExecInput exec_input_from_string(const char *s) _pure_;
diff --git a/src/core/failure-action.c b/src/core/failure-action.c
deleted file mode 100644
index ffeb5cd31..000000000
--- a/src/core/failure-action.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
- Copyright 2012 Michael Olbrich
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/reboot.h>
-#include <linux/reboot.h>
-
-#include "bus-util.h"
-#include "bus-error.h"
-#include "special.h"
-#include "failure-action.h"
-
-static void log_and_status(Manager *m, const char *message) {
- log_warning("%s", message);
- manager_status_printf(m, STATUS_TYPE_EMERGENCY,
- ANSI_HIGHLIGHT_RED_ON " !! " ANSI_HIGHLIGHT_OFF,
- "%s", message);
-}
-
-int failure_action(
- Manager *m,
- FailureAction action,
- const char *reboot_arg) {
-
- int r;
-
- assert(m);
- assert(action >= 0);
- assert(action < _FAILURE_ACTION_MAX);
-
- if (action == FAILURE_ACTION_NONE)
- return -ECANCELED;
-
- if (m->running_as == SYSTEMD_USER) {
- /* Downgrade all options to simply exiting if we run
- * in user mode */
-
- log_warning("Exiting as result of failure.");
- m->exit_code = MANAGER_EXIT;
- return -ECANCELED;
- }
-
- switch (action) {
-
- case FAILURE_ACTION_REBOOT: {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-
- log_and_status(m, "Rebooting as result of failure.");
-
- update_reboot_param_file(reboot_arg);
- r = manager_add_job_by_name(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE, true, &error, NULL);
- if (r < 0)
- log_error("Failed to reboot: %s.", bus_error_message(&error, r));
-
- break;
- }
-
- case FAILURE_ACTION_REBOOT_FORCE:
- log_and_status(m, "Forcibly rebooting as result of failure.");
-
- update_reboot_param_file(reboot_arg);
- m->exit_code = MANAGER_REBOOT;
- break;
-
- case FAILURE_ACTION_REBOOT_IMMEDIATE:
- log_and_status(m, "Rebooting immediately as result of failure.");
-
- sync();
-
- if (reboot_arg) {
- log_info("Rebooting with argument '%s'.", reboot_arg);
- syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, reboot_arg);
- }
-
- log_info("Rebooting.");
- reboot(RB_AUTOBOOT);
- break;
-
- case FAILURE_ACTION_POWEROFF: {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-
- log_and_status(m, "Powering off as result of failure.");
-
- r = manager_add_job_by_name(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE, true, &error, NULL);
- if (r < 0)
- log_error("Failed to poweroff: %s.", bus_error_message(&error, r));
-
- break;
- }
-
- case FAILURE_ACTION_POWEROFF_FORCE:
- log_and_status(m, "Forcibly powering off as result of failure.");
- m->exit_code = MANAGER_POWEROFF;
- break;
-
- case FAILURE_ACTION_POWEROFF_IMMEDIATE:
- log_and_status(m, "Powering off immediately as result of failure.");
-
- sync();
-
- log_info("Powering off.");
- reboot(RB_POWER_OFF);
- break;
-
- default:
- assert_not_reached("Unknown failure action");
- }
-
- return -ECANCELED;
-}
-
-static const char* const failure_action_table[_FAILURE_ACTION_MAX] = {
- [FAILURE_ACTION_NONE] = "none",
- [FAILURE_ACTION_REBOOT] = "reboot",
- [FAILURE_ACTION_REBOOT_FORCE] = "reboot-force",
- [FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate",
- [FAILURE_ACTION_POWEROFF] = "poweroff",
- [FAILURE_ACTION_POWEROFF_FORCE] = "poweroff-force",
- [FAILURE_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate"
-};
-DEFINE_STRING_TABLE_LOOKUP(failure_action, FailureAction);
diff --git a/src/core/failure-action.h b/src/core/failure-action.h
deleted file mode 100644
index 1af4dd987..000000000
--- a/src/core/failure-action.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
- Copyright 2012 Michael Olbrich
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-typedef enum FailureAction {
- FAILURE_ACTION_NONE,
- FAILURE_ACTION_REBOOT,
- FAILURE_ACTION_REBOOT_FORCE,
- FAILURE_ACTION_REBOOT_IMMEDIATE,
- FAILURE_ACTION_POWEROFF,
- FAILURE_ACTION_POWEROFF_FORCE,
- FAILURE_ACTION_POWEROFF_IMMEDIATE,
- _FAILURE_ACTION_MAX,
- _FAILURE_ACTION_INVALID = -1
-} FailureAction;
-
-#include "macro.h"
-#include "manager.h"
-
-int failure_action(Manager *m, FailureAction action, const char *reboot_arg);
-
-const char* failure_action_to_string(FailureAction i) _const_;
-FailureAction failure_action_from_string(const char *s) _pure_;
diff --git a/src/core/hostname-setup.c b/src/core/hostname-setup.c
deleted file mode 100644
index 03b0ce3b4..000000000
--- a/src/core/hostname-setup.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include "hostname-setup.h"
-#include "macro.h"
-#include "util.h"
-#include "log.h"
-#include "fileio.h"
-
-static int read_and_strip_hostname(const char *path, char **hn) {
- char *s;
- int r;
-
- assert(path);
- assert(hn);
-
- r = read_one_line_file(path, &s);
- if (r < 0)
- return r;
-
- hostname_cleanup(s, false);
-
- if (isempty(s)) {
- free(s);
- return -ENOENT;
- }
-
- *hn = s;
- return 0;
-}
-
-int hostname_setup(void) {
- int r;
- _cleanup_free_ char *b = NULL;
- const char *hn;
- bool enoent = false;
-
- r = read_and_strip_hostname("/etc/hostname", &b);
- if (r < 0) {
- if (r == -ENOENT)
- enoent = true;
- else
- log_warning_errno(r, "Failed to read configured hostname: %m");
-
- hn = NULL;
- } else
- hn = b;
-
- if (isempty(hn)) {
- /* Don't override the hostname if it is already set
- * and not explicitly configured */
- if (hostname_is_set())
- return 0;
-
- if (enoent)
- log_info("No hostname configured.");
-
- hn = "localhost";
- }
-
- if (sethostname_idempotent(hn) < 0)
- return log_warning_errno(errno, "Failed to set hostname to <%s>: %m", hn);
-
- log_info("Set hostname to <%s>.", hn);
- return 0;
-}
diff --git a/src/core/hostname-setup.h b/src/core/hostname-setup.h
deleted file mode 100644
index 8dc3a9e1d..000000000
--- a/src/core/hostname-setup.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-int hostname_setup(void);
diff --git a/src/core/ima-setup.c b/src/core/ima-setup.c
deleted file mode 100644
index 7721b3eca..000000000
--- a/src/core/ima-setup.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
- Copyright (C) 2012 Roberto Sassu - Politecnico di Torino, Italy
- TORSEC group -- http://security.polito.it
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include "ima-setup.h"
-#include "copy.h"
-#include "util.h"
-#include "log.h"
-
-#define IMA_SECFS_DIR "/sys/kernel/security/ima"
-#define IMA_SECFS_POLICY IMA_SECFS_DIR "/policy"
-#define IMA_POLICY_PATH "/etc/ima/ima-policy"
-
-int ima_setup(void) {
- int r = 0;
-
-#ifdef HAVE_IMA
- _cleanup_close_ int policyfd = -1, imafd = -1;
-
- if (access(IMA_SECFS_DIR, F_OK) < 0) {
- log_debug("IMA support is disabled in the kernel, ignoring.");
- return 0;
- }
-
- policyfd = open(IMA_POLICY_PATH, O_RDONLY|O_CLOEXEC);
- if (policyfd < 0) {
- log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
- "Failed to open the IMA custom policy file "IMA_POLICY_PATH", ignoring: %m");
- return 0;
- }
-
- if (access(IMA_SECFS_POLICY, F_OK) < 0) {
- log_warning("Another IMA custom policy has already been loaded, ignoring.");
- return 0;
- }
-
- imafd = open(IMA_SECFS_POLICY, O_WRO