chiark / gitweb /
busname: introduce Activating directive
authorDaniel Mack <zonque@gmail.com>
Mon, 17 Mar 2014 10:41:21 +0000 (11:41 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 19 Mar 2014 01:25:36 +0000 (02:25 +0100)
Add a new config 'Activating' directive which denotes whether a busname
is actually registered on the bus. It defaults to 'yes'.

If set to 'no', the .busname unit only uploads policy, which will remain
active as long as the unit is running.

Makefile.am
src/core/busname.c
src/core/busname.h
src/core/load-fragment-gperf.gperf.m4
src/libsystemd/sd-bus/bus-kernel.c
src/libsystemd/sd-bus/bus-kernel.h
units/org.freedesktop.systemd1.busname [new file with mode: 0644]

index f0cfe46e766820c2398c8dc14959e810b6dc7d4f..65a7ffeb2720ea440f6ce6c16843597701b894e5 100644 (file)
@@ -3851,10 +3851,12 @@ nodist_systemunit_DATA += \
        units/systemd-bus-driverd.service
 
 dist_systemunit_DATA += \
-       units/org.freedesktop.DBus.busname
+       units/org.freedesktop.DBus.busname      \
+       units/org.freedesktop.systemd1.busname
 
 BUSNAMES_TARGET_WANTS += \
-       org.freedesktop.DBus.busname
+       org.freedesktop.DBus.busname    \
+       org.freedesktop.systemd1.busname
 
 nodist_userunit_DATA += \
        units/user/systemd-bus-driverd.service
index ccef32e9e7daea96536399d01be4da73939cd104..0cae20d2d1b146c32276b91b0c4f89cf0ec649db 100644 (file)
@@ -29,6 +29,7 @@
 
 static const UnitActiveState state_translation_table[_BUSNAME_STATE_MAX] = {
         [BUSNAME_DEAD] = UNIT_INACTIVE,
+        [BUSNAME_REGISTERED] = UNIT_ACTIVE,
         [BUSNAME_LISTENING] = UNIT_ACTIVE,
         [BUSNAME_RUNNING] = UNIT_ACTIVE,
         [BUSNAME_FAILED] = UNIT_FAILED
@@ -96,20 +97,22 @@ static int busname_add_extras(BusName *n) {
                         return r;
         }
 
-        if (!UNIT_DEREF(n->service)) {
-                Unit *x;
+        if (n->activating) {
+                if (!UNIT_DEREF(n->service)) {
+                        Unit *x;
 
-                r = unit_load_related_unit(u, ".service", &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;
-
-                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)
@@ -172,10 +175,12 @@ static void busname_dump(Unit *u, FILE *f, const char *prefix) {
                 "%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));
 }
 
@@ -231,7 +236,7 @@ static int busname_open_fd(BusName *n) {
 
         n->starter_fd = bus_kernel_create_starter(
                         UNIT(n)->manager->running_as == SYSTEMD_SYSTEM ? "system" : "user",
-                        n->name, n->accept_fd, n->policy);
+                        n->name, n->activating, n->accept_fd, n->policy);
 
         if (n->starter_fd < 0) {
                 log_warning_unit(UNIT(n)->id, "Failed to create starter fd: %s", strerror(-n->starter_fd));
@@ -251,7 +256,7 @@ static void busname_set_state(BusName *n, BusNameState state) {
         if (state != BUSNAME_LISTENING)
                 busname_unwatch_fd(n);
 
-        if (!IN_SET(state, BUSNAME_LISTENING, BUSNAME_RUNNING))
+        if (!IN_SET(state, BUSNAME_LISTENING, BUSNAME_REGISTERED, BUSNAME_RUNNING))
                 busname_close_fd(n);
 
         if (state != old_state)
@@ -271,7 +276,7 @@ static int busname_coldplug(Unit *u) {
         if (n->deserialized_state == n->state)
                 return 0;
 
-        if (IN_SET(n->deserialized_state, BUSNAME_LISTENING, BUSNAME_RUNNING)) {
+        if (IN_SET(n->deserialized_state, BUSNAME_LISTENING, BUSNAME_REGISTERED, BUSNAME_RUNNING)) {
                 r = busname_open_fd(n);
                 if (r < 0)
                         return r;
@@ -303,17 +308,23 @@ static void busname_enter_listening(BusName *n) {
 
         r = busname_open_fd(n);
         if (r < 0) {
-                log_warning_unit(UNIT(n)->id, "%s failed to listen on bus names: %s", UNIT(n)->id, strerror(-r));
+                log_warning_unit(UNIT(n)->id, "%s failed to %s: %s", UNIT(n)->id,
+                                 n->activating ? "listen on bus name" : "register policy for name",
+                                 strerror(-r));
                 goto fail;
         }
 
-        r = busname_watch_fd(n);
-        if (r < 0) {
-                log_warning_unit(UNIT(n)->id, "%s failed to watch names: %s", UNIT(n)->id, strerror(-r));
-                goto fail;
-        }
+        if (n->activating) {
+                r = busname_watch_fd(n);
+                if (r < 0) {
+                        log_warning_unit(UNIT(n)->id, "%s failed to watch names: %s", UNIT(n)->id, strerror(-r));
+                        goto fail;
+                }
+
+                busname_set_state(n, BUSNAME_LISTENING);
+        } else
+                busname_set_state(n, BUSNAME_REGISTERED);
 
-        busname_set_state(n, BUSNAME_LISTENING);
         return;
 
 fail:
@@ -329,6 +340,9 @@ static void busname_enter_running(BusName *n) {
 
         assert(n);
 
+        if (!n->activating)
+                return;
+
         /* We don't take conenctions anymore if we are supposed to
          * shut down anyway */
 
@@ -369,7 +383,7 @@ static int busname_start(Unit *u) {
 
         assert(n);
 
-        if (UNIT_ISSET(n->service)) {
+        if (n->activating && UNIT_ISSET(n->service)) {
                 Service *service;
 
                 service = SERVICE(UNIT_DEREF(n->service));
@@ -392,7 +406,7 @@ static int busname_stop(Unit *u) {
         BusName *n = BUSNAME(u);
 
         assert(n);
-        assert(n->state == BUSNAME_LISTENING || n->state == BUSNAME_RUNNING);
+        assert(IN_SET(n->state, BUSNAME_REGISTERED, BUSNAME_LISTENING, BUSNAME_RUNNING));
 
         busname_enter_dead(n, BUSNAME_SUCCESS);
         return 0;
@@ -536,6 +550,7 @@ static void busname_trigger_notify(Unit *u, Unit *other) {
 
 static const char* const busname_state_table[_BUSNAME_STATE_MAX] = {
         [BUSNAME_DEAD] = "dead",
+        [BUSNAME_REGISTERED] = "registered",
         [BUSNAME_LISTENING] = "listening",
         [BUSNAME_RUNNING] = "running",
         [BUSNAME_FAILED] = "failed"
index 7f591974de03cbe0e4c28be8d4df8c40b0f6234c..0009c6a65e2330d40c99b34f6783b9e446110600 100644 (file)
@@ -28,6 +28,7 @@ typedef struct BusNamePolicy BusNamePolicy;
 
 typedef enum BusNameState {
         BUSNAME_DEAD,
+        BUSNAME_REGISTERED,
         BUSNAME_LISTENING,
         BUSNAME_RUNNING,
         BUSNAME_FAILED,
@@ -48,6 +49,7 @@ struct BusName {
 
         char *name;
         int starter_fd;
+        bool activating;
 
         UnitRef service;
 
index c793a1e25f361baba0fb572d6e5f8e5a86b43073..1dd9f2b909182f0199ce7f0895b0d6f79ac24fde 100644 (file)
@@ -251,6 +251,7 @@ 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
index 977a7cda408dde75fac04c047781a37201fb9319..00f58114ac3cdc0a08ebf1e6bf961aa7ab6af3ee 100644 (file)
@@ -1378,7 +1378,7 @@ static void bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbu
         }
 }
 
-int bus_kernel_create_starter(const char *bus, const char *name, bool accept_fd, BusNamePolicy *policy) {
+int bus_kernel_create_starter(const char *bus, const char *name, bool activating, bool accept_fd, BusNamePolicy *policy) {
         struct kdbus_cmd_hello *hello;
         struct kdbus_item *n;
         size_t policy_cnt = 0;
@@ -1420,7 +1420,9 @@ int bus_kernel_create_starter(const char *bus, const char *name, bool accept_fd,
         }
 
         hello->size = size;
-        hello->conn_flags = KDBUS_HELLO_ACTIVATOR | (accept_fd ? KDBUS_HELLO_ACCEPT_FD : 0);
+        hello->conn_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 = _KDBUS_ATTACH_ALL;
 
index 3a9794fbe3384351a195c8283f8569598d67e1a4..4ef26fce6476665eb402b24f36b0b9038e1a3663 100644 (file)
@@ -67,7 +67,7 @@ int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority);
 
 int bus_kernel_create_bus(const char *name, bool world, char **s);
 int bus_kernel_create_domain(const char *name, char **s);
-int bus_kernel_create_starter(const char *bus, const char *name, bool accept_fd, BusNamePolicy *policy);
+int bus_kernel_create_starter(const char *bus, const char *name, bool activating, bool accept_fd, BusNamePolicy *policy);
 int bus_kernel_create_monitor(const char *bus);
 
 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated);
diff --git a/units/org.freedesktop.systemd1.busname b/units/org.freedesktop.systemd1.busname
new file mode 100644 (file)
index 0000000..3020f1a
--- /dev/null
@@ -0,0 +1,15 @@
+#  This file is part of systemd.
+#
+#  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.
+
+[Unit]
+Description=systemd busname unit
+Documentation=man:systemd-hostnamed.service(8)
+Documentation=http://www.freedesktop.org/wiki/Software/systemd
+
+[BusName]
+Activating=no
+AllowWorld=talk