[ostree] core: A bit more daemon work



commit 2bee1bbbdfc12986d839c7be9a72da4bca47b0ad
Author: Colin Walters <walters verbum org>
Date:   Tue Nov 22 10:02:49 2011 -0500

    core: A bit more daemon work

 Makefile-daemon.am               |    2 +-
 src/daemon/{main.c => ostreed.c} |    0
 src/daemon/ot-daemon.c           |  170 +++++++++++++++++++++++++++++++++++--
 src/daemon/ot-daemon.h           |   17 ++++
 4 files changed, 178 insertions(+), 11 deletions(-)
---
diff --git a/Makefile-daemon.am b/Makefile-daemon.am
index 898e2f9..c1d21e9 100644
--- a/Makefile-daemon.am
+++ b/Makefile-daemon.am
@@ -19,7 +19,7 @@
 
 libexec_PROGRAMS += ostreed
 
-ostreed_SOURCES = src/daemon/main.c \
+ostreed_SOURCES = src/daemon/ostreed.c \
 	src/daemon/ot-daemon.h \
 	src/daemon/ot-daemon.c \
 	$(NULL)
diff --git a/src/daemon/main.c b/src/daemon/ostreed.c
similarity index 100%
rename from src/daemon/main.c
rename to src/daemon/ostreed.c
diff --git a/src/daemon/ot-daemon.c b/src/daemon/ot-daemon.c
index cb3e275..d7793b7 100644
--- a/src/daemon/ot-daemon.c
+++ b/src/daemon/ot-daemon.c
@@ -51,12 +51,143 @@ static const gchar introspection_xml[] =
   "      <arg type='s' name='revision' direction='in'/>"
   "      <arg type='u' name='op_id' direction='out'/>"
   "    </method>"
-  "    <method name='OverlayTar'>"
-  "      <arg type='s' name='filename' direction='in'/>"
+  "    <method name='Overlay'>"
+  "      <arg type='s' name='dir' direction='in'/>"
   "      <arg type='u' name='op_id' direction='out'/>"
   "    </method>"
+  "    <method name='Diff'>"
+  "      <arg type='s' name='dir' direction='in'/>"
+  "      <arg type='h' name='handle' direction='out'/>"
+  "    </method>"
+  "    <signal name='OperationEnded'>"
+  "      <arg type='u' name='op_id' />"
+  "      <arg type='b' name='successful' />"
+  "      <arg type='s' name='result_str' />"
+  "    </signal>"
   "  </interface>"
   "</node>";
