| <?xml version='1.0'?> <!--*-nxml-*--> |
| <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" |
| "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> |
| |
| <refentry id="kdbus.message"> |
| |
| <refentryinfo> |
| <title>kdbus.message</title> |
| <productname>kdbus.message</productname> |
| </refentryinfo> |
| |
| <refmeta> |
| <refentrytitle>kdbus.message</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </refmeta> |
| |
| <refnamediv> |
| <refname>kdbus.message</refname> |
| <refpurpose>kdbus message</refpurpose> |
| </refnamediv> |
| |
| <refsect1> |
| <title>Description</title> |
| |
| <para> |
| A kdbus message is used to exchange information between two connections |
| on a bus, or to transport notifications from the kernel to one or many |
| connections. This document describes the layout of messages, how payload |
| is added to them and how they are sent and received. |
| </para> |
| </refsect1> |
| |
| <refsect1> |
| <title>Message layout</title> |
| |
| <para>The layout of a message is shown below.</para> |
| |
| <programlisting> |
| +-------------------------------------------------------------------------+ |
| | Message | |
| | +---------------------------------------------------------------------+ | |
| | | Header | | |
| | | size: overall message size, including the data records | | |
| | | destination: connection ID of the receiver | | |
| | | source: connection ID of the sender (set by kernel) | | |
| | | payload_type: "DBusDBus" textual identifier stored as uint64_t | | |
| | +---------------------------------------------------------------------+ | |
| | +---------------------------------------------------------------------+ | |
| | | Data Record | | |
| | | size: overall record size (without padding) | | |
| | | type: type of data | | |
| | | data: reference to data (address or file descriptor) | | |
| | +---------------------------------------------------------------------+ | |
| | +---------------------------------------------------------------------+ | |
| | | padding bytes to the next 8 byte alignment | | |
| | +---------------------------------------------------------------------+ | |
| | +---------------------------------------------------------------------+ | |
| | | Data Record | | |
| | | size: overall record size (without padding) | | |
| | | ... | | |
| | +---------------------------------------------------------------------+ | |
| | +---------------------------------------------------------------------+ | |
| | | padding bytes to the next 8 byte alignment | | |
| | +---------------------------------------------------------------------+ | |
| | +---------------------------------------------------------------------+ | |
| | | Data Record | | |
| | | size: overall record size | | |
| | | ... | | |
| | +---------------------------------------------------------------------+ | |
| | ... further data records ... | |
| +-------------------------------------------------------------------------+ |
| </programlisting> |
| </refsect1> |
| |
| <refsect1> |
| <title>Message payload</title> |
| |
| <para> |
| When connecting to the bus, receivers request a memory pool of a given |
| size, large enough to carry all backlog of data enqueued for the |
| connection. The pool is internally backed by a shared memory file which |
| can be <function>mmap()</function>ed by the receiver. See |
| <citerefentry> |
| <refentrytitle>kdbus.pool</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| for more information. |
| </para> |
| |
| <para> |
| Message payload must be described in items attached to a message when |
| it is sent. A receiver can access the payload by looking at the items |
| that are attached to a message in its pool. The following items are used. |
| </para> |
| |
| <variablelist> |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_PAYLOAD_VEC</constant></term> |
| <listitem> |
| <para> |
| This item references a piece of memory on the sender side which is |
| directly copied into the receiver's pool. This way, two peers can |
| exchange data by effectively doing a single-copy from one process |
| to another; the kernel will not buffer the data anywhere else. |
| This item is never found in a message received by a connection. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_PAYLOAD_OFF</constant></term> |
| <listitem> |
| <para> |
| This item is attached to messages on the receiving side and points |
| to a memory area inside the receiver's pool. The |
| <varname>offset</varname> variable in the item denotes the memory |
| location relative to the message itself. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_PAYLOAD_MEMFD</constant></term> |
| <listitem> |
| <para> |
| Messages can reference <emphasis>memfd</emphasis> files which |
| contain the data. memfd files are tmpfs-backed files that allow |
| sealing of the content of the file, which prevents all writable |
| access to the file content. |
| </para> |
| <para> |
| Only memfds that have |
| <constant>(F_SEAL_SHRINK|F_SEAL_GROW|F_SEAL_WRITE|F_SEAL_SEAL) |
| </constant> |
| set are accepted as payload data, which enforces reliable passing of |
| data. The receiver can assume that neither the sender nor anyone |
| else can alter the content after the message is sent. If those |
| seals are not set on the memfd, the ioctl will fail with |
| <errorcode>-1</errorcode>, and <varname>errno</varname> will be |
| set to <constant>ETXTBUSY</constant>. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_FDS</constant></term> |
| <listitem> |
| <para> |
| Messages can transport regular file descriptors via |
| <constant>KDBUS_ITEM_FDS</constant>. This item carries an array |
| of <type>int</type> values in <varname>item.fd</varname>. The |
| maximum number of file descriptors in the item is |
| <constant>253</constant>, and only one item of this type is |
| accepted per message. All passed values must be valid file |
| descriptors; the open count of each file descriptors is increased |
| by installing it to the receiver's task. This item can only be |
| used for directed messages, not for broadcasts, and only to |
| remote peers that have opted-in for receiving file descriptors |
| at connection time (<constant>KDBUS_HELLO_ACCEPT_FD</constant>). |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| |
| <para> |
| The sender must not make any assumptions on the type in which data is |
| received by the remote peer. The kernel is free to re-pack multiple |
| <constant>KDBUS_ITEM_PAYLOAD_VEC</constant> and |
| <constant>KDBUS_ITEM_PAYLOAD_MEMFD</constant> payloads. For instance, the |
| kernel may decide to merge multiple <constant>VECs</constant> into a |
| single <constant>VEC</constant>, inline <constant>MEMFD</constant> |
| payloads into memory, or merge all passed <constant>VECs</constant> into a |
| single <constant>MEMFD</constant>. However, the kernel preserves the order |
| of passed data. This means that the order of all <constant>VEC</constant> |
| and <constant>MEMFD</constant> items is not changed in respect to each |
| other. In other words: All passed <constant>VEC</constant> and |
| <constant>MEMFD</constant> data payloads are treated as a single stream |
| of data that may be received by the remote peer in a different set of |
| chunks than it was sent as. |
| </para> |
| </refsect1> |
| |
| <refsect1> |
| <title>Sending messages</title> |
| |
| <para> |
| Messages are passed to the kernel with the |
| <constant>KDBUS_CMD_SEND</constant> ioctl. Depending on the destination |
| address of the message, the kernel delivers the message to the specific |
| destination connection, or to some subset of all connections on the same |
| bus. Sending messages across buses is not possible. Messages are always |
| queued in the memory pool of the destination connection (see above). |
| </para> |
| |
| <para> |
| The <constant>KDBUS_CMD_SEND</constant> ioctl uses a |
| <type>struct kdbus_cmd_send</type> to describe the message |
| transfer. |
| </para> |
| <programlisting> |
| struct kdbus_cmd_send { |
| __u64 size; |
| __u64 flags; |
| __u64 return_flags; |
| __u64 msg_address; |
| struct kdbus_msg_info reply; |
| struct kdbus_item items[0]; |
| }; |
| </programlisting> |
| |
| <para>The fields in this struct are described below.</para> |
| |
| <variablelist> |
| <varlistentry> |
| <term><varname>size</varname></term> |
| <listitem><para> |
| The overall size of the struct, including its items. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>flags</varname></term> |
| <listitem><para>Flags for message delivery</para> |
| <variablelist> |
| <varlistentry> |
| <term><constant>KDBUS_SEND_SYNC_REPLY</constant></term> |
| <listitem> |
| <para> |
| By default, all calls to kdbus are considered asynchronous, |
| non-blocking. However, as there are many use cases that need |
| to wait for a remote peer to answer a method call, there's a |
| way to send a message and wait for a reply in a synchronous |
| fashion. This is what the |
| <constant>KDBUS_SEND_SYNC_REPLY</constant> controls. The |
| <constant>KDBUS_CMD_SEND</constant> ioctl will block until the |
| reply has arrived, the timeout limit is reached, in case the |
| remote connection was shut down, or if interrupted by a signal |
| before any reply; see |
| <citerefentry> |
| <refentrytitle>signal</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry>. |
| |
| The offset of the reply message in the sender's pool is stored |
| in <varname>reply</varname> when the ioctl has returned without |
| error. Hence, there is no need for another |
| <constant>KDBUS_CMD_RECV</constant> ioctl or anything else to |
| receive the reply. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term> |
| <listitem> |
| <para> |
| Request a set of valid flags for this ioctl. When this bit is |
| set, no action is taken; the ioctl will fail with |
| <errorcode>-1</errorcode>, <varname>errno</varname> |
| is set to <constant>EPROTO</constant>. |
| Once the ioctl returned, the <varname>flags</varname> |
| field will have all bits set that the kernel recognizes as |
| valid for this command. |
| The <constant>KDBUS_FLAG_NEGOTIATE</constant> bit will be |
| cleared by the operation. |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>return_flags</varname></term> |
| <listitem><para> |
| Flags returned by the kernel. Currently unused and always set to |
| <constant>0</constant> by the kernel. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>msg_address</varname></term> |
| <listitem><para> |
| In this field, users have to provide a pointer to a message |
| (<type>struct kdbus_msg</type>) to send. See below for a |
| detailed description. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>reply</varname></term> |
| <listitem><para> |
| Only used for synchronous replies. See description of |
| <type>struct kdbus_cmd_recv</type> for more details. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>items</varname></term> |
| <listitem> |
| <para> |
| The following items are currently recognized. |
| </para> |
| <variablelist> |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_CANCEL_FD</constant></term> |
| <listitem> |
| <para> |
| When this optional item is passed in, and the call is |
| executed as SYNC call, the passed in file descriptor can be |
| used as alternative cancellation point. The kernel will call |
| <citerefentry> |
| <refentrytitle>poll</refentrytitle> |
| <manvolnum>2</manvolnum> |
| </citerefentry> |
| on this file descriptor, and once it reports any incoming |
| bytes, the blocking send operation will be canceled; the |
| blocking, synchronous ioctl call will return |
| <errorcode>-1</errorcode>, and <varname>errno</varname> will |
| be set to <errorname>ECANCELED</errorname>. |
| Any type of file descriptor on which |
| <citerefentry> |
| <refentrytitle>poll</refentrytitle> |
| <manvolnum>2</manvolnum> |
| </citerefentry> |
| can be called on can be used as payload to this item; for |
| example, an eventfd can be used for this purpose, see |
| <citerefentry> |
| <refentrytitle>eventfd</refentrytitle> |
| <manvolnum>2</manvolnum> |
| </citerefentry>. |
| For asynchronous message sending, this item is allowed but |
| ignored. |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| <para> |
| Unrecognized items are rejected, and the ioctl will fail with |
| <varname>errno</varname> set to <constant>EINVAL</constant>. |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| |
| <para> |
| The message referenced by the <varname>msg_address</varname> above has |
| the following layout. |
| </para> |
| |
| <programlisting> |
| struct kdbus_msg { |
| __u64 size; |
| __u64 flags; |
| __s64 priority; |
| __u64 dst_id; |
| __u64 src_id; |
| __u64 payload_type; |
| __u64 cookie; |
| __u64 timeout_ns; |
| __u64 cookie_reply; |
| struct kdbus_item items[0]; |
| }; |
| </programlisting> |
| |
| <para>The fields in this struct are described below.</para> |
| |
| <variablelist> |
| <varlistentry> |
| <term><varname>size</varname></term> |
| <listitem><para> |
| The overall size of the struct, including its items. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>flags</varname></term> |
| <listitem><para>Flags to describe message details.</para> |
| <variablelist> |
| <varlistentry> |
| <term><constant>KDBUS_MSG_EXPECT_REPLY</constant></term> |
| <listitem> |
| <para> |
| Expect a reply to this message from the remote peer. With |
| this bit set, the timeout_ns field must be set to a non-zero |
| number of nanoseconds in which the receiving peer is expected |
| to reply. If such a reply is not received in time, the sender |
| will be notified with a timeout message (see below). The |
| value must be an absolute value, in nanoseconds and based on |
| <constant>CLOCK_MONOTONIC</constant>. |
| </para><para> |
| For a message to be accepted as reply, it must be a direct |
| message to the original sender (not a broadcast and not a |
| signal message), and its |
| <varname>kdbus_msg.cookie_reply</varname> must match the |
| previous message's <varname>kdbus_msg.cookie</varname>. |
| </para><para> |
| Expected replies also temporarily open the policy of the |
| sending connection, so the other peer is allowed to respond |
| within the given time window. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_MSG_NO_AUTO_START</constant></term> |
| <listitem> |
| <para> |
| By default, when a message is sent to an activator |
| connection, the activator is notified and will start an |
| implementer. This flag inhibits that behavior. With this bit |
| set, and the remote being an activator, the ioctl will fail |
| with <varname>errno</varname> set to |
| <constant>EADDRNOTAVAIL</constant>. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term> |
| <listitem> |
| <para> |
| Requests a set of valid flags for this ioctl. When this bit is |
| set, no action is taken; the ioctl will return |
| <errorcode>0</errorcode>, and the <varname>flags</varname> |
| field will have all bits set that are valid for this command. |
| The <constant>KDBUS_FLAG_NEGOTIATE</constant> bit will be |
| cleared by the operation. |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>priority</varname></term> |
| <listitem><para> |
| The priority of this message. Receiving messages (see below) may |
| optionally be constrained to messages of a minimal priority. This |
| allows for use cases where timing critical data is interleaved with |
| control data on the same connection. If unused, the priority field |
| should be set to <constant>0</constant>. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>dst_id</varname></term> |
| <listitem><para> |
| The numeric ID of the destination connection, or |
| <constant>KDBUS_DST_ID_BROADCAST</constant> |
| (~0ULL) to address every peer on the bus, or |
| <constant>KDBUS_DST_ID_NAME</constant> (0) to look |
| it up dynamically from the bus' name registry. |
| In the latter case, an item of type |
| <constant>KDBUS_ITEM_DST_NAME</constant> is mandatory. |
| Also see |
| <citerefentry> |
| <refentrytitle>kdbus.name</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| . |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>src_id</varname></term> |
| <listitem><para> |
| Upon return of the ioctl, this member will contain the sending |
| connection's numerical ID. Should be 0 at send time. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>payload_type</varname></term> |
| <listitem><para> |
| Type of the payload in the actual data records. Currently, only |
| <constant>KDBUS_PAYLOAD_DBUS</constant> is accepted as input value |
| of this field. When receiving messages that are generated by the |
| kernel (notifications), this field will contain |
| <constant>KDBUS_PAYLOAD_KERNEL</constant>. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>cookie</varname></term> |
| <listitem><para> |
| Cookie of this message, for later recognition. Also, when replying |
| to a message (see above), the <varname>cookie_reply</varname> |
| field must match this value. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>timeout_ns</varname></term> |
| <listitem><para> |
| If the message sent requires a reply from the remote peer (see above), |
| this field contains the timeout in absolute nanoseconds based on |
| <constant>CLOCK_MONOTONIC</constant>. Also see |
| <citerefentry> |
| <refentrytitle>clock_gettime</refentrytitle> |
| <manvolnum>2</manvolnum> |
| </citerefentry>. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>cookie_reply</varname></term> |
| <listitem><para> |
| If the message sent is a reply to another message, this field must |
| match the cookie of the formerly received message. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>items</varname></term> |
| <listitem> |
| <para> |
| A dynamically sized list of items to contain additional information. |
| The following items are expected/valid: |
| </para> |
| <variablelist> |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_PAYLOAD_VEC</constant></term> |
| <term><constant>KDBUS_ITEM_PAYLOAD_MEMFD</constant></term> |
| <term><constant>KDBUS_ITEM_FDS</constant></term> |
| <listitem> |
| <para> |
| Actual data records containing the payload. See section |
| "Message payload". |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_BLOOM_FILTER</constant></term> |
| <listitem> |
| <para> |
| Bloom filter for matches (see below). |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_DST_NAME</constant></term> |
| <listitem> |
| <para> |
| Well-known name to send this message to. Required if |
| <varname>dst_id</varname> is set to |
| <constant>KDBUS_DST_ID_NAME</constant>. |
| If a connection holding the given name can't be found, |
| the ioctl will fail with <varname>errno</varname> set to |
| <constant>ESRCH</constant> is returned. |
| </para> |
| <para> |
| For messages to a unique name (ID), this item is optional. If |
| present, the kernel will make sure the name owner matches the |
| given unique name. This allows programs to tie the message |
| sending to the condition that a name is currently owned by a |
| certain unique name. |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| |
| <para> |
| The message will be augmented by the requested metadata items when |
| queued into the receiver's pool. See |
| <citerefentry> |
| <refentrytitle>kdbus.connection</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| and |
| <citerefentry> |
| <refentrytitle>kdbus.item</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| for more information on metadata. |
| </para> |
| </refsect1> |
| |
| <refsect1> |
| <title>Receiving messages</title> |
| |
| <para> |
| Messages are received by the client with the |
| <constant>KDBUS_CMD_RECV</constant> ioctl. The endpoint file of the bus |
| supports <function>poll()/epoll()/select()</function>; when new messages |
| are available on the connection's file descriptor, |
| <constant>POLLIN</constant> is reported. For compatibility reasons, |
| <constant>POLLOUT</constant> is always reported as well. Note, however, |
| that the latter does not guarantee that a message can in fact be sent, as |
| this depends on how many pending messages the receiver has in its pool. |
| </para> |
| |
| <para> |
| With the <constant>KDBUS_CMD_RECV</constant> ioctl, a |
| <type>struct kdbus_cmd_recv</type> is used. |
| </para> |
| |
| <programlisting> |
| struct kdbus_cmd_recv { |
| __u64 size; |
| __u64 flags; |
| __u64 return_flags; |
| __s64 priority; |
| __u64 dropped_msgs; |
| struct kdbus_msg_info msg; |
| struct kdbus_item items[0]; |
| }; |
| </programlisting> |
| |
| <para>The fields in this struct are described below.</para> |
| |
| <variablelist> |
| <varlistentry> |
| <term><varname>size</varname></term> |
| <listitem><para> |
| The overall size of the struct, including its items. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>flags</varname></term> |
| <listitem><para>Flags to control the receive command.</para> |
| <variablelist> |
| <varlistentry> |
| <term><constant>KDBUS_RECV_PEEK</constant></term> |
| <listitem> |
| <para> |
| Just return the location of the next message. Do not install |
| file descriptors or anything else. This is usually used to |
| determine the sender of the next queued message. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_RECV_DROP</constant></term> |
| <listitem> |
| <para> |
| Drop the next message without doing anything else with it, |
| and free the pool slice. This a short-cut for |
| <constant>KDBUS_RECV_PEEK</constant> and |
| <constant>KDBUS_CMD_FREE</constant>. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_RECV_USE_PRIORITY</constant></term> |
| <listitem> |
| <para> |
| Dequeue the messages ordered by their priority, and filtering |
| them with the priority field (see below). |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term> |
| <listitem> |
| <para> |
| Request a set of valid flags for this ioctl. When this bit is |
| set, no action is taken; the ioctl will fail with |
| <errorcode>-1</errorcode>, <varname>errno</varname> |
| is set to <constant>EPROTO</constant>. |
| Once the ioctl returned, the <varname>flags</varname> |
| field will have all bits set that the kernel recognizes as |
| valid for this command. |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>return_flags</varname></term> |
| <listitem><para> |
| Flags returned by the kernel. If the <varname>dropped_msgs</varname> |
| field is non-zero, <constant>KDBUS_RECV_RETURN_DROPPED_MSGS</constant> |
| is set. If a file descriptor could not be installed, the |
| <constant>KDBUS_RECV_RETURN_INCOMPLETE_FDS</constant> flag is set. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>priority</varname></term> |
| <listitem><para> |
| With <constant>KDBUS_RECV_USE_PRIORITY</constant> set in |
| <varname>flags</varname>, messages will be dequeued ordered by their |
| priority, starting with the highest value. Also, messages will be |
| filtered by the value given in this field, so the returned message |
| will at least have the requested priority. If no such message is |
| waiting in the queue, the ioctl will fail, and |
| <varname>errno</varname> will be set to <constant>EAGAIN</constant>. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>dropped_msgs</varname></term> |
| <listitem><para> |
| Whenever a message with <constant>KDBUS_MSG_SIGNAL</constant> is sent |
| but cannot be queued on a peer (e.g., as it contains FDs but the peer |
| does not support FDs, or there is no space left in the peer's pool) |
| the 'dropped_msgs' counter of the peer is incremented. On the next |
| RECV ioctl, the 'dropped_msgs' field is copied into the ioctl struct |
| and cleared on the peer. If it was non-zero, the |
| <constant>KDBUS_RECV_RETURN_DROPPED_MSGS</constant> flag will be set |
| in <varname>return_flags</varname>. Note that this will only happen |
| if the ioctl succeeded or failed with <constant>EAGAIN</constant>. In |
| other error cases, the 'dropped_msgs' field of the peer is left |
| untouched. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>msg</varname></term> |
| <listitem><para> |
| Embedded struct containing information on the received message when |
| this command succeeded (see below). |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>items</varname></term> |
| <listitem><para> |
| Items to specify further details for the receive command. |
| Currently unused, and all items will be rejected with |
| <varname>errno</varname> set to <constant>EINVAL</constant>. |
| </para></listitem> |
| </varlistentry> |
| </variablelist> |
| |
| <para> |
| Both <type>struct kdbus_cmd_recv</type> and |
| <type>struct kdbus_cmd_send</type> embed |
| <type>struct kdbus_msg_info</type>. |
| For the <constant>KDBUS_CMD_SEND</constant> ioctl, it is used to catch |
| synchronous replies, if one was requested, and is unused otherwise. |
| </para> |
| |
| <programlisting> |
| struct kdbus_msg_info { |
| __u64 offset; |
| __u64 msg_size; |
| __u64 return_flags; |
| }; |
| </programlisting> |
| |
| <para>The fields in this struct are described below.</para> |
| |
| <variablelist> |
| <varlistentry> |
| <term><varname>offset</varname></term> |
| <listitem><para> |
| Upon return of the ioctl, this field contains the offset in the |
| receiver's memory pool. The memory must be freed with |
| <constant>KDBUS_CMD_FREE</constant>. See |
| <citerefentry> |
| <refentrytitle>kdbus.pool</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| for further details. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>msg_size</varname></term> |
| <listitem><para> |
| Upon successful return of the ioctl, this field contains the size of |
| the allocated slice at offset <varname>offset</varname>. |
| It is the combination of the size of the stored |
| <type>struct kdbus_msg</type> object plus all appended VECs. |
| You can use it in combination with <varname>offset</varname> to map |
| a single message, instead of mapping the entire pool. See |
| <citerefentry> |
| <refentrytitle>kdbus.pool</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| for further details. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>return_flags</varname></term> |
| <listitem> |
| <para> |
| Kernel-provided return flags. Currently, the following flags are |
| defined. |
| </para> |
| <variablelist> |
| <varlistentry> |
| <term><constant>KDBUS_RECV_RETURN_INCOMPLETE_FDS</constant></term> |
| <listitem> |
| <para> |
| The message contained memfds or file descriptors, and the |
| kernel failed to install one or more of them at receive time. |
| Most probably that happened because the maximum number of |
| file descriptors for the receiver's task were exceeded. |
| In such cases, the message is still delivered, so this is not |
| a fatal condition. File descriptors numbers inside the |
| <constant>KDBUS_ITEM_FDS</constant> item or memfd files |
| referenced by <constant>KDBUS_ITEM_PAYLOAD_MEMFD</constant> |
| items which could not be installed will be set to |
| <constant>-1</constant>. |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| |
| <para> |
| Unless <constant>KDBUS_RECV_DROP</constant> was passed, the |
| <varname>offset</varname> field contains the location of the new message |
| inside the receiver's pool after the <constant>KDBUS_CMD_RECV</constant> |
| ioctl was employed. The message is stored as <type>struct kdbus_msg</type> |
| at this offset, and can be interpreted with the semantics described above. |
| </para> |
| <para> |
| Also, if the connection allowed for file descriptor to be passed |
| (<constant>KDBUS_HELLO_ACCEPT_FD</constant>), and if the message contained |
| any, they will be installed into the receiving process when the |
| <constant>KDBUS_CMD_RECV</constant> ioctl is called. |
| <emphasis>memfds</emphasis> may always be part of the message payload. |
| The receiving task is obliged to close all file descriptors appropriately |
| once no longer needed. If <constant>KDBUS_RECV_PEEK</constant> is set, no |
| file descriptors are installed. This allows for peeking at a message, |
| looking at its metadata only and dropping it via |
| <constant>KDBUS_RECV_DROP</constant>, without installing any of the file |
| descriptors into the receiving process. |
| </para> |
| <para> |
| The caller is obliged to call the <constant>KDBUS_CMD_FREE</constant> |
| ioctl with the returned offset when the memory is no longer needed. |
| </para> |
| </refsect1> |
| |
| <refsect1> |
| <title>Notifications</title> |
| <para> |
| A kernel notification is a regular kdbus message with the following |
| details. |
| </para> |
| |
| <itemizedlist> |
| <listitem><para> |
| kdbus_msg.src_id == <constant>KDBUS_SRC_ID_KERNEL</constant> |
| </para></listitem> |
| <listitem><para> |
| kdbus_msg.dst_id == <constant>KDBUS_DST_ID_BROADCAST</constant> |
| </para></listitem> |
| <listitem><para> |
| kdbus_msg.payload_type == <constant>KDBUS_PAYLOAD_KERNEL</constant> |
| </para></listitem> |
| <listitem><para> |
| Has exactly one of the items attached that are described below. |
| </para></listitem> |
| <listitem><para> |
| Always has a timestamp item (<constant>KDBUS_ITEM_TIMESTAMP</constant>) |
| attached. |
| </para></listitem> |
| </itemizedlist> |
| |
| <para> |
| The kernel will notify its users of the following events. |
| </para> |
| |
| <itemizedlist> |
| <listitem><para> |
| When connection <emphasis>A</emphasis> is terminated while connection |
| <emphasis>B</emphasis> is waiting for a reply from it, connection |
| <emphasis>B</emphasis> is notified with a message with an item of |
| type <constant>KDBUS_ITEM_REPLY_DEAD</constant>. |
| </para></listitem> |
| |
| <listitem><para> |
| When connection <emphasis>A</emphasis> does not receive a reply from |
| connection <emphasis>B</emphasis> within the specified timeout window, |
| connection <emphasis>A</emphasis> will receive a message with an |
| item of type <constant>KDBUS_ITEM_REPLY_TIMEOUT</constant>. |
| </para></listitem> |
| |
| <listitem><para> |
| When an ordinary connection (not a monitor) is created on or removed |
| from a bus, messages with an item of type |
| <constant>KDBUS_ITEM_ID_ADD</constant> or |
| <constant>KDBUS_ITEM_ID_REMOVE</constant>, respectively, are delivered |
| to all bus members that match these messages through their match |
| database. Eavesdroppers (monitor connections) do not cause such |
| notifications to be sent. They are invisible on the bus. |
| </para></listitem> |
| |
| <listitem><para> |
| When a connection gains or loses ownership of a name, messages with an |
| item of type <constant>KDBUS_ITEM_NAME_ADD</constant>, |
| <constant>KDBUS_ITEM_NAME_REMOVE</constant> or |
| <constant>KDBUS_ITEM_NAME_CHANGE</constant> are delivered to all bus |
| members that match these messages through their match database. |
| </para></listitem> |
| </itemizedlist> |
| </refsect1> |
| |
| <refsect1> |
| <title>Return value</title> |
| <para> |
| On success, all mentioned ioctl commands return <errorcode>0</errorcode>; |
| on error, <errorcode>-1</errorcode> is returned, and |
| <varname>errno</varname> is set to indicate the error. |
| If the issued ioctl is illegal for the file descriptor used, |
| <varname>errno</varname> will be set to <constant>ENOTTY</constant>. |
| </para> |
| |
| <refsect2> |
| <title> |
| <constant>KDBUS_CMD_SEND</constant> may fail with the following |
| errors |
| </title> |
| |
| <variablelist> |
| <varlistentry> |
| <term><constant>EOPNOTSUPP</constant></term> |
| <listitem><para> |
| The connection is not an ordinary connection, or the passed |
| file descriptors in <constant>KDBUS_ITEM_FDS</constant> item are |
| either kdbus handles or unix domain sockets. Both are currently |
| unsupported. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EINVAL</constant></term> |
| <listitem><para> |
| The submitted payload type is |
| <constant>KDBUS_PAYLOAD_KERNEL</constant>, |
| <constant>KDBUS_MSG_EXPECT_REPLY</constant> was set without timeout |
| or cookie values, <constant>KDBUS_SEND_SYNC_REPLY</constant> was |
| set without <constant>KDBUS_MSG_EXPECT_REPLY</constant>, an invalid |
| item was supplied, <constant>src_id</constant> was non-zero and was |
| different from the current connection's ID, a supplied memfd had a |
| size of 0, or a string was not properly null-terminated. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>ENOTUNIQ</constant></term> |
| <listitem><para> |
| The supplied destination is |
| <constant>KDBUS_DST_ID_BROADCAST</constant> and either |
| file descriptors were passed, or |
| <constant>KDBUS_MSG_EXPECT_REPLY</constant> was set, |
| or a timeout was given. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>E2BIG</constant></term> |
| <listitem><para> |
| Too many items. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EMSGSIZE</constant></term> |
| <listitem><para> |
| The size of the message header and items or the payload vector |
| is excessive. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EEXIST</constant></term> |
| <listitem><para> |
| Multiple <constant>KDBUS_ITEM_FDS</constant>, |
| <constant>KDBUS_ITEM_BLOOM_FILTER</constant> or |
| <constant>KDBUS_ITEM_DST_NAME</constant> items were supplied. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EBADF</constant></term> |
| <listitem><para> |
| The supplied <constant>KDBUS_ITEM_FDS</constant> or |
| <constant>KDBUS_ITEM_PAYLOAD_MEMFD</constant> items |
| contained an illegal file descriptor. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EMEDIUMTYPE</constant></term> |
| <listitem><para> |
| The supplied memfd is not a sealed kdbus memfd. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EMFILE</constant></term> |
| <listitem><para> |
| Too many file descriptors inside a |
| <constant>KDBUS_ITEM_FDS</constant>. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EBADMSG</constant></term> |
| <listitem><para> |
| An item had illegal size, both a <constant>dst_id</constant> and a |
| <constant>KDBUS_ITEM_DST_NAME</constant> was given, or both a name |
| and a bloom filter was given. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>ETXTBSY</constant></term> |
| <listitem><para> |
| The supplied kdbus memfd file cannot be sealed or the seal |
| was removed, because it is shared with other processes or |
| still mapped with |
| <citerefentry> |
| <refentrytitle>mmap</refentrytitle> |
| <manvolnum>2</manvolnum> |
| </citerefentry>. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>ECOMM</constant></term> |
| <listitem><para> |
| A peer does not accept the file descriptors addressed to it. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EFAULT</constant></term> |
| <listitem><para> |
| The supplied bloom filter size was not 64-bit aligned, or supplied |
| memory could not be accessed by the kernel. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EDOM</constant></term> |
| <listitem><para> |
| The supplied bloom filter size did not match the bloom filter |
| size of the bus. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EDESTADDRREQ</constant></term> |
| <listitem><para> |
| <constant>dst_id</constant> was set to |
| <constant>KDBUS_DST_ID_NAME</constant>, but no |
| <constant>KDBUS_ITEM_DST_NAME</constant> was attached. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>ESRCH</constant></term> |
| <listitem><para> |
| The name to look up was not found in the name registry. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EADDRNOTAVAIL</constant></term> |
| <listitem><para> |
| <constant>KDBUS_MSG_NO_AUTO_START</constant> was given but the |
| destination connection is an activator. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>ENXIO</constant></term> |
| <listitem><para> |
| The passed numeric destination connection ID couldn't be found, |
| or is not connected. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>ECONNRESET</constant></term> |
| <listitem><para> |
| The destination connection is no longer active. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>ETIMEDOUT</constant></term> |
| <listitem><para> |
| Timeout while synchronously waiting for a reply. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EINTR</constant></term> |
| <listitem><para> |
| Interrupted system call while synchronously waiting for a reply. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EPIPE</constant></term> |
| <listitem><para> |
| When sending a message, a synchronous reply from the receiving |
| connection was expected but the connection died before answering. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>ENOBUFS</constant></term> |
| <listitem><para> |
| Too many pending messages on the receiver side. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EREMCHG</constant></term> |
| <listitem><para> |
| Both a well-known name and a unique name (ID) was given, but |
| the name is not currently owned by that connection. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EXFULL</constant></term> |
| <listitem><para> |
| The memory pool of the receiver is full. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EREMOTEIO</constant></term> |
| <listitem><para> |
| While synchronously waiting for a reply, the remote peer |
| failed with an I/O error. |
| </para></listitem> |
| </varlistentry> |
| </variablelist> |
| </refsect2> |
| |
| <refsect2> |
| <title> |
| <constant>KDBUS_CMD_RECV</constant> may fail with the following |
| errors |
| </title> |
| |
| <variablelist> |
| <varlistentry> |
| <term><constant>EOPNOTSUPP</constant></term> |
| <listitem><para> |
| The connection is not an ordinary connection, or the passed |
| file descriptors are either kdbus handles or unix domain |
| sockets. Both are currently unsupported. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EINVAL</constant></term> |
| <listitem><para> |
| Invalid flags or offset. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EAGAIN</constant></term> |
| <listitem><para> |
| No message found in the queue. |
| </para></listitem> |
| </varlistentry> |
| </variablelist> |
| </refsect2> |
| </refsect1> |
| |
| <refsect1> |
| <title>See Also</title> |
| <simplelist type="inline"> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.bus</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.connection</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.endpoint</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.fs</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.item</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.name</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.pool</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>clock_gettime</refentrytitle> |
| <manvolnum>2</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>ioctl</refentrytitle> |
| <manvolnum>2</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>poll</refentrytitle> |
| <manvolnum>2</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>select</refentrytitle> |
| <manvolnum>2</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>epoll</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>eventfd</refentrytitle> |
| <manvolnum>2</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>memfd_create</refentrytitle> |
| <manvolnum>2</manvolnum> |
| </citerefentry> |
| </member> |
| </simplelist> |
| </refsect1> |
| </refentry> |