dbus и KDE · 6 min read · Jan 03, 2026

Интеграция dbus и KDE: запуск и остановка сессионной части dbus с KDM.

Интеграция dbus и KDE: запуск и остановка сессионной части dbus с KDM.

Содержание

  1. Введение
  2. Настройка конфигурации KDM
  3. Запуск демона сессии dbus и доступ к переменным окружения.
    2.1 О файлах запуска Bash.
    2.2 Запуск сессионной части dbus
    2.3 Остановка сессионной части dbus
    2.4 Один пользователь вошел более одного раза

0. Введение

С некоторых пор многие приложения используют D-BUS. Это касается KDE 3.5, текущей стабильной версии KDE. С предстоящим KDE 4 D-BUS становится все более важным, заменяя DCOP.

В этом руководстве я хочу описать способ запуска и остановки части dbus, зависящей от пользователя и сессии. Основные цели, которые я преследую с этим подходом, следующие:

  • сделать доступными переменные окружения, важные для приложений, работающих с d-bus;
  • убедиться, что сессионная часть dbus не запускается более одного раза для одного пользователя;
  • убедиться, что сессионная часть dbus останавливается, когда сессия пользователя заканчивается;

Я предполагаю, что пользователь входит в систему с KDM, менеджером входа для KDE 3.5. Эта конструкция также может быть использована с другими менеджерами входа (XDM, GDM).
KDM имеет возможность запускать скрипты в начале сессии (при запуске) и в конце (сброс). Один из них может запускать (и останавливать) сессионную часть dbus.

1. KDM: файлы

KDM использует несколько файлов для запуска и остановки:

. Xstartup
запускается от имени root после успешного входа пользователя.

. Xsession
работает с правами авторизованного пользователя, чтобы запустить желаемую сессию (KDE).

. Xreset
запускается от имени root после завершения сессии пользователя.

Где Xstartup — это место для запуска процессов, Xreset — это место для отмены этих команд.

Для получения дополнительной информации об этих файлах смотрите справочник KDM.

Добавив следующий код в файл Xstartup:

