Что такое Dbus

Если вы достаточно давно пользуетесь операционной системой Linux, то, наверное, уже не раз слышали о сервисе DBus. Он фигурирует в различных логах программ, инструкциях по настройке системы, а также вы можете видеть сервис DBus-daemon, который непонятно зачем загружается при старте системы.

В этой статье мы попытаемся разобраться, что такое DBus, зачем он нужен, а также как его можно использовать для эффективного управления приложениями в системе.

Что такое Dbus?

Dbus или Desktop Bus — это система, которая используется в основном в операционной системе Linux для того, чтобы различные приложения и сервисы могли общаться между собой. Но с помощью Dbus могут взаимодействовать не только приложения, но и пользователи с приложениями.

По сути, DBus состоит из управляющего демона, API для языков программирования, с помощью которых приложения могут взаимодействовать с системой и консольного клиента.

Каждое приложение, которое хочет работать с DBus, должно зарегистрировать свой сервис в демоне DBus. Поскольку все приложения и сервисы могут беспрепятственно обмениваться сообщениями, этот способ еще называется шина DBus. На шине каждое приложение имеет свой адрес, а каждое сообщение имеет своего отправителя и адресата. Приложение может обмениваться сообщениями даже не с одним, а несколькими приложениями одновременно. Каждое приложение может отправлять сообщения и прослушивать входящие.

Этот механизм дает системе огромную гибкость, например, программы могут подписываться на сообщения о подключении новых устройств, изменении настроек, изменении состояния системы и многое другое. Все это с помощью стандартизированного интерфейса DBus, что гарантирует совместимость. Также программы могут регистрировать свои сервисы таким образом, чтобы программа запускалась только при поступлении сообщений и не работала в фоне.

Обычно Dbus создает две шины или области, в которых программы могут обмениваться сообщениями. Это системная шина — для системных сервисов. Ее главная задача — доставка сообщений об изменении состояния оборудования. Вторая шина сессионная, создается отдельно для каждого пользователя и позволяет приложениям, запущенным от его имени взаимодействовать между собой.

Объекты Dbus

Каждое приложение, которое использует Dbus, регистрирует свой объект, а также может регистрировать несколько интерфейсов. Когда объекту отправляется сообщение, его получает и приложение. У каждого объекта уникальное имя. Оно похоже на путь в файловой системе. Чтобы имя каждого объекта было уникальным в нем используется префикс разработчика, например, /org/kde или /com/redhat.

Путь объекта DBus состоит из трех частей:

  • Имя сервиса;
  • Имя объекта;

Несколько примеров объектов:

  • org.freedesktop.NetworkManager
  • org.freedesktop.UDisks
  • org.freedesktop.DisplayManager
  • org.kde.plasmashell

Части имени объектов разделены точкой. Каждый объект имеет один или несколько интерфейсов, которым можно отправлять сообщения.

Интерфейсы имеют очень похожий путь на путь объекта, в некоторых случаях, имя интерфейса совпадает с  именем объекта, но если интерфейсов несколько, то они могут отличаться. В отличие от объекта имя интерфейса разделено слэшем. Вот несколько примеров имен интерфейсов, в скобках я привел объекты, в которых есть эти интерфейсы:

  • /org/mpris/MediaPlayer2/Player (org.mpris.MediaPlayer2.VLC)
  • /org/PluseAudio/ServerLookup1 (org.PluseAudio1)

 

Сообщения Dbus

Сообщения Dbus это тоже довольно сложная тема. Они бывают четырех разных типов. Это вызовы методов, результаты вызовов, сигналы и ошибки. Dbus проектировался для использования в первую очередь в программах, поэтому и были реализованы такие сложные структуры. Когда осуществляется вызов метода, программа должна обработать данные и потом в ответном сообщении вернуть результат (результат выполнения) или ошибку.

Доступные объекты Dbus

Большинство доступных объектов Dbus описаны на сайте freedesktop.org. Но лучший способ узнать какие сервисы поддерживает система — это воспользоваться программой qdbusviewer. В окружении рабочего стола kde она поставляется по умолчанию, в Gnome и других ее можно установить из пакета qttools5-dev-tools:

sudo apt install qttools5-dev-tools

Запустив программу через главное меню вы увидите вот такое главное окно:

dbus

Здесь вы можете увидеть на левой панели список доступных объектов, на правой — пути к интерфейсу внутри объекта и методы. Внизу консоль, в которую выводится информация об успешности ваших действий.

