使用buidroot编译的三星九鼎创展x6818开发板文件系统,qdbus和dbus模块默认已经是配置好了的,交叉编译含qdbus会话的程序也通过,但是运行的时候注册服务和注册对象都会失败,下面记录一些解决问题笔记或者总结。
1、buidroot将dbus的一些工具配置文件等放在了哪里
执行下面命令:[root@X6818:/]# ls /usr/bin/dbus-*
/usr/bin/dbus-cleanup-sockets /usr/bin/dbus-run-session
/usr/bin/dbus-daemon /usr/bin/dbus-send
/usr/bin/dbus-launch /usr/bin/dbus-uuidgen
/usr/bin/dbus-monitor
列出的就是dbus有关的程序了,这些命令有什么作用以及如何用可以到网站https://dbus.freedesktop.org/doc/阅读相关文档。
buidroot已经做了一个开机启动dbus的脚本,存放在/etc/init.d/S30dbus,该脚本内容为:#!/bin/sh
#
# messagebus: The D-BUS systemwide message bus
#
# chkconfig: 345 97 03
# description: This is a daemon which broadcasts notifications of system event\
# and other messages. See http://www.freedesktop.org/software/dbu/
#
# processname: dbus-daemon
# pidfile: /var/run/messagebus.pid
#
# Sanity checks.
[ -x /usr/bin/dbus-daemon ] || exit 0
# Create needed directories.
[ -d /var/run/dbus ] || mkdir -p /var/run/dbus
[ -d /var/lock/subsys ] || mkdir -p /var/lock/subsys
[ -d /tmp/dbus ] || mkdir -p /tmp/dbus
RETVAL=0
start() {
echo -n "Starting system message bus: "
dbus-uuidgen --ensure
dbus-daemon --system
RETVAL=$?
echo "done"
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/dbus-daemon
}
stop() {
echo -n "Stopping system message bus: "
## we don't want to kill all the per-user $processname, we want
## to use the pid file *only*; because we use the fake nonexistent
## program name "$servicename" that should be safe-ish
killall dbus-daemon
RETVAL=$?
echo "done"
if [ $RETVAL -eq 0 ]; then
rm -f /var/lock/subsys/dbus-daemon
rm -f /var/run/messagebus.pid
fi
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status $processname
RETVAL=$?
;;
restart)
stop
start
;;
condrestart)
if [ -f /var/lock/subsys/$servicename ]; then
stop
start
fi
;;
reload)
echo "Message bus can't reload its configuration, you have to restart i"
RETVAL=$?
;;
*)
echo "Usage: $0 {start|stop|status|restart|condrestart|reload}"
;;
esac
exit $RETVAL
分析start函数,可以看到其启动了一个---system的dbus-daemon进程,并没有启动会话进程,这应该就是qdbus会话服务不能注册的原因了。
另外dbus的配置文件存放在/etc/dbus-1目录下,可以通过下面命令查看有那些配置文件,但是配置文件如何修改还未研究过。下面是查询配置文件列表的命令和结果:[root@X6818:/]# ls /etc/dbus-1/
session.conf session.d system.conf system.d
2、确定dbus-daemon运行情况
如果只有--system的dbus-daemon进程,那是不行的。使用下面命令确定有那些dbus-daeman进程:[root@X6818:/]# ps | grep dbus
正确情况会看到一个或者多个--session的dbus-daeman进程,比如:[root@X6818:/etc/dbus-1]# ps | grep dbus
197 dbus dbus-daemon --system
203 root /usr/bin/dbus-daemon --fork --print-pid 4 --print-address 6 --session
258 root /usr/bin/dbus-daemon --fork --print-pid 4 --print-address 6 --session
另外,存在--session的dbus-daeman进程不代表环境正确了,可以通过执行dbus-monitor程序看看是否会报错,以确定环境是否正确。下面是错误的情况:[root@X6818:/]# dbus-monitor
Failed to open connection to session bus: Using X11 for dbus-daemon autolaunch was disabled at compile time, set your DBUS_SESSION_BUS_ADDRESS instead
3、解决问题
实际可以通过dbus-launch创建session运行环境,执行dbus-launch会创建一个--sesion的dbus-daeman进程,并会打印出其地址和pid,这两个值每次都不一样,获得打印的值,然后通过export创建环境变量。下面命令和结果:[root@X6818:/]# dbus-launch
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-Bih1ew3oFd,guid=423e7af85f37a215609d130154a4978a
DBUS_SESSION_BUS_PID=554
[root@X6818:/]# export DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-Bih1ew3oFd,guid=423e7af85f37a215609d130154a4978a
另外我们查看文档https://dbus.freedesktop.org/doc/dbus-launch.1.html,文档中有给出了一段启动脚本,执行这段脚本会判断当前shell环境是否有DBUS_SESSION_BUS_ADDRESS环境变量,如果没有就会运行新的--session的dbus-daeman进程并设置环境变量。下面是这段脚本内容:## test for an existing bus daemon, just to be safe
if test -z "$DBUS_SESSION_BUS_ADDRESS" ; then
## if not found, launch a new one
eval `dbus-launch --sh-syntax`
echo "D-Bus per-session daemon address is: $DBUS_SESSION_BUS_ADDRESS"
fi
而我用了自己的启动脚本,但是目的是一样的,区别是我将地址和pid存放到了文件中,下面是脚本内容(没有做环境变量判断):dbus-launch | sed 's/^/export &/g' > /var/run/dbus/session.sh
source /var/run/dbus/session.sh
echo "D-Bus per-session daemon address is:$DBUS_SESSION_BUS_ADDRESS"
另外可以直接用dbus-launch启动一个对dbus session有依赖的app,app路径作为dbus-launch的参数就可以了,这种方法每次都会创建一个新--sesion的dbus-daemon进程供app使用。
4、技巧
开发板不方便开多个shell窗口,如果要用dbus-monitor监听,可以将其后台并将其运行结果保存到一个临时文件,需要查看结果的时候cat这个临时文件就可以了,比如:[root@X6818:/]# dbus-monitor > /tmp/dbus-session.log &
如果有需要,使用kill删掉进程:[root@X6818:/]# ps | grep dbus-m
749 root dbus-monitor
784 root grep dbus-m
[root@X6818:/]# kill 749
或者使用killall删掉进程:[root@X6818:/]# killall dbus-monitor