-- snip --
for script in /etc/session.d/kdm/startup/*.sh; do
    if [ -x $script ]; then
        eval $script $USER kdm
    fi;
done;

и код в файл Xreset:

-- snip --
for script in /etc/session.d/kdm/reset/*.sh; do
    if [ -x $script ]; then
        eval $script $USER kdm
    fi;
done;

Создайте директории, куда будут помещены скрипты:

install -m755 -d /etc/session.d/kdm/startup  
install -m755 -d /etc/session.d/kdm/reset  
install -m755 -d /etc/session.d/scripts/start  
install -m755 -d /etc/session.d/scripts/stop

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

Каждый пользователь должен иметь возможность выполнять скрипт, но только root может их изменять.

1. Запуск демона сессии dbus и доступ к переменным окружения

Пакет dbus разделен на две части: одна системная часть и одна для (каждой) сессии/пользователя. Системная часть (демон) запускается при загрузке с особыми привилегиями выделенного пользователя. Сессионная часть (также демон) должна быть запущена, когда начинается сессия для пользователя, и остановлена, когда сессия заканчивается.

Конструкция с kdm, которую я использую здесь, идеальна для этого. Один скрипт в каталоге startup для запуска демона сессии для пользователя, работающий с привилегиями этого пользователя, и один в каталоге reset, другой скрипт должен остановить этот демон.

Но это не так просто. Некоторые переменные (DBUS_SESSION_BUS_ADDRESS и DBUS_SESSION_BUS_PID) должны быть доступны в окружении для каждого приложения, которое работает с dbus. На мой взгляд, установка этих переменных должна происходить в скриптах запуска bash. Тогда, какой бы скрипт или приложение вы ни запускали, эти переменные будут установлены на правильное значение.

1.1 О файлах запуска Bash

Демон сессии dbus создает файл, который содержит переменные окружения. Как уже упоминалось, этот файл должен быть прочитан (подключен) bash, когда он запускается для этого пользователя.

Когда bash запускается через “login” как интерактивная оболочка входа, он читает /etc/profile и ~/.bash_profile. Bash также запускается через “kdm”, и файлы /etc/profile и ~/.bash_profile подключаются.

Моя идея заключается в том, чтобы сохранить вывод команды

dbus-launch --auto-syntax

в файл

$HOME/.dbus-session

Этот файл “подключается”, когда bash запускается. Это не происходит автоматически, но вам нужно добавить следующий скрипт в /etc/profile.d :

cat >> /etc/profile.d/dbus-session.sh << "EOF"
if [ -f $HOME/.dbus-session ]; then
        . $HOME/.dbus-session
fi;
EOF

Таким образом, переменные окружения становятся доступными, когда Bash запускается.

1.2 Запуск сессионной части dbus

Я предполагаю, что dbus установлен и запускается при загрузке.
Создайте скрипт в каталоге /etc/session.d/scripts/start dbus-session-start.sh:

cd /etc/session.d/scripts/start  
  
cat >> dbus-session-start.sh << "EOF"
#!/bin/bash
retcode=0;
userid=$1
userproperties=$(getent passwd | grep -m 1 -E "^$userid")
homedir=$(echo $userproperties | cut -d ":" -f 6);
gidnr=$(echo $userproperties | cut -d ":" -f 4);
uidnr=$(echo $userproperties | cut -d ":" -f 3);
if [ -d $homedir ]; then
    #
    # проверьте, запущен ли уже dbus-daemon
    # dbus-daemon должен быть запущен пользователем (uidnr), который входит в систему
    #
    
    if [ -f $homedir/.dbus-session ]; then
        # проверьте, что dbus-daemon для этого пользователя запущен с pid
        # в файле .dbus-session
 
        # pid согласно команде ps
        ps_dbus_session_pid=$(ps aux | grep -m 1 -E "^$userid.*dbus-daemon.*session.*" 
        | grep -v "grep" | sed 's@[[:space:]][[:space:]]*@ @g' | cut -d " " -f 2)
        
        # прочитайте pid из файла .dbus-session
        . $homedir/.dbus-session
        # проверьте, совпадают ли они       
        if [ -z "$ps_dbus_session_pid" ]; then
            # dbus для этого пользователя не запущен
            rm $homedir/.dbus-session
            
        elif [ $DBUS_SESSION_BUS_PID -ne $ps_dbus_session_pid ]; then
            # что-то не так: остановите dbus-daemon для этого пользователя 
            # и удалите файл .dbus-session
            if [ $(id -u) -eq 0 ]; then
                sudo -H -u $userid sh -c "kill $ps_dbus_session_pid"
            elif [ $(id -u) -eq $uidnr ]; then
                kill -SIGTERM $ps_dbus_session_pid;
            fi
            rm $homedir/.dbus-session
            
        fi
    fi  
    if [ ! -f $homedir/.dbus-session ]; then
        # запускайте сессию dbus только если файл .dbus-session не найден
        # в домашнем каталоге пользователя  
        
        if [ $(id -u) -eq 0 ]; then
            sudo -u $userid -H /bin/sh -c "dbus-launch --auto-syntax > $homedir/.dbus-session"
            retcode=$?
            chown $uidnr:$gidnr $homedir/.dbus-session
        elif [ $(id -u) -eq $uidnr ]; then 
            dbus-launch --auto-syntax > $homedir/.dbus-session
            retcode=$?
        fi
    fi
fi;
if [ $retcode -ne 0 ]; then
    echo "Ошибка с dbus ($retcode)."
fi;
exit $retcode
EOF
chmod --verbose --mode 755 /etc/session.d/scripts/start/dbus-session-start.sh  
ln -v -sf ../../scripts/start/dbus-session-start.sh /etc/session.d/kdm/startup/10dbus.sh

Этот скрипт, выполняемый KDM при запуске, запустит демон сессии dbus для этого пользователя и создаст файл .dbus-session в домашнем каталоге этого пользователя, содержащий все переменные dbus.
Он сделает это только в том случае, если dbus уже не запущен для этого пользователя.

Теперь, когда bash запускается при входе, он читает (подключает) этот файл.

Как вы видите, я разделил запуск dbus на две части:

  • dbus-session-start.sh, выполняется, когда начинается (kdm) сессия
  • .dbus-session, подключается, когда начинается (bash) сессия, может подключаться несколько раз

Кроме того, я использую параметр –auto-syntax, где предполагаю, что используется Bash. Так что я мог бы использовать здесь –sh-syntax, но это работает.

И Sudo необходим для запуска dbus-launcher от имени пользователя, который входит в систему, потому что KDM запускает этот скрипт от имени root. (на самом деле скрипт проверяет идентификатор учетной записи, выполняющей этот скрипт. Если это root (id = 0), то используется sudo для переключения на пользователя, начинающего сессию. Когда идентификатор и идентификатор пользователя, входящего в систему, совпадают, ничего делать не нужно.

2.3 Остановка сессионной части dbus

Создание скрипта dbus-session-stop.sh в каталоге сброса:

cd /etc/session.d/scripts/stop  
  
cat >> dbus-session-stop.sh << "EOF"
#!/bin/bash
retcode=0;
userid=$1
userproperties=$(getent passwd | grep -m 1 -E "^$userid")
homedir=$(echo $userproperties | cut -d ":" -f 6);
gidnr=$(echo $userproperties | cut -d ":" -f 4);
uidnr=$(echo $userproperties | cut -d ":" -f 3);
        
if [ -f $homedir/.dbus-session ]; then
        
        . $homedir/.dbus-session
        
        if [ -n "$DBUS_SESSION_BUS_PID" ]; then
                if [ $(id -u) -eq 0 ]; then
                    sudo -u $userid -H /bin/sh -c "kill $DBUS_SESSION_BUS_PID"
                    retcode=$?
                    rm $homedir/.dbus-session
                elif [ $(id -u) -eq $uidnr ]; then
                    kill $DBUS_SESSION_BUS_PID
                    retcode=$?
                    rm $homedir/.dbus-session
                fi
        
        fi
fi;
if [ $retcode -ne 0 ]; then
    echo "Ошибка с dbus ($retcode)."
fi;
exit $retcode
EOF
chmod --verbose --mode 755 dbus-session-stop.sh  
ln -v -sf ../../scripts/stop/dbus-session-stop.sh /etc/session.d/kdm/reset/90dbus.sh

Этот скрипт останавливает сессионную часть dbus-daemon.

2.4 Один пользователь вошел более одного раза

Для большинства ситуаций эта конструкция достаточно хороша. Большинство пользователей имеют одну сессию одновременно. Теперь что происходит, когда пользователь имеет более одной сессии одновременно? Необходимо ли запускать сессионную часть dbus для каждой сессии или одного экземпляра достаточно?

Эта конструкция не позволяет иметь более одного dbus-daemon на пользователя. Я думаю, что этого должно быть достаточно.

CHANGELOG:

[2006-01-18]

  • Первоначальное руководство
    [2006-07-18]
  • Изменены скрипты bash
    [2006-09-09]
  • добавлена проверка, чтобы увидеть, запущен ли dbus-daemon для этого пользователя и правильна ли информация, найденная в .dbus-session
Share: X/Twitter LinkedIn

Get new posts in your inbox

No spam. Unsubscribe anytime.