В программе, как и положено, есть две шины, сессионная и системная. К каждой из них вы можете получить доступ. С помощью программы даже можно отсылать сообщения вызывая методы и меняя свойства. Но это не совсем правильный способ. Как пользоваться Dbus мы рассмотрим ниже.

Как использовать Dbus?

Обращаться к сервисам Dbus можно с помощью консольной утилиты dbus-send. Рассмотрим ее синтаксис:

$ dbus-send опции —dest адрес_объекта интерфейс метод параметры

  • опции — настраивают общее поведение утилиты;
  • адрес_объекта — объект, которому мы собираемся отправлять сообщение;
  • интерфейс — интерфейс объекта, который получит сообщение;
  • метод — метод интерфейса, который будет вызван, или сигнал;
  • параметры — дополнительные параметры, если они нужны.

Рассмотрим опции утилиты:

  • —system — использовать системную шину для отправки сообщений;
  • —session — использовать сессионную шину;
  • —dest — объект, которому будет отправлено сообщение;
  • —print-reply — напечатать ответ;
  • —reply-timeout — таймаут ожидания ответа;
  • —type — тип сообщения, может быть signal, method_call, error, method_result.

Таким образом, когда выполняется запрос, скажем method_call утилита отправляет сообщение указанному нами объекту, затем ждет от него ответа, ответ приходит сообщением method_result, и если было указанно, что ответ нужно вывести на экран, он будет выведен. Все поля нужно заполнять полностью, полный путь объекта, полное имя интерфейса и полное имя метода, включая имя интерфейса.

Вы уже знаете, как и где искать нужные вам интерфейсы, а теперь рассмотрим пару примеров отправки сообщений Dbus.

Получаем список сетевых адаптеров NetworkManager:

  dbus-send --system --print-reply --reply-timeout=120000 --type=method_call --dest='org.freedesktop.NetworkManager' '/org/freedesktop/NetworkManager' org.freedesktop.NetworkManager.GetDevices

Что здесь происходит? Мы сообщаем программе, что хотим видеть ответ, тип сообщения — вызов метода, объект org.freedesktop.NetworkManager, интерфейс /org/freedesktop/NetworkManager, и метод org.freedesktop.NetworkManager.GetDevices

Включим музыку в плеере VLC:

dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Play

Поставим на паузу:

dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Pause

Здесь org.mpris.MediaPlayer2.vlc — объект, интерфейс — /org/mpris/MediaPlayer2, метод — org.mpris.MediaPlayer2.Player.Pause

Методы могут получать параметры, например, перемотаем наш трек на несколько секунд:

dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Seek int64:10000000

Узнать тип переменной можно тоже с помощью qdbusviewer. Кликните по методу правой кнопкой и выберите Call, в открывшемся диалоговом окне будет предложено ввести значение переменной, а также указан ее тип.

Кроме методов, здесь есть переменные. Понять с чем мы имеем дело, методом или переменной можно тоже с помощью qdbusviewer. Для методов будет написано method, для переменных property. Но посмотреть значение переменной не так просто, для этого используется такая конструкция:

dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:org.mpris.MediaPlayer2.Player string:Volume

Вместо того чтобы обратиться напрямую к переменной интерфейса, мы используем метод org.freedesktop.DBus.Properties.Get объекта /org/mpris/MediaPlayer2 и передаем ему две строки. Имя интерфейса и имя переменной. Данный пример показывает, как посмотреть текущую громкость VLC.

Установить значение переменной еще сложнее. Для этого используется метод org.freedesktop.DBus.Properties.Set:

dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set string:org.mpris.MediaPlayer2.Player string:Volume variant:double:1.1

Пример изменяет громкость воспроизведения VLC. Этот метод принимает уже три параметра две уже знакомые нам строки и новое значение переменной. Значение переменной имеет тип variant и ему нужно задать нужный тип переменной, в нашем случае нужна double. Посмотреть какой тип переменной нужен вам можно в qdbusviewer, кликните по переменной правой кнопкой мыши и нажмите Set Value. Здесь кроме поля ввода значения вы увидите нужный тип переменной.

Выводы

Теперь вы знаете не только что такое Dbus, но и все необходимые основы, чтобы использование Dbus было для вас достаточно простым в вашей системе и вы могли применять его на полную для управления своими программами. Нашли интересную команду Dbus, которая будет полезна другим пользователям? Напишите в комментариях!



2016-08-04T19:59:42
Информация