当使用gdbus-codegen生成的管理代理时,我无法接收systemd DBus信号。但是,我能够成功地通过DBus调用systemd提供的方法。
我在网上搜索并查看了这些链接,但没有取得太大的成功。在使用gdbus-codegen进行systemd API时,没有太多的示例可供参考。
- https://developer.gnome.org/gio/stable/gdbus-codegen.html
- http://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/gio/ch30s05.html
这是我做的事情以及代码片段。
1)我生成了systemd内省,并将其XML用作gdbus-codegen的输入。
...剪辑
<interface name="org.freedesktop.systemd1.Manager">
<signal name="JobRemoved">
<arg type="u"/> <arg type="o"/> <arg type="s"/> <arg type="s"/>
</signal>
2) 编写客户端代码使用由gdbus-codegen生成的C API,并创建管理器代理。(所有内容都在系统总线上运行)。
SystemdManager *systemdProxy = systemd_manager_proxy_new_for_bus_sync(
G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
"org.freedesktop.systemd1", "/org/freedesktop/systemd1",
NULL, error);
3) 定义一个信号处理程序
static void on_done(GDBusProxy *proxy,
gchar *sender_name,
gchar *signal_name,
GVariant *parameters,
gpointer user_data)
{
LOG_ERROR("on_done");
}
4) 为该代理连接了一个信号处理程序,用于处理JobRemoved信号。
if (g_signal_connect(systemdProxy, "job-removed",
G_CALLBACK(on_done), NULL) <= 0 )
{
LOG_ERROR("Failed to connect to signal job-removed");
}
5) 使用代理启动systemd服务。此操作返回成功,我可以看到该单元启动并运行了一两秒钟后终止。
ret = systemd_manager_call_start_unit_sync(
systemdProxy, unit_name, unit_mode, &job_obj,
NULL, &error);
6) systemd 生成 JobRemoved 信号。dbus-monitor 显示它。
signal sender=:1.0 -> dest=(null destination) serial=11931
path=/org/freedesktop/systemd1;
interface=org.freedesktop.systemd1.Manager;
member=JobRemoved
uint32 7009
object path "/org/freedesktop/systemd1/job/7009"
string "mysample.service"
string "done"
7) 我的信号处理程序从未被调用。(一切都使用系统总线,没有其他总线)。我尝试了各种字符串作为g_signal_connect
的detailed_signal
第二个参数(如:JobRemoved
,job_removed
,::job-removed
,有些被g_signal_connect
不接受)。
非常感谢您的帮助!