D-Bus
D-Bus (short for "Desktop Bus"[4]) is a message-oriented middleware mechanism that allows communication between multiple processes running concurrently on the same machine.[5][6] D-Bus was developed as part of the freedesktop.org project, initiated by GNOME developer Havoc Pennington to standardize services provided by Linux desktop environments such as GNOME and KDE.[7][8]
"DBus" redirects here. For the Tibetan province, see Dbus.Developer(s)
The freedesktop.org project also developed a free and open-source software library called libdbus, as a reference implementation of the specification. This library should not be confused with D-Bus itself, as other implementations of the D-Bus specification also exist, such as GDBus (GNOME),[9] QtDBus (Qt/KDE),[10] dbus-java[11] and sd-bus (part of systemd).[12]
D-Bus is an inter-process communication (IPC) mechanism initially designed to replace the software component communications systems used by the GNOME and KDE Linux desktop environments (CORBA and DCOP respectively).[13][14] The components of these desktop environments are normally distributed in many processes, each one providing only a few—usually one—services. These services may be used by regular client applications or by other components of the desktop environment to perform their tasks.[15]
Due to the large number of processes involved—adding up processes providing the services and clients accessing them—establishing one-to-one IPC between all of them becomes an inefficient and quite unreliable approach. Instead, D-Bus provides a software-bus abstraction that gathers all the communications between a group of processes over a single shared virtual channel.[6] Processes connected to a bus do not know how it is internally implemented, but D-Bus specification guarantees that all processes connected to the bus can communicate with each other through it.
Linux desktop environments take advantage of the D-Bus facilities by instantiating multiple buses, notably:[16][6][17]
A process can connect to any number of buses, provided that it has been granted access to them. In practice, this means that any user process can connect to the system bus and to its current session bus, but not to another user's session buses, or even to a different session bus owned by the same user. The latter restriction may change in the future if all user sessions are combined into a single user bus.[18]
D-Bus provides additional or simplifies existing functionality to the applications, including information-sharing, modularity and privilege separation. For example, information on an incoming voice-call received through Bluetooth or Skype can be propagated and interpreted by any currently-running music player, which can react by muting the volume or by pausing playback until the call is finished.[19]
D-Bus can also be used as a framework to integrate different components of a user application. For instance, an office suite can communicate through the session bus to share data between a word processor and a spreadsheet.
D-Bus specification[edit]
Bus model[edit]
Every connection to a bus is identified in the context of D-Bus by what is called a bus name.[5] A bus name consists of two or more dot-separated strings of letters, digits, dashes, and underscores. An example of a valid bus name is org.freedesktop.NetworkManager
.[6]
When a process sets up a connection to a bus, the bus assigns to the connection a special bus name called unique connection name.[17][6] Bus names of this type are immutable—it is guaranteed they will not change as long as the connection exists—and, more importantly, they cannot be reused during the bus lifetime.[5][17][6] This means that no other connection to that bus will ever have assigned such unique connection name, even if the same process closes down the connection to the bus and creates a new one. Unique connection names are easily recognizable because they start with the otherwise forbidden colon character.[17][6] An example of a unique connection name is :1.1553
(the characters after the colon have no particular meaning[17]).
A process can ask for additional bus names for its connection,[17] provided that any requested name is not already being used by another connection to the bus. In D-Bus parlance, when a bus name is assigned to a connection, it is said the connection owns the bus name.[5][17] In that sense, a bus name cannot be owned by two connections at the same time, but, unlike unique connection names, these names can be reused if they are available: a process may reclaim a bus name released—purposely or not—by another process.[5][6]
The idea behind these additional bus names, commonly called well-known names, is to provide a way to refer to a service using a prearranged bus name.[17][6] For instance, the service that reports the current time and date in the system bus lies in the process whose connection owns the org.freedesktop.timedate1 bus name, regardless of which process it is.
Bus names can be used as a simple way to implement single-instance applications (second instances detect that the bus name is already taken).[17] It can also be used to track a service process lifecycle, since the bus sends a notification when a bus name is released due to a process termination.[17]
Object model[edit]
Because of its original conception as a replacement for several component oriented communications systems, D-Bus shares with its predecessors an object model in which to express the semantics of the communications between clients and services. The terms used in the D-Bus object model mimic those used by some object oriented programming languages. That does not mean that D-Bus is somehow limited to OOP languages—in fact, the most used implementation (libdbus) is written in C, a procedural programming language.
Most existing D-Bus implementations follow the architecture of the reference implementation. This architecture consists of two main components:[5]
The libdbus library (or its equivalent) internally uses a native lower-level IPC mechanism to transport the required D-Bus messages between the two processes in both ends of the D-Bus connection. D-Bus specification does not mandate which particular IPC transport mechanisms should be available to use, as it is the communications library that decides what transport methods it supports. For instance, in Unix-like operating systems such as Linux libdbus typically uses Unix domain sockets as the underlying transport method, but it also supports TCP sockets.[5][17]
The communications libraries of both processes must agree on the selected transport method and also on the particular channel used for their communication. This information is defined by what D-Bus calls an address.[6][17] Unix-domain sockets are filesystem objects, and therefore they can be identified by a filename, so a valid address would be unix:path=/tmp/.hiddensocket
.[5][16] Both processes must pass the same address to their respective communications libraries to establish the D-Bus connection between them. An address can also provide additional data to the communications library in the form of comma-separated key=value
pairs.[6][16] This way, for example, it can provide authentication information to a specific type of connection that supports it.
When a message bus daemon like dbus-daemon is used to implement a D-Bus bus, all processes that want to connect to the bus must know the bus address, the address by which a process can establish a D-Bus connection to the central message bus process.[5][17] In this scenario, the message bus daemon selects the bus address and the remainder processes must pass that value to their corresponding libdbus or equivalent libraries. dbus-daemon defines a different bus address for every bus instance it provides. These addresses are defined in the daemon's configuration files.
Two processes can use a D-Bus connection to exchange messages directly between them,[21] but this is not the way in which D-Bus is normally intended to be used. The usual way is to always use a message bus daemon (i.e. dbus-daemon) as a communications central point to which each process should establish its point-to-point D-Bus connection. When a process—client or service—sends a D-Bus message, the message bus process receives it in the first instance and delivers it to the appropriate recipient. The message bus daemon may be seen as a hub or router in charge of getting each message to its destination by repeating it through the D-Bus connection to the recipient process.[17] The recipient process is determined by the destination bus name in the message's header field,[16] or by the subscription information to signals maintained by the message bus daemon in the case of signal propagation messages.[6] The message bus daemon can also produce its own messages as a response to certain conditions, such as an error message to a process that sent a message to a nonexistent bus name.[17]
dbus-daemon improves the feature set already provided by D-Bus itself with additional functionality. For example, service activation allows automatic starting of services when needed—when the first request to any bus name of such service arrives at the message bus daemon.[5] This way, service processes neither need to be launched during the system initialization or user initialization stage nor need they consume memory or other resources when not being used. This feature was originally implemented using setuid helpers,[22] but nowadays it can also be provided by systemd's service activation framework. Service activation is an important feature that facilitates the management of the process lifecycle of services (for example when a desktop component should start or stop).[17]
Implementations[edit]
libdbus[edit]
Although there are several implementations of D-Bus, the most widely used is the reference implementation libdbus, developed by the same freedesktop.org project that designed the specification. However, libdbus is a low-level implementation that was never meant to be used directly by application developers, but as a reference guide for other reimplementations of D-Bus (such as those included in standard libraries of desktop environments, or in programming language bindings). The freedesktop.org project itself recommends applications authors to "use one of the higher level bindings or implementations" instead.[28] The predominance of libdbus as the most used D-Bus implementation caused the terms "D-Bus" and "libdbus" to be often used interchangeably, leading to confusion.
GDBus[edit]
GDBus[9] is an implementation of D-Bus based on GIO streams included in GLib, aiming to be used by GTK+ and GNOME. GDBus is not a wrapper of libdbus, but a complete and independent reimplementation of the D-Bus specification and protocol.[29] MATE Desktop[30] and Xfce (version 4.14), which are also based on GTK+ 3, also use GDBus.
sd-bus[edit]
In 2013, the systemd project rewrote libdbus in an effort to simplify the code,[31] but it also resulted in a significant increase of the overall D-Bus performance. In preliminary benchmarks, BMW found that the systemd's D-Bus library increased performance by 360%.[32] By version 221 of systemd, the sd-bus API was declared stable.[33]