]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-bus: make "close+flush-on-exit" optional when using sd-event with sd-bus
authorLennart Poettering <lennart@poettering.net>
Sat, 6 Oct 2018 16:43:28 +0000 (18:43 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 9 Nov 2018 16:08:59 +0000 (17:08 +0100)
This adds a new pair of API calls sd_bus_set_close_on_exit() and
sd_bus_get_close_on_exit(). They control whether an sd_bus object
attached to a an sd-event loop shall automatically be flushed/closed
when the event loop goes down. Usually that's a good thing, except for
very few cases where the bus connection is longer living than the event
loop it is attached on. Specifically, this is the case for nspawn, where
we run the event loop only while the container is up, but afterwards
still want to be able to use the bus connection.

man/rules/meson.build
man/sd-bus.xml
man/sd_bus_set_close_on_exit.xml [new file with mode: 0644]
src/libsystemd/libsystemd.sym
src/libsystemd/sd-bus/bus-internal.h
src/libsystemd/sd-bus/sd-bus.c
src/systemd/sd-bus.h

index b3011c5f04b186b03645e6b7ea8f5e765b7313a3..33301d4b6dd4bb6a8f06344e55232d0b61bda5c5 100644 (file)
@@ -289,6 +289,7 @@ manpages = [
    'sd_bus_release_name_async',
    'sd_bus_request_name_async'],
   ''],
