diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/special.h | 1 | ||||
-rw-r--r-- | src/basic/unit-name.c | 15 | ||||
-rw-r--r-- | src/basic/unit-name.h | 17 | ||||
-rw-r--r-- | src/core/busname.h | 69 | ||||
-rw-r--r-- | src/core/dbus-busname.c | 37 | ||||
-rw-r--r-- | src/core/dbus-busname.h | 23 | ||||
-rw-r--r-- | src/core/load-fragment-gperf.gperf.m4 | 9 | ||||
-rw-r--r-- | src/core/load-fragment.c | 109 | ||||
-rw-r--r-- | src/core/load-fragment.h | 3 | ||||
-rw-r--r-- | src/core/meson.build | 4 | ||||
-rw-r--r-- | src/core/unit.c | 1 | ||||
-rw-r--r-- | src/core/unit.h | 2 | ||||
-rw-r--r-- | src/systemctl/systemctl.c | 5 | ||||
-rw-r--r-- | src/test/test-tables.c | 4 |
14 files changed, 299 insertions, 0 deletions
diff --git a/src/basic/special.h b/src/basic/special.h index 012ac8d9c2..48b36de557 100644 --- a/src/basic/special.h +++ b/src/basic/special.h @@ -46,6 +46,7 @@ /* Early boot targets */ #define SPECIAL_SYSINIT_TARGET "sysinit.target" #define SPECIAL_SOCKETS_TARGET "sockets.target" +#define SPECIAL_BUSNAMES_TARGET "busnames.target" #define SPECIAL_TIMERS_TARGET "timers.target" #define SPECIAL_PATHS_TARGET "paths.target" #define SPECIAL_LOCAL_FS_TARGET "local-fs.target" diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c index f9c034c94b..0be9859f8f 100644 --- a/src/basic/unit-name.c +++ b/src/basic/unit-name.c @@ -608,6 +608,7 @@ const char* unit_dbus_interface_from_type(UnitType t) { static const char *const table[_UNIT_TYPE_MAX] = { [UNIT_SERVICE] = "org.freedesktop.systemd1.Service", [UNIT_SOCKET] = "org.freedesktop.systemd1.Socket", + [UNIT_BUSNAME] = "org.freedesktop.systemd1.BusName", [UNIT_TARGET] = "org.freedesktop.systemd1.Target", [UNIT_DEVICE] = "org.freedesktop.systemd1.Device", [UNIT_MOUNT] = "org.freedesktop.systemd1.Mount", @@ -838,6 +839,7 @@ bool slice_name_is_valid(const char *name) { static const char* const unit_type_table[_UNIT_TYPE_MAX] = { [UNIT_SERVICE] = "service", [UNIT_SOCKET] = "socket", + [UNIT_BUSNAME] = "busname", [UNIT_TARGET] = "target", [UNIT_DEVICE] = "device", [UNIT_MOUNT] = "mount", @@ -882,6 +884,19 @@ static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = { DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState); +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 device_state_table[_DEVICE_STATE_MAX] = { [DEVICE_DEAD] = "dead", [DEVICE_TENTATIVE] = "tentative", diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h index 15558b4fbd..0a20aae9cb 100644 --- a/src/basic/unit-name.h +++ b/src/basic/unit-name.h @@ -28,6 +28,7 @@ typedef enum UnitType { UNIT_SERVICE = 0, UNIT_SOCKET, + UNIT_BUSNAME, UNIT_TARGET, UNIT_DEVICE, UNIT_MOUNT, @@ -72,6 +73,19 @@ typedef enum AutomountState { _AUTOMOUNT_STATE_INVALID = -1 } AutomountState; +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; + /* We simply watch devices, we cannot plug/unplug them. That * simplifies the state engine greatly */ typedef enum DeviceState { @@ -321,6 +335,9 @@ UnitActiveState unit_active_state_from_string(const char *s) _pure_; const char* automount_state_to_string(AutomountState i) _const_; AutomountState automount_state_from_string(const char *s) _pure_; +const char* busname_state_to_string(BusNameState i) _const_; +BusNameState busname_state_from_string(const char *s) _pure_; + const char* device_state_to_string(DeviceState i) _const_; DeviceState device_state_from_string(const char *s) _pure_; diff --git a/src/core/busname.h b/src/core/busname.h new file mode 100644 index 0000000000..a8562db458 --- /dev/null +++ b/src/core/busname.h @@ -0,0 +1,69 @@ +#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; + +#include "unit.h" +#include "bus-policy.h" + +typedef enum BusNameResult { + BUSNAME_SUCCESS, + BUSNAME_FAILURE_RESOURCES, + BUSNAME_FAILURE_TIMEOUT, + BUSNAME_FAILURE_EXIT_CODE, + BUSNAME_FAILURE_SIGNAL, + BUSNAME_FAILURE_CORE_DUMP, + BUSNAME_FAILURE_START_LIMIT_HIT, + BUSNAME_FAILURE_SERVICE_START_LIMIT_HIT, + _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_result_to_string(BusNameResult i) _const_; +BusNameResult busname_result_from_string(const char *s) _pure_; diff --git a/src/core/dbus-busname.c b/src/core/dbus-busname.c new file mode 100644 index 0000000000..cf816ba15b --- /dev/null +++ b/src/core/dbus-busname.c @@ -0,0 +1,37 @@ +/*** + 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 "busname.h" +#include "dbus-busname.h" +#include "string-util.h" +#include "unit.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 new file mode 100644 index 0000000000..8643d1a404 --- /dev/null +++ b/src/core/dbus-busname.h @@ -0,0 +1,23 @@ +#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/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 0e87e8d29e..f8a0724b61 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -370,6 +370,15 @@ EXEC_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl CGROUP_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl KILL_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl m4_dnl +BusName.Name, config_parse_string, 0, offsetof(BusName, name) +BusName.Activating, config_parse_bool, 0, offsetof(BusName, activating) +BusName.Service, config_parse_busname_service, 0, 0 +BusName.AllowUser, config_parse_bus_policy, 0, 0 +BusName.AllowGroup, config_parse_bus_policy, 0, 0 +BusName.AllowWorld, config_parse_bus_policy_world, 0, offsetof(BusName, policy_world) +BusName.SELinuxContext, config_parse_exec_selinux_context, 0, 0 +BusName.AcceptFileDescriptors, config_parse_bool, 0, offsetof(BusName, accept_fd) +m4_dnl Mount.What, config_parse_unit_string_printf, 0, offsetof(Mount, parameters_fragment.what) Mount.Where, config_parse_path, 0, offsetof(Mount, where) Mount.Options, config_parse_unit_string_printf, 0, offsetof(Mount, parameters_fragment.options) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 61dd1d632b..43991db634 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2027,6 +2027,115 @@ int config_parse_user_group_strv( return 0; } +int config_parse_busname_service( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + BusName *n = data; + int r; + Unit *x; + _cleanup_free_ char *p = NULL; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + r = unit_name_printf(UNIT(n), rvalue, &p); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue); + return 0; + } + + if (!endswith(p, ".service")) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Unit must be of type service, ignoring: %s", rvalue); + return 0; + } + + r = manager_load_unit(UNIT(n)->manager, p, NULL, &error, &x); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r)); + return 0; + } + + unit_ref_set(&n->service, x); + + return 0; +} + +DEFINE_CONFIG_PARSE_ENUM(config_parse_bus_policy_world, bus_policy_access, BusPolicyAccess, "Failed to parse bus name policy access"); + +int config_parse_bus_policy( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_free_ BusNamePolicy *p = NULL; + _cleanup_free_ char *id_str = NULL; + BusName *busname = data; + char *access_str; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + p = new0(BusNamePolicy, 1); + if (!p) + return log_oom(); + + if (streq(lvalue, "AllowUser")) + p->type = BUSNAME_POLICY_TYPE_USER; + else if (streq(lvalue, "AllowGroup")) + p->type = BUSNAME_POLICY_TYPE_GROUP; + else + assert_not_reached("Unknown lvalue"); + + id_str = strdup(rvalue); + if (!id_str) + return log_oom(); + + access_str = strpbrk(id_str, WHITESPACE); + if (!access_str) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid busname policy value '%s'", rvalue); + return 0; + } + + *access_str = '\0'; + access_str++; + access_str += strspn(access_str, WHITESPACE); + + p->access = bus_policy_access_from_string(access_str); + if (p->access < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid busname policy access type '%s'", access_str); + return 0; + } + + p->name = id_str; + id_str = NULL; + + LIST_PREPEND(policy, busname->policy, p); + p = NULL; + + return 0; +} + int config_parse_working_directory( const char *unit, const char *filename, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index 2473b6f005..7d8c4ffa68 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -66,6 +66,9 @@ int config_parse_trigger_unit(const char *unit, const char *filename, unsigned l int config_parse_path_spec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_socket_service(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_service_sockets(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_busname_service(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_bus_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_bus_policy_world(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_unit_env_file(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_ip_tos(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_unit_condition_path(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/core/meson.build b/src/core/meson.build index 7bffe27c57..5ff69214db 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -7,12 +7,16 @@ libcore_la_sources = ''' bpf-firewall.h bus-policy.c bus-policy.h + busname.c + busname.h cgroup.c cgroup.h chown-recursive.c chown-recursive.h dbus-automount.c dbus-automount.h + dbus-busname.c + dbus-busname.h dbus-cgroup.c dbus-cgroup.h dbus-device.c diff --git a/src/core/unit.c b/src/core/unit.c index 357306dce8..7e769eb646 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -65,6 +65,7 @@ const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = { [UNIT_SERVICE] = &service_vtable, [UNIT_SOCKET] = &socket_vtable, + [UNIT_BUSNAME] = &busname_vtable, [UNIT_TARGET] = &target_vtable, [UNIT_DEVICE] = &device_vtable, [UNIT_MOUNT] = &mount_vtable, diff --git a/src/core/unit.h b/src/core/unit.h index ded0edc8e2..cbcd1b0593 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -302,6 +302,7 @@ typedef enum UnitSetPropertiesMode { } UnitSetPropertiesMode; #include "automount.h" +#include "busname.h" #include "device.h" #include "path.h" #include "scope.h" @@ -496,6 +497,7 @@ extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX]; DEFINE_CAST(SERVICE, Service); DEFINE_CAST(SOCKET, Socket); +DEFINE_CAST(BUSNAME, BusName); DEFINE_CAST(TARGET, Target); DEFINE_CAST(DEVICE, Device); DEFINE_CAST(MOUNT, Mount); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 933cb92134..5b83f27394 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -7352,6 +7352,11 @@ static void help_states(void) { puts(automount_state_to_string(i)); if (!arg_no_legend) + puts("\nAvailable busname unit substates:"); + for (i = 0; i < _BUSNAME_STATE_MAX; i++) + puts(busname_state_to_string(i)); + + if (!arg_no_legend) puts("\nAvailable device unit substates:"); for (i = 0; i < _DEVICE_STATE_MAX; i++) puts(device_state_to_string(i)); diff --git a/src/test/test-tables.c b/src/test/test-tables.c index a16b04dbd2..294d219869 100644 --- a/src/test/test-tables.c +++ b/src/test/test-tables.c @@ -19,6 +19,7 @@ #include "architecture.h" #include "automount.h" +#include "busname.h" #include "cgroup.h" #include "compress.h" #include "condition.h" @@ -53,6 +54,9 @@ int main(int argc, char **argv) { test_table(architecture, ARCHITECTURE); test_table(automount_result, AUTOMOUNT_RESULT); test_table(automount_state, AUTOMOUNT_STATE); + test_table(bus_policy_access, BUS_POLICY_ACCESS); + test_table(busname_result, BUSNAME_RESULT); + test_table(busname_state, BUSNAME_STATE); test_table(cgroup_device_policy, CGROUP_DEVICE_POLICY); test_table(condition_type, CONDITION_TYPE); test_table(assert_type, CONDITION_TYPE); |