GLT 2025

Submission

systemd’s D-Bus Implementation, And Its Python asyncio Binding

Abstract

An overview of D-Bus, systemd, and systemd’s own D-Bus implementation, sd-bus. Less slide show, more live coding in Python and asyncio.

Description

D-Bus is a broker-based interprocess communication mechanism which has been used for ages in Linux’s desktop environments like GNOME or KDE.

systemd, the Linux init system and service manager, likewise consists of many loosely coupled components. Since systemd’s inception, likewise, its components are using D-Bus to communicate.

Over time, the systemd developers have become uncomfortable with the existing D-Bus implementation they were using. They created another implementation, sd-bus, tailored towards systemd’s needs - minimal and fast.

This talk gives an overview of D-Bus and its concepts, and then shows how sd-bus is used to implement one’s own interfaces and components. Out of its many language bindings, we will use Python to implement a use case, just to show how simple this is.

You will probably like the use of asyncio in the talk. For those of you who don’t know what this is and what problems it solves, I’ll try to explain, however hard that may be.

Talk Concept

  • incoming AF_UNIX dgrams

    • v1: single receiving socket

      #!/usr/bin/env python
      
      import socket
      
      
      sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
      
      while True:
          msg = input('message (utf-8 please): ')
          sock.sendto(msg.encode(encoding='utf-8'), '/tmp/incoming')
      
      #!/usr/bin/env python
      
      import socket
      
      
      sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
      sock.bind('/tmp/incoming')
      
      while True:
          print(sock.recv(1024))
      
      # socket.fileno()
      
    • v2: multiple receiving sockets

      #!/usr/bin/env python
      
      import socket, sys
      
      sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
      
      while True:
          msg = input('message (utf-8 please): ')
          sock.sendto(msg.encode(encoding='utf-8'), sys.argv[1])
      
      #!/usr/bin/env python
      
      import socket, sys, threading
      
      sockets = []
      for name in sys.argv[1:]:
          sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
          sock.bind(name)
          sockets.append(sock)
      
      def server(sock):
          while True:
              print(sock.recv(1024))
      
      threads = []
      for _ in sockets:
          th = threading.thread(server, (sock,))
          th.run()
          threads.append(th)
      
      for th in threads:
          th.join()
      

    imagine other data sources …

    • CAN socket jjj link

    • GPIO interrupt

    • any kind of events

  • event loop programming

    asyncio intro: add second incoming-socket -> second task -> strace -f

  • dbus server

    • method: get incoming (list, because multiple) -> setup graph

    • setup chart plot

    • animation?

  • hmm

    • Example from python-sdbus

    • Project

      • gpiod interrupt, and asyncio

      • dbus server emits sdbus signal

      • dbus client iterates over it in a task