+
+static void
+operation_new (OstreeDaemon            *self,
+               const char              *sender,
+               guint                  *out_id,
+               OstreeDaemonOperation **out_op)
+{
+  
+  *out_id = ++self->op_id;
+  *out_op = g_new0 (OstreeDaemonOperation, 1);
+  (*out_op)->requestor_dbus_name = g_strdup (sender);
+  (*out_op)->cancellable = g_cancellable_new ();
+}
+
+static void
+operation_free (OstreeDaemonOperation   *op)
+{
+  g_free (op->requestor_dbus_name);
+  g_object_unref (op->cancellable);
+  g_free (op);
+}
+
+static gboolean
+op_return (OstreeDaemon          *self,
+           OstreeDaemonOperation *op,
+           GError                *error_return)
+{
+  gboolean ret = FALSE;
+  GVariant *args = NULL;
+
+  g_hash_table_remove (self->ops, GUINT_TO_POINTER (op->id));
+
+  if (error_return)
+    args = g_variant_new ("(ubs)", op->id, FALSE, error_return->message);
+  else
+    args = g_variant_new ("(ubs)", op->id, TRUE, "Success");
+
+  g_dbus_connection_emit_signal (self->bus,
+                                 op->requestor_dbus_name,
+                                 OSTREE_DAEMON_PATH,
+                                 OSTREE_DAEMON_IFACE,
+                                 "OperationEnded",
+                                 args,
+                                 NULL);
+
+  ret = TRUE;
+  operation_free (op);
+  if (args)
+    g_variant_unref (args);
+  return ret;
+}
+
+typedef struct {
+  OstreeDaemonOperation *op;
+  GFile *dir;
+} OverlayDirThreadData;
+
+typedef struct {
+  OverlayDirThreadData *tdata;
+  GError *error;
+} OverlayDirEmitInIdleData;
+
+static gboolean
+overlay_dir_emit_in_idle (gpointer data)
+{
+  OverlayDirEmitInIdleData *idledata = data;
+
+  op_return (idledata->tdata->op->daemon,
+             idledata->tdata->op,
+             idledata->error);
+             
+  g_free (idledata);
+  
+  return FALSE;
+}
+
+static gpointer
+overlay_dir_thread (gpointer data)
+{
+  OverlayDirThreadData *tdata = data;
+  GMainContext *context = NULL;
+  GFile *sysroot_f = NULL;
+  OverlayDirEmitInIdleData *idledata = g_new0 (OverlayDirEmitInIdleData, 1);
+ 
+  idledata->tdata = tdata;
+
+  context = g_main_context_new ();
+
+  sysroot_f = ot_gfile_new_for_path ("/sysroot/ostree/current");
+
+  g_main_context_push_thread_default (context);
+
+  (void)ot_gfile_merge_dirs (sysroot_f,
+                             tdata->dir,
+                             tdata->op->cancellable,
+                             &(idledata->error));
+  g_idle_add (overlay_dir_emit_in_idle, idledata);
+  
+  g_main_context_pop_thread_default (context);
+
+  g_main_context_unref (context);
+
+  g_clear_object (&tdata->dir);
+  g_free (tdata);
+  
+  return NULL;
+}
+
+static void
+do_op_overlay (OstreeDaemon            *self,
+               const char              *dir,
+               OstreeDaemonOperation   *op)
+{
+  OverlayDirThreadData *tdata = g_new0 (OverlayDirThreadData, 1);
+  
+  tdata->op = op;
+  tdata->dir = ot_gfile_new_for_path (dir);
+
+  g_thread_create_full (overlay_dir_thread, tdata, 0, FALSE, FALSE,
+                        G_THREAD_PRIORITY_NORMAL, NULL);
+}
+
 static void
 handle_method_call (GDBusConnection       *connection,
                     const gchar           *sender,
@@ -67,6 +198,23 @@ handle_method_call (GDBusConnection       *connection,
                     GDBusMethodInvocation *invocation,
                     gpointer               user_data)
 {
+  OstreeDaemon *self = user_data;
+  guint32 op_id;
+  OstreeDaemonOperation *op;
+
+  if (g_strcmp0 (method_name, "Overlay") == 0)
+    {
+      const gchar *dirpath;
+
+      g_variant_get (parameters, "(&s)", &dirpath);
+
+      operation_new (self, sender, &op_id, &op);
+
+      do_op_overlay (self, dirpath, op);
+
+      g_dbus_method_invocation_return_value (invocation,
+                                             g_variant_new ("(u)", op_id));
+    }
 }
 
 static const GDBusInterfaceVTable interface_vtable =
@@ -81,10 +229,13 @@ on_bus_acquired (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
 {
+  OstreeDaemon *self = user_data;
   guint id;
 
+  self->bus = g_object_ref (connection);
+
   id = g_dbus_connection_register_object (connection,
-                                          "/org/gnome/OSTree",
+                                          OSTREE_DAEMON_PATH,
                                           introspection_data->interfaces[0],
                                           &interface_vtable,
                                           NULL,  /* user_data */
@@ -98,11 +249,11 @@ on_name_acquired (GDBusConnection *connection,
                   const gchar     *name,
                   gpointer         user_data)
 {
-  OstreeDaemon *daemon = user_data;
+  OstreeDaemon *self = user_data;
   GError *error = NULL;
 
-  daemon->repo = ostree_repo_new ("/sysroot/ostree/repo");
-  if (!ostree_repo_check (daemon->repo, &error))
+  self->repo = ostree_repo_new ("/sysroot/ostree/repo");
+  if (!ostree_repo_check (self->repo, &error))
     {
       g_printerr ("%s\n", error->message);
       g_clear_error (&error);
@@ -118,7 +269,6 @@ on_name_lost (GDBusConnection *connection,
   exit (1);
 }
 
-
 OstreeDaemon *
 ostree_daemon_new (void)
 {
@@ -126,10 +276,8 @@ ostree_daemon_new (void)
 
   ret->loop = g_main_loop_new (NULL, TRUE);
 
-  introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
-
   ret->name_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
-                                 "org.gnome.OSTree",
+                                 OSTREE_DAEMON_NAME,
                                  G_BUS_NAME_OWNER_FLAGS_NONE,
                                  on_bus_acquired,
                                  on_name_acquired,
@@ -137,6 +285,8 @@ ostree_daemon_new (void)
                                  NULL,
                                  NULL);
 
+  ret->ops = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, NULL);
+
   return ret;
 }
 
diff --git a/src/daemon/ot-daemon.h b/src/daemon/ot-daemon.h
index 4077bf1..b0d8778 100644
--- a/src/daemon/ot-daemon.h
+++ b/src/daemon/ot-daemon.h
@@ -25,15 +25,32 @@
 
 #include <gio/gio.h>
 
+#define OSTREE_DAEMON_NAME "org.gnome.OSTree"
+#define OSTREE_DAEMON_PATH "/org/gnome/OSTree"
+#define OSTREE_DAEMON_IFACE "org.gnome.OSTree"
+
 G_BEGIN_DECLS
 
 typedef struct {
   GMainLoop *loop;
   OstreeRepo  *repo;
 
+  GDBusConnection *bus;
+
   int name_id;
+
+  guint32 op_id;
+
+  GHashTable *ops;
 } OstreeDaemon;
 
+typedef struct {
+  guint32 id;
+  OstreeDaemon *daemon;
+  char *requestor_dbus_name;
+  GCancellable *cancellable;
+} OstreeDaemonOperation;
+
 OstreeDaemon *ostree_daemon_new (void);
 
 G_END_DECLS



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]