summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/special.h1
-rw-r--r--src/basic/unit-name.c15
-rw-r--r--src/basic/unit-name.h17
-rw-r--r--src/core/busname.h69
-rw-r--r--src/core/dbus-busname.c37
-rw-r--r--src/core/dbus-busname.h23
-rw-r--r--src/core/load-fragment-gperf.gperf.m49
-rw-r--r--src/core/load-fragment.c109
-rw-r--r--src/core/load-fragment.h3
-rw-r--r--src/core/meson.build4
-rw-r--r--src/core/unit.c1
-rw-r--r--src/core/unit.h2
-rw-r--r--src/systemctl/systemctl.c5
-rw-r--r--src/test/test-tables.c4
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);