[Spice-devel] [PATCH linux vdagent] Bug62033: export ConnectionInfo interface of vdagent via D-Bus
Fedor Lyakhov
fedor.lyakhov at gmail.com
Mon Dec 30 14:14:44 PST 2013
This is RFC/preview-only patch - initial work of adding D-Bus
interface for vdagent.
---
Makefile.am | 12 +++--
configure.ac | 3 +-
src/vdagent-dbus.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/vdagent-dbus.h | 27 ++++++++++++
src/vdagent.c | 30 +++++++++++++
5 files changed, 194 insertions(+), 4 deletions(-)
create mode 100644 src/vdagent-dbus.c
create mode 100644 src/vdagent-dbus.h
diff --git a/Makefile.am b/Makefile.am
index 74cc313..c61a0dd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,9 +4,14 @@ NULL =
bin_PROGRAMS = src/spice-vdagent
sbin_PROGRAMS = src/spice-vdagentd
-src_spice_vdagent_CFLAGS = $(X_CFLAGS) $(SPICE_CFLAGS) $(GLIB2_CFLAGS)
-src_spice_vdagent_LDADD = $(X_LIBS) $(SPICE_LIBS) $(GLIB2_LIBS)
-src_spice_vdagent_SOURCES = src/vdagent.c src/vdagent-x11.c
src/vdagent-x11-randr.c src/vdagent-file-xfers.c src/udscs.c
+src_spice_vdagent_CFLAGS = $(X_CFLAGS) $(SPICE_CFLAGS)
$(GLIB2_CFLAGS) ${GIO2_CFLAGS}
+src_spice_vdagent_LDADD = $(X_LIBS) $(SPICE_LIBS) $(GLIB2_LIBS) ${GIO2_LIBS}
+src_spice_vdagent_SOURCES = src/vdagent.c \
+ src/vdagent-x11.c \
+ src/vdagent-x11-randr.c \
+ src/vdagent-file-xfers.c \
+ src/udscs.c \
+ src/vdagent-dbus.c
src_spice_vdagentd_CFLAGS = $(DBUS_CFLAGS) $(LIBSYSTEMD_LOGIN_CFLAGS) \
$(PCIACCESS_CFLAGS) $(SPICE_CFLAGS) $(GLIB2_CFLAGS) $(PIE_CFLAGS)
@@ -34,6 +39,7 @@ noinst_HEADERS = src/glib-compat.h \
src/vdagent-virtio-port.h \
src/vdagent-x11.h \
src/vdagent-x11-priv.h \
+ src/vdagent-dbus.h \
src/vdagentd-proto.h \
src/vdagentd-proto-strings.h \
src/vdagentd-uinput.h \
diff --git a/configure.ac b/configure.ac
index 79905a8..2d98c43 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,7 +76,8 @@ AC_ARG_ENABLE([static-uinput],
[enable_static_uinput="$enableval"],
[enable_static_uinput="no"])
-PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.12])
+PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.26])
+PKG_CHECK_MODULES([GIO2], [gio-2.0 >= 2.26])
PKG_CHECK_MODULES(X, [xfixes xrandr >= 1.3 xinerama x11])
PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.5])
diff --git a/src/vdagent-dbus.c b/src/vdagent-dbus.c
new file mode 100644
index 0000000..47f1d31
--- /dev/null
+++ b/src/vdagent-dbus.c
@@ -0,0 +1,126 @@
+/* vdagent-dbus.c vdagent dbus interface
+
+ Copyright 2013 Fedor Lyakhov
+
+ Authors:
+ Fedor Lyakhov <fedor.lyakhov at gmail.com>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <syslog.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <spice/vd_agent.h>
+#include "vdagent-dbus.h"
+
+static const char *vdagent_dbus_name = "com.redhat.spice.vdagent";
+static guint vdagent_dbus_name_owner_id = 0;
+static const char *vdagent_dbus_connection_info_object_path =
+ "/com/redhat/spice/vdagent/ConnectionInfo";
+
+/* Introspection data for vdagent service */
+/* TODO: document the interface */
+static const gchar *vdagent_dbus_introspection_xml =
+ "<node>"
+ " <interface name='com.redhat.spice.vdagent.ConnectionInfo'>"
+ " <property type='b' name='Connected' access='read' />"
+ " <property type='s' name='Type' access='read' />" /* local, remote */
+ " <property type='u' name='Speed' access='read' />" /* In kbps,
e.g. 512K, 1024K = 1M etc. */
+ " </interface>"
+ "</node>";
+
+static GDBusNodeInfo *vdagent_dbus_introspection_data = NULL;
+
+static GVariant *vdagent_dbus_handle_get_property(GDBusConnection
*connection, const gchar *sender,
+ const gchar *object_path, const gchar *interface_name, const
gchar *property_name,
+ GError **error, gpointer user_data)
+{
+ GVariant *ret = NULL;
+
+ syslog(LOG_DEBUG, "Handling D-Bus get property");
+
+ /* TODO: implement actual handlers */
+ if (g_strcmp0(property_name, "Connected") == 0)
+ {
+ ret = g_variant_new_boolean(TRUE);
+ }
+ else if (g_strcmp0 (property_name, "Type") == 0)
+ {
+ ret = g_variant_new_string("remote");
+ }
+ else if (g_strcmp0 (property_name, "Speed") == 0)
+ {
+ ret = g_variant_new_uint32(512);
+ }
+ return ret;
+}
+
+static const GDBusInterfaceVTable vdagent_dbus_interface_vtable =
+{
+ NULL,
+ vdagent_dbus_handle_get_property, /* Only handling getters now */
+ NULL
+};
+
+static void vdagent_dbus_handle_bus_acquired(GDBusConnection *connection,
+ const gchar *name, gpointer user_data)
+{
+ guint registration_id;
+
+ syslog(LOG_DEBUG, "Acquired connection to session bus");
+ registration_id = g_dbus_connection_register_object(connection,
+ vdagent_dbus_connection_info_object_path,
vdagent_dbus_introspection_data->interfaces[0],
+ &vdagent_dbus_interface_vtable, NULL, NULL, NULL);
+ /* TODO: handle GError in case of registration failure */
+ g_assert(registration_id > 0);
+}
+
+static void vdagent_dbus_handle_name_acquired(GDBusConnection *connection,
+ const gchar *name, gpointer user_data)
+{
+ syslog(LOG_DEBUG, "Acquired the name %s on the session bus", name);
+}
+
+static void vdagent_dbus_handle_bus_name_lost(GDBusConnection *connection,
+ const gchar *name, gpointer user_data)
+{
+ if (!connection)
+ {
+ syslog(LOG_ERR, "Failed to acquire connection to session bus");
+ return;
+ }
+ syslog(LOG_DEBUG, "Lost the name %s on the session bus", name);
+}
+
+int vdagent_dbus_init()
+{
+ vdagent_dbus_introspection_data =
g_dbus_node_info_new_for_xml(vdagent_dbus_introspection_xml,
+ NULL);
+ /* TODO: handle GError in case of generation failure */
+ g_assert(vdagent_dbus_introspection_data != NULL);
+
+ vdagent_dbus_name_owner_id = g_bus_own_name(G_BUS_TYPE_SESSION,
vdagent_dbus_name,
+ G_BUS_NAME_OWNER_FLAGS_NONE, vdagent_dbus_handle_bus_acquired,
+ vdagent_dbus_handle_name_acquired,
vdagent_dbus_handle_bus_name_lost, NULL, NULL);
+ return (vdagent_dbus_name_owner_id > 0);
+}
+
+void vdagent_dbus_cleanup()
+{
+ g_bus_unown_name(vdagent_dbus_name_owner_id);
+ g_dbus_node_info_unref(vdagent_dbus_introspection_data);
+}
diff --git a/src/vdagent-dbus.h b/src/vdagent-dbus.h
new file mode 100644
index 0000000..7bbc66a
--- /dev/null
+++ b/src/vdagent-dbus.h
@@ -0,0 +1,27 @@
+/* vdagent-dbus.h vdagent dbus code header file
+
+ Copyright 2013 Fedor Lyakhov
+
+ Authors:
+ Fedor Lyakhov <fedor.lyakhov at gmail.com>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __VDAGENT_DBUS_H
+#define __VDAGENT_DBUS_H
+
+int vdagent_dbus_init();
+void vdagent_dbus_cleanup();
+
+#endif
diff --git a/src/vdagent.c b/src/vdagent.c
index d7f7aba..beeb756 100644
--- a/src/vdagent.c
+++ b/src/vdagent.c
@@ -35,12 +35,14 @@
#include <sys/stat.h>
#include <spice/vd_agent.h>
#include <glib.h>
+#include <gio/gio.h>
#include "udscs.h"
#include "vdagentd-proto.h"
#include "vdagentd-proto-strings.h"
#include "vdagent-x11.h"
#include "vdagent-file-xfers.h"
+#include "vdagent-dbus.h"
static const char *portdev = "/dev/virtio-ports/com.redhat.spice.0";
static const char *vdagentd_socket = VDAGENTD_SOCKET;
@@ -52,6 +54,7 @@ static struct vdagent_file_xfers *vdagent_file_xfers = NULL;
static struct udscs_connection *client = NULL;
static int quit = 0;
static int version_mismatch = 0;
+static GMainLoop *loop = NULL;
void daemon_read_complete(struct udscs_connection **connp,
struct udscs_message_header *header, uint8_t *data)
@@ -177,6 +180,14 @@ static int file_test(const char *path)
return stat(path, &buffer);
}
+static gpointer thread_func_loop(gpointer data)
+{
+ syslog(LOG_INFO, "Loop thread func entered");
+ loop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(loop);
+ return NULL;
+}
+
int main(int argc, char *argv[])
{
fd_set readfds, writefds;
@@ -184,6 +195,7 @@ int main(int argc, char *argv[])
int do_daemonize = 1;
int x11_sync = 0;
struct sigaction act;
+ GThread *thread_loop = NULL;
for (;;) {
if (-1 == (c = getopt(argc, argv, "-dxhys:f:o:S:")))
@@ -238,6 +250,21 @@ int main(int argc, char *argv[])
if (do_daemonize)
daemonize();
+ g_type_init();
+
+ /* TODO: use g_thread_create for GIO < 2.32, g_thread_new for GIO
>= 2.32 */
+ thread_loop = g_thread_new("Loop", thread_func_loop, NULL);
+ if (thread_loop == NULL)
+ {
+ syslog(LOG_ERR, "Failed to create loop thread");
+ return 1;
+ }
+
+ if (!vdagent_dbus_init()) {
+ syslog(LOG_ERR, "Failed to own DBus name");
+ return 1;
+ }
+
reconnect:
if (version_mismatch) {
syslog(LOG_INFO, "Version mismatch, restarting");
@@ -304,5 +331,8 @@ reconnect:
if (!quit && do_daemonize)
goto reconnect;
+ g_main_loop_quit(loop);
+ g_thread_join(thread_loop);
+ vdagent_dbus_cleanup();
return 0;
}
--
1.8.1.4
More information about the Spice-devel
mailing list