+ ['sd_bus_set_close_on_exit', '3', ['sd_bus_get_close_on_exit'], ''],
  ['sd_bus_set_connected_signal', '3', ['sd_bus_get_connected_signal'], ''],
  ['sd_bus_set_description',
   '3',
index bf2f37a86d9e628e3bb6bf1a2ff73c3603bce9ca..1df988cf7aeb9fa96032e649effb45fb9a2f118c 100644 (file)
@@ -84,6 +84,7 @@
 <citerefentry><refentrytitle>sd_bus_set_description</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_set_sender</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_set_watch_bind</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+<citerefentry><refentrytitle>sd_bus_set_close_on_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>
 <citerefentry><refentrytitle>sd_bus_slot_set_description</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_slot_set_destroy_callback</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_slot_set_floating</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
diff --git a/man/sd_bus_set_close_on_exit.xml b/man/sd_bus_set_close_on_exit.xml
new file mode 100644 (file)
index 0000000..dc4f6a3
--- /dev/null
@@ -0,0 +1,105 @@
+<?xml version='1.0'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+-->
+
+<refentry id="sd_bus_set_close_on_exit"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>sd_bus_set_close_on_exit</title>
+    <productname>systemd</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_bus_set_close_on_exit</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_bus_set_close_on_exit</refname>
+    <refname>sd_bus_get_close_on_exit</refname>
+
+    <refpurpose>Control whether to close the bus connection during the event loop exit phase</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_set_close_on_exit</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+        <paramdef>int <parameter>b</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_get_close_on_exit</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+      </funcprototype>
+
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><function>sd_bus_set_close_on_exit()</function> may be used to enable or disable whether the bus connection
+    is automatically flushed (as in
+    <citerefentry><refentrytitle>sd_bus_flush</refentrytitle><manvolnum>3</manvolnum></citerefentry>) and closed (as in
+    <citerefentry><refentrytitle>sd_bus_close</refentrytitle><manvolnum>3</manvolnum></citerefentry>) during the exit
+    phase of the event loop. This logic only applies to bus connections that are attached to an
+    <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry> event loop, see
+    <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>. By default
+    this mechanism is enabled and makes sure that any pending messages that have not been written to the bus connection
+    are written out when the event loop is shutting down. In some cases this behaviour is not desirable, for example
+    when the bus connection shall remain usable until after the event loop exited. If <parameter>b</parameter> is
+    true, the feature is enabled (which is the default), otherwise disabled.</para>
+
+    <para><function>sd_bus_get_close_on_exit()</function> may be used to query the current setting of this feature. It
+    returns zero when the feature is disabled, and positive if enabled.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, <function>sd_bus_set_close_on_exit()</function> returns 0 or a positive integer. On failure, it returns a negative errno-style
+    error code.</para>
+
+    <para><function>sd_bus_get_close_on_exit()</function> returns 0 if the feature is currently turned off or a
+    positive integer if it is on. On failure, it returns a negative errno-style error code.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Errors</title>
+
+    <para>Returned errors may indicate the following problems:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><constant>-ECHILD</constant></term>
+
+        <listitem><para>The bus connection has been created in a different process.</para></listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <xi:include href="libsystemd-pkgconfig.xml" />
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_flush</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_event_add_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+
+</refentry>
index 1f2238ca37eb5470866e167e06dcc123c8da32ce..6a64b929dd3e704469bd7eb08888c864e62b37d3 100644 (file)
@@ -579,6 +579,9 @@ global:
 
         sd_bus_error_move;
 
+        sd_bus_set_close_on_exit;
+        sd_bus_get_close_on_exit;
+
         sd_device_ref;
         sd_device_unref;
 
index 55f2bc36fb2686a999e692e2f0f7e0841c3b4ffc..4bc945d9eea39be571dc4eaba45a39224be9efd4 100644 (file)
@@ -211,6 +211,7 @@ struct sd_bus {
         bool accept_fd:1;
         bool attach_timestamp:1;
         bool connected_signal:1;
+        bool close_on_exit:1;
 
         int use_memfd;
 
index bc7d00c3d045b16be0e5dec5ca094eb60456adaa..f086d13898f285a94b1c3e4073c678eec0e3ff1e 100644 (file)
@@ -232,18 +232,22 @@ _public_ int sd_bus_new(sd_bus **ret) {
 
         assert_return(ret, -EINVAL);
 
-        b = new0(sd_bus, 1);
+        b = new(sd_bus, 1);
         if (!b)
                 return -ENOMEM;
 
-        b->n_ref = REFCNT_INIT;
-        b->input_fd = b->output_fd = -1;
-        b->inotify_fd = -1;
-        b->message_version = 1;
-        b->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
-        b->accept_fd = true;
-        b->original_pid = getpid_cached();
-        b->n_groups = (size_t) -1;
+        *b = (sd_bus) {
+                .n_ref = REFCNT_INIT,
+                .input_fd = -1,
+                .output_fd = -1,
+                .inotify_fd = -1,
+                .message_version = 1,
+                .creds_mask = SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME,
+                .accept_fd = true,
+                .original_pid = getpid_cached(),
+                .n_groups = (size_t) -1,
+                .close_on_exit = true,
+        };
 
         assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0);
 
@@ -3409,8 +3413,10 @@ static int quit_callback(sd_event_source *event, void *userdata) {
 
         assert(event);
 
-        sd_bus_flush(bus);
-        sd_bus_close(bus);
+        if (bus->close_on_exit) {
+                sd_bus_flush(bus);
+                sd_bus_close(bus);
+        }
 
         return 1;
 }
@@ -4135,3 +4141,18 @@ _public_ int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret) {
         *ret = bus->method_call_timeout = BUS_DEFAULT_TIMEOUT;
         return 0;
 }
+
+_public_ int sd_bus_set_close_on_exit(sd_bus *bus, int b) {
+        assert_return(bus, -EINVAL);
+        assert_return(bus = bus_resolve(bus), -ENOPKG);
+
+        bus->close_on_exit = b;
+        return 0;
+}
+
+_public_ int sd_bus_get_close_on_exit(sd_bus *bus) {
+        assert_return(bus, -EINVAL);
+        assert_return(bus = bus_resolve(bus), -ENOPKG);
+
+        return bus->close_on_exit;
+}
index 9c4bbed9dcfa6624b7814d927afd9660d161d735..220ddb99eceecf28ac5b60c43897b71dc5e83270 100644 (file)
@@ -154,6 +154,8 @@ int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b);
 int sd_bus_get_allow_interactive_authorization(sd_bus *bus);
 int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b);
 int sd_bus_get_exit_on_disconnect(sd_bus *bus);
+int sd_bus_set_close_on_exit(sd_bus *bus, int b);
+int sd_bus_get_close_on_exit(sd_bus *bus);
 int sd_bus_set_watch_bind(sd_bus *bus, int b);
 int sd_bus_get_watch_bind(sd_bus *bus);
 int sd_bus_set_connected_signal(sd_bus *bus, int b);