[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